Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed system plugin: npose_remenu #36

Open
BadJenny opened this issue Sep 19, 2019 · 8 comments
Open

Proposed system plugin: npose_remenu #36

BadJenny opened this issue Sep 19, 2019 · 8 comments

Comments

@BadJenny
Copy link

With the advent of UDP's determining which menus are available to each user, the possibility exists for a user to have a menu already open, which might then be made invalid by the state change of a UDP by another user.

Redrawing everyone's menu when a UDP changes state is problematic. Instead, if there were a remenu by seat command it could be used by the creator to redraw the menus only for those seats which would be impacted by the state change of the UDP:

REMENU|UDPBOOLE to monitor for state change |seat list (filterable by UDPs)|flag

The seatblist filterable by UDPs is important to allow the creator to cause a menu redraw only for those seats who are affected by the state change. Among other cases, it would allow the creator to cause a menu redraw only if a UDP changed state in one direction (I.e. from true to false, but not from false to true) thusly, (assuming the command executes after the UDPBOOLE is updated):

REMENU|isOpen| 1 ~ 2 & !isOpen|1

The flag would be used to include/exclude the user who's action precipitated the state change. Reason being, some user likely clicked a button which caused the UDPBOOLE to change state, so their menu is getting redrawn already and we wouldn't want it redrawn twice in a row.

@LeonaMorro
Copy link
Member

With the advent of UDP's determining which menus are available to each user, the possibility exists for a user to have a menu already open, which might then be made invalid by the state change of a UDP by another user.

Yes, this can/will be happen.

Redrawing everyone's menu when a UDP changes state is problematic. Instead, if there were a remenu by seat command it could be used by the creator to redraw the menus only for those seats which would be impacted by the state change of the UDP:

Well, redrawing a menu is problematic in any case, because if a user closes a menu the script will NOT be informed. A remenu would then open a already closed menu box (see also: #26)
Example:

  • we are both sitting on your object
  • I open the menu and close it again -> the script thinks it is opened

do this until I'm stressed out {

  • you do something within the menu which requires a remenu for me
  • my menu opens again without interaction from me
  • I close it again

}

Currently I see 4 ways to handle the problem and none of them is good:
a) the current behaviour: disadvantage: you already outlined the problem
b) remenu: disadvantage: menus will open again and again (this can be very annoying)
c) invalidate the menu: disadvantage: we can't close the menu box from within the script so if the users presses a button of the invalidated menu nothing will happen (this would give the impression of a malfunction)
d) a nicer variant of c): currently the permissions are only verified at the time the menu box opens. It would be better to also verify them when a button is pressed.

@BadJenny
Copy link
Author

Your Option d occurred to me as well as an alternate approach and it does seem like for all the reasons you mentioned that's the est way to deal with it. You would need some kind of message to the user "that menu choice is no longer available" or something along those lines (perhaps configurable by the creator). It also makes more sense than invalidating the menu because the part of the menu the user is on might be perfectly valid. No idea how much weight this adds to the scripts, but could be an option only turned on if needed if that helps.

@BadJenny
Copy link
Author

Have been thinking about this option d and not sure why you had said it was a bad option?

That said, it turns out this can be implemented now using the brand new DOCARDIF plug-in Howard has been working on: DOCARDIF|UDP|card to execute if true|card to execute if false

It's a bit of a pain because you would need to create an intermediate card to check the permissions before sending them to the real card. If the permission fails, you would send them to a card that pops up a notice. I haven't played with it yet to see how that might affect the menu, but it seems like you could send them to a notecard with a valid menu path such that when the user gets the new menu with the fail notice they end up in a reasonable place.

This will work so long as all of the sitters have the same permissions. If they have different permissions you would need to do a different intermediate card for each so you can check the permissions separately. Example, I have this rather complicated card: SET:Watch..{4 & !in4 ~ 2 & !in2 & !onT ~5 ~6 ~7}. This is a menu group, so I would need to have 3 different cards for each SET in the group: one for sitter 4 to check in4 permission, one for sitter 2 to check in2 and onT permissions, and another one for sitters 5,6, and 7 since I don't need to check their permissions at all (each sitter in ''tis case has their own SCHMO animation, so I could have had them all on a single card).

