More methods!

main
Nicholas Hope 2022-10-05 21:32:07 -04:00
parent 607894648c
commit 9331f13786
1 changed files with 125 additions and 138 deletions

View File

@ -28,19 +28,19 @@ class Bind(object):
bindTypes = []
instances = {}
def __init__(self, key='', fields={}, *, parent=None):
def __init__(self, key='', fields={}, /,*, parent=None):
if parent is None:
self.alias = False
self.key = str(key)
self.fields = fields
self.errors = []
self.warnings = []
self.alias = False
self.key = str(key)
self.fields = fields
self.errors = []
self.warnings = []
self.TargetType = None
else:
self.alias = parent.alias
self.key = parent.key
self.fields = parent.fields
self.errors = parent.errors
self.alias = parent.alias
self.key = parent.key
self.fields = parent.fields
self.errors = parent.errors
self.warnings = parent.warnings
# redefined for each unique type, default just verifies key
@ -72,15 +72,11 @@ class Bind(object):
self.instances[type(self)] = [self]
def verify(self):
try:
self.alias = self.fields.pop('alias')
if not isinstance(self.alias, bool):
self.errors.append(
f'alias should be "yes" or "no", not "{self.alias}"'
)
self.alias = False
except popErrors:
self.alias = False
self.alias = self.optional('alias', default=False)
if not isinstance(self.alias, bool):
self.err(
f'`alias` should be "yes" or "no", not "{self.alias}"'
)
try:
typeName, self.key = self.key.split(' ', 1)
@ -107,6 +103,21 @@ class Bind(object):
if (not self.alias) and (self.key not in validKeyList):
self.errors.append(f'invalid key name: "{self.key}"')
def optional(self, name, /,*, default=None):
try:
return self.fields.pop(name)
except popErrors:
return default
def cmdListFrom(self, name, /,*, default=None):
result = self.fields.pop(name)
if isinstance(result, str):
return result.split(';')
elif isinstance(result, list):
return result
else:
return default
def toTargetType(self):
if self.TargetType is None:
# do nothing
@ -128,21 +139,20 @@ class Bind(object):
class Impulse(Bind):
def verify(self):
self.command = None
self.command: list = None
if not isinstance(self.fields, dict):
self.fields = {'command': self.fields}
try:
self.command = self.fields.pop('command')
if isinstance(self.command, str):
self.command = self.command.split(';')
elif not isinstance(self.command, list):
self.err('`command` field must be argument of string or list')
self.command = None
except KeyError:
self.command = self.cmdListFrom(
'command',
default=self.fields
)
if self.command is None:
self.err('`command` field must be string or list')
except popErrors:
self.err('requires `command` field')
def toTF2(self) -> str:
if self.alias:
bindOrAlias = 'alias'
@ -167,11 +177,8 @@ class Impulse(Bind):
'secondary': 'slot2',
'melee': 'slot3'
}
try:
cmd = simpleSCs[cmd]
except KeyError:
# not a shortcut
pass
# if is shortcut, change
cmd = simpleSCs.get(cmd, cmd)
if cmd == 'voice':
cmd = 'voicemenu'
@ -183,8 +190,8 @@ class Impulse(Bind):
elif cmd == 'loadout' and restOfCmd.isalpha():
cmd = 'load_itempreset'
try:
restOfCmd = restOfCmd.lower()
restOfCmd = str(['a','b','c','d'].index(restOfCmd))
loadoutNum = ['a','b','c','d'].index(restOfCmd.lower())
restOfCmd = str(loadoutNum)
except ValueError:
# not a load_itempreset shortcut
pass
@ -204,9 +211,9 @@ class Impulse(Bind):
keyword = keyword.lower()
allLists = (
('medic', 'thanks', 'go', 'move up', 'go left', 'go right', 'yes', 'no', 'pass to me'),
('incoming', 'spy', 'sentry ahead', 'teleporter here', 'dispenser here', 'sentry here', 'activate uber', 'uber ready'),
('help', 'battle cry', 'cheers', 'jeers', 'positive', 'negative', 'nice shot', 'good job'),
('medic', 'thanks', 'go', 'move up', 'go left', 'go right', 'yes', 'no', 'pass to me'),
('incoming', 'spy', 'sentry ahead', 'teleporter here', 'dispenser here', 'sentry here', 'activate uber', 'uber ready'),
('help', 'battle cry', 'cheers', 'jeers', 'positive', 'negative', 'nice shot', 'good job'),
)
for menu, voiceList in enumerate(allLists):
@ -221,40 +228,32 @@ class Impulse(Bind):
'exit': '1 1',
'sentry': '2 0'
}
for shortBuild, num in buildingNums.items():
if building == shortBuild:
return num
return buildingNums.get(building, building)
class Hold(Bind):
def verify(self):
self.press = None
self.release = None
self.press: list = None
self.release: list = None
if not isinstance(self.fields, dict):
self.fields = {'press': self.fields}
# verify press
try:
self.press = self.fields.pop('press')
if isinstance(self.press, str):
self.press = self.press.split(';')
elif not isinstance(self.press, list):
self.press = self.cmdListFrom('press')
if self.press is None:
self.err('`press` field must be string or list')
self.press = None
except KeyError:
except popErrors:
self.err('requires `press` field')
if self.press is None:
return
# verify release
try:
self.release = self.fields.pop('release')
if isinstance(self.release, str):
self.release = self.release.split(';')
elif not isinstance(self.release, list):
self.release = self.cmdListFrom('release')
if self.release is None:
self.err('`release` field must be string or list')
self.release = None
except popErrors:
if self.press is None:
return
self.warn('has no `release`, creating one')
# no release specified, do -action for each item in press
self.release = []
@ -271,11 +270,11 @@ class Hold(Bind):
# Making impulse instances from self.press and .release
# allows them to share the shortcuts
pressObj = Impulse(f'+{holdStr}', self.press)
pressObj = Impulse('+' + holdStr, self.press)
pressObj.alias = True
pressStr = pressObj.toTF2()
releaseObj = Impulse(f'-{holdStr}', self.release)
releaseObj = Impulse('-' + holdStr, self.release)
releaseObj.alias = True
releaseStr = releaseObj.toTF2()
@ -296,34 +295,29 @@ class Hold(Bind):
class Toggle(Bind):
def verify(self):
self.on = None
self.off = None
self.on : list = None
self.off: list = None
if not isinstance(self.fields, dict):
self.fields = {'on': self.fields}
# verify on
try:
self.on = self.fields.pop('on')
if isinstance(self.on, str):
self.on = self.on.split(';')
elif not isinstance(self.on, list):
self.err('`on` field must be string or list')
self.on = None
except KeyError:
self.on = self.cmdListFrom('on')
if self.on is None:
self.err(f'`on` field must be string or list')
except popErrors:
self.err('requires `on` field')
if self.on is None:
return
# verify off
try:
self.off = self.fields.pop('off')
if isinstance(self.off, str):
self.off = self.off.split(';')
elif not isinstance(self.off, list):
self.err('`off` field must be string or list')
self.off = self.cmdListFrom('off')
if self.off is None:
self.err(f'`off` field must be string or list')
except popErrors:
# no off specified, do -action for each item in on
self.off = []
if self.on is None:
return
for cmd in self.on:
if cmd[0] == '+':
self.off.append('-' + cmd[1:])
@ -357,25 +351,20 @@ class Toggle(Bind):
class Double(Bind):
defaultDict = {}
condDict = {}
bindNames = []
condDict = {}
bindNames = []
def verify(self):
self.primary = None
self.primStr = f'{self.key}_primary'
self.secondary = None
self.secondStr = f'{self.key}_secondary'
self.condition = None
self.isToggle = False
# name of a bind type
self.type = None
# either 'released' (default) or 'both'
self.primStr = f'{self.key}_primary'
self.secondStr = f'{self.key}_secondary'
self.isToggle = False
self.cancelBoth = False
self.primary: Bind = None
self.secondary: Bind = None
self.condition: str = None
self.type: str = None
# toggler
try:
self.condition = self.fields.pop('condition')
@ -384,15 +373,12 @@ class Double(Bind):
except popErrors:
self.err('requires `condition` field')
try:
self.isToggle = self.fields.pop('toggle')
if not isinstance(self.isToggle, bool):
self.err(
'`toggle` field should be "yes" or "no", '
+ f'not "{self.isToggle}"'
)
except popErrors:
self.isToggle = False
self.isToggle = self.optional('toggle', default=False)
if not isinstance(self.isToggle, bool):
self.err(
'`toggle` field should be "yes" or "no",'
+ f' not "{self.isToggle}"'
)
# type
try:
@ -407,56 +393,57 @@ class Double(Bind):
return
# cancel mode, must happend after type has been inferred
try:
cancel = self.fields.pop('cancel')
cancel = self.optional('cancel', default='released')
if not isinstance(cancel, str):
self.err(f'`cancel` field must be "released" or "both"')
else:
if cancel == 'both':
if self.type == 'hold':
self.cancelBoth = True
else:
self.err(
'`cancel` field only affects "hold", '
+ f'not "{self.type}"'
)
elif cancel != 'released':
if not isinstance(cancel, str):
self.err(f'`cancel` field must be "released" or "both"')
else:
if cancel == 'both':
if self.type == 'hold':
self.cancelBoth = True
else:
self.err(
'`cancel` field must be "released" '
+ f'or "both", not "{cancel}"'
'`cancel` field only affects "hold",'
+ f' not "{self.type}"'
)
except popErrors:
cancel = 'released'
elif cancel == 'released':
self.cancelBoth = False
else:
self.err(
'`cancel` field must be "released"'
+ f' or "both", not "{cancel}"'
)
# primary action
try:
mainSection = self.fields.pop('primary')
mainBind = Bind(f'{self.type} {self.primStr}', mainSection)
mainBind = mainBind.toTargetType()
self.errors.extend(mainBind.errors)
self.warnings.extend(mainBind.warnings)
self.errors.remove(f'invalid key name: "{self.primStr}"')
self.primary = mainBind
self.primary = self.getSection('primary', self.primStr)
except popErrors:
self.err('requires `primary` field')
self.primary = None
# secondary action
try:
altSection = self.fields.pop('secondary')
altBind = Bind(f'{self.type} {self.secondStr}', altSection)
altBind = altBind.toTargetType()
self.errors.extend(altBind.errors)
self.warnings.extend(altBind.warnings)
self.errors.remove(f'invalid key name: "{self.secondStr}"')
self.secondary = altBind
self.secondary = self.getSection('secondary', self.secondStr)
except popErrors:
self.err('requires `secondary` field')
self.secondary = None
if self.primary is self.secondary is None:
self.err('has neither primary nor secondary')
def getSection(self, popName, key, /) -> Bind:
section = self.fields.pop(popName)
bind = Bind(f'{self.type} {key}', section)
bind = bind.toTargetType()
bind.errors.remove(f'invalid key name: "{key}"')
self.prettifyList(bind.errors, key)
self.errors.extend(bind.errors)
self.prettifyList(bind.warnings, key)
self.warnings.extend(bind.warnings)
return bind
def prettifyList(self, strList, origStr):
repStr = ' '.join(origStr.split('_', 1))
for i, cmd in enumerate(strList):
strList[i] = cmd.replace(origStr, repStr)
def toTF2(self) -> str:
# Get code for primary and secondary actions.