Changing AutoGold

Posted by Rash on Tue 05 Jan 2010 07:59 PM — 7 posts, 31,541 views.

United Kingdom #0
I've recently implemented Druids Currency System perfectly and all's working well there just one
annoying thing and I can't for the life of me gear my brain up to deal with it so I'm hoping you
guy's can help point me in the right direction.

Here's the problem; With AutoGold switched on, it does 3 do_get's to recover the 3 coin types from
a corpse. Each attempt responds like below (Assuming there is no gold, 5 silver and no copper).

I see nothing like that in the corpse.
You get 5 silver coins from the corpse of the guard
I see nothing like that in the corpse.

I wish to stop it from reporting those lines concerning gold, silver and copper and replace it with:

You lift a coin purse from the corpse.
There is 0 Gold, 5 Silver and 0 Copper in the purse which you take.

I still want it to come up with the normal message's when looting gold from corpses and containers
(Treasure Chests and so on) when AutoGold is not on or is typed manually (get gold coins chest/corpse).
It's purely for AutoGold I would like the message to differ.

I know do_get use get_obj to recover the coins and add them to a player's total and I originally thought
that perhaps the answer lies there but the attempts I've tried to modify it to my needs have failed.
It's probably something simple like a couple of if/else if checks but I simply can't see it. Been staring
at it for a good 2 hour's now too, probably doesn't help.

Note: specific_damage is originally damage but I've modified the way my damage and combat flows in the mud.
So in case you was wondering why it was called that or where the damage function was, that's why.


Taken from fight.c
Function: specific_damage


/* Autogold by Scryn 8/12 */
/* Gold/Copper/Silver Support -Druid */

if ( xIS_SET(ch->act, PLR_AUTOGOLD) )
{
  init_gold = ch->gold;
  init_silver = ch->silver;
  init_copper = ch->copper;
  
  /* This is the call to do_get which then cals get_obj which causes the message to appear. */
  do_get( ch, "'gold coins' corpse" );
  do_get( ch, "'silver coins' corpse" );
  do_get( ch, "'copper coins' corpse" );
  
  new_gold = ch->gold;
  new_silver = ch->silver;
  new_copper = ch->copper;
  
  gold_diff = (new_gold - init_gold);
  silver_diff = (new_silver - init_silver);
  copper_diff = (new_copper - init_copper);
  
  /* This is what I'd rather they see then the 3 messages of getting coins or not getting coins */
  ch_printf( ch, "You lift a coin purse from the corpse.\n\r" );
  ch_printf( ch, "There is %d Gold, %d Silver and %d Copper in the purse which you take.\n\r", gold_diff, silver_diff, copper_diff );
  
  if (gold_diff > 0)
  {
    sprintf(buf1,"%d gold",gold_diff);
    do_split( ch, buf1 );
  }
  if (silver_diff > 0)
  {
    sprintf(buf1,"%d silver",silver_diff);
    do_split( ch, buf1 );
  }
  if (copper_diff > 0)
  {
    sprintf(buf1,"%d copper",copper_diff);
    do_split( ch, buf1 );
  } 
}

United Kingdom #1
(Rest of the code, ran out of room in the above post)

Taken from act_obj.c
Function: get_obj

	  if ( IS_OBJ_STAT( container, ITEM_CLANCORPSE ) && !IS_NPC( ch ) && str_cmp( container->name+7, ch->name ) )
	      container->value[5]++;
	      obj_from_obj( obj );
    }
    else
    {
        /* This is the message that appears I think */
	      act( AT_ACTION, "You get $p.", ch, obj, container, TO_CHAR );
	      act( AT_ACTION, "$n gets $p.", ch, obj, container, TO_ROOM );
	      obj_from_room( obj );
    }

    /* Clan storeroom checks */
    if ( IS_SET(ch->in_room->room_flags, ROOM_CLANSTOREROOM) && (!container || container->carried_by == NULL) )
    {
        save_clan_storeroom( ch );
    }

    if ( obj->item_type != ITEM_CONTAINER )
	      check_for_trap( ch, obj, TRAP_GET );
    if ( char_died(ch) )
	  return;

    /* Gold from containers and corpses here */
    /* Gold/Copper/Silver Support -Druid */
    if ( obj->item_type == ITEM_GOLD 
    || obj->item_type == ITEM_COPPER 
    || obj->item_type == ITEM_SILVER )
    {

        amt = obj->value[0];
        if(obj->item_type == ITEM_GOLD) ch->gold += amt;
        if(obj->item_type == ITEM_COPPER) ch->copper += amt;
        if(obj->item_type == ITEM_SILVER) ch->silver +=amt;
        extract_obj( obj ); 
    }
    else
    {
	      obj = obj_to_char( obj, ch );
    }

    

Taken from act_obj.c
Function: do_get

      /* I think this is the right call to get_obj that is used. */
      
	    for ( obj = container->first_content; obj; obj = obj_next )
	    {
		    obj_next = obj->next_content;

    		if ( ( fAll || nifty_is_name( chk, obj->name ) ) &&   can_see_obj( ch, obj ) )
		    {
		         found = TRUE;

             if ( number && (cnt + obj->count) > number )
             			split_obj( obj, number - cnt );
		              cnt += obj->count;
		              get_obj( ch, obj, container );
		              
		         if ( char_died(ch)
		         ||   ch->carry_number >= can_carry_n( ch )
		         ||   ch->carry_weight >= can_carry_w( ch )
		         ||   (number && cnt >= number) )
		         return;
		     }
		   }

      /* And here is the message to say that it cant find said item in the container */
		   
		  if ( !found )
	    {
		    if ( fAll )
		    {
		         if ( container->item_type == ITEM_KEYRING && !IS_OBJ_STAT(container, ITEM_COVERING) )
                    act( AT_PLAIN, "The $T holds no keys.", ch, NULL, arg2, TO_CHAR );
		         else
              			act( AT_PLAIN, IS_OBJ_STAT(container, ITEM_COVERING) ? "I see nothing beneath the $T." : "I see nothing in the $T.", ch, NULL, arg2, TO_CHAR );
		    }
		    else
		    {
		         if ( container->item_type == ITEM_KEYRING && !IS_OBJ_STAT(container, ITEM_COVERING) )
			              act( AT_PLAIN, "The $T does not hold that key.", ch, NULL, arg2, TO_CHAR );
		         else
			              act( AT_PLAIN, IS_OBJ_STAT(container, ITEM_COVERING) ? "I see nothing like that beneath the $T." : "I see nothing like that in the $T.", ch, NULL, arg2, TO_CHAR );
		    }
		  }