So, in example above I might then have a card SET:Watch..:Lean 1{2} with content:
DOCARDIF|in2 ~ onT|(name of error card)|(name of actual pose card)
And then I would have two more cards as well: and the SET:Watch..:Lean 1{5 ~ 6 ~7) wouldn't need the intermediate card because there are no permissions to check for those sitters.

Of course, this makes things a whole lot more clunky because we're adding a lot of intermediate cards as well as maybe even breaking cards up as noted above, but it should work and might be worth the effort depending on what a menu selection with an invalid permission might do to your build.

@LeonaMorro
Copy link
Member

Have been thinking about this option d and not sure why you had said it was a bad option?

Well, to be honest: I remember that I thought about implementing it in V3, but I don't remember the exact cause why I decided against it. Maybe a memory issue or something more fundamental. I will look at it again, but I don't think that the cause vanished ... so I would not expect that this will be part of V4.

I haven't played with it yet to see how that might affect the menu, but it seems like you could send them to a notecard with a valid menu path such that when the user gets the new menu with the fail notice they end up in a reasonable place.

I don't think so even if I havn't look at the code for the plugin (@HowardBaxton which is btw. a very nice idea), I guess that the card is executed asynchronously (after the current card, and after the remenu process of the current card).

In V4 you will (very likely) have the opportunity to use UDPs with each and every command like this:

DOCARD{udp}|cardName
LINKMSG{udp}|...
MENUPROMPT{upd}|....
...

So you will be able to do different things within one card depending on the UDPs. Or you may use it as you outlined: giving an error message if the permissions changed while the menu was open and do something if not.

@BadJenny
Copy link
Author

BadJenny commented Sep 28, 2019

In V4 you will (very likely) have the opportunity to use UDPs with each and every command like this:

OMG, that's totally awesome! Each and every command = SCHMO/SCMOE too I assume? If that isn't the case, you can do your double check on the command right there without having to do an intermediate card. When is V4 scheduled to be out? I can help you Beta test those particular commands right now!

I would also like to be able to use UDPs in the seat order command (I forget its name) the same way you can inthe change seat command, in order to have some seats that no one can sit on for instance (these seats then only being available for the builder in the case where they have to move someone to a speak also seat for a specific purpose).

I don't think so even if I havn't look at the code for the plugin (@HowardBaxton which is btw. a very nice idea), I guess that the card is executed asynchronously (after the current card, and after the remenu process of the current card).

I think it does execute like that but Howard would need to confirm. That can be a problem if you need things to happen in a certain order, it means even if you needed to run a check on something (so you could change it if needed before executing the commands in the current card), that check won't happen until after the subsequent commands are run. This happened to me and I had to put the subsequent commands into a second DOCARDIF command to get them to happen after my initial check. It's also a little slow, doubly so when you need to chain them together like that.

Anyway, sounds like V4 already addresses the need for the DOCARDIF and goes way beyond, and this ability to put UDPs into the cards can be used to address the invalid menu issue as well.

@LeonaMorro
Copy link
Member

Each and every command = SCHMO/SCMOE too I assume

yes, each and every.

I would also like to be able to use UDPs in the seat order command (I forget its name) the same way you can inthe change seat command, in order to have some seats that no one can sit on for instance (these seats then only being available for the builder in the case where they have to move someone to a speak also seat for a specific purpose).

Well, yes. I have already implemented something I called seatPermissions (thanks goes to Howard who suggested it to me). But it will have the same limitations as the menuPermissions: It doesn't check the sitter on each change of the permission, only when you try to sit. If the seatPermission disallows you to sit, then the next seat is checked (regarding to the global option seatAssignList) and if no valid seat is found, then you will be unsit. Also currently neither the internal SWAP nor the internal PickSeat dialog is forced to respect the seatPermission (I currently don't know if it would fit into our memory budget).

When is V4 scheduled to be out?

Well, I hope until the end of the year or early in the next year. I wasn't online for a long time, thats not a problem for the coding part (I'm usally coding offline), but to do the alpha test. After alpha test I usually give it to Howard for testing and commenting.

@BadJenny
Copy link
Author

