Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ SMAUG
➜ SMAUG coding
➜ Checking if objects are in inventory
Checking if objects are in inventory
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Tue 25 Jan 2005 08:06 AM (UTC) |
Message
| Hi all, what im needing to do is check through a players inventory to see of they have X amount of an object in there,
The way it was done in the smippet i have is as follows,
for (x = 0; x <= mnum; x++)
{
material = get_obj_carry (ch, "corpse" );
if (material == NULL)
{
send_to_char( "You didn't realize it when you started, but you haven't enough material\n\r", ch);
return;
}
extract_obj( material );
}
The trouble with doing it this way is that once the first object is extracted it fails to find find the next corpse in inventory and always fails, could someone show me a better way to achieve the same outcome, or is there an existing function that i can use that will check how many of an object there are in a players inventory.
Thanks in advance. |
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| Frobozz
(75 posts) Bio
|
Date
| Reply #1 on Tue 25 Jan 2005 08:11 AM (UTC) |
Message
| I dont understand why you have:
if (material == NULL)
that if you're trying to count for a specific number of materials. Shouldn't that be something like:
if (material < 3)
and so on?
IT's 4 am here, so maybe I just missed it? | Top |
|
Posted by
| Frobozz
(75 posts) Bio
|
Date
| Reply #2 on Tue 25 Jan 2005 08:12 AM (UTC) |
Message
| Alternatively you can check the SPELLCOMPONETS code, I believe that checks the player inventory for material, ie spell components. | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #3 on Tue 25 Jan 2005 08:16 AM (UTC) |
Message
| I think that the material == null is checking what get_obj_carry would return if it didnt find that obect
code from get_obj_carry
for ( obj = ch->last_carrying; obj; obj = obj->prev_content )
if ( obj->wear_loc == WEAR_NONE
&& can_see_obj( ch, obj )
&& (nifty_is_name( arg, obj->name ) || obj->pIndexData->vnum == vnum) )
if ( (count += obj->count) >= number )
return obj;
if ( vnum != -1 )
return NULL;
|
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #4 on Tue 25 Jan 2005 08:18 AM (UTC) |
Message
| Right, a better way of doing it would be to iterate over the objects in the inventory, and count how many are correct. A for loop would do this quite nicely. But, you have to keep track of them as you go along, so that you can eventually remove them. C++ would make this task oh-so-easier with STL vectors or such, but in C you'd use a linked list or dynamic array or something. (Probably a dynamic array, which is simpler.) |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Greven
Canada (835 posts) Bio
|
Date
| Reply #5 on Tue 25 Jan 2005 08:22 AM (UTC) |
Message
| If your looking for something like this, take a look at something like do_makecontainer in swskills.c in the SWR codebase. It can be downloaded from this website, and it has a system similar to what your trying to accomplish. |
Nobody ever expects the spanish inquisition!
darkwarriors.net:4848
http://darkwarriors.net | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #6 on Tue 25 Jan 2005 08:29 AM (UTC) |
Message
| Thanks, not being much of a coder i find it much easier to work out how to do things from looking at code that does something simular to what i am trying to acheive, i dont know much about linked lists or dynamic arrays so i will have to look them up on the web and read about those, but in the mean time im downloading swr to take a look at the makcontainer code. |
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #7 on Tue 25 Jan 2005 09:16 AM (UTC) |
Message
| OK, have had a look at the makecontainer code and am assuming that this is the piece of code that i was looking for,
for ( obj = ch->last_carrying; obj; obj = obj->prev_content )
{
if (obj->item_type == ITEM_THREAD)
checksew = TRUE;
if (obj->item_type == ITEM_FABRIC && checkfab == FALSE)
{
checkfab = TRUE;
separate_obj( obj );
obj_from_char( obj );
material = obj;
}
}
and that, that will start at the last object you have and work its way to the beginning checking if you have some fabric and thread and when it finds fabric and you previously didnt have any, says you now have fabric, removes it from containers takes it from you, and will do that till it reaches the first object in your inv??
so i guess i could do something like this,
for ( obj = ch->last_carrying; obj; obj = obj->prev_content )
{
if (obj->item_type == ITEM_CORPSE)
{
checkcorpses == checkcorpses++
obj_from_char( obj );
}
if checkcorpses = number_of_corpses_needed)
{
return; //bailout only take what i need
}
if checkcorpses != number_of_corpses_needed)
{
//better work out a way to give back the objects
}
}
i havent tryed this yet, tho im about to, hope im on the right track. Please tell me what you think and thanks again. |
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #8 on Tue 25 Jan 2005 12:05 PM (UTC) |
Message
| Ok, i have got it to work now, well sort of, it took some tinkering around on my part to work out exactly waht the hell was going on there for a while, Alas that call to seperate_obj(obj) was the most important part of all this code, trouble is that if all the objects are the same, ie, the corpse of robert (100), it still fails to seperate them and then the code fails, i have also config -combine, but that makes no difference either, here is the code as it stands
for ( obj = ch->last_carrying; obj; obj = obj->prev_content )
{
separate_obj( obj );
if (obj->item_type == ITEM_CORPSE_NPC)
{
checkcorpses++;
}
if (checkcorpses == mnum)
{
obj_from_char( obj ); //take the last one;
break; //Bust out now, dont take more than is needed.
}
separate_obj( obj );
obj_from_char( obj );
}
if (checkcorpses != mnum)
{
send_to_char("You dont have enough corpses.\n\r", ch);
return;//better work out a way to give back the objects
}
If anyone has any ideas how i can solve this stacking of objects i would love to hear them. Thanks
|
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | Top |
|
Posted by
| David Haley
USA (3,881 posts) Bio
|
Date
| Reply #9 on Tue 25 Jan 2005 05:24 PM (UTC) |
Message
| You will have to allocate an array of the size of the number of materials. Every time you find a material, you put that into the array. Once the array is full, you are done. If you can't fill up the array, you inform the player that there aren't enough materials and you free the array memory. if there array is full, you remove all those objects from the character and free the array memory.
The SWR code doesn't seem to take into account multiple source materials, so I'm not sure it'll work. |
David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone
http://david.the-haleys.org | Top |
|
Posted by
| Greven
Canada (835 posts) Bio
|
Date
| Reply #10 on Tue 25 Jan 2005 06:37 PM (UTC) Amended on Tue 25 Jan 2005 06:40 PM (UTC) by Greven
|
Message
| The reason that your losing 100 instead of one is that your likely missing the separate_obj( obj ); call. This will ungroup the object if there is more than one. If you want to use more than 1, you could do something like this:for ( obj = ch->last_carrying; obj; obj = obj->prev_content )
{
if (obj->item_type == ITEM_THREAD)
checksew = TRUE;
if (obj->item_type == ITEM_FABRIC && checkfab == FALSE && count < 4)
{
checkfab = TRUE;
separate_obj( obj );
obj_from_char( obj );
material = obj;
count++;
}
}
With this, to prevent losing 3 if thats all you have, the upper portion of that skill has the same checks before the add_timer call, but does not remove anything, so you cuold do the counting there.
[EDIT] Hmm, actually, I don't know if seperate_obj puts the rest of the grouped objects before obj, after, at the end, etc, so it might skip them. I can't check as I am at work, but you could try a simple compile and see if it finds the rest in the inventory. |
Nobody ever expects the spanish inquisition!
darkwarriors.net:4848
http://darkwarriors.net | Top |
|
Posted by
| Robert Powell
Australia (367 posts) Bio
|
Date
| Reply #11 on Tue 25 Jan 2005 11:36 PM (UTC) Amended on Tue 25 Jan 2005 11:46 PM (UTC) by Robert Powell
|
Message
| This dont work, i dont realy know why it fails but it does, I think its as greven says and that seperate_obj put the new object in the wrong place and it all gets lost. At some point it just plain stops finding more of the same type of object, i guess it has something to do with seperate_obj and what it does, i think at best it finds 3 then fails. Here is the code for split_obj as seperate_obj calls that asking it to seperate one object off the group.
if ( count <= num || num == 0 )
return;
rest = clone_object(obj);
--obj->pIndexData->count; /* since clone_object() ups this value */
--numobjsloaded;
rest->count = obj->count - num;
obj->count = num;
if ( obj->carried_by )
{
LINK( rest, obj->carried_by->first_carrying,
obj->carried_by->last_carrying,
next_content, prev_content );
rest->carried_by = obj->carried_by;
rest->in_room = NULL;
rest->in_obj = NULL;
}
I dont mind that the tailor corpse code doesnt use more that one corpse to make an object as its a cheap skill, tho i was going to cheat some in my mining, forge eq and weapons code and do it in a simular way to the do_tailor.
I have decided that the best thing i could do now is change do_mining so that it adds a weight value to an existing ore object in a players inv, might even make a new obect called ore_container and have all the ore's stored in there, then create a new ore if one doesnt exist or increment the weight of the ore if it does. Then i will only be dealing with one object and wont have the trouble of grouped objects. |
Just a guy having a bit of fun. Nothing more, nothing less, I do not need I WIN to feel validated. | 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.
29,229 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top