[Home] [Downloads] [Search] [Help/forum]

Gammon Software Solutions forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  SMAUG
. -> [Folder]  SMAUG coding
. . -> [Subject]  skin code problem
Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

skin code problem

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page


Pages: 1 2  

Posted by Addrodoc   (15 posts)  [Biography] bio
Date Mon 28 Feb 2005 08:05 PM (UTC)  quote  ]
Message
Greetings everyone.

I'm trying to rewrite the smaug skin code so that, instead of skinning the corpse of another player, players can skin the corpse of a npc and get a hide or a pelt that they could sell in the store.

I'm not really a coder, but I learn fast and I dont give up easily..

I've managed to change the code so that it now allows us to skin NPC's instead of PC's, the problem is that it works on every NPC, when it should only work on certain animals (I'm looking for a way to link it so that it will only work on the NPC class: animal)

Here's the one line that I've changed so far:

in skills.c on line 476

if( corpse->item_type != ITEM_CORPSE_NPC ) /* I changed PC to NPC */

I did the same thing a little further down: skills.c on line 491

korps = create_object( get_obj_index( OBJ_VNUM_CORPSE_NPC ), 0 );


Another problem that I ran across, is that you can continously strip down a corpse. It should be just one pelt or hide per corpse.


Here's the piece of code that is handling corpse skinning.. (maybe there is more that I dont know of)

void do_skin( CHAR_DATA * ch, char *argument )
{
OBJ_DATA *korps;
OBJ_DATA *corpse;
OBJ_DATA *obj;
OBJ_DATA *skin;
bool found;
char *name;
char buf[MAX_STRING_LENGTH];
found = FALSE;

if( !IS_PKILL( ch ) && !IS_IMMORTAL( ch ) )
{
send_to_char( "Dat is iets voor echte jagers!\n", ch );
return;
}
if( argument[0] == '\0' )
{
send_to_char( "Welk kadaver wil je villen?\n\r", ch );
return;
}
if( ( corpse = get_obj_here( ch, argument ) ) == NULL )
{
send_to_char( "Je kunt het niet vinden.\n\r", ch );
return;
}
if( ( obj = get_eq_char( ch, WEAR_WIELD ) ) == NULL )
{
send_to_char( "Je hebt een scherp wapen nodig om te kunnen villen.\n\r", ch );
return;
}
if( corpse->item_type != ITEM_CORPSE_NPC )
{
send_to_char( "Dit lichaam kun je niet villen.\n\r", ch );
return;
}
if( obj->value[3] != 1 && obj->value[3] != 2 && obj->value[3] != 3 && obj->value[3] != 11 )
{
send_to_char( "Je kunt hier niks mee..\n\r", ch );
return;
}
if( get_obj_index( OBJ_VNUM_SKIN ) == NULL )
{
bug( "Vnum 23 (OBJ_VNUM_SKIN) not found for do_skin!", 0 );
return;
}
korps = create_object( get_obj_index( OBJ_VNUM_CORPSE_NPC ), 0 );
skin = create_object( get_obj_index( OBJ_VNUM_SKIN ), 0 );
name = IS_NPC( ch ) ? korps->short_descr : corpse->short_descr;
sprintf( buf, skin->short_descr, name );
STRFREE( skin->short_descr );
skin->short_descr = STRALLOC( buf );
sprintf( buf, skin->description, name );
STRFREE( skin->description );
skin->description = STRALLOC( buf );
act( AT_BLOOD, "$n vilt $p.", ch, corpse, NULL, TO_ROOM );
act( AT_BLOOD, "Je vilt $p.", ch, corpse, NULL, TO_CHAR );
/* act( AT_MAGIC, "\nThe skinless corpse is dragged through the ground by a strange force...", ch, corpse, NULL, TO_CHAR);
act( AT_MAGIC, "\nThe skinless corpse is dragged through the ground by a strange force...", ch, corpse, NULL, TO_ROOM);
extract_obj( corpse ); */
obj_to_char( skin, ch );
return;
}



So, what I want it to do is only skin the corpse of a NPC with the class animal (or something similar), and have it so that only one pelt will come of the corpse.

I would be very thankfull if someone could help me fix this..

-Addrodoc-
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Reply #1 on Mon 28 Feb 2005 08:15 PM (UTC)  quote  ]

Amended on Mon 28 Feb 2005 08:16 PM (UTC) by David Haley

Message
There are a few ways of doing this. Perhaps the simplest is to just store a value on the object (in the object values) upon death of the NPC stating whether or not this is skinnable; a one-line if-check would then suffice on both ends (for value setting, and for value checking) to make sure that only the right kind of NPCs are skinned.

