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


Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  SMAUG
. -> [Folder]  SMAUG coding
. . -> [Subject]  Linked lists and objects getting messed up in SWR

Linked lists and objects getting messed up in SWR

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Posted by Greven   Canada  (835 posts)  [Biography] bio
Date Thu 12 Aug 2004 08:30 AM (UTC)

Amended on Thu 12 Aug 2004 08:33 AM (UTC) by Greven

Message
I've spoken with a few coders on SWR muds, and this bug seems to keep popping up. At some random point which no one seems to be able to track down, characters are removed from the linked lists of rooms and the global list of players. This causes players not to be able to see each other, but able to hear the say command, or to show up on who, but not be able to use the at command on them. As best as I can tell, there seems to be a problem with char_from or char_to room, though I can't see anything in the stock SWR code.

If anyone has ever come across this problem, and especially if they have the fix, I would most grateful to hear about it. I do not know if this happens in SMAUG, as I've never heard about it, so I have to assume it is a SWR change.

The second issue that I have seen come up, totally unrelated to the first, is some objects appear not to want to stay equipped to characters. The character may equip the object, and soon after find it in their inventory. I am fairly certain that the problem lies somewhere in re_equip_char, but I can't track it down either. Again, this seems to be purely a SWR issue, but if others have come across it, and feedback would be great.

If no one has any info on this, I will post what code I have for these issues in way of possible problem areas when I get home and have access to the code.

Nobody ever expects the spanish inquisition!

darkwarriors.net:4848
http://darkwarriors.net
[Go to top] top

Posted by Darrik Vequir   (24 posts)  [Biography] bio
Date Reply #1 on Thu 12 Aug 2004 01:15 PM (UTC)
Message

The only thing similar I found was that *ships* would disappear from the look command, meaning they were removed from the next_in_room linked list, but would still show up on ships, which scrolled through every ship one by one and checked to see if it was located there.

This was the result of a change *I* did to the serin public shuttle code, but I never could track it down, so I just changed everything to scroll through the entire list. A CPU drain, but what can you do.

On second thought, I did encounter this problem on occasion when I loaded up a player, or when I destroyed an online player. I do not know why, but apparently some immortal commands cause some confusion in the next_in_room lists. If this is the case, than a reboot will fix it until the same immortal command is done in the same circumstances.

If a reboot does not fix it, then it is something you have changed in the code. I'd advise attaching GDB to it and stepping through the loop manually to see what the problem is, then see if you can figure out where that might be getting changed.

Darrik Vequir
[Go to top] top

Posted by Greven   Canada  (835 posts)  [Biography] bio
Date Reply #2 on Fri 13 Aug 2004 01:31 AM (UTC)
Message
I found the answer to the second one. In my mud, I have fix_char on an update. When it would trigger, it would screw up players that had the exact same object worn in two different wear_locs. fix_char de_equip_char's the person, and then does this:
    ncarry = 0;
    while ( (obj=ch->first_carrying) != NULL )
    {
	carry[ncarry++]  = obj;
	obj_from_char( obj );
    }
Now, I can't seen ANY reason for this. fix_char is a minor function compared to save_char_obj, and this is not done in save_char_obj, so I see absolutely no reason to use it in fix_char. It is accompanied with this:
    for ( x = 0; x < ncarry; x++ )
	obj_to_char( carry[x], ch );
to give it back to the player.

I tracked down the reason for this. de_equip_char is where on a character through a double array, using wear_loc and layer as indexes, the characters objects are saved in save_equipment, which is the double array of object_data pointers. So, we now have where everything is supposed to be, but just off of the character. The above code, when obj_from_char is applied, groups objects together if everything is the same. At this point, since wear_loc and layer have been reset after being de_equiped, they ARE the same, so it groups them. Now, we have one object, ch->first_carry, for example, with a 2 count, and 2 objects saved in save_equipment, each with a 1 count. So the code for fix_char is applied, the objects are given back, but are NOT seperated, since there is no way to know how to do this. Now, these objects are re-applied through re_equip_char. Here is the tricky part, when it gets to the first object in save_equipment(first first ring, for example), it has a pointer to an object with a 2 count. If detects this 2 count in the process of re-applying the object to the character, and seperates them, creating a third object(first ring in save_equipment, the clone of the first, and the second in save_equipment). This object is linked in to the characters list of objects carried. When the process loops through the next time, the call to get_eq_char returns the clone, instead of the one in save_equipment. The changes to put the object back on the character is applied to the clone instead of the second ring, and the second ring is left in the inventory.

This took me a while through gdb, but I am almost positive that this is the process for this bug. As far as I can tell, this should be a bug in stock SMAUG as well. If someone can test for me, that would be great. You need to:

Oinvoke one piece of armor twice(jewelry works best, since you can have them on the same layer)

Wear them both(left wrist and right wrist, for example)

Use the fixchar command on the character

If one of the objects is now in the players inventory, then I'm not crazy. I just want to confirm this is the issue. I remove the above code from my fixchar, and it seems to have solved the issue. If there is an actual reason for that bit of code, though, I would love to be enlightened about it.

Nobody ever expects the spanish inquisition!

darkwarriors.net:4848
http://darkwarriors.net
[Go to top] top

Posted by Greven   Canada  (835 posts)  [Biography] bio
Date Reply #3 on Fri 13 Aug 2004 06:04 AM (UTC)
Message
Well, I did actually find a use for them, but I have made a work around. I beleive the from_ and to_ were there to properly calculate object weight and number of items in your inventory. However, that seems like overkill, so I made the bottom of fix_char look like
        for (aff = ch->first_affect; aff; aff = aff->next)
                affect_modify(ch, aff, TRUE);
        re_equip_char(ch);

        ch->carry_weight = 0;
        ch->carry_number = 0;

		for ( obj = ch->first_carrying ; obj ; obj = obj->next_content )
		{
        	if (obj->wear_loc == WEAR_NONE)
                ch->carry_number += get_obj_number(obj);
            if (!IS_SET(obj->extra_flags, ITEM_MAGIC))
                ch->carry_weight += get_obj_weight(obj);
		}
}
And it seems to have done the trick.

Nobody ever expects the spanish inquisition!

darkwarriors.net:4848
http://darkwarriors.net
[Go to top] top

Posted by Samson   USA  (683 posts)  [Biography] bio
Date Reply #4 on Sat 14 Aug 2004 11:55 PM (UTC)
Message
For those of us who aren't following ( me ) could you post your entire fix_char function? What you did seems reasonable but doesn't quite make sense without seeing it in the whole thing.
[Go to top] top

Posted by Greven   Canada  (835 posts)  [Biography] bio
Date Reply #5 on Sun 15 Aug 2004 02:31 PM (UTC)

Amended on Sun 15 Aug 2004 02:35 PM (UTC) by Greven

Message
Ok, sorry, didn't mean to be confusing, this is what I am currently using
/*
 * "Fix" a character's stats					-Thoric
 * Modified to keep the objects on characters properly- Greven
 */
void fix_char(CHAR_DATA * ch)
{
        AFFECT_DATA *aff;
		OBJ_DATA *obj;

        de_equip_char(ch);

        for (aff = ch->first_affect; aff; aff = aff->next)
                affect_modify(ch, aff, FALSE);

        ch->affected_by = 0;
        SET_BIT(ch->affected_by, ch->race->affected);
        ch->mental_state = 0;
        ch->hit = UMAX(1, ch->hit);
        ch->endurance = UMAX(1, ch->endurance);
        ch->endurance = UMAX(1, ch->endurance);
        ch->armor = 100;
        ch->mod_str = 0;
        ch->mod_dex = 0;
        ch->mod_wis = 0;
        ch->mod_int = 0;
        ch->mod_con = 0;
        ch->mod_cha = 0;
        ch->mod_lck = 0;
        ch->damroll = 0;
        ch->hitroll = 0;
        ch->alignment = URANGE(-1000, ch->alignment, 1000);
        ch->saving_breath = 0;
        ch->saving_wand = 0;
        ch->saving_para_petri = 0;
        ch->saving_spell_staff = 0;
        ch->saving_poison_death = 0;

        ch->bonus_frc = 0;

        for (aff = ch->first_affect; aff; aff = aff->next)
                affect_modify(ch, aff, TRUE);

        re_equip_char(ch);

        ch->carry_weight = 0;
        ch->carry_number = 0;

        for ( obj = ch->first_carrying ; obj ; obj = obj->next_content )
        {
                if (obj->wear_loc == WEAR_NONE)
    	            ch->carry_number += get_obj_number(obj);
        	if (!IS_SET(obj->extra_flags, ITEM_MAGIC))
            	    ch->carry_weight += get_obj_weight(obj);
        }
}