BadJenny commented Oct 4, 2019

Ok, so a couple more thoughts on this:

  1. Super excited to be able to add the UDPs to any command. This opens up lots of possibilties. MENUPROMPTs based on context, etc.
  2. Please consider using the full filter capabilities as currently implemented inside {} brackets in card names, and not just UDPs. In other words, allow for seat numbers as well. Reason being the original concern of this post where context had changed while a user's menu was open, potentially rendering the menu choices invalid. A change in context could be a UDP changing value, but it also could be a user changing seats (including a case where it wasn't by the user's own volition, I.e. someone else swapped with them).
  3. Adding a command to force a menu update on any sitter. Combined with the filter described above, the builder could design the remenu in such a way that it only impacts those who actually need it. A good example here is the involuntary seat change noted above. Using the filter, you could check the context that the sitter has been involuntarily moved to and offer up a new menu with choices appropriate to the new context. I think being able to do this is important and outweighs the concerns of new menus popping up driving you nutty, mostly because it would be pretty rare.
  4. As I mentioned above, this feature will allow the builder to work around the issue of an open menu becoming invalid. However, if you do decide to add this as a check within the scripts, it should check against the full filter to address the possible seat change issue as well (probably you have already thought of that). And, if this is implemented, there would ideally be some kind of event ( ONMENUFAIL? ) that is broadcast that the builder could trap and respond to in the case where the double check of context results in an invalid choice. This would allow the builder to respond and, combined with the remenu command noted above redirect the sitter to a valid menu.

Example where Sitting is a Boolean UDP and Standing is a menu group:
ONMENUFAIL{1 & !Sitting}|REMENU|sitter1|Main:Standing

  1. I mentioned this to Howard already, and it's really a separate issue, but since it's related to the subject of context I am bringing it up here: There needs to be a way to trap a true unsit event. The current ONUNSIT is useful for rezzing props and so forth, but really it's a pose change event and not an UNSIT event because it fires whenever the pose changes, or someone enters/exits the seat including swaps with other sitters.
    I'm suggesting that we need an event that fires only when the seat is vacated, which would exclude someone swapping in with another user. Reason here is that vacating a seat could change the context and you would then want to update UDP's appropriately or posisbly do a different pose set, while so long as someone is in the seat the context is valid and you don't want to do anything.

It's probably evident that I've been running into limitations with V3 and I am excited for version 4. Probably you have considered some or all of these ideas already but regardless I do hope this feedback is helpful!

Thank you guys so much for volunteering your time and efforts into the nPose project, you rock!

@LeonaMorro
Copy link
Member

(2) yes, thats the way I like it, too. BTW. in V3.10 you can already use the {singe integer value} (where the single interger value is a seatnumber) with all commands (but MENUPROMPT). Example:

DOCARD{1}|cardname only gets executed if the menu user is sitting in seat one.

(3+4) Again, currently I don't think this can be implemented (but I have to take a look at it), so don't expect that this will become part of the (initial) V4 release.

(5) There is something like that inside the nPose-SAT-NOTSAT-Plugin. But currently it is only usable from inside your own script (and it may be changed in the future). Please have a look at hte beginning of the nPose SAT-NOTSAT Plugin below the comment //generic message numbers. This events will be send with the corresponding number and data if you enable them via the global option enableEvents. Example:

if you use this (for example in your .init file):

OPTION|enableEvents=16

then the nPose-SAT-NOTSAT-Plugin will generate a linkmessage with the number -704 and the string seatnumber and the key avatarUuid everytime a user unsits from the nPose Object. A small script for using it to manipulate an UDP would look like this:

//don't forget to place `OPTION|enableEvents=16` into your .init file
//this piece of code isn't tested
integer ON_LOST=-704;
integer DO=220;
integer seatNumberYouWantToObserve=2;

default {
	link_message(integer sender_num, integer num, string str, key id) {
		if(num==ON_LOST) {
			if(seatNumberYouWantToObserve==(integer)str) {
				llMessageLinked(LINK_SET, DO, "UDPBOOL|yourUDPName=yourUDPValue", id);
			}
		}
	}
}

I do hope this feedback is helpful

Of course!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants