Skip to content

Commit

Permalink
Merge pull request #78 from splaplapla/splatoon2-inertia-cancel
Browse files Browse the repository at this point in the history
スティックを傾けるとマクロを発動できる機能
  • Loading branch information
jiikko authored Mar 3, 2022
2 parents 51d691a + 1ce9aaf commit 56e3958
Show file tree
Hide file tree
Showing 16 changed files with 458 additions and 50 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## [0.1.21] - 2022-2-
## [0.1.21] - 2022-03-03
- install_macro_pluginしていないマクロをlayer内で使うとクラッシュしていた問題を修正しました
- 数十時間起動しっぱなしだとpbm-cloudとのwebsocketの接続が切断される問題を修正しました
- 誤発動を防ぐために、マクロを無効にする設定ができるようになりました
Expand All @@ -8,8 +8,12 @@
- 特定のマクロを無効にする
- disable_macro TheMacro
- disable_macro TheMacro, if_pressed: [:a]
- スティックを傾けたタイミングでマクロを発動するオプションを実装しました
- これによってスプラトゥーン2の惰性キャンセルができるようになります
- ただし、精度がイマイチなので今後改善していきます
- 詳しくは `スプラトゥーン2: 惰性キャンセル マクロの設定方法` を参照してください

## [0.1.20.2] - 2022-2-18
## [0.1.20.2] - 2022-02-18
- 起動時にreniceするようにしました
- 起動時にusb gadgetモードを有効にするようにしました
- pbm-cloudからprocon_bypass_manをアップグレードできるようになりました
Expand Down
73 changes: 73 additions & 0 deletions docs/setting/splatoon2_macro_dasei_cancel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# スプラトゥーン2: 惰性キャンセル マクロの設定方法

* 本マクロは実験段階で、オプション名などの仕様が変更される可能性が高いです
* procon_bypass_man: 0.1.21以上が必要です

## 1. install_macro_pluginでマクロを有効化します
* `setting.yml``install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel` と書きます
* これを記述することで、layer内でmacroを呼び出せるようになります

```ruby
install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel
```

## 2. どのlayerで発動するかを宣言します
* `setting.yml` のlayer内に`macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_pressed: [:zl]` と書きます
* `if_pressed` がどのボタンを押したときにこのマクロが発動するかの設定です
* 惰性キャンセルなのでイカ状態になるためにzlを押します
* `if_tilted_left_stick` がスティックを倒した時に発動するオプションで、trueを渡すと有効になります
* また、傾けた時の閾値を変更することができて、trueの代わりに `{ threshold: 500 }` と書くことができます
* デフォルトが500で、ここの数値を上げると、スティックを倒した判定がより厳しくなります。最大1400くらいです。
* 連打中に、マクロの発動を無効にしたい場合は `disable_macro` で無効にできます

```ruby
layer :up do
macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_tilted_left_stick: true, if_pressed: [:zl]
end
```
```ruby
layer :up do
macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_tilted_left_stick: { threshold: 500 }, if_pressed: [:zl]
end
```
```ruby
layer :up do
disable_macro :all, if_pressed: :a
disable_macro :all, if_pressed: :zr
macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_tilted_left_stick: true, if_pressed: [:zl]
end
```

## 3. 設定を反映させる
* 上記の記述を加えたsetting.ymlを起動中のprocon_bypass_manプロセスで読み込むには、プロセスにその旨を伝える必要があります
* ラズベリーパイを再起動して、プロセスを立ち上げ直す、でも目的は達成できますが、もっと簡単にsetting.ymlを再読み込みする必要があります
* 書き換えたsetting.ymlを、起動中のprocon_bypass_manプロセスへ即時反映するには、procon_bypass_manプロセスを動かしたまま、別のshellから 以下をを実行してください
* setting.ymlのシンタックスが正しければ、switchとの接続が継続したままsetting.ymlの内容を読み込んでいるはずです

## 設定例1
```yaml
version: 1.0
setting: |-
prefix_keys_for_changing_layer [:zr, :zl, :l]
install_macro_plugin ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel
layer :up do
disable_macro :all, if_pressed: :a
disable_macro :all, if_pressed: :zr
macro ProconBypassMan::Plugin::Splatoon2::Macro::DaseiCancel, if_tilted_left_stick: true, if_pressed: [:zl]
end
```
## 設定例2
* `open_macro` キーワードを使っても同じことが実行可能です。
* この場合は、 `install_macro_plugin` が不要です。

