Thread Tools Display Modes
04/24/23, 05:30 AM   #1
Simon Belmont
 
Simon Belmont's Avatar
Join Date: Nov 2020
Posts: 3
Crouch / Stand (unCrouch)

Hello and firstly, I am brand new to ESO's API.

Most of my "coding" experience was back in the days when Morrowind modding was going gangbusters, and since then in AutoHotkey; just to give you some vague idea of 'where I'm coming from'.

My goal is to find a means of converting the Crouch "toggle on/off" action into two separate "one-way toggle" actions.

But, before I bother altering-a/creating-a-new Keybind in a .lua, I thought I'd just ask real-quick if this .xml is viable. IE: am I doing it wrong?

I did poke around ESOUI's Addon Wiki but got pretty lost. Thanks,

.xml
Code:
<Bindings>
	<Layer name="SI_KEYBINDINGS_LAYER_GENERAL">
		<Category name="SI_KEYBINDINGS_CATEGORY_COMBAT">
			<Action name="SPECIAL_MOVE_CROUCH">
				<Down>
					if not GetUnitStealth(player) >= 2 then
						OnSpecialMoveKeyPressed(SPECIAL_MOVE_INDEX_CROUCH)
					end
				</Down>
			</Action>

			<Action name="SPECIAL_MOVE_STAND">
				<Down>
					if GetUnitStealth(player) >= 2 then
						OnSpecialMoveKeyPressed(SPECIAL_MOVE_INDEX_CROUCH)
					end
				</Down>
			</Action>
		</Category>
	</Layer>
</Bindings>
I would also settle, should the above prove impossible, for the Crouch-key to be a one-way (into) Stealth action; as there are already many ways in this game to exit Stealth, without specifically "uncrouching".

Thank you very much for taking the time to read this.

Last edited by Simon Belmont : 04/24/23 at 05:34 AM. Reason: syntax
  Reply With Quote
04/24/23, 06:07 AM   #2
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,966
Hi Simon,

I'm not sure if this will work as some of the move etc. keybinds are protected in a way you cannot change or missuse them for botting.
If the default crouch keybind provides an API function that will toggle the change (I assume this is OnSpecialMoveKeyPressed(SPECIAL_MOVE_INDEX_CROUCH) ? ) then you should be able to put some lua if .. then around it as you did, to make 2 keybinds of it.

This Bindings.xml needs to be included in your addon's manifest (YourAddon.txt file) then so it get's loaded.
https://wiki.esoui.com/Addon_Structure
https://wiki.esoui.com/Addon_manifest_(.txt)_format

https://wiki.esoui.com/Keybindings


Edit:
I just saw that SPECIAL_MOVE_CROUCH already is the vanilla code's name of that keybind!
So you cannot overwrite this, you need to create your own one like

<Action name="MYADDON_SPECIAL_MOVE_CROUCH">
<Action name="MYADDON_SPECIAL_MOVE_STAND">

And use ZO_CreateStringId to define the texts for the keybinds too in your lua files:

ZO_CreateStringId("SI_BINDING_NAME_MYADDON_SPECIAL_MOVE_CROUCH", "Crouch on")
ZO_CreateStringId("SI_BINDING_NAME_MYADDON_SPECIAL_MOVE_STAND", "Crouch off")


