class_name StateModifier extends Resource ## State modification ## ## A state modifier doesn't have any direct control of a game object. ## They are transfered from the enter and exit of other states and ## influence the movement or animation of their parent states. ## Rather than going full into paralell state machines I hope that this ## modifier will be suitable for a basic state machine. ## ## @WIP ## Deprecated, should use modifier level # Used for mutually exclusive modifiers to aid merging enum TYPE { NONE, # Usually just a physics modifier EXIT_ANIMATION, # Adds an animation at the end? Not really sure anymore ANIMATION_SUFFIX, # Adds an animation suffix to aid slightly modified animations REPLACE_ANIMATION # Completely replaces a state animation. } enum EVENT_ID { ACTIVATED, DEACTIVATED } var debug: bool = false ##TODO: Animation speed ## Modification Type ## if an animation is specified, the default behavior will be just to override ## the state animation. Or perform a 'Replace Animation' var modifier_type = TYPE.NONE export var name :String = '' #var ready :bool = false var is_active: bool = false signal modifier_event(event_id ) # Move Speed in Pixels Per Second # These should only apply if Modification Type Set to None. # (But I'm not sure if I like that model.) #var move_speed: float #var move_speed_modifier: float = 0 #var move_speed_modifier_decay: float = 0 #var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity") # Attempting to use this as an animation suffix that can linger after # state transition like 'run-fire' to 'idle-fire' 'jump-fire' etc. #var animation_suffix: bool = false #var pre_append_animation: bool = false # not sure if I can do the array thing from state change. Maybe? # disabling this sequencing for now. # export(Array, String) var animation_sequence # var animation_index: int = 0 # var current_animation_sequence: int = 0 #var animation_sequence_timer: Timer var timeout: Timer export var timeout_seconds: float = 0.0 # Meant to be called on timeout or other counters this modifier may have. # Should be updated whenever modifier owner transfers var state_call_function: FuncRef #func merge_modifier(merging_mod: ModifierProperties): # if merging_mod.modifier_type != TYPE.NONE: # print("Warning Merging modifier types that aren't set to 'none' is not supported!") # return #func get_modifier_properties() -> ModifierProperties: # #( p_move_speed:float, p_gravity:int , p_move_acceleration , p_move_speed_modifier:float, # # p_move_modifier_move_acceleration:float, p_jerk_factor: float): # var mp = ModifierProperties.new( modifier_properties.move_speed, # modifier_properties.gravity, # modifier_properties.move_acceleration, # modifier_properties.move_speed_modifier, # modifier_properties.move_modifier_move_acceleration, # modifier_properties.jerk_factor) # mp.directional_modifier = modifier_properties.directional_modifier # return mp ## Because I've tried a few ways to identify the object without a CR error func _to_string(): return "StateModifier" func setup(modifier_name:String, type = TYPE.NONE,_timeout_seconds : float = 0): name = modifier_name modifier_type = type if _timeout_seconds > 0: timeout = Timer.new() timeout.wait_time = _timeout_seconds timeout.one_shot = true timeout.autostart = false timeout.connect("timeout",self,"deactivate") func reset(): name = '' modifier_type = TYPE.NONE is_active = false func copy(_copy_state: StateModifier): ## This should really be the other way. # _copy_state.name = name # _copy_state.modifier_type = modifier_type name = _copy_state.name modifier_type = _copy_state.modifier_type func merge(_merge_from_modifier: StateModifier): pass func activate(): is_active = true if timeout != null: timeout.start() emit_signal("modifier_event",EVENT_ID.ACTIVATED, to_string()) func deactivate(): is_active = false print(name," <- Got call to deactivate.") emit_signal("modifier_event",EVENT_ID.DEACTIVATED, to_string()) #func ready(modifier_name:String, anim_name:String = '', type = TYPE.NONE, timeout : float = 0, parent:Node = null, function_name : String = "") -> Timer: # name = modifier_name # # If somebody forgot to specify the type # if anim_name != '' and type == TYPE.NONE: # modifier_type = TYPE.REPLACE_ANIMATION # animation_name = anim_name # modifier_type = type ## if parent != null and function_name != "": ## state_call_function = funcref(parent, function_name) # ## modifier_properties = ModifierProperties.new(0,0,0,0,0,0) # # if timeout > 0: # state_timeout = Timer.new() # state_timeout.wait_time = timeout # state_timeout.one_shot = true # state_timeout.autostart = false # return state_timeout # #add_child(state_timeout) # #ModifierProperties.new() # return null ## Transfer and callback related methods. These sort of worked but I didn't end up using them ## They're an interesting idea though. #func transfer_owner(parent:Node): # print("Modifier owner will now be: ", parent.name) # state_call_function = funcref(parent, 'update_animation') func _on_Timer_timeout(): #print("Oh Crap! I can't beleive it worked") if state_call_function: if state_call_function.is_valid(): state_call_function.call_func() else: print("Warning! Modifier timed out with no callback to alert.") else: print("Warning! no function applies.")