Jump to content

BindControl - Keybinds Generator and Manager


Recommended Posts

4 hours ago, emersonrp said:

Looks like "Teleport Combo Key" however will correctly cast the basic teleport power, as well as adding in the movement details settings, camera distance settings, and hiding the windows, so maybe it's what you're looking for?

Digging deeper I see that there was supposed to be some sort of interaction between "Teleport Combo Key" and "Teleport Bind Key" where "Bind Key" was only active when "Combo Key" was held down and otherwise did nothing.  There is also behavior intended for press and release functionality having to do with "hover during teleport" and this whole thing seems both a little bit overengineered and underfeatured, missing some stuff from i27's Teleport revamp.

 

What you're wanting is to be able to bind double-click to cast "teleport to max distance," right?  Forward, or in the direction the camera is facing?  I'm considering adding that, leaving combo key as the "hold to teleport" function, and coming up with some scheme for Combat Teleport.  Any requests?

Link to comment
Share on other sites

On 2/8/2023 at 12:05 AM, emersonrp said:

What you're wanting is to be able to bind double-click to cast "teleport to max distance," right?

 

I don't know if this helps anything, but I made pop-up menus for a handful of my characters to help manage their teleport (and related things like jaunt, translocate, and mystic flight) and targeted AOE powers. Then I bound that menu to the E key. Here's the content of one of the files:
 

    //
    Menu Erasyerhead
        {
        Title "Teleport"
        Divider
            Option "&A Combat TP to Target" <&powexec_location target Combat Teleport&>
            Option "&S Retreat" <&powexec_location back:60 Combat Teleport$$face&> // Since I plan on using this in combat, 
            // I want the bonus that Combat Teleport gives. This is for when you port right to an enemy, execute a melee attack like Sands of Mu, then want to jump back to use ranged attacks. "Face" is necessary to keep toon facing same direction. 
            // Without it, character will turn 180 degrees, which would be disorienting, unless you plan on running away.
            Option "&D TP Target to Self" <&tell $target, I'm teleporting you to my location...$$powexec_location forward:10 Teleport Target&>
            Option "&F TP to Target" <&powexec_location target Teleport&>
            Option "&R TP Ring" <&powexecname Teleport&>
        Divider
            Option "&W Up And Away!" <&powexec_location up:max Teleport&>
            Option "&E BUG OUT!" <&powexec_location back:max Teleport&> // When you want to turn and run in opposite direction. Turn 180 degrees and teleport far away.
        }


I found it useful to make the character-specific pop menu key and "BUG OUT!" key the same since if I'm panicking and need to get away ASAP, I can't always remember which menu key to press. This way, I don't have to since I just have to hit "E" twice to try escaping certain death.

I couldn't get the turn-around command to work with (IIRC... been a while) teleport-adjacent powers like Jaunt.

I also made a bunch of .cbm simple bind files for CityBinder containing various commands like that. If you don't want to grab them from a .zip file, you can find the loose files here: https://sourceforge.net/projects/citybinder-for-homecoming/files/unfinished_CB4H_v0.2/Sample_Binds/Simple/