Nobody ever expects the spanish inquisition!

darkwarriors.net:4848
http://darkwarriors.net
[Go to top] top

Posted by Samson   USA  (683 posts)  [Biography] bio
Date Reply #6 on Sun 15 Aug 2004 06:41 PM (UTC)
Message
Ahah, ok. That makes more sense now. Of course fix_char is only called in like 2 placed for my code. One in the command itself, the other in the do_immortalize command. But a fix is a fix. Good catch. I think it would also be a Smaug bug as well so I'll go add it to the FUSS packages now. :)
[Go to top] top

Posted by Greven   Canada  (835 posts)  [Biography] bio
Date Reply #7 on Sun 15 Aug 2004 08:14 PM (UTC)

Amended on Sun 15 Aug 2004 08:15 PM (UTC) by Greven

Message
As to the first problem, I spoke with Ewarta, head coder on the RitS SWR MUD, and he pointed this out:
	if ( !IS_IMMORTAL(ch) && ch->pcdata->release_date > current_time )
	{
	    char_to_room( ch, get_room_index(6) );
	}
	else if ( ch->in_room && !IS_IMMORTAL( ch ) 
             && !IS_SET( ch->in_room->room_flags, ROOM_SPACECRAFT )
             && ch->in_room != get_room_index(6) )
	{
	    char_to_room( ch, ch->in_room );
	}
	else if ( ch->in_room && !IS_IMMORTAL( ch )  
             && IS_SET( ch->in_room->room_flags, ROOM_SPACECRAFT )
             && ch->in_room != get_room_index(6) )
	{
	    SHIP_DATA *ship;
	    
	    for ( ship = first_ship; ship; ship = ship->next )
	      if ( ch->in_room->vnum >= ship->firstroom && ch->in_room->vnum <= ship->lastroom )
                if ( ship->class != SHIP_PLATFORM || ship->starsystem ) 
                  char_to_room( ch, ch->in_room );
	}
	else
	{
	    char_to_room( ch, get_room_index( wherehome(ch) ) );
	}
The check regarding the ships are completely unnessecary, and can lead to mislinked players I modified that section to look like this(please excuse the difference in indenting/spacing, mine has had indent applied to it, above is stock SWR):
                else
                {
                        if (!IS_IMMORTAL(ch)
                            && ch->pcdata->release_date > current_time)
                        {
                                char_to_room(ch, get_room_index(6));
                        }
                        else if (ch->in_room && !IS_IMMORTAL(ch)
                                 && ch->in_room->vnum != 6)
                        {
                                char_to_room(ch, ch->in_room);
                        }
                        else
                        {
								ch->in_room = get_room_index(wherehome(ch));
                                char_to_room(ch, ch->in_room);
                        }
                }


This seems to be at least one of the causes of mis-linked players, as I applied this change to an SWR with a 50+ codbase, and the problem seems to have gone away. Hope that help some folks out.

Nobody ever expects the spanish inquisition!

darkwarriors.net:4848
http://darkwarriors.net
[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.


19,117 views.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

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

[Best viewed with any browser - 2K]    [Hosted at HostDash]