リファクタリング

diff --git a/lib/vortex/alerm_mod.rb b/lib/vortex/alerm_mod.rb
new file mode 100644
index 0000000..e69de29
diff --git a/lib/vortex/assets/garage_band/alerm.aif b/lib/vortex/assets/garage_band/alerm.aif
new file mode 100644
index 0000000..8ac0900
Binary files /dev/null and b/lib/vortex/assets/garage_band/alerm.aif differ
diff --git a/lib/vortex/assets/garage_band/cursor.aif b/lib/vortex/assets/garage_band/cursor.aif
new file mode 100644
index 0000000..c3295e2
Binary files /dev/null and b/lib/vortex/assets/garage_band/cursor.aif differ
diff --git a/lib/vortex/assets/garage_band/field_jump.aif b/lib/vortex/assets/garage_band/field_jump.aif
new file mode 100644
index 0000000..266e0bb
Binary files /dev/null and b/lib/vortex/assets/garage_band/field_jump.aif differ
diff --git a/lib/vortex/assets/garage_band/item_break.aif b/lib/vortex/assets/garage_band/item_break.aif
new file mode 100644
index 0000000..adda6ea
Binary files /dev/null and b/lib/vortex/assets/garage_band/item_break.aif differ
diff --git a/lib/vortex/base_controller.rb b/lib/vortex/base_controller.rb
index 38bb8e9..d721883 100644
--- a/lib/vortex/base_controller.rb
+++ b/lib/vortex/base_controller.rb
@@ -90,6 +90,7 @@ def next_piece_type_get(player)
       :user_irs_success_signal,
       :block_up_call_signal,
       :top_out_start_signal,
+      :item_break_signal,
       :before_clear_lines,
       :signal_field_down_signal,
       :intent_lock_signal,
@@ -103,6 +104,8 @@ def next_piece_type_get(player)
       :user_controll,
       :piece_lock_signal,
       :block_up_wait_state_start_signal,
+      :alerm_start_signal,
+      :alerm_end_signal,
     ].each do |method|
       define_method(method) do |*args, &block|
       end
diff --git a/lib/vortex/config.rb b/lib/vortex/config.rb
index 9397983..69d6421 100644
--- a/lib/vortex/config.rb
+++ b/lib/vortex/config.rb
@@ -6,7 +6,7 @@ module Vortex

   config.piece_size         = [8*2-1, 8*2-1]
   config.edge               = :inside           # nil or :inside or :OUTSID
-  config.sound_set           = :puyopuyo
+  config.sound_set          = :garage_band

   config.uri                = "druby://libretto:8470"

diff --git a/lib/vortex/field.rb b/lib/vortex/field.rb
index 32ebc35..a06184e 100644
--- a/lib/vortex/field.rb
+++ b/lib/vortex/field.rb
@@ -283,6 +283,15 @@ def mountain_height(x = nil)
         height - top_y2(x)
       end

+      # 窒息度合
+      # 天井をNライン越えている場合 → -N
+      # 天井に衝突                  → 0
+      # あと1ラインで窒息           → 1
+      # 最初の状態なら              → 20
+      def suffocation
+        top_y2 - hidden_lines
+      end
+
       alias inspect_old inspect
       def inspect
         lines = to_s(:compact => true).split(/\n/)
diff --git a/lib/vortex/item.rb b/lib/vortex/item.rb
index 77919fe..92261dd 100644
--- a/lib/vortex/item.rb
+++ b/lib/vortex/item.rb
@@ -102,6 +102,7 @@ def execute(player)
                 jump.h       = 1.0
               end
               player.controller.jump = jump
+              player.controller.compact_fall_jump_by_item
             end
             player.controller.jump.counter += 1
             if player.controller.jump.counter >= player.controller.jump.frames
diff --git a/lib/vortex/item_versus_mod.rb b/lib/vortex/item_versus_mod.rb
index b6c9fd5..2b26d6b 100644
--- a/lib/vortex/item_versus_mod.rb
+++ b/lib/vortex/item_versus_mod.rb
@@ -108,6 +108,7 @@ def before_clear_lines(player)

     # ここがアイテムの投入口
     def item_push(player, item)
+      item_break_signal
       player.field.all_item_clear
       # この if は AttackType か RepairType にまかせるとうまくいく気がする
       if item < Item::AttackType
diff --git a/lib/vortex/mode/standard_mode.rb b/lib/vortex/mode/standard_mode.rb
index 867cb75..8c9e169 100644
--- a/lib/vortex/mode/standard_mode.rb
+++ b/lib/vortex/mode/standard_mode.rb
@@ -37,8 +37,6 @@ def initialize
       @next_display_type   = :side # ネクストの表示タイプ
       @szo_reject_on_start = false # 最初にSZOを除外しない
       @soft_drop_speed     = 0.5
