Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.


Dark Dreams of Furiae - a new module for NWN:EE! Buy now
Attention, new and old users! Please read the new rules of conduct for the forums, and we hope you enjoy your stay!

Applications of the UI

AquadrizztAquadrizzt Member Posts: 1,022
I'm unfamiliar with the internal workings of the UI system, so I figured I'd ask and let someone who actually knows what's going on answer my question.

Are UI elements able to cause in-game effects? For example, could you add a toggle above the hotbar that grants improved movement speed? If so, could that toggle be only made available to certain characters (such as only Barbarians and Monks)?

If this is possible, how would one go about implementing it?


  • BubbBubb Member Posts: 834
    edited April 2018
    The UI is largely disconnected from the rest of the game. Basically, the only interaction the UI can have with the game world is through console commands. It might be possible to do what you are describing by having the button use C:CreateCreature to create an invisible and non-colliding creature. This summoned creature's script could apply a spell to all party members that applies opcode 176; you could even have this script check for player class, if you wish. To disable the speed you could use opcode 321, again using the invisible-creature trick, and this time applying a "speed removal" spell. I've attached a rough version of what you are describing; I think you would learn more from looking at that than me trying (and probably failing!) to explain all of the details. :)

    Edit: I forgot to mention, the rough example I attached is for BG2EE

    Post edited by Bubb on
  • AquadrizztAquadrizzt Member Posts: 1,022
    edited March 2018
    @Bubb, cool I'll poke through your code.

    To further explain the context of the question, I'm trying to implement some form of 5e Style Bonus Actions/Reactions.

    My thoughts were to have Reactions be contingencies you toggle on or off, which only activate if you haven't Reacted in the last round. A UI toggle for each possible Reaction your character can make will make the management of such a system much less unwieldy (as you don't have to go into a dialog menu to change the configuration).

    Bonus actions basically say how you spend your "not attacking or casting a spell" action each round. So a set of buttons that you can press to perform one of your bonus actions would make that much less miserable. (For example, I could have my Barbarian Enter or Exit Rage as a bonus action instead of taking their main action.)

    It looks like this *is* possible because of the ability to tie scripts to buttons. That's really exciting.

    EDIT: Is it possible to change the buttons presented depending on the character you have currently selected?

    EDIT2: Is it possible to target only the currently selected character with the script?

    Post edited by Aquadrizzt on
  • BubbBubb Member Posts: 834
    I've updated the with an example of how to switch between which buttons are showing based on what class the currently selected character is.

    The issue of only targeting the currently selected player is a tough one. I don't think that is possible, to be honest. There isn't enough cross-talk between the UI and the game environment to accurately do it.. sorry :(

  • AquadrizztAquadrizzt Member Posts: 1,022
    edited March 2018
    @Bubb, that's a shame. Thank you anyway for all the help. I'm sure there's a roundabout solution, but no idea what it would be without further investigation.

    EDIT: Would you mind clarifying the exact behavior of the code you wrote? I see the class checks, but I'm not sure how those tie into the buttons that are displayed. (Sorry for all the questions.)

    Perhaps this is also a stupid question, but parts of the UI seem to refer to character[currentID]., is there not some way that you could read the current character and pass that to the script somehow?

    EDIT2: Hacky thought of the day: you can check a creature's stats to determine which buttons are visible right? Why not just assign every party NPC to a different value of the tracking stat? Imoen is 1, Jaheira is 2, etc... This gives you 256 unique identifiers from just tracking (which is not actually used by any system, including the Tracking HLA).

    And then you can fine-tune targeting because the summoned creature's can specifically target them.

    Post edited by Aquadrizzt on
  • BubbBubb Member Posts: 834
    The key in the button-switching is the Infinity_PushMenu() calls. Basically, bubbShowSpeedButtons() is deciding which button to show based on the character's current class. Infinity_PushMenu() is what is used to "open" a menu and display it to the user. Infinity_PopMenu is the inverse of Infinity_PushMenu; it closes the specified menu and hides it from the user. bubbShowSpeedButtons() is hiding all the menus which contain the wrong buttons, and showing the one that has the right buttons. In my example, the only difference between the two buttons (contained in BUBB_SPEED_MAGE and BUBB_SPEED_FIGHTER) are the tooltips.

    You are correct; UI.MENU does indeed know the currently selected character, I just can't see a way of passing it to the scripting environment as a object. I'm pretty sure the id variable that is used to access the current character is an internal reference to the character, though I don't believe we can use it anywhere else. I've tried many times to figure out a way to target specific characters with a script from the UI; I just cannot get something to remotely work, not even a hacky workaround. :/

  • kjeronkjeron Member Posts: 2,329
    edited March 2018
    Bubb said:

    I'm pretty sure the id variable that is used to access the current character is an internal reference to the character, though I don't believe we can use it anywhere else.

    The creature ID in the UI is the combined global and local id of the creature (the number stored in the 4 bytes at 0x27c of the CRE file), not that it helps any. Those id's are reset every time an area is loaded/reloaded, and the only manner I've ever seen it utilized is when opcode 237 stores it in stats [138][PUPPETMASTERID] and [139][PUPPETID].

  • The user and all related content has been deleted.

  • AquadrizztAquadrizzt Member Posts: 1,022
    @subtledoctor , tying it to a spellstate is clever. I'm positive there is some way to identify unique characters through the spell check (probably by a unique stat identifier).

    Have the script cast the effect on all characters in the party, but the spell only affects people with exactly X tracking, or this kit, etc. (How often do you run two characters of the same kit, etc.) It's a bandaid to be sure, but it means that you can have UI buttons that typically only affect a single character.

  • AquadrizztAquadrizzt Member Posts: 1,022
    At the very least, one could trivially implement a Short Rest mechanic (a la 5e). Just have the script make 1-2 hours pass, heal everyone for 3d8 or whatever, maybe recharge some spell slots/abilities.

  • BubbBubb Member Posts: 834
    I don't know if you are still interested in this - but I did manage to figure out a *really* hacky way of specifically targeting Player1-6 from the UI. It has to do with giving each player a marker spell, and then detecting this marker spell in the UI to figure out their scripting object. I've updated the with the code, if you are interested.

  • GreenmanGreenman Member Posts: 1
    @Bubb That is really cool, very clever way of doing this :)

    In function scheduleCompilePlayerIds() you write that you have to put something in the log to prevent quickload check from firing more than once. What do you mean by this?

  • BubbBubb Member Posts: 834
    Wow, it's been a while since I did this bit of hackery! :)

    @Greenman: The way the code detects a reload is by checking if the combat log is empty. Once a reload is detected, I have to throw a line into the log to prevent that check from firing indefinitely, (since the only thing it is checking for is an empty log).

Sign In or Register to comment.