Australia Forum Administrator #2
My guess is that it's here:


/* Gold from containers and corpses here */
    /* Gold/Copper/Silver Support -Druid */
    if ( obj->item_type == ITEM_GOLD 
    || obj->item_type == ITEM_COPPER 
    || obj->item_type == ITEM_SILVER )
    {

        amt = obj->value[0];
        if(obj->item_type == ITEM_GOLD) ch->gold += amt;
        if(obj->item_type == ITEM_COPPER) ch->copper += amt;
        if(obj->item_type == ITEM_SILVER) ch->silver +=amt;
        extract_obj( obj ); 
    }


You see that for item types gold, copper or silver, it extracts all three in one shot. So after the first call, nothing will be left.

Strike that, didn't see the second set of ifs.
Amended on Tue 05 Jan 2010 09:29 PM by Nick Gammon
Australia Forum Administrator #3
Actually it is that code. See this:


if(obj->item_type == ITEM_GOLD) ch->gold += amt;
if(obj->item_type == ITEM_COPPER) ch->copper += amt;
if(obj->item_type == ITEM_SILVER) ch->silver +=amt;
extract_obj( obj ); 


You only extract one of gold, copper or silver, but regardless you remove that item from the corpse. That is why you get those messages.

It needs to be something like:


if(obj->item_type == ITEM_GOLD)
  {
  ch->gold += amt;
  extract_obj( obj ); 
  }
 
if(obj->item_type == ITEM_COPPER)
  {
  ch->copper += amt;
  extract_obj( obj ); 
  }

if(obj->item_type == ITEM_SILVER)
  {
  ch->silver += amt;
  extract_obj( obj ); 
  }





.... or maybe I was right the first time. :)

Anyway, I would be looking here.
Amended on Tue 05 Jan 2010 09:33 PM by Nick Gammon
United Kingdom #4
After looking at what you said and experimenting it would seem nothing has changed. I've tried using this;

if(obj->item_type == ITEM_GOLD)
  {
  ch->gold += amt;
  extract_obj( obj ); 
  }
 
if(obj->item_type == ITEM_COPPER)
  {
  ch->copper += amt;
  extract_obj( obj ); 
  }

if(obj->item_type == ITEM_SILVER)
  {
  ch->silver += amt;
  extract_obj( obj ); 
  }


But I still receive this output;

I see nothing like that in the corpse.
You get 5 silver coins from the corpse of the guard
I see nothing like that in the corpse.
You lift a money purse from the corpse.
There is 0 Gold, 5 Silver and 0 Copper in the purse.

I know this is affecting it;
fight.c

/* Autogold by Scryn 8/12 */
/* Gold/Copper/Silver Support -Druid */
if ( xIS_SET(ch->act, PLR_AUTOGOLD) )
{
  init_gold = ch->gold;
  init_silver = ch->silver;
  init_copper = ch->copper;
  do_get( ch, "'gold coins' corpse" );
  do_get( ch, "'silver coins' corpse" );
  do_get( ch, "'copper coins' corpse" );
Canada #5
The section of act_obj.c you want for get_obj is just above the section you posted, specifically this;
    if ( container )
    {
	if ( container->item_type == ITEM_KEYRING && !IS_OBJ_STAT(container, ITEM_COVERING) )
	{
	    act( AT_ACTION, "You remove $p from $P", ch, obj, container, TO_CHAR );
	    act( AT_ACTION, "$n removes $p from $P", ch, obj, container, TO_ROOM );
	}
	else
	{
	    act( AT_ACTION, IS_OBJ_STAT(container, ITEM_COVERING) ? 
		"You get $p from beneath $P." : "You get $p from $P",
		ch, obj, container, TO_CHAR );
	    act( AT_ACTION, IS_OBJ_STAT(container, ITEM_COVERING) ?
		"$n gets $p from beneath $P." : "$n gets $p from $P",
		ch, obj, container, TO_ROOM );
	}
	if ( IS_OBJ_STAT( container, ITEM_CLANCORPSE )
	&&  !IS_NPC( ch ) && str_cmp( container->name+7, ch->name ) )
                container->value[5]++;
	obj_from_obj( obj );
    }

More specifically line 158 "You get $p from $P" is the 'looting' line.
To do what you want, this is what I would suggest. Keep in mind *this is just a guess* of a solution.

Keep everything in 'autogold' the same and try adding
if ( container ) && !PLR_AUTOGOLD

to line 148 above. (That coding may be wrong, so to explain, add a "if its a container and the player is not using autogold" code check.)

Or you may need to move the new lines from autogold to after the above as some 'else' statement. (If container and player is not using autogold, do this, else do the thing about the purse)
Amended on Wed 06 Jan 2010 12:08 AM by Hanaisse
Australia Forum Administrator #6
http://www.gammon.com.au/gdb

Then you can see what is happening. :)