-
-      @end_delay           = 60
     end
   end

diff --git a/lib/vortex/player.rb b/lib/vortex/player.rb
index 63f1039..aeb5510 100644
--- a/lib/vortex/player.rb
+++ b/lib/vortex/player.rb
@@ -147,7 +147,7 @@ def next_frame
           end
         when :move_state       # 操作している状態
           if @state.start?
-            @controller.before_move
+            @controller.before_move(self)
           end
           @controller.user_controll(self)
           begin
diff --git a/lib/vortex/sound_mod.rb b/lib/vortex/sound_mod.rb
index 00c234f..112e1c4 100644
--- a/lib/vortex/sound_mod.rb
+++ b/lib/vortex/sound_mod.rb
@@ -4,141 +4,213 @@
 require_relative 'sound_set'

 module Vortex
-  module ItemSoundMod
-    def item_mode_one_line_clear_signal
-      super
-      se_play :kill_one_line_by_item
-    end
+  module SoundMod
+    module Core
+      extend ActiveSupport::Concern

-    def compact_fall_down_by_item
-      super
-      se_play :field_down
-    end
+      def initialize
+        super

-    def compact_fall_jump_by_item
-      super
-      se_play :field_jump
-    end
-  end
+        @sound_set = SoundSet[:default]
+        if v = SoundSet[Vortex.config.sound_set]
+          @sound_set = @sound_set.deep_merge(v)
+        end

-  module SoundMod
-    include ItemSoundMod
+        @se_aliases = {}
+        @sound_set[:se].each do |key, attrs|
+          case attrs
+          when Hash
+            Stylet::SE.load_file(attrs[:file], :volume => attrs[:volume], :key => key)
+          when Symbol
+            until @sound_set[:se][attrs].kind_of? Hash
+              attrs = @sound_set[:se][attrs]
+            end
+            @se_aliases[key] = attrs
+          end
+        end
+      end

-    def initialize
-      super
+      private

-      @sound_set = SoundSet[:default]
-      if v = SoundSet[Vortex.config.sound_set]
-        @sound_set = @sound_set.deep_merge(v)
+      def se_play(key)
+        se_obj(key).play
       end

-      @se_aliases = {}
-      @sound_set[:se].each do |key, attrs|
-        case attrs
-        when Hash
-          Stylet::SE.load_file(attrs[:file], :volume => attrs[:volume], :key => key)
-        when Symbol
-          until @sound_set[:se][attrs].kind_of? Hash
-            attrs = @sound_set[:se][attrs]
+      def se_stop(key)
+        se_obj(key).fade_out
+      end
+
+      def music_play(key)
+        if music = @sound_set[:music]
+          if attrs = music[key.to_sym]
+            Stylet::Music.play(attrs[:file], :volume => attrs[:volume])
           end
-          @se_aliases[key] = attrs
         end
       end

-      p [:se_aliases, @se_aliases]
+      def se_obj(key)
+        Stylet::SE[@se_aliases[key] || key]
+      end
+
+      def music_stop
+        Stylet::Music.halt
+      end
     end

-    def start_signal(player)
-      super
-      unless Stylet::Music.play?
-        # 自分から見て相手が自分でなければ対戦
-        if player.controller.respond_to?(:target_player) && player.controller.target_player
-          if player.controller.target_player != player
-            music_play :bgm_versus
+    module Basic
+      extend ActiveSupport::Concern
+
+      def start_signal(player)
+        super
+        unless Stylet::Music.play?
+          # 自分から見て相手が自分でなければ対戦
+          if player.controller.respond_to?(:target_player) && player.controller.target_player
+            if player.controller.target_player != player
+              music_play :bgm_versus
+            end
+          elsif player.controller.speed >= 20 # FIXME: max_velocity みたいなメソッドにする
+            music_play :bgm_high_speed
+          else
+            music_play :bgm_training
           end
-        elsif player.controller.speed >= 20 # FIXME: max_velocity みたいなメソッドにする
-          music_play :bgm_high_speed
-        else
-          music_play :bgm_training
         end
       end
-    end

-    def piece_set_signal(player)
-      super
-      if player.current_piece
-        se_play "piece_#{player.current_piece.class.shape_key}"
+      def piece_set_signal(player)
+        super
+        if player.current_piece
+          se_obj("piece_#{player.current_piece.class.shape_key}").play
+        end
       end
-    end

-    def max_velocity_fall_collision_signal
-      super
-      se_play :collision
-    end
+      def max_velocity_fall_collision_signal
+        super
+        se_obj(:collision).play
+      end