Edit2:
Another hint: API functions like GetUnitStealth return a stealth state variable (number).
The API documentation (linked at the WIKI -> API version https://wiki.esoui.com/APIVersion -> current live https://wiki.esoui.com/APIVersion#live_API_version e.g. or PTS https://wiki.esoui.com/APIVersion#PTS_API_version if you are on the Public Test Server API documentation txt file, e.g. for the live version: API TXT Documentation: https://www.esoui.com/forums/attachm...6&d=1675236301)
provides you the type of the returned number format AND a list of that type.

Code:
* GetUnitStealthState(*string* _unitTag_)
** _Returns:_ *integer* _stealthState_
In this case it's stealthState

Search for that in the same file:
Code:
h5. StealthState
* STEALTH_STATE_DETECTED
* STEALTH_STATE_HIDDEN
* STEALTH_STATE_HIDDEN_ALMOST_DETECTED
* STEALTH_STATE_HIDING
* STEALTH_STATE_NONE
* STEALTH_STATE_STEALTH
* STEALTH_STATE_STEALTH_ALMOST_DETECTED
Now you got the global constant names and shuld use those instead of 2 or 1 numbers, as the numbers could change!
STEALTH_STATE_NONE = 0 I think, so you could use the "crouch" keybind if the state is currently none, and if it's not none uncrouch = stand?

Code:
<Bindings>
	<Layer name="SI_KEYBINDINGS_LAYER_GENERAL">
		<Category name="SI_KEYBINDINGS_CATEGORY_COMBAT">
			<Action name="MYADDON_SPECIAL_MOVE_CROUCH">
				<Down>
					if GetUnitStealth(player) == STEALTH_STATE_NONE then
						OnSpecialMoveKeyPressed(SPECIAL_MOVE_INDEX_CROUCH)
					end
				</Down>
			</Action>

			<Action name="MYADDON_SPECIAL_MOVE_STAND">
				<Down>
					if GetUnitStealth(player) > STEALTH_STATE_NONE then
						OnSpecialMoveKeyPressed(SPECIAL_MOVE_INDEX_CROUCH)
					end
				</Down>
			</Action>
		</Category>
	</Layer>
</Bindings>

Last edited by Baertram : 04/24/23 at 06:20 AM.
  Reply With Quote
04/24/23, 10:17 AM   #3
Simon Belmont
 
Simon Belmont's Avatar
Join Date: Nov 2020
Posts: 3
Just a quick reply here to say thank you Baertram, for a very prompt and thorough reply!

As I'm very new to this scripting language, it will take me some time to digest all the info that you've included. Though, green as I am to the API, a lot of this is making sense.

For example, I didn't know that we could not re-define the stock .xml Actions. And I somehow doubt that would have returned a proper error, had I tried. Which would have left me chasing my tail for at least a while!

I also didn't know that an if statement could inquire after a function, by name, rather than by numeric value. Very good to know!

I'll do more reading; starting with the links you've provided. When I have further iterations or questions, I'll be back to post them here. I'm sure there's a way to do this; despite any protected or private denotations (but keeping well-within the TOS, of course).

Thanks again!
  Reply With Quote
04/24/23, 11:41 AM   #4
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,966
Important hint:
IsUnit* and GetUnit* API functions need an unitTag which is a string by default so you need to use "player" and not player!
if GetUnitStealthState("player") ... -> else it won't work.

For example, I didn't know that we could not re-define the stock .xml Actions
I think we can for some of them, if it was not defined as noOverride or similar.
But it often leads to problems so better define your own and leave the stock/vanilla in place and unbind the key there.


I also didn't know that an if statement could inquire after a function, by name, rather than by numeric value. Very good to know!
STEALTH_STATE_NONE is actually a variable, a global one, no "name".
And it's value is a number, like your number 2.

All variables that are just defined, without using the "local" tag in front of it, will be added to the global table _G and is available lua wide (in the wole ESO environment) then!
Which makes defining variables always necessary to be local or at least added with a uniqueName if not local.

e.g.
local var = "test"

localt tab1 = {} -- local table
function tab1.myFunc(param1)
return var
end

MyAddon = {} --global table! All other addons and ESO environment got access to it now
local myAddon = MyAddon --local pointer to global table MyAddon! All other addons and ESO environment got access to MyAddon but only the current "scope" (like if ... then, for ... do, function() .... end, or the lua file where the local myAddon was defined at the top) got access to the local myAddon variable!




Here is a compilation for new addon devs, with links to the often asked questions, best practices, what addons can and cannot do etc.
https://www.esoui.com/forums/showthread.php?t=9867

If you got further questions feel free to join our Element / gitter chat too:
https://app.gitter.im/#/room/#esoui_esoui:gitter.im

Last edited by Baertram : 04/24/23 at 11:47 AM.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » Crouch / Stand (unCrouch)


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off