/***************************************************************************
*                           STAR WARS REALITY 1.0                          *
*--------------------------------------------------------------------------*
* Star Wars Reality Code Additions and changes from the Smaug Code         *
* copyright (c) 1997 by Sean Cooper                                        *
* -------------------------------------------------------------------------*
* Starwars and Starwars Names copyright(c) Lucas Film Ltd.                 *
*--------------------------------------------------------------------------*
* SMAUG 1.0 (C) 1994, 1995, 1996 by Derek Snider                           *
* SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus,                    *
* Scryn, Rennard, Swordbearer, Gorog, Grishnakh and Tricops                *
* ------------------------------------------------------------------------ *
* Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael        *
* Chastain, Michael Quan, and Mitchell Tse.                                *
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,          *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.     *
* ------------------------------------------------------------------------ *
*		            Bounty Hunter Module    			   *   
*                    (  and area capturing as well  )                      * 
****************************************************************************/

#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
/* #include <stdlib.h> */
#include <time.h>
#include "mud.h"


BOUNTY_DATA * first_bounty;
BOUNTY_DATA * last_bounty;
BOUNTY_DATA * first_disintigration;
BOUNTY_DATA * last_disintigration;


// from honour.c
void gain_honour (CHAR_DATA *ch, int hincrease);

//from clans.c
void remroster (CHAR_DATA *ch);

void   disintigration args ( ( CHAR_DATA *ch , CHAR_DATA *victim , long amount ) );
void nodisintigration args ( ( CHAR_DATA *ch , CHAR_DATA *victim , long amount ) );
int xp_compute( CHAR_DATA *ch , CHAR_DATA *victim);

void save_disintigrations()
{    
    BOUNTY_DATA *tbounty;
    FILE *fpout;
    char filename[256];
    
    sprintf( filename, "%s%s", SYSTEM_DIR, DISINTIGRATION_LIST );
    fpout = fopen( filename, "w" );
    if ( !fpout )
    {
         bug( "FATAL: cannot open disintigration.lst for writing!\n\r", 0 );
         return;
    }
    for ( tbounty = first_disintigration; tbounty; tbounty = tbounty->next )
    {
        fprintf( fpout, "%s\n", tbounty->target );
        fprintf( fpout, "%ld\n", tbounty->amount );
    }
    fprintf( fpout, "$\n" );
    fclose( fpout );    
}
                                                                    

bool is_disintigration( CHAR_DATA *victim )
{
    BOUNTY_DATA *bounty;
    
    for ( bounty = first_disintigration; bounty; bounty = bounty->next )
    if ( !str_cmp( victim->name , bounty->target ) )
             return TRUE;
    return FALSE;                           
}

BOUNTY_DATA *get_disintigration( char *target )
{
    BOUNTY_DATA *bounty;
    
    for ( bounty = first_disintigration; bounty; bounty = bounty->next )
       if ( !str_cmp( target, bounty->target ) )
         return bounty;
    return NULL;
}

void load_bounties( )
{
    FILE *fpList;
    char *target;
    char bountylist[256];
    BOUNTY_DATA *bounty;
    long int  amount;
     
    first_disintigration = NULL;
    last_disintigration	= NULL;

    log_string( "Loading disintigrations..." );

    sprintf( bountylist, "%s%s", SYSTEM_DIR, DISINTIGRATION_LIST );
    fclose( fpReserve );
    if ( ( fpList = fopen( bountylist, "r" ) ) == NULL )
    {
	perror( bountylist );
	exit( 1 );
    }

    for ( ; ; )
    {
        target = feof( fpList ) ? "$" : fread_word( fpList );
        if ( target[0] == '$' )
        break;                                  
	CREATE( bounty, BOUNTY_DATA, 1 );
        LINK( bounty, first_disintigration, last_disintigration, next, prev );
	bounty->target = STRALLOC(target);
	amount = fread_number( fpList );
	bounty->amount = amount;
    }
    fclose( fpList );
    log_string(" Done bounties " );
    fpReserve = fopen( NULL_FILE, "r" );

    return;
}