A slightly hackish way would be to make a new object type, ITEM_CORPSE_SKINNABLE and only let those be skinned but that's fairly ugly and I strongly recommend against it - it's still a kind of NPC corpse and should behave as such. (OOP would be a great solution to this kind of thing, incidentally.)

Incidentally, you should use the \[code\] tag, not the \[b\] tag for indicating code. :)

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Meerclar   USA  (554 posts)  [Biography] bio
Date Reply #2 on Mon 28 Feb 2005 08:46 PM (UTC)  quote  ]

Amended on Mon 28 Feb 2005 08:47 PM (UTC) by Meerclar

Message
Another option is to do race checks for the races you want skinned. Check for either the allowed or disallowed, whichever is a smaller list and have the skin function bail on the bad races. As for allowing only 1 skin per kill, simple matter of adding an extraction call to the skin function. If you want to leave remains of some kind after skinning thats fairly easy too, extract the original corpse and replace it with a skinned corpse or chunk of meat or whatever.

Heh, looking over the code again I see the extract call is already there and commented out.

Meerclar - Lord of Cats
Coder, Builder, and Tormenter of Mortals
Stormbringer: Rebirth
storm-bringer.org:4500
www.storm-bringer.org
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Reply #3 on Mon 28 Feb 2005 08:51 PM (UTC)  quote  ]
Message
I don't think a race check would work because you don't have the race encoded in the corpse; you'd have to encode it into it at death in which case you might as well encode a boolean for skinnable or not. Unless of course this information will be useful later on, in which case you might as well have the race...

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Addrodoc   (15 posts)  [Biography] bio
Date Reply #4 on Mon 28 Feb 2005 09:09 PM (UTC)  quote  ]
Message
Would it be possible to point out the piece of code that I would have to change? I'm really a newb when it comes to coding..

I'm having problems understanding where to start, what to look for and what to change. I dont want to waste anyones time but, since I'm a writer, not a coder, I could seriously use the help.

I'm also a newb when it comes to using the forum codes, sorry about that. :)

Also. I'm dutch which is why my grammar might look a bit weird at times. :)

Anyone willing to help, or just chat about building on smaug, is welcome to add me on msn. caravero@hotmail.com

Thanks in advance.
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Reply #5 on Mon 28 Feb 2005 09:19 PM (UTC)  quote  ]
Message
I think there's a function called make_corpse from a character, which is where you would set one of the item values (preferably one unused or not useful to you) depending on the character's race and if it's an NPC. Look over that function and let me know if it makes sense to you. Since you're a builder you probably know what item values are; are you using all the values on the corpse item?

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Addrodoc   (15 posts)  [Biography] bio
Date Reply #6 on Mon 28 Feb 2005 09:42 PM (UTC)  quote  ]
Message
I'm not sure if I know what you mean..

The corpse item, as in the one that is defined in the code under vnum 23?

Or am I mistaking that vnum for the skinned version of the corpse?

I'm a newbie builder also, with writer I meant to say that I write stories and adventure campaigns..

I've been building on smaug for more then year on and off, so I'm not completely new to olc. I know how to make mobs, objects and I even know how to write progs (simple progs atleast)


I'm browsing through the code atm, looking for the make_corpse function and the item values to see if I can make anything from that..
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Reply #7 on Mon 28 Feb 2005 10:14 PM (UTC)  quote  ]
Message
Well, let's do one thing at a time. :) First we'll deal with making only certain corpses skinnable, then we can worry about skinned corpses.

What platform are you running under? It's usually very, very easy to find functions using a find in files command. Windows does this with the 'search' command (don't search for file name, but for file contents) and on Unix/Unix-like you can use a program like grep.

For example:
grep make_corpse *.c
will search for the text 'make_corpse' in all files ending in .c.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Addrodoc   (15 posts)  [Biography] bio
Date Reply #8 on Mon 28 Feb 2005 10:58 PM (UTC)  quote  ]
Message
I'm currently running win XP, working under cygwin.

I'm using a text editor named 'Crimson Editor'.

I've done a few searches already and came up with a couple of lines of code referring to make_corpse, but I still haven't made any improvement..

I did, however, put the extract code back in use so that the corpse will disappear after it is skinned.. ofcourse that is just a temporary change, it doesnt really fix the bug, except for the fact that no one would be able to use the bug and take advantage of it by skinning the corpse 100 times or more.

I just did another search again and came up with this:

in fight.c (this is pc combat if im not mistaking so I will skip it for now)

I found this in makeobjs.c:

  if( !IS_NPC( ch ) && !IS_NPC( killer ) )
         corpse->value[3] = 1;
      else
         corpse->value[3] = 0;
   }  


a lot more (not sure if I should paste everything here, it would be spammy)

Also, in mud.h:

 /* makeobjs.c */
void make_corpse args( ( CHAR_DATA * ch, CHAR_DATA * killer ) );
void make_blood args( ( CHAR_DATA * ch ) );
void make_bloodstain args( ( CHAR_DATA * ch ) );
void make_scraps args( ( OBJ_DATA * obj ) );
void make_fire args( ( ROOM_INDEX_DATA * in_room, short timer ) );
OD *make_trap args( ( int v0, int v1, int v2, int v3 ) );
OD *create_money args( ( int amount ) ); 



btw, thanks for taking the time to help a noob. I hope I'm not working on your nerves. :)
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Reply #9 on Tue 01 Mar 2005 04:27 AM (UTC)  quote  ]
Message
OK, the function you want is in makeobjs.c then - mud.h is what's called a 'header file'. Headers are where you define the functions and types you'll be using. Typically it's not good practice to lump everything into one huge header, but that's how SMAUG is so that's what we have to work with.

In any case, you'll want to look at the make_corpse function in makeobjs.c. You'll have to figure out which item values mean what for corpses - a good way of doing this is to check out the appropriate help file (objectvalues? Itemvalues? don't remember) and hope that it's up to date. :)

Then, what you'll do is set one of the unused values to, for instance, 1 if the corpse is skinnable or 0 otherwise. Alternatively, you could set the value to the race (or class, whichever matters) number of the character. A third option would be to set it to the mob vnum. Whatever, it does not matter, all you need to be able to do is look up whether or not the corpse is skinnable in some fashion or another.

