OpenDiablo2/d2game/d2player/key_map.go

140 lines
4.3 KiB
Go

package d2player
import (
"sync"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
)
// KeyMap represents the key mappings of the game. Each game event
// can be associated to 2 different keys. A key of -1 means none
type KeyMap struct {
mutex sync.RWMutex
mapping map[d2enum.Key]d2enum.GameEvent
controls map[d2enum.GameEvent]*KeyBinding
}
// NewKeyMap returns a new instance of a KeyMap
func NewKeyMap() *KeyMap {
return &KeyMap{
mapping: make(map[d2enum.Key]d2enum.GameEvent),
controls: make(map[d2enum.GameEvent]*KeyBinding),
}
}
// SetPrimaryBinding binds the first key for gameEvent
func (km *KeyMap) SetPrimaryBinding(gameEvent d2enum.GameEvent, key d2enum.Key) {
if key == d2enum.KeyEscape {
return
}
km.mutex.Lock()
defer km.mutex.Unlock()
if km.controls[gameEvent] == nil {
km.controls[gameEvent] = &KeyBinding{}
}
currentKey := km.controls[gameEvent].Primary
delete(km.mapping, currentKey)
km.mapping[key] = gameEvent
km.controls[gameEvent].Primary = key
}
// SetSecondaryBinding binds the second key for gameEvent
func (km *KeyMap) SetSecondaryBinding(gameEvent d2enum.GameEvent, key d2enum.Key) {
if key == d2enum.KeyEscape {
return
}
km.mutex.Lock()
defer km.mutex.Unlock()
if km.controls[gameEvent] == nil {
km.controls[gameEvent] = &KeyBinding{}
}
currentKey := km.controls[gameEvent].Secondary
delete(km.mapping, currentKey)
km.mapping[key] = gameEvent
if km.controls[gameEvent].Primary == key {
km.controls[gameEvent].Primary = d2enum.Key(-1)
}
km.controls[gameEvent].Secondary = key
}
func (km *KeyMap) getGameEvent(key d2enum.Key) d2enum.GameEvent {
km.mutex.RLock()
defer km.mutex.RUnlock()
return km.mapping[key]
}
// GetKeysForGameEvent returns the bindings for a givent game event
func (km *KeyMap) GetKeysForGameEvent(gameEvent d2enum.GameEvent) *KeyBinding {
km.mutex.RLock()
defer km.mutex.RUnlock()
return km.controls[gameEvent]
}
// KeyBinding holds the primary and secondary keys assigned to a GameEvent
type KeyBinding struct {
Primary d2enum.Key
Secondary d2enum.Key
}
func getDefaultKeyMap() *KeyMap {
keyMap := NewKeyMap()
defaultControls := map[d2enum.GameEvent]KeyBinding{
d2enum.ToggleCharacterPanel: {d2enum.KeyA, d2enum.KeyC},
d2enum.ToggleInventoryPanel: {d2enum.KeyB, d2enum.KeyI},
d2enum.ToggleHelpScreen: {d2enum.KeyH, -1},
d2enum.TogglePartyPanel: {d2enum.KeyP, -1},
d2enum.ToggleMessageLog: {d2enum.KeyM, -1},
d2enum.ToggleQuestLog: {d2enum.KeyQ, -1},
d2enum.ToggleChatOverlay: {d2enum.KeyEnter, -1},
d2enum.ToggleAutomap: {d2enum.KeyTab, -1},
d2enum.CenterAutomap: {d2enum.KeyHome, -1},
d2enum.ToggleSkillTreePanel: {d2enum.KeyT, -1},
d2enum.ToggleRightSkillSelector: {d2enum.KeyS, -1},
d2enum.UseSkill1: {d2enum.KeyF1, -1},
d2enum.UseSkill2: {d2enum.KeyF2, -1},
d2enum.UseSkill3: {d2enum.KeyF3, -1},
d2enum.UseSkill4: {d2enum.KeyF4, -1},
d2enum.UseSkill5: {d2enum.KeyF5, -1},
d2enum.UseSkill6: {d2enum.KeyF6, -1},
d2enum.UseSkill7: {d2enum.KeyF7, -1},
d2enum.UseSkill8: {d2enum.KeyF8, -1},
d2enum.UseSkill9: {-1, -1},
d2enum.UseSkill10: {-1, -1},
d2enum.UseSkill11: {-1, -1},
d2enum.UseSkill12: {-1, -1},
d2enum.UseSkill13: {-1, -1},
d2enum.UseSkill14: {-1, -1},
d2enum.UseSkill15: {-1, -1},
d2enum.UseSkill16: {-1, -1},
d2enum.ToggleBelts: {d2enum.KeyTilde, -1},
d2enum.UseBeltSlot1: {d2enum.Key1, -1},
d2enum.UseBeltSlot2: {d2enum.Key2, -1},
d2enum.UseBeltSlot3: {d2enum.Key3, -1},
d2enum.UseBeltSlot4: {d2enum.Key4, -1},
d2enum.ToggleRunWalk: {d2enum.KeyR, -1},
d2enum.HoldRun: {d2enum.KeyControl, -1},
d2enum.HoldShowGroundItems: {d2enum.KeyAlt, -1},
d2enum.HoldShowPortraits: {d2enum.KeyZ, -1},
d2enum.HoldStandStill: {d2enum.KeyShift, -1},
d2enum.ClearScreen: {d2enum.KeySpace, -1},
}
for gameEvent, keys := range defaultControls {
keyMap.SetPrimaryBinding(gameEvent, keys.Primary)
keyMap.SetSecondaryBinding(gameEvent, keys.Secondary)
}
return keyMap
}