Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Key_Combo
- def initialize
- @timeline = {}
- @running = []
- @actions = []
- @ticks = 0
- @total_ticks = 0
- end
- ##
- # Put an action into the timeline
- #
- def put(action, start)
- @timeline[start] = [] if @timeline[start].nil?
- @timeline[start] << action
- @actions << action
- # Update the total ticks if necessary
- total_ticks = start + action.total_ticks
- if total_ticks > @total_ticks
- @total_ticks = total_ticks
- end
- end
- ##
- # Resets the timeline and all the actions
- #
- def reset
- @ticks = 0
- @running.clear
- for action in @actions
- action.reset
- end
- end
- ##
- # Updates the combo
- #
- # Returns
- # nil - Not completed yet
- # false - The action failed
- # true - The action succeeded
- #
- def update
- # Add new actions
- new_actions = @timeline[@ticks]
- unless new_actions.nil?
- for action in new_actions
- @running << action
- end
- end
- # Check and update the running actions
- for action in @running
- # Update the action
- result = action.update
- # Check if the action still is running
- unless result.nil?
- if result
- # It was successful
- @running.delete(action)
- else
- # It was not successful
- return false
- end
- end
- end
- # Tick
- @ticks += 1
- # Check if all ticks has been used
- if @ticks >= @total_ticks
- # No failures => success
- return true
- end
- return nil
- end
- end
- class Key_Action
- attr_reader :ticks
- attr_reader :total_ticks
- def reset
- raise NotImplementedError.new(self.class.to_s + ".reset")
- end
- def update
- raise NotImplementedError.new(self.class.to_s + ".update")
- end
- end
- class Conjunction_Key_Action < Key_Action
- ##
- # Initialization
- # condition - The condition that must be fulfilled
- # *actions - The actions to check if they in conjunction succeed
- # The first action entered is the first to be executed
- # The second action entered is the next and so on
- #
- # action1 ^ action2 ^ action3 ^ ... ^ actionN
- #
- # Note: Automatically succeeds if no actions are entered unless condition is
- # false
- #
- def initialize(condition, *actions)
- @total_ticks = 0
- @condition = condition
- @actions = []
- for action in actions
- if action.is_a?(Key_Action)
- @actions << action
- @total_ticks += action.total_ticks
- else
- raise IllegalArgumentError.new("On of the arguments in " + self.class.to_s +
- " is not a Key_Action, it is a " + condition.class.to_s)
- end
- end
- @index = 0
- @ticks = 0
- end
- ##
- # Reset the action so it can be used again
- #
- def reset
- @index = 0
- @ticks = 0
- for action in @actions
- action.reset
- end
- end
- ##
- # Returns
- # nil - Not completed yet
- # false - The action failed
- # true - The action succeeded
- #
- def update
- # Check if the condition is fulfilled
- unless @condition.checkCondition
- return false
- end
- # Check if the correct keys have been triggered
- action = @actions[@index]
- if action.nil?
- return true
- end
- # Get the result from the action update
- @ticks += 1
- result = action.update
- # If the action has failed
- if result == false
- return false
- # If the action has succeeded
- elsif result == true
- # Move to next action
- @index += 1
- # If no more actions
- if @actions.size <= @index
- return true
- end
- end
- return nil
- end
- end
- class Disjunction_Key_Action < Key_Action
- ##
- # Initialization
- # condition - The condition that must be fulfilled
- # *actions - The actions to check if they in disjunction succeed
- # The first action entered is the first to be executed
- # The second action entered is the next and so on
- #
- # action1 v action2 v action3 v ... v actionN
- #
- # Note: Automatically fails if no actions are entered.
- #
- def initialize(condition, *actions)
- @total_ticks = 0
- @condition = condition
- @actions = []
- for action in actions
- if action.is_a?(Key_Action)
- @actions << action
- @total_ticks += action.total_ticks
- else
- raise IllegalArgumentError.new("On of the arguments in " + self.class.to_s +
- " is not a Key_Action, it is a " + condition.class.to_s)
- end
- end
- @index = 0
- @ticks = 0
- end
- ##
- # Reset the action so it can be used again
- #
- def reset
- @index = 0
- @ticks = 0
- for action in @actions
- action.reset
- end
- end
- ##
- # Returns
- # nil - Not completed yet
- # false - The action failed
- # true - The action succeeded
- #
- def update
- # Check if the condition is fulfilled
- unless @condition.checkCondition
- return false
- end
- # Check if the correct keys have been triggered
- action = @actions[@index]
- if action.nil?
- return false
- end
- # Get the result from the action update
- @ticks += 1
- result = action.update
- # If the action has failed
- if result == false
- # Move to next action
- @index += 1
- # If no more actions
- if @actions.size <= @index
- return false
- end
- # If the action has succeeded
- elsif result == true
- return true
- end
- return nil
- end
- end
- class Trigger_Key_Action < Key_Action
- ##
- # Initialization
- # key_press - The keys to press
- # condition - The condition that must be fulfilled
- # ticks - The number of ticks to press the key
- #
- def initialize(key_press, condition, ticks)
- @key_press = key_press
- @condition = condition
- @total_ticks = ticks
- @ticks = 0
- end
- ##
- # Reset the action so it can be used again
- #
- def reset
- @ticks = @total_ticks
- end
- ##
- # Returns
- # nil - Not completed yet
- # false - The action failed
- # true - The action succeeded
- #
- def update
- # Check if the condition is fulfilled
- unless @condition.checkCondition
- return false
- end
- # Check if the correct keys have been triggered
- if @key_press.trigger?
- return true
- end
- # Removes the amount of ticks for the action
- @ticks += 1
- # Check if all ticks has been used
- if @ticks >= @total_ticks
- return false
- end
- return nil
- end
- end
- class Release_Key_Action < Key_Action
- ##
- # Initialization
- # key_press - The keys to press
- # condition - The condition that must be fulfilled
- # ticks - The number of ticks to hold the key pressed
- # delta - The amounts of ticks before and after the right tick which are
- # considered as being timely release
- #
- def initialize(key_press, condition, ticks, delta)
- @key_press = key_press
- @condition = condition
- @total_ticks = ticks + delta
- @ticks = 0
- @delta = delta
- end
- ##
- # Reset the action so it can be used again
- #
- def reset
- @ticks = 0
- end
- ##
- # Returns
- # nil - Not completed yet
- # false - The action failed
- # true - The action succeeded
- #
- def update
- # Check if the condition is fulfilled
- unless @condition.checkCondition
- return false
- end
- # Check if the correct keys is still pressed
- unless @key_press.press?
- if @total_ticks - @delta * 2 <= @ticks && @total_ticks >= @ticks
- return true
- else
- return false
- end
- end
- # Removes the amount of ticks for the action
- @ticks += 1
- # Check if all ticks has been used
- if @ticks >= @total_ticks
- return false
- end
- return nil
- end
- end
- ##
- # Manages a serie of keys and whether they are pressed, triggered and repeated
- # Basically the same as the Input module except that it can check an arbitrary
- # number of keys instead of 1 key
- #
- class Key_Press
- @keys = []
- ##
- # Initialization
- # *args - integer values of the keys to press. (Refer to Input constants)
- def initialize(*args)
- @keys = args.flatten.compact
- end
- ##
- # Check if all keys are triggered
- #
- def trigger?
- for key in @keys
- unless Input.trigger?(key)
- return false
- end
- end
- return true
- end
- ##
- # Check if all keys are pressed
- #
- def press?
- for key in @keys
- unless Input.press?(key)
- return false
- end
- end
- return true
- end
- ##
- # Check if all keys are repeated
- #
- def repeat?
- for key in @keys
- unless Input.repeat?(key)
- return false
- end
- end
- return true
- end
- end
- class IllegalArgumentError < StandardError
- end
- class StandardError < Exception
- def to_s
- b = self.backtrace
- b.delete_at(0)
- return super + "\n\nBacktrace:\n" + b.join("\n")
- end
- end
- class Condition
- def checkCondition(*args)
- raise NotImplementedError.new(self.class.to_s + ".checkCondition")
- end
- end
- class ConjunctionCondition < Condition
- def initialize(*conditions)
- @conditions = []
- for condition in conditions
- if condition.is_a?(Condition)
- @conditions << condition
- else
- raise IllegalArgumentError.new("On of the arguments in " + self.class.to_s +
- " is not a Condition, it is a " + condition.class.to_s)
- end
- end
- end
- def checkCondition(*args)
- for condition in @conditions
- return false unless condition.checkCondition(*args)
- end
- return true
- end
- end
- class DisjunctionCondition < Condition
- def initialize(*conditions)
- @conditions = []
- for condition in conditions
- if condition.is_a?(Condition)
- @conditions << condition
- else
- raise IllegalArgumentError.new("On of the arguments in " + self.class.to_s +
- " is not a Condition, it is a " + condition.class.to_s)
- end
- end
- end
- def checkCondition(*args)
- for condition in @conditions
- return true if condition.checkCondition(*args)
- end
- return false
- end
- end
- class NotCondition < Condition
- def initialize(condition)
- if condition.is_a?(Condition)
- @condition = condition
- else
- raise IllegalArgumentError.new("Given argument in " + self.class.to_s +
- " is not a condition, it is a " + condition.class.to_s)
- end
- end
- def checkCondition(*args)
- return condition.checkCondition(*args)
- end
- end
- class TrueCondition < Condition
- def checkCondition(*args)
- return true
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement