Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extends Node2D
- class_name PetWorldNode2D
- signal state_changed(state: States)
- const DEFAULT_PATHABLE_RECT: Rect2 = Rect2(Vector2.ZERO, Vector2.ONE * 1280)
- enum States {
- STANDING,
- ROAMING,
- ANIMATING,
- SOCIALIZING,
- }
- const META_LAST_ANIMATION: String = "PET_META_LAST_ANIMATION"
- const META_STATE_ROAMING_TARGET: String = "PET_META_STATE_ROAMING_TARGET_GLOBAL_POS"
- const META_STATE_SOCIALIZING_TARGET: String = "PET_META_STATE_SOCIALIZING_TARGET_NODE"
- const TIME_ROAMING_PATH_WAIT: String = "PET_META_ROAMING_TIME_COUNTER_DECISION"
- const STATE_ROAMING_MAX_SPEED: float = 2
- const STATE_ROAMING_MIN_SPEED: float = 80
- @export var resource: Pet
- var animator := PetWorldAnimator2D.new()
- var pathable_rect_global: Rect2
- var state_current: States
- var state_decision_timer: SceneTreeTimer
- var time_counters: Dictionary
- var meta: Dictionary
- var texture_to_draw: Texture2D
- var sprite_animation_tweens: Dictionary
- static func create_from_resource(pet_res: Pet) -> PetWorldNode2D:
- var new_node := PetWorldNode2D.new()
- new_node.resource = pet_res
- return new_node
- func _enter_tree() -> void:
- update_pathable_rect()
- func _ready() -> void:
- resource.sprite_sheet_update()
- add_child(animator)
- state_changed.connect(on_state_changed)
- resource.action_performed.connect(on_pet_action_performed)
- resource.stat_changed.connect(on_pet_stat_changed)
- state_decide()
- update_animations()
- sprite_animation_play("default")
- func _process(delta: float) -> void:
- queue_redraw()
- #Advance time counters
- for counter: String in time_counters:
- var time_left: float = time_counter_get_time(counter)
- time_counter_set_time(counter, time_left - delta)
- if time_left < 0:
- time_counters.erase(counter)
- #Handle current state
- match state_current:
- States.ROAMING:
- if time_counter_get_time(TIME_ROAMING_PATH_WAIT) <= 0:
- state_roaming_update_target()
- state_roaming_update_timer()
- global_position = global_position.move_toward(state_roaming_get_target(), state_roaming_get_speed() * delta)
- queue_redraw()
- States.SOCIALIZING:
- var target_pos: Vector2 = state_socializing_get_target().global_position
- if is_zero_approx(target_pos.length() - global_position.length()):
- print_debug("The target is right here!?")
- state_decide()
- return
- var ideal_distance: float = (8 + resource.spritesheet_texture.get_size().x) / resource.resource_dna.get_value_nature_modifier(PetDna.NatureProperties.SHY_SOCIAL)
- if global_position.distance_to(target_pos) > ideal_distance:
- global_position = global_position.move_toward(target_pos, state_roaming_get_speed() * delta)
- func _input(event: InputEvent) -> void:
- if event.is_action_pressed("poke_random"):
- resource.action_perform(Pet.Actions.GET_POKED)
- func _draw() -> void:
- if not texture_to_draw:
- return
- draw_texture(texture_to_draw, -texture_to_draw.get_size() / 2)
- func get_rect_global() -> Rect2:
- return Rect2(global_position - Vector2(resource.sprite_get_base_size()/2), resource.sprite_get_base_size())
- func state_change(state: States):
- state_current = state
- state_changed.emit(state)
- func state_decide():
- if state_can_change():
- var new_state: States = States.values().pick_random()
- state_change(new_state)
- state_start_decision_timer()
- func state_can_change() -> bool:
- return is_inside_tree()
- func state_get_query_time() -> float:
- return randf() * 5 + 0.5
- func state_start_decision_timer():
- if not state_decision_timer is SceneTreeTimer or state_decision_timer.time_left == 0:
- state_decision_timer = get_tree().create_timer(state_get_query_time())
- state_decision_timer.timeout.connect(state_decide, CONNECT_ONE_SHOT)
- func state_roaming_update_target():
- var spot: Vector2 = Vector2(
- randf_range(pathable_rect_global.position.x, pathable_rect_global.end.x),
- randf_range(pathable_rect_global.position.y, pathable_rect_global.end.y)
- )
- assert(pathable_rect_global.has_point(spot))
- meta[META_STATE_ROAMING_TARGET] = spot
- func state_roaming_update_timer():
- time_counter_set_time(TIME_ROAMING_PATH_WAIT, randf() * 5)
- func state_roaming_get_target()->Vector2:
- var target: Vector2 = meta.get(META_STATE_ROAMING_TARGET, global_position)
- return target
- func state_roaming_get_speed() -> float:
- var speed_value: float = resource.get_value_speed() + 10
- speed_value *= resource.get_value_nature_modifier(PetDna.NatureProperties.LAZY_ENERGETIC) * resource.get_value_nature_modifier(PetDna.NatureProperties.CALM_ROWDY)
- return wrapf( speed_value as float, STATE_ROAMING_MIN_SPEED, STATE_ROAMING_MAX_SPEED)
- func state_socializing_set_target():
- var pet_nodes: Array[PetWorldNode2D] = PeManager.pet_get_node_list()
- if pet_nodes.is_empty():
- push_warning("List is empty!")
- return
- var candidates: Array[PetWorldNode2D] = []
- for possible_target_count: int in 5:
- candidates.append(pet_nodes.pick_random())
- var chosen: PetWorldNode2D = candidates.pick_random()
- assert(chosen is PetWorldNode2D)
- meta[META_STATE_SOCIALIZING_TARGET] = chosen
- func state_socializing_get_target() -> PetWorldNode2D:
- return meta.get(META_STATE_SOCIALIZING_TARGET, self)
- func time_counter_set_time(key: String, time: float):
- time_counters[key] = time
- func time_counter_get_time(key: String) -> float:
- return time_counters.get(key, 0.0)
- func update_pathable_rect():
- pathable_rect_global = DEFAULT_PATHABLE_RECT
- func update_animations():
- sprite_animation_stop()
- sprite_animation_tweens.clear()
- for animation: String in resource.sprite_get_animation_names():
- var tween: Tween = resource.sprite_tween_property_with_animation(self, "texture_to_draw", animation)
- sprite_animation_tweens[animation] = tween
- func sprite_animation_play(animation: String, loops: int = 0):
- sprite_animation_stop()
- if not sprite_animation_tweens.has(animation):
- push_error("No such animation is present for this pet.")
- return
- var tween: Tween = sprite_animation_tweens[animation]
- tween.set_loops(loops)
- tween.play()
- set_meta(META_LAST_ANIMATION, animation)
- func sprite_animation_stop(last_anim: String = get_meta(META_LAST_ANIMATION, "")):
- if last_anim != "":
- if sprite_animation_tweens.has(last_anim):
- sprite_animation_tweens[last_anim].stop()
- func on_state_changed(state: States):
- match state:
- States.ANIMATING:
- animator.play_animation()
- States.SOCIALIZING:
- state_socializing_set_target()
- func on_pet_action_performed(action: Pet.Actions):
- match action:
- Pet.Actions.GET_POKED:
- animator.queued_animation = PetWorldAnimator2D.Animations.DRAINED
- state_change(States.ANIMATING)
- func on_pet_stat_changed(_stat: Pet.Stats, amount: float):
- if amount < -15:
- animator.queued_animation = PetWorldAnimator2D.Animations.DRAINED
- state_change(States.ANIMATING)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement