Login
User Name:

Password:



Register

Forgot your password?
Changes list / Addchange
Author: Khonsu
Submitted by: Khonsu
6Dragons mp3 sound pack
Author: Vladaar
Submitted by: Vladaar
AFKMud 2.2.3
Author: AFKMud Team
Submitted by: Samson
SWFOTEFUSS 1.5
Author: Various
Submitted by: Samson
SWRFUSS 1.4
Author: Various
Submitted by: Samson
Users Online
Google, DotBot, AhrefsBot, Bing

Members: 0
Guests: 23
Stats
Files
Topics
Posts
Members
Newest Member
488
3,788
19,631
595
Khonsu

Today's Birthdays
There are no member birthdays today.
» SmaugMuds » Codebases » SmaugFUSS » Bug with mpat in a greet prog
Forum Rules | Mark all | Recent Posts

Bug with mpat in a greet prog
< Newer Topic :: Older Topic >

Pages:<< prev 1 next >>
Post is unread #1 Oct 12, 2009 5:17 pm   
Go to the top of the page
Go to the bottom of the page

Gatz
Apprentice
GroupMembers
Posts60
JoinedJul 25, 2005

 
When you use an mpat in a mprog's greet, it'll end up firing twice.

Example:
mpedit X add greet 100
' Hello, $n!
mpat 10 look


The above will make the NPC fire the say twice. Probably has something to do with the mpat making the NPC leave the room and come back.

Post is unread #2 Oct 12, 2009 5:18 pm   
Go to the top of the page
Go to the bottom of the page

Zeno
Sorcerer
GroupMembers
Posts723
JoinedMar 5, 2005

 
I was able to reproduce this with BIYG and stock Smaug that SBI has.

Post is unread #3 Oct 12, 2009 7:10 pm   
Go to the top of the page
Go to the bottom of the page

Remcon
Geomancer
GroupAdministrators
Posts1,914
JoinedJul 26, 2005

 
Also in LoP, now interestingly enough if you add more mpats it still only does it twice. So wonder why it limits it to twice yet it will cause it to do it twice.

Post is unread #4 Oct 12, 2009 7:34 pm   
Go to the top of the page
Go to the bottom of the page

Samson
Black Hand
GroupAdministrators
Posts3,685
JoinedJan 1, 2002

 
That's an odd little bug, wonder why nobody noticed it before.

Post is unread #5 Oct 12, 2009 8:02 pm   
Go to the top of the page
Go to the bottom of the page

Remcon
Geomancer
GroupAdministrators
Posts1,914
JoinedJul 26, 2005

 
Well the problem is that mprog_greet_trigger never takes into consideration that if they leave the room and come back in while its executing there position in the list changes to the end. So it will allow it to fire twice (maybe more under the right circumstances like if it minvoked/transed someone and then did another mpat) Im open for suggestions on best way to go about doing this though lol.

Post is unread #6 Oct 12, 2009 8:14 pm   
Go to the top of the page
Go to the bottom of the page

Remcon
Geomancer
GroupAdministrators
Posts1,914
JoinedJul 26, 2005

 
The best I can guess is that you need to make a list of all the characters in the room at the start and use that list instead of the chars in the room list as it goes since it can change.

Post is unread #7 Oct 13, 2009 12:00 am   
Go to the top of the page
Go to the bottom of the page

Samson
Black Hand
GroupAdministrators
Posts3,685
JoinedJan 1, 2002

 
Heh. Would figure this is one of those weird list things. They do seem to love to pop up everywhere.

Post is unread #8 Oct 13, 2009 2:45 am   
Go to the top of the page
Go to the bottom of the page

InfiniteAxis
Off the Edge of the Map
GroupAdministrators
Posts1,200
JoinedMar 21, 2006

 
The commands at/atobj/mpat/whatever else, should just be modified to not remove the person from the list. I never understood why they were handled that way to begin with.

Post is unread #9 Oct 13, 2009 4:08 am   
Go to the top of the page
Go to the bottom of the page

Samson
Black Hand
GroupAdministrators
Posts3,685
JoinedJan 1, 2002

 
If that can be done safely without some kind of odd pointer issues coming up, then I don't see why not. Right now it's because they make use of char_from_room() and char_to_room() to do what they do.

Post is unread #10 Dec 4, 2009 4:10 pm   
Go to the top of the page
Go to the bottom of the page

Matteo2303
Apprentice
GroupMembers
Posts86
JoinedAug 25, 2003

 
Hello, in my opinion we have two problems at same time,

1) xxxx_prog_trigger like GREET_PROG (but probably much other) loop CHAR_DATA in room to check if the prog is present or not. But, if the list of CHAR_DATA in room change for some reason (mpat command is one possibile situation), a mud prog could re-fire more than one time.

2) MPAT (and other commands) can invoke a char_from_room / char_to_room so the list of CHAR_DATA in room change [up at point (1)].

