Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Neverwinter Nights: Enhanced Edition has been released! Visit nwn.beamdog.com to make an order. NWN:EE FAQ is available.
Soundtracks for BG:EE, SoD, BG2:EE, IWD:EE, PST:EE are now available in the Beamdog store.
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: 882
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?

Comments

  • BubbBubb Member Posts: 377
    edited April 2018
    @Aquadrizzt
    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
    Aquadrizzt
  • AquadrizztAquadrizzt Member Posts: 882
    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: 377
    @Aquadrizzt
    I've updated the override.zip 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: 882
    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: 377
    @Aquadrizzt
    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: 1,468
    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].

    Bubb
  • subtledoctorsubtledoctor Member Posts: 9,857
    @Aquadrizzt here's a possibility for an alternative implementation:

    I don't think contingencies would work very well, because they are slow to trigger. So they might not adequately reflect a reaction.

    BUT, you could patch target: living actor spells to add a 326 effect conditioned on the target having a particular spellstate; and you could apply the same as an on-hit effect of weapons. And then have the player toggle the spellstate on and off. This way you could have extremely fine-tuned contingency conditions:
    - any time you are affected by fire damage;
    - any time you are affected by fear;
    - any time you are hit by a +3 or greater magical weapon;
    - ...all sorts of stuff

    And they would trigger instantly as part of the spell or weapon effect causing the reaction.

    This is of course unrelated to the question of whether you could have a UI element set to toggle the spellstate on or off, of course. Just thinking out loud about the other half of your idea.

  • AquadrizztAquadrizzt Member Posts: 882
    @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: 882
    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: 377
    @Aquadrizzt
    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 override.zip with the code, if you are interested.

Sign In or Register to comment.