-    def fall_collision_signal
-      super
-      se_play :collision
-    end
+      def fall_collision_signal
+        super
+        se_obj(:collision).play
+      end

-    def lock_signal(player)
-      super
-      se_play :lock
-    end
+      def lock_signal(player)
+        super
+        se_obj(:lock).play
+      end

-    def signal_field_down_signal(player)
-      super
-      se_play :field_down
-    end
+      def signal_field_down_signal(player)
+        super
+        se_obj(:field_down).play
+      end

-    def user_irs_success_signal(*args)
-      super
-      se_play :irs
-    end
+      def user_irs_success_signal(*args)
+        super
+        se_obj(:irs).play
+      end

-    def before_clear_lines(player)
-      super
-      line_count = player.field.complate_info.size
-      if line_count <= 2
-        se_play :delete_s
-      else
-        se_play :delete_l
+      def before_clear_lines(player)
+        super
+        line_count = player.field.complate_info.size
+        if line_count <= 2
+          se_play :delete_s
+        else
+          se_obj(:delete_l).play
+        end
       end
-    end

-    def ren_signal(count)
-      case count
-      when 0
-        se_play :applause_s
-      when 1
-        se_play :applause_m
-      else
-        se_play :applause_l
+      def ren_signal(count)
+        case count
+        when 0
+          se_obj(:applause_s).play
+        when 1
+          se_obj(:applause_m).play
+        else
+          se_obj(:applause_l).play
+        end
       end
-    end

-    def top_out_start_signal(player)
-      super
-      music_stop
-      se_play :top_out
+      def top_out_start_signal(player)
+        super
+        music_stop
+        se_obj(:top_out).play
+      end
+
+      def item_break_signal(*)
+        super
+        se_obj(:item_break).play
+      end
     end

-    private
+    module ItemSoundMod
+      def item_mode_one_line_clear_signal
+        super
+        se_obj(:kill_one_line_by_item).play
+      end

-    def se_play(key)
-      Stylet::SE[@se_aliases[key] || key].play
+      def compact_fall_down_by_item
+        super
+        se_obj(:field_down).play
+      end
+
+      def compact_fall_jump_by_item
+        super
+        se_obj(:field_jump).play
+      end
     end

-    def music_play(key)
-      if music = @sound_set[:music]
-        if attrs = music[key.to_sym]
-          Stylet::Music.play(attrs[:file], :volume => attrs[:volume])
+    module AlermMod
+      extend ActiveSupport::Concern
+
+      def initialize(*)
+        super if defined? super
+        @alerm_trigger_level = 4
+        @alermer = State.new(:idol)
+      end
+
+      def before_move(player)
+        super if defined? super
+        @alermer.loop_in do
+          case @alermer.state
+          when :idol
+            if alerm_invoke?(player)
+              alerm_start_signal(player)
+              @alermer.jump_to :alerm_in
+            end
+          when :alerm_in
+            unless alerm_invoke?(player)
+              alerm_end_signal(player)
+              @alermer.jump_to :idol
+            end
+          end
         end
       end
-    end

-    def music_stop
-      Stylet::Music.halt
+      def top_out_start_signal(player)
+        super if defined? super
+        alerm_end_signal(player)
+      end
+
+      def alerm_start_signal(*)
+        super
+        se_obj(:alerm).play(loop: true)
+      end
+
+      def alerm_end_signal(*)
+        super
+        se_obj(:alerm).halt
+      end
+
+      private
+
+      def alerm_invoke?(player)
+        player.field.suffocation <= @alerm_trigger_level
+      end
     end
+
+    extend ActiveSupport::Concern
+    include Core
+    include Basic
+    include ItemSoundMod
+    include AlermMod
   end
 end
diff --git a/lib/vortex/sound_set.rb b/lib/vortex/sound_set.rb
index ccb941e..55aeedf 100644
--- a/lib/vortex/sound_set.rb
+++ b/lib/vortex/sound_set.rb
@@ -17,15 +17,15 @@ module Vortex
         :section_up => {:file => "#{__dir__}/assets/section_up.wav", :volume => 0.5},
         :irs        => {:file => "#{__dir__}/assets/irs.wav",        :volume => 0.3},
         :lock       => {:file => "#{__dir__}/assets/lock.wav",       :volume => 0.5},