...so I suppose we can change xxxx_prog_trigger loop system with something like a queded list... otherwise we need to change command like MPAT to prevent the change list of CHAR_DATA in a room.

I think, another way, could be simply do something like this via building:

>greet_prog 100
if wasinroom($i) == 214
break
endif
' Hello, $n!
mpat 214 mpechoall TRIG TEST

I don't know if this really "FIX" all cases.

Bye
mat

Post is unread #11 Jan 31, 2010 10:35 am   
Go to the top of the page
Go to the bottom of the page

Remcon
Geomancer
GroupAdministrators
Posts1,914
JoinedJul 26, 2005

 
So did anyone every do anything on this?

Post is unread #12 Jan 31, 2010 11:24 am   
Go to the top of the page
Go to the bottom of the page

InfiniteAxis
Off the Edge of the Map
GroupAdministrators
Posts1,200
JoinedMar 21, 2006

 
I haven't. I got distracted with Mass Effect 2, Dragon Age: Origins, Halo 3: ODST, and Fallout 3. It was a good Holiday season for games. >.> lol

Post is unread #13 Jan 31, 2010 11:42 am   
Go to the top of the page
Go to the bottom of the page

Remcon
Geomancer
GroupAdministrators
Posts1,914
JoinedJul 26, 2005

 
Sounds like fun, I had went through once and fixed it in mine then didn't like how i fixed it so took it out. Plus was waiting to see if anyone else had a better idea. Earlier today I got to wondering if I had took it out or not so got to looking and noticed I had so got to wondering if anyone had come up with something when I seen no one has I did another temporary list inside the function itself. It is always a pain though when dealing with programs since they can cause things to die, move, etc.... When I do the next release of LoP (eventually going to be done sooner or later) It will have the fix in it unless someone comes up with something better etc... I'm going to go ahead and put in what I have here for people to look at and decide if there is a better way etc... Who knows maybe it will help us all get it solved or at least get some people working on coming up with something better or something.

Here it is:
void mprog_greet_trigger( CHAR_DATA *ch )
{
   /* We need a temporary list of the chars to keep it only firing ones it needs to, probably needed in other locations too */
   typedef struct tmp_char TMP_CHAR;
   struct tmp_char
   {
      TMP_CHAR *next, *prev;
      CHAR_DATA *who; /* Who are we checking now? */
   };
   TMP_CHAR *tmp_first = NULL, *tmp_last = NULL, *tmpmob, *tmpmob_next;
   CHAR_DATA *vmob, *vmob_next;
   int rvnum;

   if( !ch || !ch->in_room )
      return;

   rvnum = ch->in_room->vnum;

   /* Ok link them in the tmp list */
   for( vmob = ch->in_room->first_person; vmob; vmob = vmob_next )
   {
      vmob_next = vmob->next_in_room;

      if( !vmob || !vmob->in_room || vmob->in_room->vnum != rvnum || !is_npc( vmob ) || !can_see( vmob, ch )
      || vmob->fighting || !is_awake( vmob ) || char_died( vmob ) || char_died( ch ) || ( is_npc( ch ) && ch->pIndexData == vmob->pIndexData ) )
         continue;

      CREATE( tmpmob, TMP_CHAR, 1 );
      tmpmob->who = vmob;
      LINK( tmpmob, tmp_first, tmp_last, next, prev );
   }

   /* Ok now toss through the tmp list and remove them as we go */
   for( tmpmob = tmp_first; tmpmob; tmpmob = tmpmob_next )
   {
      tmpmob_next = tmpmob->next;

      vmob = tmpmob->who;

      if( !vmob || !vmob->in_room || vmob->in_room->vnum != rvnum || !is_npc( vmob ) || !can_see( vmob, ch )
      || vmob->fighting || !is_awake( vmob ) || char_died( vmob ) || char_died( ch ) || ( is_npc( ch ) && ch->pIndexData == vmob->pIndexData ) )
      {
         UNLINK( tmpmob, tmp_first, tmp_last, next, prev );
         tmpmob->who = NULL;
         DISPOSE( tmpmob );
         continue;
      }

      if( HAS_PROG( vmob->pIndexData, GREET_PROG ) )
         mprog_percent_check( vmob, ch, NULL, NULL, GREET_PROG );
      else if( HAS_PROG( vmob->pIndexData, ALL_GREET_PROG ) )
         mprog_percent_check( vmob, ch, NULL, NULL, ALL_GREET_PROG );

      UNLINK( tmpmob, tmp_first, tmp_last, next, prev );
      tmpmob->who = NULL;
      DISPOSE( tmpmob );
   }

   /* Just incase for some reason something is still in need to remove it now */
   for( tmpmob = tmp_first; tmpmob; tmpmob = tmpmob_next )
   {
      tmpmob_next = tmpmob->next;
      UNLINK( tmpmob, tmp_first, tmp_last, next, prev );
      tmpmob->who = NULL;
      DISPOSE( tmpmob );
   }
}

So lets see what we can all come up with on this lol.

Pages:<< prev 1 next >>