void do_bounties( CHAR_DATA *ch, char *argument )
{
    BOUNTY_DATA *bounty;
    int count = 0;
    
    set_char_color( AT_WHITE, ch );
    send_to_char( "\n\rBounty                      Amount\n\r", ch );
    for ( bounty = first_disintigration; bounty; bounty = bounty->next )
    {
        set_char_color( AT_RED, ch );
        ch_printf( ch, "%-26s %-14ld\n\r", bounty->target, bounty->amount );
        count++;
    }

    if ( !count )
    {
        set_char_color( AT_GREY, ch );
        send_to_char( "There are no bounties set at this time.\n\r", ch );
	return;
    }
}

void disintigration ( CHAR_DATA *ch , CHAR_DATA *victim , long amount )
{
    BOUNTY_DATA *bounty;
    bool found;
    char buf[MAX_STRING_LENGTH];

    found = FALSE;
    
    for ( bounty = first_disintigration; bounty; bounty = bounty->next )
    {
    	if ( !str_cmp( bounty->target , victim->name ))
    	{
    		found = TRUE;
    		break;
    	}
    }        
    
    if (! found)                                            
    {
        CREATE( bounty, BOUNTY_DATA, 1 );
        LINK( bounty, first_disintigration, last_disintigration, next, prev );
    
        bounty->target      = STRALLOC( victim->name );
        bounty->amount      = 0;
    }


/*added by shriak to prevent adding a negative bounty*/
if ((bounty->amount + amount) <= 0)
{
	sprintf(buf,"\r&RHaving that much bounty on them would\r");
	sprintf(buf,"&Rbe unnatural!\r\r");
	return;
}

/*end added by shriak*/
        

    bounty->amount      = bounty->amount + amount;
    save_disintigrations();

    sprintf( buf, "%ld credits has been added to the bounty on %s.", amount , victim->name );
    echo_to_all ( AT_RED , buf, 0 );                    
    
}

void do_addbounty( CHAR_DATA *ch, char *argument )
{
    char arg[MAX_STRING_LENGTH];
    long int amount;
    CHAR_DATA *victim;
             
    if ( !argument || argument[0] == '\0' )
    {
         do_bounties( ch , argument );
         return;
    }
    
    argument = one_argument(argument, arg);
    
    if (argument[0] == '\0' )
    {
    	send_to_char( "Usage: Addbounty <target> <amount>\n\r", ch );
    	return;
    }

    if ( ch->pcdata && ch->pcdata->clan && !str_cmp(ch->pcdata->clan->name, "Hunters-Guild"))
    {
    	send_to_char( "Your job is to collect bounties not post them.", ch );
    	return;
    }
   
/*
	commented out by shriak to make bounty's mud wide
    
    if ( !ch->in_room || ch->in_room->vnum != 6604 )
    {
    	send_to_char( "You will have to go to the Hunters Guild to add a new bounty.", ch );
    	return;
    }

*/
    
    if (argument[0] == '\0' )
        amount = 0;
    else
    	amount = atoi (argument); 

     if ( amount < 250000 && !IS_IMMORTAL(ch))
     {
    	send_to_char( "Don't waste bounty hunter's time.... 250,000 credits MINIMUM.\n\r", ch );
    	return;
    }
    
    if ( !(victim = get_char_world( ch, arg )) )
    {
        send_to_char( "They don't appear to be here .. wait til they log in.\n\r", ch );
        return;
    }

    if ( IS_NPC(victim) )
    {
    	send_to_char( "You can only set bounties on other players .. not mobs!\n\r", ch );
	return;
    }
    if ( victim->pcdata && victim->pcdata->clan && !str_cmp(victim->pcdata->clan->name, "Hunters-Guild"))
    {
        send_to_char( "Posting that bounty is a waste of time, hunters don't hunt their own.\n\r", ch);
        return;
    } 
    if (amount <= 0 && !IS_IMMORTAL(ch))
    {
        send_to_char( "Why are you bounting people? Dumbass...\n\r", ch );
        return;
    }
    
    if (ch->gold < amount && !IS_IMMORTAL(ch))
    {
    	send_to_char( "You don't have that many credits!\n\r", ch );
    	return;
    }
    
    ch->gold = ch->gold - amount;
    
    disintigration( ch, victim, amount);
}