(In fact it does matter, a little; you want the most general solution which would probably be to store the mob's vnum.)

I have this vague memory, actually, of mob vnums already being stored on the corpses, and this is used in raising the dead. I could be mistaken, or it could be a non-stock feature that I saw... I don't have the code handy so can't take a look. Still, what you'll want to do is study the make_corpse function - it's not too long and it's a good one to understand. The best is to understand it line by line. Let me know if anything confuses you. :)

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Addrodoc   (15 posts)  [Biography] bio
Date Reply #10 on Tue 01 Mar 2005 11:43 PM (UTC)  quote  ]
Message
I've read the code over and over again, some of it makes sense, yet most of it is still difficult to figure out.

I partially understand what I need to do, but I still have a problem figuring out where to start and what to change.

I also cant seem to find out what the values for corpses are, as corpses are not defined as an object on the list that I get from 'help itemvalues'.

The function make_corpse in makeobjs.c:

 void make_corpse( CHAR_DATA * ch, CHAR_DATA * killer )
{
   char buf[MAX_STRING_LENGTH];
   OBJ_DATA *corpse;
   OBJ_DATA *obj;
   OBJ_DATA *obj_next;
   char *name;

   if( IS_NPC( ch ) )
   {
      name = ch->short_descr;
      corpse = create_object( get_obj_index( OBJ_VNUM_CORPSE_NPC ), 0 );
      corpse->timer = 6;
      if( ch->gold > 0 )
      {
         if( ch->in_room )
         {
            ch->in_room->area->gold_looted += ch->gold;
            sysdata.global_looted += ch->gold / 100;
         }
         obj_to_obj( create_money( ch->gold ), corpse );
         ch->gold = 0;
      }

/* Cannot use these!  They are used.
	corpse->value[0] = (int)ch->pIndexData->vnum;
	corpse->value[1] = (int)ch->max_hit;
*/
/*	Using corpse cost to cheat, since corpses not sellable */
      corpse->cost = ( -( int )ch->pIndexData->vnum );
      corpse->value[2] = corpse->timer;
   }
   else
   {
      name = ch->name;
      corpse = create_object( get_obj_index( OBJ_VNUM_CORPSE_PC ), 0 );
      if( in_arena( ch ) )
         corpse->timer = 0;
      else
         corpse->timer = 40;
      corpse->value[2] = ( int )( corpse->timer / 8 );
      corpse->value[4] = ch->level;
      corpse->value[87] = 1;
      if( CAN_PKILL( ch ) && sysdata.pk_loot )
         xSET_BIT( corpse->extra_flags, ITEM_CLANCORPSE );
      /*
       * Pkill corpses get save timers, in ticks (approx 70 seconds)
       * This should be anough for the killer to type 'get all corpse'. 
       */
      if( !IS_NPC( ch ) && !IS_NPC( killer ) )
         corpse->value[3] = 1;
      else
         corpse->value[3] = 0;
   }
 
   if( CAN_PKILL( ch ) && CAN_PKILL( killer ) && ch != killer )
   {
      sprintf( buf, "%s", killer->name );
      STRFREE( corpse->action_desc );
      corpse->action_desc = STRALLOC( buf );
   }

   /*
    * Added corpse name - make locate easier , other skills 
    */
   sprintf( buf, "corpse %s", name );
   STRFREE( corpse->name );
   corpse->name = STRALLOC( buf );

   sprintf( buf, corpse->short_descr, name );
   STRFREE( corpse->short_descr );
   corpse->short_descr = STRALLOC( buf );

   sprintf( buf, corpse->description, name );
   STRFREE( corpse->description );
   corpse->description = STRALLOC( buf );

   for( obj = ch->first_carrying; obj; obj = obj_next )
   {
      obj_next = obj->next_content;
      obj_from_char( obj );
      if( IS_OBJ_STAT( obj, ITEM_INVENTORY ) || IS_OBJ_STAT( obj, ITEM_DEATHROT ) )
         extract_obj( obj );
      else
         obj_to_obj( obj, corpse );
   }

   obj_to_room( corpse, ch->in_room );
   return;
} 


(sorry if it's too spammy)

If it's not too much trouble, could you please point out the lines of code that I need to change, and maybe give an example of what it should look like, or anything else to shet some light on this..

I'm feeling kind of dumb right now. :S
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Reply #11 on Wed 02 Mar 2005 01:58 AM (UTC)  quote  ]
Message
Ah, it looks like I remembered correctly... look at the following line:
corpse->cost = ( -( int )ch->pIndexData->vnum );
This solves the vast majority of your problems. In fact, you now have nothing to change in make_corpse. Let me know if you can describe, in English at least, what needs to be done from here, then we can worry about writing it in code.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Addrodoc   (15 posts)  [Biography] bio
Date Reply #12 on Wed 02 Mar 2005 09:33 PM (UTC)  quote  ]
Message
Smaugfuss, and even earlier versions of smaug had a skin snippet installed already. The problem was that the skin command could only be used on other players.

I now have it so that it can be used on npc's (I simply changed ITEM_CORPSE_PC to ITEM_CORPSE_NPC, and did the same thing with OBJ_VNUM_CORPSE_PC, as I explained in the beginning of my post)

The problem is that it can still be used on every npc, meaning you could kill a guard and skin it, not to mention the fact that you can skin it a 100 times or more.

I want to have it so that only certain animals, for example, a rabbit or a deer, could be skinned. The person skinning the corpse will get a pelt. after that, the corpse itself should be skinless. I want players to be able to sell the pelts they gather, as a way to make gold.

I read this post from LrdElder and tried to follow his instructions, hoping I would solve the problem of skinning corpses more then once, but after compiling the code, I get an error at the end, it doesnt seem to recognise the last line: corpse->value[5]==0;

LrdElders post can be found here:
http://www.shadow-lands.com/sml/1998/msg07510.html

I tried this more then once, I'm going to try it again on a clean version of smaugfuss to see if I accidently changed something in the code. I'm not ready to give up.

I seriously hope that you, or anyone else will be able to come up with a solution for the make_corpse/pelt creation. I'm learning a lot from all this, but I'm not able to write any of this by myself. So I'm thankfull for the replies I got so far, wether I will get it to work or not..

-Addrodoc-
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Reply #13 on Wed 02 Mar 2005 10:01 PM (UTC)  quote  ]
Message
Quote:
corpse->value[5]==0;
That probably should be a single =, not double ==. It's hard to know if this will solve all the problems but it's a problem and probably a fairly serious one.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Addrodoc   (15 posts)  [Biography] bio
Date Reply #14 on Wed 02 Mar 2005 11:06 PM (UTC)  quote  ]
Message
Thanks, that was indeed why it didn't get through the compile.. But after changing it and compiling the code again, it did not make a difference. I can still skin a corpse numerous times.

Perhaps It's because I changed the code to handle NPC corpses instead of PC corpses, and maybe it should be changed somewhere else as well. But I have no clue where to look, although I am looking. I can not find it. I'm constantly browsing the code and making changes to see if can find where the problem is located. But again, I'm having too much trouble understanding the code. :S

I'm still not ready to give up though, I will probably still be working on this when I'm old and grey, in about a week from now. :)
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


5,806 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

[Home]

Written by Nick Gammon - 5K

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]