```yaml
version: 1.0
setting: |-
prefix_keys_for_changing_layer [:zr, :zl, :l]
layer :up do
open_macro :dacan, steps: [:pressing_r_for_0_03sec, :pressing_r_and_pressing_zl_for_0_2sec], if_tilted_left_stick: true, if_pressed: [:zl]
end
```
1 change: 1 addition & 0 deletions lib/procon_bypass_man.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
require_relative "procon_bypass_man/support/update_remote_pbm_action_status_http_client"
require_relative "procon_bypass_man/support/send_device_stats_http_client"
require_relative "procon_bypass_man/support/server_pool"
require_relative "procon_bypass_man/support/analog_stick_hypotenuse_tilting_power_scaler"
require_relative "procon_bypass_man/support/never_exit_accidentally"
require_relative "procon_bypass_man/background"
require_relative "procon_bypass_man/commands"
Expand Down
8 changes: 4 additions & 4 deletions lib/procon_bypass_man/buttons_setting_configuration/layer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ def flip(button, if_pressed: false, force_neutral: nil, flip_interval: nil)
end

# @param [String, Class] プラグインのclass
def macro(name, if_pressed: )
def macro(name, if_pressed: , if_tilted_left_stick: nil)
macro_name = name.to_s.to_sym
if ProconBypassMan::ButtonsSettingConfiguration.instance.macro_plugins[macro_name]
self.macros[macro_name] = { if_pressed: if_pressed }
self.macros[macro_name] = { if_pressed: if_pressed, if_tilted_left_stick: if_tilted_left_stick }.compact
else
warn "#{macro_name}マクロがinstallされていません"
end
Expand All @@ -67,10 +67,10 @@ def macro(name, if_pressed: )
# 設定ファイルに直接マクロを打ち込める
# @param [String, Class] macroの識別子
# @paramh[Array<Symbol>] macroの本体. ボタンの配列
def open_macro(name, steps: , if_pressed: )
def open_macro(name, steps: , if_pressed: , if_tilted_left_stick: nil)
macro_name = name || "OpenMacro-#{steps.join}".to_sym
ProconBypassMan::Procon::MacroRegistry.install_plugin(macro_name, steps: steps)
self.macros[macro_name] = { if_pressed: if_pressed }
self.macros[macro_name] = { if_pressed: if_pressed, if_tilted_left_stick: if_tilted_left_stick }.compact
end

def disable_macro(name, if_pressed: nil)
Expand Down
21 changes: 21 additions & 0 deletions lib/procon_bypass_man/plugin/splatoon2/macro/dasei_cancel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module ProconBypassMan
module Plugin
module Splatoon2
module Macro
module DaseiCancel
def self.display_name
:dasei_cancel
end

def self.steps
[:pressing_r_for_0_03sec, :pressing_r_and_pressing_zl_for_0_2sec].freeze
end

def self.description
'惰性キャンセル'
end
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/procon_bypass_man/plugins.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require_relative "plugin/splatoon2/macro/jump_to_up_key"
require_relative "plugin/splatoon2/macro/jump_to_left_key"
require_relative "plugin/splatoon2/macro/sokuwari_for_splash_bomb"
require_relative "plugin/splatoon2/macro/dasei_cancel"
require_relative "plugin/splatoon2/mode/guruguru"

module ProconBypassMan
Expand Down
19 changes: 18 additions & 1 deletion lib/procon_bypass_man/procon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def self.reset!
ongoing_macro: MacroRegistry.load(:null),
ongoing_mode: ModeRegistry.load(:manual),
}
@@left_stick_tilting_power_scaler = ProconBypassMan::AnalogStickTiltingPowerScaler.new
end
reset!

Expand Down Expand Up @@ -47,6 +48,9 @@ def apply!
return
end

analog_stick = ProconBypassMan::Procon::AnalogStick.new(binary: user_operation.binary.raw)
dumped_tilting_power = @@left_stick_tilting_power_scaler.add_sample(analog_stick.relative_hypotenuse)

enable_all_macro = true
enable_macro_map = Hash.new {|h,k| h[k] = true }
current_layer.disable_macros.each do |disable_macro|
Expand All @@ -61,8 +65,21 @@ def apply!

if ongoing_macro.finished? && enable_all_macro
current_layer.macros.each do |macro_name, options|
if user_operation.pressing_all_buttons?(options[:if_pressed]) && enable_macro_map[macro_name]
next unless enable_macro_map[macro_name]

if(if_tilted_left_stick_value = options[:if_tilted_left_stick])
threshold = (if_tilted_left_stick_value.is_a?(Hash) && if_tilted_left_stick_value[:threshold]) || ProconBypassMan::AnalogStickTiltingPowerScaler::DEFAULT_THRESHOLD
if dumped_tilting_power&.tilting?(threshold: threshold, current_position_x: analog_stick.relative_x, current_position_y: analog_stick.relative_y) && user_operation.pressing_all_buttons?(options[:if_pressed])
@@status[:ongoing_macro] = MacroRegistry.load(macro_name)
break
end

next
end

if user_operation.pressing_all_buttons?(options[:if_pressed])
@@status[:ongoing_macro] = MacroRegistry.load(macro_name)
break
end
end
end
Expand Down
71 changes: 48 additions & 23 deletions lib/procon_bypass_man/procon/macro.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
class ProconBypassMan::Procon::Macro
class NestedStep
class BaseNestedStep
def initialize(value)
@hash = value
end

private

def incr_step_index!
if step_index
@hash[:step_index] += 1
else
@hash[:step_index] = 0
end
end

def current_step
@hash[:steps][step_index]
end
end

class OnetimeNestedStep < BaseNestedStep
def over?
current_step.nil?
end

def next_step
step = current_step
incr_step_index!
step
end

private

def step_index
@hash[:step_index] ||= 0
end
end

class NestedStep < BaseNestedStep
def initialize(value)
super
unless @hash[:end_at]
@hash[:end_at] = (Time.now + @hash[:continue_for]).round(4)
end
end

def over_end_at?
def over?
(@hash[:end_at] < Time.now).tap do |result|
if result
ProconBypassMan.logger.debug { "[Macro] nested step is finished(#{@hash})" }
Expand All @@ -17,8 +55,6 @@ def over_end_at?

def next_step
incr_step_index!

debug_incr_called_count!
if step = current_step
return step
else
Expand All @@ -29,30 +65,13 @@ def next_step

private

def current_step
@hash[:steps][step_index]
end

def step_index
@hash[:step_index]
end

def incr_step_index!
if step_index
@hash[:step_index] += 1
else
@hash[:step_index] = 0
end
end

def reset_step_index!
@hash[:step_index] = 0
end

def debug_incr_called_count!
@hash[:debug_called_count] ||= 0
@hash[:debug_called_count] += 1
end
end

attr_accessor :name, :steps
Expand All @@ -69,8 +88,14 @@ def next_step
end

if step.is_a?(Hash)
nested_step = NestedStep.new(step)
if nested_step.over_end_at?
nested_step =
if step[:continue_for]
NestedStep.new(step)
else
OnetimeNestedStep.new(step)
end

if nested_step.over?
steps.shift # NestedStepを破棄する
return next_step
else
Expand Down
28 changes: 14 additions & 14 deletions lib/procon_bypass_man/procon/macro_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def initialize(steps)

# @return [Arary<Symbol>]
def build
steps = @steps.map { |step|
steps = @steps.flat_map { |step|
if is_reserved?(step: step) || v1_format?(step: step)
step.to_sym
elsif value = build_if_v2_format?(step: step)
Expand All @@ -65,7 +65,8 @@ def build
nil
end
}
steps.compact.flatten

steps.compact
end

private
Expand Down Expand Up @@ -93,17 +94,16 @@ def build_if_v2_format?(step: )

if %r!^(pressing_|toggle_)! =~ step && (subjects = step.scan(%r!pressing_[^_]+|toggle_[^_]+!)) && (match = step.match(%r!_for_([\d_]+)(sec)?\z!))
if sec = match[1]
return [
{ continue_for: to_f(sec),
steps: SubjectMerger.merge(subjects.map { |x| Subject.new(x) }).select { |x|
if x.is_a?(Array)
x.select { |y| is_button(y) || RESERVED_WORD_NONE == y }
else
is_button(x) || RESERVED_WORD_NONE == x
end
},
}
]
return {
continue_for: to_f(sec),
steps: SubjectMerger.merge(subjects.map { |x| Subject.new(x) }).select { |x|
if x.is_a?(Array)
x.select { |y| is_button(y) || RESERVED_WORD_NONE == y }
else
is_button(x) || RESERVED_WORD_NONE == x
end
},
}
end
end

Expand All @@ -114,7 +114,7 @@ def build_if_v2_format?(step: )
else
is_button(x) || RESERVED_WORD_NONE == x
end
}.flatten
}
end
end

Expand Down
Loading

0 comments on commit 56e3958

Please sign in to comment.