void remove_disintigration( BOUNTY_DATA *bounty )
{
	UNLINK( bounty, first_disintigration, last_disintigration, next, prev );
	STRFREE( bounty->target );
	DISPOSE( bounty );
	
	save_disintigrations();
}

void claim_disintigration( CHAR_DATA *ch , CHAR_DATA *victim )
{
	BOUNTY_DATA *bounty;
	int hgain;
	long int     exp;
	char buf[MAX_STRING_LENGTH];

        if ( IS_NPC(victim) )
            return;

	bounty = get_disintigration( victim->name );
            
        if ( ch == victim )
        {
            if ( bounty != NULL )
               remove_disintigration(bounty);
            return;
	}

 //
 // Comnmented Out, Raijen, 9-20-01
 // Un-Commented out, Shiro 10/12/03
 // 
/*
        if (bounty && 
        (!ch->pcdata || !ch->pcdata->clan || str_cmp(ch->pcdata->clan->name, "Hunters-Guild") ) ) 
	{
	   remove_disintigration(bounty);                	
	   bounty = NULL;
	}
*/	
// **********
// End Comment Out
// **********

            log_string( "Honour Check" );
             if ( !ch->pcdata->status)
		ch->pcdata->status = 0;
             if (!victim->pcdata->status)
		victim->pcdata->status = 1;
	     if  ( ch->pcdata->status <= victim->pcdata->status + 5)
{
	if (!victim->pcdata->status) victim->pcdata->status = 1;
	hgain =   UMAX( 1, victim->pcdata->status);
	
            log_string( "Honour Gain" );
		gain_honour (ch, hgain);
}

	if (bounty == NULL)
	{
	    if ( IS_SET(victim->act , PLR_KILLER ) && !IS_NPC(ch) )
	    {
	       exp = URANGE(1, xp_compute(ch, victim) , ( exp_level(ch->skill_level[HUNTING_ABILITY]+1) - exp_level(ch->skill_level[HUNTING_ABILITY]) ));	
	       gain_exp( ch , exp , HUNTING_ABILITY );
	       set_char_color( AT_BLOOD, ch );
	       ch_printf( ch, "You receive %ld hunting experience for executing a wanted killer.\n\r", exp );
	     }
	     else if ( !IS_NPC(ch) ) 
	     {
	        SET_BIT(ch->act, PLR_KILLER );
	        ch_printf( ch, "You are now wanted for the murder of %s.\n\r", victim->name );
	     }
 
	     
	     sprintf( buf, "%s is Dead!", victim->name );
             echo_to_all ( AT_RED , buf, 0 );
	     return;
	     
	}

		
	ch->gold += bounty->amount;	
	
        exp = URANGE(1, bounty->amount + xp_compute(ch, victim) , ( exp_level(ch->skill_level[HUNTING_ABILITY]+1) - exp_level(ch->skill_level[HUNTING_ABILITY]) ));	
	gain_exp( ch , exp , HUNTING_ABILITY );
        	
	set_char_color( AT_BLOOD, ch );
	ch_printf( ch, "You receive %ld experience and %ld credits,\n\r from the bounty on %s\n\r", exp, bounty->amount, bounty->target );
	
	sprintf( buf, "%s has claimed the disintigration bounty on %s!",ch->name, victim->name );
	echo_to_all ( AT_RED , buf, 0 );
	sprintf( buf, "%s is Dead!", victim->name );
	echo_to_all ( AT_RED , buf, 0 ); 
	
	if ( !IS_SET(victim->act , PLR_KILLER ) )
	       SET_BIT(ch->act, PLR_KILLER );
	remove_disintigration(bounty);                	
}

