
Pages:<< prev 1 next >>



Apprentice

GroupMembers
Posts60
JoinedJul 25, 2005
When you use an mpat in a mprog's greet, it'll end up firing twice.
Example:
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.
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.



Sorcerer

GroupMembers
Posts723
JoinedMar 5, 2005
I was able to reproduce this with BIYG and stock Smaug that SBI has.



Geomancer

GroupAdministrators
Posts1,992
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.


Black Hand

GroupAdministrators
Posts3,707
JoinedJan 1, 2002
That's an odd little bug, wonder why nobody noticed it before.



Geomancer

GroupAdministrators
Posts1,992
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.



Geomancer

GroupAdministrators
Posts1,992
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.


Black Hand

GroupAdministrators
Posts3,707
JoinedJan 1, 2002
Heh. Would figure this is one of those weird list things. They do seem to love to pop up everywhere.


Off the Edge of the Map

GroupAdministrators
Posts1,199
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.


Black Hand

GroupAdministrators
Posts3,707
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.



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
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



Geomancer

GroupAdministrators
Posts1,992
JoinedJul 26, 2005
So did anyone every do anything on this?


Off the Edge of the Map

GroupAdministrators
Posts1,199
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



Geomancer

GroupAdministrators
Posts1,992
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:
So lets see what we can all come up with on this lol.
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 >>