extends Node2D const ANIM_RATE_DEFAULT = 3.5 const ANIM_RATE_AGGRESSIVE = 6.0 const ANIM_RATE_CONTENT = 1.0 const EXCITEMENT_MIN_SPEED = 150 const EXCITEMENT_MAX_SPEED = 350 # Mood = r: , g: , b: # Affects how strong a players push is and how strong the player's collision with the world will be. # Affects how quickly and strongly the player will follow the mouse # Affects how slowly mood color is shifted back to neutral and widens comfort distance var _mood = Color.black onready var _spr = get_parent().get_node("Sprite") onready var _body_radius = get_parent().get_node("CollisionShape2D").shape.radius func reset_mood(): _mood = Color.black _spr.material.set_shader_param("cell_color", _mood); func adjust_mood(r, g, b): _mood.r = clamp(_mood.r + r, 0.0, 1.0) _mood.g = clamp(_mood.g + g, 0.0, 1.0) _mood.b = clamp(_mood.b + b, 0.0, 1.0) _spr.material.set_shader_param("cell_color", _mood); if is_aggressive(): _spr.material.set_shader_param("cell_energy", ANIM_RATE_AGGRESSIVE) elif is_content(): _spr.material.set_shader_param("cell_energy", ANIM_RATE_CONTENT) else: _spr.material.set_shader_param("cell_energy", ANIM_RATE_DEFAULT) func adjust_mood_from_color(c): if c.r != c.g or c.r != c.b: # Only adjust mood if not all values are the same. # Even if not all the same, there must be a single dominant color for mood to be adjusted. if c.r > c.g and c.r > c.b: adjust_mood(0.25, 0.0, 0.0) if c.g > c.r and c.g > c.b: adjust_mood(0.0, 0.25, 0.0) if c.b > c.r and c.b > c.g: adjust_mood(0.0, 0.0, 0.25) func is_aggressive(): return _mood.r > _mood.g and _mood.r > _mood.b func is_needie(): return _mood.g > _mood.r and _mood.g > _mood.b func is_content(): return _mood.b > _mood.r and _mood.b > _mood.g func is_neutral(): return not is_aggressive() and not is_needie() and not is_content() func get_aggression(): return _mood.r func get_need(): return _mood.g func get_contentment(): return _mood.b func get_comfort_distance(): return get_parent().get_node("CollisionShape2D").shape.radius * 2.1 func get_mood_color(): return _mood func _agg_shift(in_air, speed): var v = -0.1 # By default, aggression is always lowering if in_air and speed >= EXCITEMENT_MIN_SPEED and speed <= EXCITEMENT_MAX_SPEED: v = 0.1 # If in the air, going at an "exciting" speed, aggression rises! elif is_aggressive(): v = -0.05 # Otherwise, if we're dominantly aggressive, slow aggression cooldown. if speed > 1.0 and _mood.r * 0.5 > _mood.b and _mood.r * 0.5 > _mood.g: v = 0.0 # But, if we're moving and our aggression is more than twice the other emotions, don't cooldown at all. return v func _need_shift(in_air, distance): var v = -0.1 if in_air: # Decrease neediness faster while in air, as "player" is giving attension (in the air) or # otherwise excited!! v = -0.25 else: var cdist = get_comfort_distance() if distance > cdist: v = 0.1 if distance > cdist * 8.0: v = 0.25 return v func _con_shift(in_air, speed, distance): var v = -0.1 if in_air and speed < EXCITEMENT_MIN_SPEED: v = 0.1 if is_aggressive(): # Assuming aggression hasn't taken over... v = 0.05 # Levitating in the air is nice! else: var cdist = get_comfort_distance() if distance <= cdist: v = 0.1 # It's nice when the player is nearby if is_needie(): v = 0.05 # My neediness is slowing my contentment. elif is_aggressive(): v = -0.25 # If aggressive, reduce contentment a lot. return v func shift_mood(delta, in_air, speed, distance): adjust_mood( _agg_shift(in_air, speed) * delta, _need_shift(in_air, distance) * delta, _con_shift(in_air, speed, distance) * delta )