I didn't really use CityBinder's SoD module since it was clunky and confusing, so I can't say how useful or not it'd still be since the travel power update, but maybe the module could have separate tabs for each type of movement (especially if you'd like to offer different uses like in the menu above).

I wonder if having Kheldian settings as its own module would make more sense than how CityBinder did it as a section that only appears in SoD if you select one of those Archetypes.

Link to comment
Share on other sites

1 hour ago, Tailcoat said:

I didn't really use CityBinder's SoD module since it was clunky and confusing, so I can't say how useful or not it'd still be since the travel power update, but maybe the module could have separate tabs for each type of movement (especially if you'd like to offer different uses like in the menu above).

 

I've been pondering just that, esp after seeing how you expanded Inspiration Popper that way.  Really it's always been the case that the "Speed on Demand" module has more in there than just speed on demand, so I'm mulling yeah changing it to "Movement Powers" and making Speed on Demand a subset of it.  Then, yeah, put Teleport in its own tab for sure and add in combat TP and stuff from your popmenu and so forth.  I think the speed on demand stuff is still useful to leveling characters who can sometimes be endurance-starved, so I think I'm going to continue to have it in there, but it does need a rethink for the travel power changes.

 

I already have the "just show Kheldian UI to Kheldians" functionality in there though the whole thing is commented out because I don't have the Kheldian binds working correctly (I need to level a couple on Homecoming still), but it could be its own tab too, that's only visible to kheldians.  I mean, similarly, if stuff all gets broken out into tabs, it could just show the ones that are in the power pool picks in the main character UI.

 

I start to wonder if it might not be useful to be able to create / write popup menu files, but that's a whole other ball of wax.

 

I'm going to look at your sample binds later this evening -- I got your version 0.2 downloaded and working, which is awesome, thank you.

 

 

Additionally, I made a quick change to the existing Teleport functionality so that the teleport bind key, formerly 'nop,' now casts "powexec_location cursor:max" on the teleport power, and does the right thing bound to double-click;  and the teleport combo key shows the target ring like it always has, but a little more cleanly since it's not interacting with the teleport bind key any more.  I'm going to upload that here in a little bit just to see how it plays for people.  I think it's a good marginal improvement.

 

Edited by emersonrp
cursor, not camera
  • Thumbs Up 1
Link to comment
Share on other sites

Just released v0.8.3 which makes changes to the possible teleport binds:

"Teleport to Cursor" which will immediately teleport the max distance toward the cursor, good for use with click / double-click binds

"Show Teleport Reticle" which will show the targeting reticle while held, like the existing "Teleport Combo Key" did.

Link to comment
Share on other sites

Looks like the latest build has fixed my issues.  Teleport works properly with ldblclick.  Can enter missions/buildings properly.  lshift+lclick works properly to trigger Caltrops (thought at first it was broken, but it's the CoH UI showing Caltrops as being recharged too soon).  Plus, my ctrl+spacebar chat channel bind workds too!  My wishlist item would be to have options set as defaults (for example, always having TeamSelect binds as part of a profile and custom simple binds [chat] included).

 

 

 

Link to comment
Share on other sites

10 hours ago, DevoDog68 said:

Looks like the latest build has fixed my issues.  Teleport works properly with ldblclick.  Can enter missions/buildings properly.  lshift+lclick works properly to trigger Caltrops (thought at first it was broken, but it's the CoH UI showing Caltrops as being recharged too soon).  Plus, my ctrl+spacebar chat channel bind workds too!  My wishlist item would be to have options set as defaults (for example, always having TeamSelect binds as part of a profile and custom simple binds [chat] included).

Awesome, glad to hear it's working for you.

 

The "default profile" feature was in the original CityBinder, but I never got around to implementing it yet.  I can see a pretty quick path to it, knock wood, so I may see if I can bash that together.  You'd just put together a profile, "Save as Default" and then any time you did "New Profile" it would start with that one.

 

In other news, I have reimplemented (read: gratefully copied) much of Tailcoat's work on the Inspiration Popper, and after a bit more tinkering and testing will release that.  Tailcoat's UI decisions are so much better than mine...  😉

 

Additionally I'm continuing slowly to work on movement powers as a class, including detangling the notion of speed on demand from the core notion of binding keys to movement.  It's slow going because the existing speed-on-demand stuff is very very tangly and not super-well documented, as well as reliant on conceits that are no longer true, like, say, "Hover" and "Fly" being mutually exclusive.  I need to work out what people want to do with speed on demand (if anything, is this simply a dead idea?) in a post-i25 world.

Edited by emersonrp
  • Thumbs Up 1
Link to comment
Share on other sites

  • emersonrp changed the title to BindControl (alternative to CityBinder)

I've been wondering if it would be useful if users could choose separate paths for saving profiles vs. generated files. It'd be convenient for an app to be able to take the profile's name and create a folder with that name when the profile is saved. It could be an optional setting.

Link to comment
Share on other sites

On 2/19/2023 at 10:17 PM, Tailcoat said:

I've been wondering if it would be useful if users could choose separate paths for saving profiles vs. generated files. It'd be convenient for an app to be able to take the profile's name and create a folder with that name when the profile is saved. It could be an optional setting.

 

So, like, create a subfolder in Documents for the profile (and currently-hypothetical other profile-related files), or do you mean specify a full arbitrary path for saving the profile, anywhere in the filesystem?  Currently the profiles are saved to %userprofile%\Documents\bindcontrol\ProfileName.bcp (or the analogous location on Mac and Linux), and the keybinds are saved to the location specified in preferences.

Link to comment
Share on other sites

7 hours ago, emersonrp said:

 

So, like, create a subfolder in Documents for the profile (and currently-hypothetical other profile-related files), or do you mean specify a full arbitrary path for saving the profile, anywhere in the filesystem?  Currently the profiles are saved to %userprofile%\Documents\bindcontrol\ProfileName.bcp (or the analogous location on Mac and Linux), and the keybinds are saved to the location specified in preferences.

 

I meant allow the user to specify a full path for the profiles anywhere. Personally, I never save anything to the default C:\Documents folder and I keep gaming stuff in a separate folder. I've been keeping my binds and profiles in character-specific subfolders like this:
image.thumb.png.eb0a1040e0dc3a0ccf33690b934c8b3c.png

The idea about subfolders I had was separate from that but similar to your first idea. If I made a new profile for my character Erasyerhead (or a general profile called Warshade Binds) and entered that as the profile's name then hit "Save As", if the app didn't detect a pre-existing folder called "Erasyerhead" in my chosen directory, it could ask to create one, then save the binds or profiles inside.

 

Edited by Tailcoat
Link to comment
Share on other sites

  • 3 weeks later

Sorry for the silence;  this spring is pretty busy for me so I'll be getting to this sporadically.

 

I'm totally going to look into implementing the full-path and probably the auto-subfolder ideas mentioned above;  I think these are both good QoL improvements.

 

 

Meanwhile, I've just released v0.10, implementing the bulk of the Inspiration Popper UI / logic from CB4HC 0.2, and many many thanks to tailcoat for releasing that previously-unreleased version for me to pick through.  Please check it out and let me know your luck with it!

 

Link to comment
Share on other sites

  • 4 months later

I know I've been silent here for quite a while, but I got a feature request on github so I am tinkering again with how to improve the movement powers bindings to include more recent changes and additions.  Look for an update in a bit, here.

Link to comment
Share on other sites

  • 2 weeks later

I've just added a prerelease "movementpowers-alpha-0.1" that incorporates many of the movement powers improvements that have been needed to bring the speed-on-demand binds into the modern era.  It is not at all rigorously tested, and almost certainly not even in its final form, but any feedback would be deeply appreciated.

 

https://github.com/emersonrp/bindcontrol/releases/tag/movement-0.1

Link to comment
Share on other sites

Is BindControl able to be modified by players? I'm thinking more along the lines of City Mod Installer, where people add the mods they've made, and the app offers them up as an option for anyone with the app. 

 

I'm sure there's a ton of players who have created AMAZING binds and macros who would love to share. It would also take a lot of burden off of you by allowing others to create content/binds. At most, you'd have to test the binds to see if they work as intended for a little quality control. Anyway, just an idea. 

 

 

  • Like 1
Link to comment
Share on other sites

10 hours ago, BlackSpectre said:

Is BindControl able to be modified by players? I'm thinking more along the lines of City Mod Installer, where people add the mods they've made, and the app offers them up as an option for anyone with the app. 

 

I'm sure there's a ton of players who have created AMAZING binds and macros who would love to share. It would also take a lot of burden off of you by allowing others to create content/binds. At most, you'd have to test the binds to see if they work as intended for a little quality control. Anyway, just an idea. 

 

 

 

CityBinder had a notion of importing and exporting configurations for each individual window, and individual binds for the various custom-binds schemes, that I currently haven't reproduced in BindControl.  Tailcoat, in his work on modernizing CityBinder, was planning to include a collection of interesting configuration snippets, and it's an idea I really like in principle.

 

It's not something that's trivial to do but isn't at all impossible, I'd just need to design and implement it in a BindControl-appropriate way, and wedge it in there.  Having a library of cool binds seems like a win for everyone, I agree, so I'm going to put some thought into this.  Thanks for the suggestion!

  • Thumbs Up 1
Link to comment
Share on other sites

2 hours ago, emersonrp said:

CityBinder, was planning to include a collection of interesting configuration snippets


When updating CityBinder, I considered a couple of ways of making it easier for players to add and share modules.

As mentioned, I did include a bunch of snippets, although those files only work with CityBinder, but could provide useful material to adapt for BindControl. They're in the "Sample_Binds" folder included in my SourceForge uploads, which only work with CityBinder's modules for Simple (in the "Custom Binds" section), Complex (binds requiring multiple txt files), and Ultra binds. I never figured out Ultra binds and it wasn't documented much, so that file is just what was included in the original CityBinder just in case anyone else could figure it out. I think Ultra binds were meant to help people make more complex modules w/o needing to know coding? It's an interesting idea. Below, I've included some screenshots of the kinds of binds I included. Several are movement related, so would best be incorporated into a movement module if that hasn't been done already. I can explain what they are if anything interesting jumps out.

The other thing I started to make modules shareable (but wasn't able to finish in the last stable version of CB. However, it should work in the unfinished v0.2 files I uploaded to SourceForge.) was instead of hard-coding the modules into the script that loads them up, I had it check its current directory for a subfolder called "modules" and load up the .lua files in there. Within that folder was another called "inactive" so files can easily be taken out of rotation without deleting them (it was useful for bug testing).
In those LUA files, I added some more variables to help categorize the modules into a tree and also generate credit info in a popup if the user clicks the button for that. Including the last update as a variable could also help authors (should they change how their code works) find and update things used in previous versions of the app (or it may make more sense to focus on versions of the module itself instead). I pasted an image of the text next to the popup to illustrate my attempt at improving user-friendliness to encourage people to make and share their own modules.

 

I even worked on trying to de-hard-code the interface colors and turn them into variables in an attempt to create a dark mode option (and down the road, potentially programming in customization options for interface colors), but I just couldn't get Lua to do what I wanted consistently!

image.thumb.png.79a4cdb7fa8d6a1184526c2fe796579f.png

image.thumb.png.19cf213f8e22e7ed16629a7332c0de39.pngimage.thumb.png.37adccfe4eb2e7470b02dc7d0beecd23.png

Edited by Tailcoat
clarification of where to upload a Simple Bind in CB
  • Thumbs Up 2
Link to comment
Share on other sites

  • 2 weeks later

I also keep mulling how possible it might be to take the text representation of a bind and split/parse it into a Complex Bind.  Then, assuming I put together a scheme to import/export custom binds, it would be possible to convert a raw bind string into an import/export-able chunk for easier sharing and editing.  This might be overly optimistic but I may look into trying it.

Link to comment
Share on other sites

6 hours ago, emersonrp said:

I also keep mulling how possible it might be to take the text representation of a bind and split/parse it into a Complex Bind.  Then, assuming I put together a scheme to import/export custom binds, it would be possible to convert a raw bind string into an import/export-able chunk for easier sharing and editing.  This might be overly optimistic but I may look into trying it.

 

If it helps, here are the basics of what CB did using a complex bind I set up that makes the character do a different dance every time the user presses "Y".

The Complex Bind button pulls up a table (I'd recommend adding a pale background color to every other row to make it clearer to the user that each row is associated with the keybind at the start of it). I entered "Y" for the bind and added a different dance emote command to each space in that row. I chose 8 that I felt segued decently into each other (In CB, you can add up to 599 commands to a row, which I think is overkill!). Pressing the ">>" button lets the user view any other user-defined Complex Binds that may've been imported into the profile (in this case, there are 4 Complex Binds loaded and the dance cycle is the first). You can have one "page" with multiple Complex Binds on it too by using more than one row.
Here's a screencap of how the dance bind cycle looks in CB:
image.thumb.png.f27eb43959f26acb5fe0ccbe16a4b2d6.png 

 

When the user hits the Generate Bindfiles button, CB makes TXT files for the game to read which include the "bindloadfilesilent" command after the dance command. CB generates numerical number names for them in a subfolder called "cbinds". I'm thinking that the first number in the file name is taken from the "page" number of the Complex Bind, then the second number comes from the "Cycle" column. This is in the folder for the default profile I set up for CB, which contains multiple Complex Binds. Here's a screen of how those look in file explorer, plus the opened TXT files:
image.thumb.png.9b14f4b1f847abf618d0e7e234907548.png


CB uses its own file extension ".cbm" for imported/exported binds. The extension ".cbp" is for profiles. The .cbm files can be opened in Notepad. Here's what the exported dance cycle Complex Bind looks like: 
image.thumb.png.88b6f226c34fa29c2fa4d8fbd0232f60.png

 

I wasn't aware of all the workings of how CB generated binds, but skimming through some files, I think a lot of that stuff is in the file "cbutility.lua" if you want to check it out.

EDIT:
If you do check out the CB files I worked on, just be aware that there will be differences between the files contained in the last stable version of CB4H and the unfinished v0.2 version.

"cbutilityUI.lua" contains code related to import/export buttons, which must link back to cbutility.lua.

The Complex Bind module file, "complexbinds.lua" could be especially useful for ideas. Here's the code for that:
 

local module = {}

local function addCBind(cbinds,n,profile) -- this returns an IUP vbox/hbox to be inserted into the CBind Dialog box
	local cbind = cbinds[n]
	local bindtext = iup.label{title = ""; SIZE = "100X"}
	local function matrix_value(_,l,c)
		if l == 0 then -- return the titles of columns
			if c == 0 then return "" elseif c == 1 then return "Bindkey" else return "Cycle "..(c - 1) end
		elseif c > 0 then -- return the values of the bindkeys
			if cbind[l] == nil then return "" end
			if c == 1 then return cbind[l].bindkey or nil else return cbind[l][c-1] or nil end
		end
	end
	local function matrix_value_edit(_,l,c,newval)
		cbind[l] = cbind[l] or {} 
		if newval == "" then newval = nil end
		if c == 1 then cbind[l].bindkey = newval else cbind[l][c-1] = newval end profile.modified = true 
		return iup.DEFAULT
	end
	local function matrix_entercell(_,l,c)
		if cbind[l] == nil then bindtext.title = "" else
			if c == 1 then
				bindtext.title = cbind[l].bindkey or ""
			else
				bindtext.title = cbind[l][c-1] or ""
			end
		end
		return iup.DEFAULT
	end
	local altBGcolor = 50, 50, 50
	local matrix = iup.matrix{numcol="600";numlin="50";numcol_visible="5";numlin_visible="10";
		height0=8;value_cb = matrix_value; value_edit_cb = matrix_value_edit; enteritem_cb = matrix_entercell}
	for i = 2,600 do matrix["alignment"..i] = "ALEFT" end
	
	local delbtn = cbButton("Delete This Bind",function()
		if iup.Alarm("Confirm Deletion","Are you sure you want to delete this bind?","Yes","No") == 1 then
			table.remove(cbinds,n)
			cbinds.curbind = cbinds.curbind - 1
			if cbinds.curbind == 0 then cbinds.curbind = 1 end
			cbinds.dlg:hide()
			--cbinds.dlg:destroy()
			cbinds.dlg = nil
			module.createDialog(cbinds,profile)
			cbShowDialog(cbinds.dlg,nil,nil,profile,cbinds.dlg_close_cb)
			profile.modified = true 
		end end,125)
	local exportbtn = cbButton("Export...",function() cbExportModuleSettings(profile,n,cbinds,"ComplexBind") end,125)
	return iup.frame{iup.vbox{bindtext,matrix,iup.fill{rastersize="x10"},iup.hbox{delbtn,exportbtn,margin="0x0"},iup.fill{rastersize="x10"},alignment="ACENTER"},cx = 0, cy = 65 * (n-1)}
end

local function newCBind() -- this returns the default empty Simple Bind table to be inserted into SBinds
	local t = {}
	return t
end

function module.createDialog(cbinds,profile)
	local box = {}
	for i = 1,table.getn(cbinds) do
		table.insert(box,addCBind(cbinds,i,profile))
	end
	cbinds.curbind = cbinds.curbind or 1
	local newbindbtn = cbButton("New Complex Bind",
		function()
			table.insert(cbinds,newCBind())
			cbinds.curbind = table.getn(cbinds)
			cbinds.dlg:hide()
			--cbinds.dlg:destroy()
			cbinds.dlg = nil
			module.createDialog(cbinds,profile)
			cbShowDialog(cbinds.dlg,nil,nil,profile,cbinds.dlg_close_cb)
			profile.modified = true 
		end,125)
	local importbtn = cbButton("Import Complex Bind",function()
		local newcbind = newCBind() -- we will be filling this new BBind up.
		table.insert(cbinds,newcbind)
		local newcbind_n = table.getn(cbinds)
		if cbImportModuleSettings(profile,newcbind_n,cbinds,"ComplexBind") then
			cbinds.curbind = table.getn(cbinds)
			cbinds.dlg:hide()
			cbinds.dlg = nil
			-- Resolve Key COnflicts.
			cbResolveKeyConflicts(profile,true)
			module.createDialog(cbinds,profile)
			cbShowDialog(cbinds.dlg,nil,nil,profile,cbinds.dlg_close_cb)
			profile.modified = true
		else
			-- user cancelled, remove the new table from bbinds.
			table.remove(cbinds)
		end
	end,125)
	local sbEnablePrev = "NO"
	local sbEnableNext = "NO"
	local okbtn = cbOKbutton()
	if cbinds.curbind > 1 then sbEnablePrev = "YES" end
	cbinds.prevbind = cbButton("<<",function(self)
			cbinds.curbind = cbinds.curbind - 1
			cbinds.zbox.value = box[cbinds.curbind]
			cbinds.poslabel.title = cbinds.curbind.."/"..table.getn(cbinds)
			local sbEnablePrev = "NO"
			if cbinds.curbind > 1 then sbEnablePrev = "YES" end
			cbinds.prevbind.active=sbEnablePrev
			local sbEnableNext = "NO"
			if cbinds.curbind < table.getn(cbinds) then sbEnableNext = "YES" end
			cbinds.nextbind.active=sbEnableNext
		end,25,nil,{active=sbEnablePrev})
	if cbinds.curbind < table.getn(cbinds) then sbEnableNext = "YES" end
	cbinds.nextbind = cbButton(">>",function(self)
			cbinds.curbind = cbinds.curbind + 1
			cbinds.zbox.value = box[cbinds.curbind]
			cbinds.poslabel.title = cbinds.curbind.."/"..table.getn(cbinds)
			local sbEnablePrev = "NO"
			if cbinds.curbind > 1 then sbEnablePrev = "YES" end
			cbinds.prevbind.active=sbEnablePrev
			local sbEnableNext = "NO"
			if cbinds.curbind < table.getn(cbinds) then sbEnableNext = "YES" end
			cbinds.nextbind.active=sbEnableNext
		end,25,nil,{active=sbEnableNext})
	cbinds.poslabel = iup.label{title = cbinds.curbind.."/"..table.getn(cbinds);rastersize="50x";alignment="ACENTER"}
	box.value = box[cbinds.curbind]
	cbinds.zbox = iup.zbox(box)
	cbinds.dlg = iup.dialog{iup.vbox{cbinds.zbox,iup.fill{rastersize="10x"},iup.hbox{cbinds.prevbind;newbindbtn;importbtn;cbinds.poslabel;cbinds.nextbind;alignment="ACENTER",margin="0x0"};iup.fill{rastersize="10x"};okbtn;alignment="ACENTER"};title = "General : Complex Binds",maxbox="NO",resize="YES",icon = appicon,parentdialog=cbdlg,mdichild="YES",margin=dlgMargins}
	okbtn.action = function() cbinds.dlg:hide() end
	cbinds.dlg_close_cb = function(self) cbinds.dlg = nil end
end

function module.bindsettings(profile)
	local cbinds = profile.cbinds
	if cbinds == nil then
		cbinds = {}
		profile.cbinds = cbinds
	end
	if cbinds.dlg then
		cbinds.dlg:show()
	else
		module.createDialog(cbinds,profile)
		cbShowDialog(cbinds.dlg,nil,nil,profile,cbinds.dlg_close_cb)
	end
end

local function maxKeys(cbind)
	local maxK = 0
	for n = 1,600 do
		if cbind[n] then
			if cbind[n].bindkey and not (cbind[n].bindkey == "") then
				maxK = n
			end
		end
	end
	return maxK
end

local function maxCycles(cbind,maxK)
	local maxC = 0
	for m = 1,maxK do
		for n = 2,600 do
			if cbind[m][n] and not (cbind[m][n] == "") then
				if n > maxC then maxC = n end
			end
		end
	end
	return maxC+1
end

local function writeBind(file,cbinds,key,cycle,bindset,maxC,profile)
	local nextCycle = cycle+1
	if nextCycle > maxC then nextCycle = 1 end
	local k = cbinds[bindset][key].bindkey
	local cmd = ''
	if cbinds[bindset][key][cycle] and not (cbinds[bindset][key][cycle] == "") then
		cmd = cbinds[bindset][key][cycle].."$$"
	end
	cmd = cmd.."bindloadfilesilent "..profile.base.."\\cbinds\\"..bindset.."-"..nextCycle..'.txt'
	cbWriteBind(file,k,cmd)
end

function module.makebind(profile)
	local resetfile = profile.resetfile
	local cbinds = profile.cbinds
	local cbindfile
	local maxK
	local maxC
	cbMakeDirectory(profile.base.."\\cbinds")
	for k = 1, table.getn(cbinds) do -- for each complex bind set
		maxK = maxKeys(cbinds[k])
		maxC = maxCycles(cbinds[k],maxK)
		--print("maxK = "..maxK..", maxC = "..maxC)
		for j = 1, maxC do -- for each cycle in this bindset, counting the first one twice
			--create a new bindfile if cycle is 2+
			if j > 1 then
				cbindfile = cbOpen(profile.base.."\\cbinds\\"..k.."-"..(j-1)..".txt","w")
				--print("created "..profile.base.."\\cbinds\\"..k.."-"..(j-1)..".txt")
			end
			for i = 1,maxK do -- for each key in the bindset
				if j == 1 then
					writeBind(resetfile,cbinds,i,j,k,maxC-1,profile)
				else
					writeBind(cbindfile,cbinds,i,j-1,k,maxC-1,profile)
				end
			end
			if j > 1 then
				cbindfile:close()
				--print("closed "..profile.base.."\\cbinds\\"..k.."-"..(j-1)..".txt")
			end
		end
	end
end

function module.findconflicts(profile)
	local resetfile = profile.resetfile
	local cbinds = profile.cbinds
	for k = 1, table.getn(cbinds) do -- for each complex bind set
		local maxK = maxKeys(cbinds[k])
		for i = 1,maxK do -- for each key in the bindset
			cbCheckConflict(cbinds[k][i],"bindkey","Complex Bind "..k)
		end
	end
end

function module.bindisused(profile)
	if profile.cbinds == nil then return nil end
	return table.getn(profile.cbinds) > 0
end

cbAddModule(module,"Complex Binds","General")

 

Edited by Tailcoat
more info
Link to comment
Share on other sites

  • 1 month later
On 12/23/2023 at 8:57 PM, Premmy said:

Hey, I was playing with this a while ago and I was wondering if we could get an update that adds Controller support.

 

So to clarify - do you mean binds useful to the Controller archetype, or support for hardware controllers like for XBox etc?

 

The former would certainly be possible though I'd need input on what sorts of things would be useful for Controllers having never played one myself.  I'd be delighted to get some ideas on that.

 

The latter, though, is beyond the scope of BindControl, since City of Heroes itself doesn't have any support for binding to controller buttons or sticks or the like, and BindControl just uses the built-in /bind commands.  You'd have to use some third-party app to map your controller to keyboard/mouse commands.  I think you could use Steam's input configurator if you have City of Heroes added as a non-Steam game, but I'd have to tinker with that for a while to see for sure.

 

(If you did map your controller to keyboard/mouse commands, you could of course use BindControl to make interesting binds that used those keys and mouse buttons!)

Link to comment
Share on other sites

On 12/25/2023 at 11:19 PM, emersonrp said:

 

So to clarify - do you mean binds useful to the Controller archetype, or support for hardware controllers like for XBox etc?

 

The former would certainly be possible though I'd need input on what sorts of things would be useful for Controllers having never played one myself.  I'd be delighted to get some ideas on that.

 

The latter, though, is beyond the scope of BindControl, since City of Heroes itself doesn't have any support for binding to controller buttons or sticks or the like, and BindControl just uses the built-in /bind commands.  You'd have to use some third-party app to map your controller to keyboard/mouse commands.  I think you could use Steam's input configurator if you have City of Heroes added as a non-Steam game, but I'd have to tinker with that for a while to see for sure.

 

(If you did map your controller to keyboard/mouse commands, you could of course use BindControl to make interesting binds that used those keys and mouse buttons!)

The latter, actually. And. uh..Unless I’ve been hallucinating/ confused for years now, or we’re talking past each other and discussing different things, that’s not..true?

 

 

I’ve been using a rather clunky controller setup using manually crafted Keybind files since 2019. It was intended for a controller that includes a mini keyboard and later exclusively on a pocket PC with a built in controller and keyboard since 2020. Sadly, the Pocket PC died recently and I’ve had trouble retrieving the files from it.
 

With this problem, and the recent  updates to controller support, I thought this might be a good opportunity to update my old controller layout format.


Unfortunately I can’t get Bind control to recognize input from any of the controller devices I have connected and tested it with.

Edited by Premmy
Link to comment
Share on other sites

5 hours ago, Premmy said:

The latter, actually. And. uh..Unless I’ve been hallucinating/ confused for years now, or we’re talking past each other and discussing different things, that’s not..true?

 

Wow, that is indeed not true, and I'm not sure why I've spent years of my life believing it was.  Sorry about that.

 

I am totally on board with adding in controller support.  I have some apprehension about how easy it might or might not be since BindControl "listens" for the key/button to bind, so it, itself, will need to learn to support controllers, on Windows, Linux, and Mac, but what's life without a challenge?  I'll take a look at this in the coming weeks now that I'm freed up from the holiday rush.

 

Again sorry for the misinformation and ignorance.  I'm seriously not sure how I've never seen that before.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...