-        :piece_J    => {:file => "#{__dir__}/assets/piece_J.wav",     :volume => 0.2},
-        :piece_T    => {:file => "#{__dir__}/assets/piece_T.wav",     :volume => 0.2},
-        :piece_Z    => {:file => "#{__dir__}/assets/piece_Z.wav",     :volume => 0.2},
-        :piece_L    => {:file => "#{__dir__}/assets/piece_L.wav",     :volume => 0.2},
-        :piece_S    => {:file => "#{__dir__}/assets/piece_S.wav",     :volume => 0.2},
-        :piece_I    => {:file => "#{__dir__}/assets/piece_I.wav",     :volume => 0.2},
-        :piece_O    => {:file => "#{__dir__}/assets/piece_O.wav",     :volume => 0.2},
+        :piece_J    => {:file => "#{__dir__}/assets/piece_J.wav",     :volume => 0.15},
+        :piece_T    => {:file => "#{__dir__}/assets/piece_T.wav",     :volume => 0.15},
+        :piece_Z    => {:file => "#{__dir__}/assets/piece_Z.wav",     :volume => 0.15},
+        :piece_L    => {:file => "#{__dir__}/assets/piece_L.wav",     :volume => 0.15},
+        :piece_S    => {:file => "#{__dir__}/assets/piece_S.wav",     :volume => 0.15},
+        :piece_I    => {:file => "#{__dir__}/assets/piece_I.wav",     :volume => 0.15},
+        :piece_O    => {:file => "#{__dir__}/assets/piece_O.wav",     :volume => 0.15},

-        :field_jump => {:file => "#{__dir__}/../../../sound_effects/ds_puyo_puyo_fever/WAVE_SE_013.wav",     :volume => 0.9},
+        # :field_jump => {:file => "#{__dir__}/../../../sound_effects/ds_puyo_puyo_fever/WAVE_SE_013.wav",     :volume => 0.9},
         # :field_jump => {:file => "#{__dir__}/../../../sound_effects/super_mario_bros/jump.wav",     :volume => 0.9},

         # :field_down => {:file => "#{__dir__}/assets/field_down.wav", :volume => 0.2},
@@ -39,5 +39,12 @@ module Vortex
         :bgm_training   => {:file => "#{__dir__}/assets/bgm_training.wav",   :volume => 1.0},
       },
     },
+    :garage_band => {
+      :se => {
+        # :field_jump => {:file => "#{__dir__}/assets/garage_band/field_jump.aif", :volume => 0.3},
+        :item_break => {:file => "#{__dir__}/assets/garage_band/item_break.aif", :volume => 0.4},
+        :alerm      => {:file => "#{__dir__}/assets/garage_band/alerm.aif",      :volume => 0.2},
+      },
+    },
   }
 end
diff --git a/lib/vortex/window.rb b/lib/vortex/window.rb
index e1bcf44..f8b8370 100644
--- a/lib/vortex/window.rb
+++ b/lib/vortex/window.rb
@@ -76,7 +76,6 @@ def initialize(target)
         # end

         Stylet.config.production_keys = [SDL::Key::K0]
-
         SDL::Mouse.hide
       end

diff --git a/spec/core/field_spec.rb b/spec/core/field_spec.rb
index dd30c1b..0cb40dc 100644
--- a/spec/core/field_spec.rb
+++ b/spec/core/field_spec.rb
@@ -198,6 +198,25 @@
     f.damage.should == 3
   end

+  it "suffocation" do
+    f = -> field_str { Field.new(width: 1, height: 3, field_str: field_str) }
+    f.call(<<-EOS).suffocation.should == 1
+.
+.
+.
+    EOS
+    f.call(<<-EOS).suffocation.should == 0
+.
+.
+r
+    EOS
+    f.call(<<-EOS).suffocation.should == -1
+.
+r
+.
+    EOS
+  end
+
   it "clone" do
     f0, f1 = get_piece_write_field(Piece::Classic::PieceT, Piece::Classic::PieceJ)
     (f0 == f0.clone).should == true

勉強会用のコードをメニューから呼べるようにした
r "(\brandomizer\b.*)\"([a-z]+)\"" "#{\$1}\\"#{\$2.tr('yrbogpc','OIJLZST')}\\"" -x
ホールドが残る不具合→修正
tpm

diff --git a/lib/vortex/tech_list.rb b/lib/vortex/tech_list.rb
index a84e840..9efaa52 100644
--- a/lib/vortex/tech_list.rb
+++ b/lib/vortex/tech_list.rb
@@ -531,8 +531,8 @@ def initialize

   # Vortex::TechList.each{|e| break if Simulator.start_auto(e) == :break}; exit

-    Simulator.start(TechList.last)
-    exit
+    # Simulator.start(TechList.last)
+    # exit

   e = Vortex::TechList.find{|e|e[:title] == "DDT砲"} # アルバトロスSP
   # Simulator.start_auto(e)
IHS
player.rb の巨大な when を method 化。LHS。LaserItem, ShotgunItem
apm lpm garage band tasks effect
テストこける→修正