void do_rembounty(CHAR_DATA *ch, char *argument)
{
  BOUNTY_DATA *bounty;
  char buf[MAX_STRING_LENGTH];
    
  if(IS_NPC(ch))
  { 
    ch_printf(ch, "Huh?\n\r");
    return;
  }     
        
  if(!argument || argument[0] == '\0')
  {     
    ch_printf(ch, "Syntax: rembounty <person>\n\r");
    return;
  }     

  if((bounty = get_disintigration(argument)) == NULL)
  {            
    ch_printf(ch, "No bounties on that person.\n\r");
    return;
  }     

  sprintf( buf, "%s has removed the bounty on %s.", ch->name, bounty->target );
  echo_to_all ( AT_RED , buf, 0 );
  
  remove_disintigration(bounty);
  
  return;
}

/* New Research Target, By Arcturus */
void do_researchtarget(CHAR_DATA *ch, char *argument)
{
    AFFECT_DATA af;
    CHAR_DATA *victim;
    int level, chance;
    if( argument[0] == '\0')
    {
       send_to_char("You need to choose a target.\n\r", ch);
       return;
    }
    if ( ( victim = get_char_world( ch, argument ) ) == NULL
    ||   victim == ch    
    ||   !victim->in_room
    ||  (IS_NPC(victim)) )
    {
        send_to_char( "Your target cannot be found.\n\r", ch );
        return;
    }
    if(IS_NPC(victim))
    {
        send_to_char("This skill doesn't work on NPCs.\n\r", ch);
        return;
    }
    chance = IS_NPC(ch) ? ch->top_level
           : (int) (ch->pcdata->learned[gsn_researchtarget]);
    WAIT_STATE(ch, PULSE_VIOLENCE);
    if (  number_percent() >= chance )
    {
        ch_printf(ch, "You fail to dig up dirt on %s.\n\r", NAME(victim) );
        learn_from_failure(ch, gsn_researchtarget);
        return;
    }

    if ( victim->subclass == SUBCLASS_STEALTH_HUNT || victim->subclass == SUBCLASS_SNEAK )
    {
        ch_printf(ch, "It is impossible to dig up dirt on %s.\n\r", NAME(victim));
        learn_from_success(ch, gsn_researchtarget);
        return;
    }


    if ( IS_IMMORTAL(victim) && (victim->top_level > ch->top_level ) )
    {
       af.type      = gsn_researchtarget;
       af.location  = APPLY_HITROLL;
       af.modifier  = -666;
       af.duration  = 32000;
       af.bitvector = AFF_BLIND;
       affect_to_char( ch, &af );
       set_char_color( AT_MAGIC, victim );
       send_to_char( "You are blinded by your target's immortal aura!\n\r", ch );
       return;
    }
    ch_printf(ch, "&wYour research has concluded the following information:\n\r");
    ch_printf(ch, "&wTitle: %0.74s&w\n\r", victim->pcdata->title);
    ch_printf(ch, "&wRace: %0.20s Class: %0.20s Subclass: %0.20s\n\r", npc_race[victim->race], ability_name[victim->main_ability], subclasses[victim->subclass]);
    if(victim->pcdata->clan)
        ch_printf(ch, "Affiliation: %0.20s\n\r", victim->pcdata->clan_name);
    ch_printf(ch, "Hitpoints: %5.5d/%5.5d Movement: %5.5d/%5.5d\n\r", victim->hit, victim->max_hit, victim->move, victim->max_move);
    ch_printf(ch, "Armor: %4.4d Hitroll: %5.5d Damroll: %5.5d Alignment: %4.4d", GET_AC(victim), GET_HITROLL(victim), 
        GET_DAMROLL(victim), victim->alignment);
    learn_from_success(ch, gsn_researchtarget);
    return;
}