From 9ce284ccd23267ed49ed6853715a0090725cd3bc Mon Sep 17 00:00:00 2001 From: uncreativeCultist Date: Wed, 23 Oct 2024 09:43:45 -0400 Subject: [PATCH] Add scripts --- Scenes/Entities/Player/player-nyoomcompat.gd | 2343 ------------------ Scenes/Entities/Player/player.gd | 2343 ------------------ 2 files changed, 4686 deletions(-) delete mode 100644 Scenes/Entities/Player/player-nyoomcompat.gd delete mode 100644 Scenes/Entities/Player/player.gd diff --git a/Scenes/Entities/Player/player-nyoomcompat.gd b/Scenes/Entities/Player/player-nyoomcompat.gd deleted file mode 100644 index 4fb75c4..0000000 --- a/Scenes/Entities/Player/player-nyoomcompat.gd +++ /dev/null @@ -1,2343 +0,0 @@ -extends Actor - -enum STATES{DEFAULT, BUSY, OBTAIN, EMOTING, FREECAM, FISHING_CHARGE, FISHING_CAST, FISHING, FISHING_CANCEL, FISHING_STRUGGLE, SHOVEL_CAST, SHOVEL_STRUGGLE, SHOVEL_CANCEL, \ -NET_CAST, NET_STRUGGLE, NET_CANCEL, SHOWCASE, CONSUME_ITEM, METAL_DETECTOR, GUITAR, GAMBLING} - -const GRAVITY = 32.0 -const BAIT_DATA = { - "": {"catch": 0.0, "max_tier": 0, "quality": []}, - - "worms": {"catch": 0.06, "max_tier": 1, "quality": [1.0]}, - "cricket": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.05]}, - "leech": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.15, 0.05]}, - "minnow": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.5, 0.25, 0.05]}, - "squid": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.8, 0.45, 0.15, 0.05]}, - "nautilus": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.98, 0.75, 0.55, 0.25, 0.05]}, -} -const PARTICLE_DATA = { - "dust_run": preload("res://Scenes/Particles/dust_running.tscn"), - "dust_land": preload("res://Scenes/Particles/dust_land.tscn"), - "splash": preload("res://Scenes/Particles/water_splash.tscn"), - "small_splash": preload("res://Scenes/Particles/small_splash.tscn"), - "music": preload("res://Scenes/Particles/music_particle.tscn"), - "kiss": preload("res://Scenes/Particles/kiss.tscn"), -} - -export (NodePath) var hand_sprite_node -export (NodePath) var hand_bone_node -export var NPC_body = false -export var NPC_cosmetics = {"species": "species_cat", "pattern": "pattern_none", "primary_color": "pcolor_white", "secondary_color": "scolor_tan", "hat": "hat_none", "undershirt": "shirt_none", "overshirt": "overshirt_none", "title": "title_rank_1", "bobber": "bobber_default", "eye": "eye_halfclosed", "nose": "nose_cat", "mouth": "mouth_default", "accessory": [], "tail": "tail_cat"} -export var NPC_name = "NPC Test" -export var NPC_title = "npc title here" - -var camera_zoom = 5.0 - -var direction = Vector3() -var gravity_vec = Vector3() -var dive_vec = Vector3() -var velocity = Vector3() -var player_scale = 1.0 -var player_scale_y = 1.0 - -var cam_orbit_node = null -var cam_follow_node = null -var cam_push = 0.0 -var cam_push_cur = 0.0 -var cam_return = 1.0 -var force_cam_look = false -var mouse_world_pos = Vector3() -var mouse_look = false - -var state = STATES.DEFAULT -var walk_speed = 3.2 -var slow_walk_speed = 1.0 -var sprint_speed = 6.88 -var sneak_speed = 1.3 -var jump_height = 7.5 -var jump_leap = 0.0 -var dive_distance = 15.0 -var accel = 64.0 -var sprinting = false -var slow_walking = false -var sneaking = false -var diving = false -var request_jump = false -var ignore_snap = 0 -var snapped = false -var sitting = false -var locked = false -var busy = false -var in_air = false -var gravity_disable = false -var hud -var int_text = "" -var interact_cooldown = 60 -var xp_buildup = 0 -var showcase_ref - -var held_item = PlayerData.FALLBACK_ITEM -var caught_item = PlayerData.FALLBACK_ITEM -var held_item_weight = 1.0 -var previous_item = 0 -var primary_hold_timer = 0 -var fish_zone_data = {} -var rod_cast_data = "" -var casted_bait = "" -var rod_cast_dist = 0.0 -var rod_depth = 0 -var failed_casts = 0 -var recent_reel = 0.0 -var item_scene = null -var bobber_hpos = Vector3() -var bobber_vpos = 0 -var bobber_control = true -var last_valid_pos = Vector3() -var retract_splash = false -var show_local = false -var bait_warn = 2 -var in_rain = false -var consume_on_state_change = - 1 -var item_cooldown = 0 - -var rod_damage = 1.0 -var rod_spd = 1.0 -var rod_chance = 0.0 - - - -var boost_timer = 0 -var boost_amt = 1.3 -var boost_mult = 1.0 -var catch_drink_timer = 0 -var catch_drink_boost = 1.0 -var catch_drink_reel = 1.0 -var catch_drink_xp = 1.0 -var catch_drink_gold_add = Vector2(0, 0) -var catch_drink_gold_percent = 0.0 -var catch_drink_tier = 0 -var drunk_timer = 0 -var drunk_tier = 0 -var drunk_wander_length = 0 -var drunk_wander_dir = 0 - -var death_counter = 0 -var metal_detect_flop = false -var metal_detect_alert_level = 0 -var metal_detect_alert_cd = 0 - -var emoting = false -var emote_full = false -var emote_locked = false -var emote_looping = false -var animation_timer = 0 -var animation_goal = 99 -var buffer_state = - 1 -var animation_data = { - "moving": false, - "sprinting": false, - "sneaking": false, - "emoting": false, - "emote_full": false, - "diving": false, - "sitting": false, - "alert": false, - "emote": "", - "arm_state": "", - "caught_item": {}, - "arm_value": 0.0, - "item_bend": 0.0, - "busy": false, - "land": 0.0, - "talking": 0.0, - "recent_reel": 0.0, - "bobber_position": Vector3(), - "bobber_visible": false, - "caught_fish": false, - "player_scale": 1.0, - "player_scale_y": 1.0, - "mushroom": false, - "run_mult": 1.0, - "walk_mult": 1.25, - "drunk_tier": 0, - "wagging": false, - "emote_timescale": 1.0, - "back_bend": 0.0, - "dive_scrape": false, - "reel_slow": false, - "reel_fast": false, - "state": state, -} - - - -var custom_held_item = "" - -var cosmetic_data = {} -var selected_build_object -var old_rot = Vector3() -var rot_diff = 0.0 - -var prop_ids = [] -var cam_move = false -var freecamming = false - -onready var cam_base = $cam_base -onready var cam_pivot = $cam_base / cam_pivot -onready var camera = $Camera -onready var camera_point = $cam_base / cam_pivot / SpringArm / camera_point -onready var cam_arm = $cam_base / cam_pivot / SpringArm -onready var body = $body -onready var body_mesh = $body / player_body / Armature / Skeleton / body_main -onready var rot_help = $rot_help -onready var interact_range = $interact_range -onready var anim_tree = $body / AnimationTree -onready var skeleton = $body / player_body / Armature / Skeleton -onready var title = $Viewport / player_label -onready var item_sprite = get_node(hand_sprite_node) -onready var hand_bone = get_node(hand_bone_node) -onready var sound_emit = $sound_emit -onready var face = $body / player_body / Armature / Skeleton / face / player_face -onready var tail = $body / player_body / Armature / Skeleton / tail / holder / tail -onready var freecam_anchor = $camera_freecam_anchor -onready var sound_manager = $sound_manager - -onready var fish_detect = $detection_zones / fishing_detect -onready var fishing_update = $detection_zones / fishing_update -onready var fishing_area = $detection_zones / fishing_detect / fishing_area -onready var fish_timer = $fish_catch_timer -onready var bobber_preview = $bobber_preview -onready var bobber = $bobber -onready var bobber_mesh = $bobber / bobber_mesh -onready var bobber_line = $bobber / line -onready var ripples = $bobber / ripples -onready var caught_fish = $bobber / caught_item - -onready var shovel_area = $detection_zones / shovel_detect -onready var net_area = $detection_zones / net_detect - -onready var safe_check = $safe_check - -onready var lvlparticle = $emotion_particles / lvl_particles -onready var lvlparticleb = $emotion_particles / lvl_particles2 - -signal _animation_finished -signal _primary_release -signal _state_change -signal _menu_closed - - - - - -func _ready(): - add_to_group("player") - rot_help.set_as_toplevel(true) - cam_base.set_as_toplevel(true) - camera.set_as_toplevel(true) - freecam_anchor.set_as_toplevel(true) - anim_tree.tree_root = anim_tree.tree_root.duplicate(true) - _update_cosmetics(cosmetic_data) - title.visible = not dead_actor - - if NPC_body: - camera.queue_free() - remove_from_group("player") - - yield (get_tree(), "idle_frame") - var new = NPC_cosmetics - Network._send_actor_action(actor_id, "_update_cosmetics", [new]) - _update_cosmetics(new) - - yield (get_tree(), "idle_frame") - title.visible = true - title.label = NPC_name - title.title = NPC_title - - -func _setup_controlled(): - if NPC_body: return - - add_to_group("controlled_player") - camera = $Camera - camera.current = true - hud = load("res://Scenes/HUD/playerhud.tscn").instance() - hud.player = self - hud.connect("_player_sit", self, "_toggle_sit") - hud.connect("_play_emote", self, "_play_emote") - hud.connect("_menu_entered", self, "_hud_menu_entered") - hud.connect("_message_sent", self, "_message_sent") - hud.connect("_freecam_toggle", self, "_toggle_freecam") - get_tree().get_root().add_child(hud) - - PlayerData.connect("_clear_all_props", self, "_clear_all_props") - PlayerData.connect("_place_prop", self, "_create_prop") - PlayerData.connect("_play_sfx", self, "_play_sfx") - PlayerData.connect("_play_guitar", self, "_strum_guitar") - PlayerData.connect("_hammer_guitar", self, "_hammer_string") - PlayerData.connect("_return_to_spawn", self, "_return_to_spawn") - PlayerData.connect("_punched", self, "_punched") - PlayerData.connect("_item_removal", self, "_item_removal") - var delayed_update = get_tree().create_timer(1.0).connect("timeout", self, "_change_cosmetics") - - PlayerData.connect("_wag_toggle", self, "_wag") - PlayerData.connect("_kiss", self, "_kiss") - Network.connect("_user_connected", self, "_refresh_cosmetics") - - -func _setup_not_controlled(): - camera = $Camera - camera.queue_free() - - $bobber_preview.visible = false - $local_range.visible = false - $detection_zones / metal_detect_consume.monitoring = false - $detection_zones / metal_detect_consume.monitorable = false - - - $detection_zones / prop_detect.monitoring = false - $detection_zones / metal_detect_far.monitoring = false - $detection_zones / metal_detect.monitoring = false - $detection_zones / metal_detect_close.monitoring = false - $detection_zones / metal_detect_veryclose.monitoring = false - $detection_zones / punch.monitoring = false - $interact_range.monitoring = false - $water_detect.monitoring = false - $raincloud_check.monitoring = false - - - - - -func _physics_process(delta): - _process_animation() - _process_sounds() - - if ( not in_zone != $CollisionShape.disabled): - $CollisionShape.disabled = not in_zone - -func _process(delta): - if controlled: $paint_node._paint_process(delta) - -func _controlled_process(delta): - _get_input() - _process_movement(delta) - _process_timers() - _interact_check() - _update_animation_data() - _camera_update() - - _freecam_input(delta) - - body.visible = camera_zoom > 0.5 or cam_orbit_node != null - current_zone = world.active_zone - current_zone_owner = world.active_zone_owner - - fish_detect.translation.z = - rod_cast_dist - bobber_preview.translation.z = - clamp(primary_hold_timer * 0.06, 1.5, 9.0) - if bobber_preview.is_colliding(): $"%bobber_prev_mesh".global_transform.origin = bobber_preview.get_collision_point() + Vector3(0, 0.05, 0) - bobber_preview.visible = state == STATES.FISHING_CHARGE - - if recent_reel > 0: recent_reel -= 1 - if interact_cooldown > 0: interact_cooldown -= 1 - - animation_data["reel_slow"] = recent_reel > 8 - animation_data["reel_fast"] = state == STATES.FISHING_STRUGGLE - - - if (packet_send_interval == - 1 or Engine.get_physics_frames() % packet_send_interval == 0): - Network._send_actor_animation_update(actor_id, animation_data) - - Network.MESSAGE_ORIGIN = global_transform.origin - $local_range.visible = show_local - - $paint_node.global_transform.origin = mouse_world_pos - $metaldetect_dot.modulate.a = lerp($metaldetect_dot.modulate.a, 0.0, 0.1) - - -func _camera_update(): - cam_push_cur = lerp(cam_push_cur, cam_push * rod_cast_dist, 0.2) - var push = global_transform.basis.z * cam_push_cur - camera_zoom = clamp(camera_zoom, 0.0, 20.0) - - var cam_zoom = camera_zoom - var cam_zoom_lerp = 0.4 - var cam_follow_point = true - var cam_follow_pos = Vector3() - var cam_follow_rot = Vector3() - var sit_add = Vector3(0, - 0.2, 0.0) if sitting else Vector3.ZERO - var cam_base_pos = global_transform.origin + push + sit_add - - var desired_fov = 50 - if sprinting and direction != Vector3.ZERO: - desired_fov += 2 - if boost_timer > 0: desired_fov += 2 * boost_amt - if animation_data["mushroom"]: desired_fov += 10 - - camera.fov = lerp(camera.fov, desired_fov, 0.2) - - if is_instance_valid(cam_orbit_node) and cam_orbit_node.is_visible_in_tree(): - cam_base_pos = cam_orbit_node.global_transform.origin - - if is_instance_valid(cam_follow_node) and cam_follow_node.is_visible_in_tree(): - cam_follow_point = false - cam_follow_pos = cam_follow_node.global_transform.origin - cam_follow_rot = cam_follow_node.global_rotation - - var cam_speed = 0.08 - if cam_follow_point: - cam_return = lerp(cam_return, 1.0, cam_speed * 0.5) - camera.global_transform.origin = lerp(camera.global_transform.origin, camera_point.global_transform.origin, cam_return) - camera.rotation.x = lerp_angle(camera.rotation.x, camera_point.global_rotation.x, cam_return) - camera.rotation.y = lerp_angle(camera.rotation.y, camera_point.global_rotation.y, cam_return) - camera.rotation.z = lerp_angle(camera.rotation.z, camera_point.global_rotation.z, cam_return) - else : - cam_return = 0.0 - camera.global_transform.origin = lerp(camera.global_transform.origin, cam_follow_pos, cam_speed) - camera.rotation.x = lerp_angle(camera.rotation.x, cam_follow_rot.x, cam_speed) - camera.rotation.y = lerp_angle(camera.rotation.y, cam_follow_rot.y, cam_speed) - camera.rotation.z = lerp_angle(camera.rotation.z, cam_follow_rot.z, cam_speed) - - cam_base.global_transform.origin = cam_base_pos - cam_arm.spring_length = lerp(cam_arm.spring_length, cam_zoom, cam_zoom_lerp) - -func _interact_check(): - if not controlled: return - var in_range = false - for area in interact_range.get_overlapping_areas(): - if area.is_in_group("interactable") and area.is_visible_in_tree(): - int_text = area.text - in_range = true - break - if hud: - hud.interact = in_range - hud.int_text = int_text - -func _hud_menu_entered(menu): - if menu == 0: - if not freecamming: - cam_orbit_node = null - cam_follow_node = null - force_cam_look = false - _exit_showcase() - emit_signal("_menu_closed") - -func _process_timers(): - if catch_drink_timer > 0: - catch_drink_timer -= 1 - if catch_drink_timer <= 0: - catch_drink_boost = 1.0 - catch_drink_reel = 1.0 - catch_drink_xp = 1.0 - catch_drink_gold_add = Vector2(0, 0) - catch_drink_gold_percent = 0.0 - - drunk_tier = 0 - if drunk_timer > 0: - drunk_timer -= 1 - if drunk_timer >= 19000: drunk_tier = 3 - elif drunk_timer >= 10000: drunk_tier = 2 - elif drunk_timer > 0: drunk_tier = 1 - else : drunk_tier = 0 - - if item_cooldown > 0: item_cooldown -= 1 - - - - - -func _get_input(): - direction = Vector3.ZERO - - if Input.is_action_just_released("primary_action"): _primary_action_release() - if Input.is_action_pressed("primary_action"): _primary_action_hold() - else : primary_hold_timer = 0 - - if busy: - Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) - return - - if Input.is_action_pressed("secondary_action") or camera_zoom <= 0.0: - if Input.mouse_mode != Input.MOUSE_MODE_CAPTURED: - PlayerData.original_mouse_position = get_tree().get_nodes_in_group("world_viewport")[0].get_mouse_position() - Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) - else : - if Input.mouse_mode != Input.MOUSE_MODE_VISIBLE: - Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) - Input.warp_mouse_position(PlayerData.original_mouse_position) - - if Input.is_action_just_released("zoom_in"): camera_zoom -= 0.5 - if Input.is_action_just_released("zoom_out"): camera_zoom += 0.5 - - if Input.is_action_just_pressed("interact"): _interact() - - if Input.is_action_just_pressed("bind_1"): _equip_hotbar(0) - if Input.is_action_just_pressed("bind_2"): _equip_hotbar(1) - if Input.is_action_just_pressed("bind_3"): _equip_hotbar(2) - if Input.is_action_just_pressed("bind_4"): _equip_hotbar(3) - if Input.is_action_just_pressed("bind_5"): _equip_hotbar(4) - - if Input.is_action_just_pressed("bark"): - _bark() - if Input.is_action_just_pressed("kiss"): - _kiss() - - if locked: return - - - if is_instance_valid(camera): - var camera_cam = camera - var ray_length = 1000 - var mouse_pos = get_tree().get_nodes_in_group("world_viewport")[0].get_mouse_position() / Globals.pixelize_amount - var from = camera_cam.project_ray_origin(mouse_pos) - var to = from + camera_cam.project_ray_normal(mouse_pos) * ray_length - var space_state = get_world().get_direct_space_state() - var result = space_state.intersect_ray(from, to, []) - if result.has("position"): - mouse_world_pos = result["position"] - mouse_world_pos.y = global_transform.origin.y - - if freecamming: return - if Input.is_action_just_pressed("move_jump"): request_jump = true - - mouse_look = false - - if sitting: return - - if Input.is_action_pressed("move_forward"): direction -= cam_base.transform.basis.z - if Input.is_action_pressed("move_back"): direction += cam_base.transform.basis.z - if Input.is_action_pressed("move_right"): direction += cam_base.transform.basis.x - if Input.is_action_pressed("move_left"): direction -= cam_base.transform.basis.x - - if drunk_wander_length > 0: - direction += drunk_wander_dir - drunk_wander_length -= 1 - - mouse_look = Input.is_action_pressed("mouse_look") - - sprinting = not Input.is_action_pressed("move_sneak") and Input.is_action_pressed("move_sprint") - sneaking = Input.is_action_pressed("move_sneak") and not Input.is_action_pressed("move_sprint") - slow_walking = Input.is_action_pressed("move_walk") - - if emote_locked: - request_jump = false - direction = Vector3.ZERO - -func _input(event): - if not controlled: return - - var mouse_sens = OptionsMenu.mouse_sens - var invert = Vector2(1, 1) - if OptionsMenu.mouse_invert == 1: invert.x = - 1 - elif OptionsMenu.mouse_invert == 2: invert.y = - 1 - elif OptionsMenu.mouse_invert == 3: invert = Vector2( - 1, - 1) - - if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: - cam_base.rotation_degrees.y -= event.relative.x * mouse_sens * invert.x - cam_pivot.rotation_degrees.x -= event.relative.y * mouse_sens * invert.y - cam_pivot.rotation_degrees.x = clamp(cam_pivot.rotation_degrees.x, - 80, 80) - -func _unhandled_input(event): - if not controlled: return - - if event.is_action_pressed("primary_action"): _primary_action() - - - - -func _process_movement(delta): - var snap_vec = Vector3(0, - 0.4, 0) - var y_slow = 0.02 - - if is_on_floor() and in_air: - if gravity_vec.y <= - 12.0 and not diving: - diving = true - dive_vec = gravity_vec.length() * - transform.basis.z * 0.2 - player_scale_y = 1.0 - clamp(((abs(gravity_vec.y) / 24.0) * 6.0), 0.0, 0.6) - in_air = false - _sync_particle("dust_land", Vector3(0, - 1, 0)) - _sync_sfx("land") - animation_data["land"] = 0.3 - elif gravity_vec.y < - 6.0: - in_air = true - - player_scale_y = lerp(player_scale_y, 1.0, 0.35) - - if is_on_floor() and ignore_snap <= 0: - y_slow = 0.2 - gravity_vec = get_floor_normal() * - 1.0 - snapped = true - elif snapped and ignore_snap <= 0: - gravity_vec = Vector3.ZERO - snapped = false - else : - snap_vec = Vector3.ZERO - var grav = GRAVITY * Vector3.DOWN * delta - gravity_vec += grav - - if request_jump: - request_jump = false - snap_vec = Vector3.ZERO - if is_on_floor(): - _sync_sfx("jump") - snapped = false - diving = false - gravity_vec = Vector3(0, jump_height, 0) - if sprinting and jump_leap > 0.0: - gravity_vec += - transform.basis.z.normalized() * jump_leap - elif not diving: - _sync_sfx("dive_woosh") - snapped = false - diving = true - dive_vec = - transform.basis.z.normalized() * dive_distance - dive_vec.y = 0 - gravity_vec += Vector3(0, jump_height * 1, 0) - _toggle_sit(true) - - if ignore_snap > 0: - snap_vec = Vector3.ZERO - ignore_snap -= 1 - snapped = false - - boost_mult = 1.0 - if boost_timer > 0: - boost_timer -= 1 - boost_mult = boost_amt - - var _speed = walk_speed - if sprinting: _speed = sprint_speed * boost_mult - elif sneaking: _speed = sneak_speed - elif slow_walking: _speed = slow_walk_speed - var _accel = accel if is_on_floor() else accel * 0.35 - - var speed_mult = 1.25 - - - speed_mult = clamp(speed_mult - ((held_item_weight / 25.0) * 0.05), 0.15, 1.0) - - if diving: speed_mult = 1.0 - if gravity_disable: gravity_vec = Vector3.ZERO - - velocity = velocity.move_toward(direction.normalized() * _speed * speed_mult, delta * _accel) - move_and_slide_with_snap(velocity + gravity_vec + dive_vec, snap_vec, Vector3.UP) - - dive_vec = dive_vec.move_toward(Vector3.ZERO, delta * _accel * y_slow) - if not diving: dive_vec = Vector3.ZERO - - rot_help.global_transform.origin = global_transform.origin - - if direction != Vector3.ZERO: - var dir = direction - if diving and dive_vec != Vector3.ZERO: dir = dive_vec.normalized() - - rot_help.look_at(cam_base.global_transform.origin + dir, Vector3.UP) - rotation.y = lerp_angle(rotation.y, rot_help.rotation.y, 0.2) - elif force_cam_look: - rot_help.look_at(camera.global_transform.origin, Vector3.UP) - rotation.y = lerp_angle(rotation.y, rot_help.rotation.y, 0.2) - elif mouse_look and not busy: - rot_help.look_at(mouse_world_pos, Vector3.UP) - rot_diff = abs(rot_help.rotation.y - rotation.y) - rotation.y = lerp_angle(rotation.y, rot_help.rotation.y, 0.2) - - rot_diff = lerp(rot_diff, 0.0, 0.5) - - if diving and dive_vec.length() > 0.4 and is_on_floor(): - - animation_data["dive_scrape"] = true - - if Engine.get_idle_frames() % 4 == 0: - _sync_particle("dust_run", Vector3(0, - 0.8, 0)) - else : - - animation_data["dive_scrape"] = false - - if gravity_vec.y < - 250: - _kill() - - - - -func _enter_state(new_state): - if new_state == - 1: return - - if consume_on_state_change != - 1: - PlayerData._remove_item(consume_on_state_change, false) - consume_on_state_change = - 1 - - state = new_state - emit_signal("_state_change") - cam_push = 0.0 - animation_data["bobber_visible"] = false - - match state: - STATES.DEFAULT: - animation_data["item_bend"] = 0.0 - locked = false - STATES.BUSY: locked = false - STATES.OBTAIN: locked = true - STATES.SHOWCASE: - locked = true - _equip_item(PlayerData._find_item_code(showcase_ref), true, true) - - STATES.FISHING: - cam_push = - 0.3 - locked = true - animation_data["bobber_visible"] = true - PlayerData.emit_signal("_help_update", "hold to reel (SPRINT reels quicker)") - _enter_animation("rod_idle", true) - STATES.FISHING_CANCEL: - animation_data["item_bend"] = 0.1 - cam_push = - 0.3 - locked = true - rod_cast_dist = 0.0 - animation_data["bobber_visible"] = true - PlayerData.emit_signal("_item_equip", held_item.ref) - _bobber_retract() - _enter_animation("rod_retract", false, true, STATES.DEFAULT) - STATES.FISHING_CAST: - cam_push = - 0.3 - animation_data["bobber_visible"] = true - locked = true - STATES.FISHING_CHARGE: - cam_push = 0.0 - locked = false - STATES.FISHING_STRUGGLE: - animation_data["item_bend"] = - 0.7 - cam_push = - 0.3 - animation_data["bobber_visible"] = true - locked = true - _enter_animation("rod_struggle", true) - - STATES.GUITAR: locked = true - - STATES.SHOVEL_CAST: locked = true - STATES.SHOVEL_STRUGGLE: - locked = true - _shovel_check() - STATES.SHOVEL_CANCEL: - locked = true - _enter_animation("shovel_retract", false, true, STATES.DEFAULT) - - STATES.NET_CAST: locked = true - STATES.NET_STRUGGLE: - locked = true - _net_check() - STATES.NET_CANCEL: - locked = true - _enter_animation("net_retract", false, true, STATES.DEFAULT) - - STATES.CONSUME_ITEM: - locked = false - _equip_item({"ref": 0}, true, true) - _enter_state(STATES.DEFAULT) - -func _primary_action(): - match state: - STATES.DEFAULT: - _use_item() - STATES.OBTAIN: - _enter_animation("equip", false, true, 0, false, 1.5) - -func _primary_action_hold(): - primary_hold_timer += 1 - - match state: - STATES.DEFAULT: - return - STATES.FISHING: - _enter_animation("rod_reel", true) - rod_cast_dist -= 0.04 if Input.is_action_pressed("move_sprint") else 0.01 - bobber_control = true - recent_reel = 15 - if rod_cast_dist < 1.5: _enter_state(STATES.FISHING_CANCEL) - -func _primary_action_release(): - emit_signal("_primary_release") - - match state: - STATES.DEFAULT: - _release_item() - STATES.FISHING: - _enter_animation("rod_idle", true) - STATES.METAL_DETECTOR: - _enter_state(STATES.DEFAULT) - - - - - -func _interact(): - if not controlled or interact_cooldown > 0: return - for area in interact_range.get_overlapping_areas(): - if area.is_in_group("interactable") and area.is_visible_in_tree(): - area._activate(self) - interact_cooldown = 60 - return - -func _enter_zone(zone, entrance_id, zone_owner = - 1): - if not controlled: return - world._enter_zone(zone, zone_owner) - PlayerData.player_saved_zone = zone - PlayerData.player_saved_zone_owner = zone_owner - - print("Finding entrance w id: ", entrance_id, " and owner: ", zone_owner) - for entrance in get_tree().get_nodes_in_group("area_entrance"): - print(entrance.entrance_id, ": ", entrance.entrance_owner, " ?") - if entrance.entrance_id == entrance_id and entrance.entrance_owner == zone_owner: - global_transform.origin = entrance.global_transform.origin - last_valid_pos = global_transform.origin - return - - print("Fallback!") - global_transform.origin = world.map.spawn_position.global_transform.origin - world._enter_zone("main_zone", - 1) - PlayerData.player_saved_zone = "main_zone" - PlayerData.player_saved_zone_owner = - 1 - last_valid_pos = global_transform.origin - -func _obtain_item(ref, bonus_text = [], journal_check = true): - old_rot = rotation - showcase_ref = ref - _equip_item({"ref": - 1}, true, true) - _enter_animation("equip", false, false, STATES.SHOWCASE, false, 1.5) - _play_sfx("strum") - - - var data = PlayerData._find_item_code(ref) - var text = "You caught a " + PlayerData._get_item_name(ref) + "! [color=#d5aa73](It's " + str(data["size"]) + "cm!)[/color]\n\n" + str(Globals.item_data[data["id"]]["file"].catch_blurb) - - if journal_check: - var new = true - for type in PlayerData.journal_logs.keys(): - for entry in PlayerData.journal_logs[type].keys(): - if entry == data.id and PlayerData.journal_logs[type][entry].count > 1: - new = false - break - if new: - text = "Woah, a new creature! " + text - - hud.dialogue_text = [text] - if bonus_text != []: hud.dialogue_text.append_array(bonus_text) - hud._change_menu(6) - - force_cam_look = true - yield (get_tree().create_timer(0.1), "timeout") - cam_follow_node = $catch_cam_position - -func _level_up(): - yield (get_tree().create_timer(0.4), "timeout") - var bubble = title._create_level_bubble() - Network._send_actor_action(actor_id, "_sync_level_bubble", [], false) - GlobalAudio._play_sound("jingle_win") - - _play_emote("emote_cheer", "happy") - - $emotion_particles / lvl_particles.restart() - $emotion_particles / lvl_particles2.restart() - -func _exit_showcase(): - if state != STATES.SHOWCASE: return - _exit_animation() - _enter_state(STATES.DEFAULT) - _equip_item(PlayerData._find_item_code(previous_item), false) - get_tree().create_tween().tween_property(self, "rotation", old_rot, 0.3) - - if xp_buildup > 0: - PlayerData._add_xp(ceil(xp_buildup)) - xp_buildup = 0 - -func _equip_hotbar(slot): - if locked or not PlayerData.hotbar.keys().has(slot): return - var ref = PlayerData.hotbar[slot] - _equip_item(PlayerData._find_item_code(ref)) - -func _equip_item(item_data, skip_anim = false, forced = false, set_prev = true): - if set_prev and held_item["ref"] != 0: previous_item = held_item["ref"] - if (state != STATES.DEFAULT and not forced) or held_item["ref"] == item_data["ref"]: return - - if not item_data.keys().has("id") or not Globals.item_data.keys().has(item_data["id"]): - item_data = PlayerData.FALLBACK_ITEM - - PlayerData.emit_signal("_item_equip", item_data["ref"]) - - if not skip_anim: - _sync_sfx("equip") - _enter_state(STATES.BUSY) - _enter_animation("equip", false, false, STATES.DEFAULT, false, 1.5) - yield (self, "_animation_finished") - - - var held_data = item_data.duplicate() - - hud.show_bait = Globals.item_data[item_data["id"]]["file"].show_bait - - var data = Globals.item_data[item_data["id"]]["file"] - held_item_weight = item_data["size"] - if not data.uses_size: held_item_weight = 0.0 - - _update_held_item(held_data) - Network._send_actor_action(actor_id, "_update_held_item", [held_item], false) - -func _use_item(): - if held_item.empty(): return - var item_data = Globals.item_data[held_item["id"]]["file"] - if has_method(item_data.action) and item_data.action != "": - callv(item_data.action, item_data.action_params) - -func _release_item(): - if held_item.empty(): return - var item_data = Globals.item_data[held_item["id"]]["file"] - if has_method(item_data.release_action) and item_data.release_action != "": - call(item_data.release_action) - - - - - - - -func _cast_fishing_rod(): - rod_cast_data = PlayerData.LURE_DATA[PlayerData.lure_selected].effect_id - animation_data["caught_item"] = {} - bait_warn = 1 - - rod_damage = [1, 3, 10, 20, 35, 50][PlayerData.rod_power_level] - rod_spd = [0.0, 0.1, 0.24, 0.4, 0.7, 1.0][PlayerData.rod_speed_level] - rod_chance = [0.0, 0.02, 0.04, 0.06, 0.08, 0.1][PlayerData.rod_chance_level] - - _enter_state(STATES.FISHING_CHARGE) - _enter_animation("rod_wind", true, false, - 1, false) - yield (self, "_primary_release") - if state != STATES.FISHING_CHARGE: return - _enter_state(STATES.FISHING_CAST) - _sync_sfx("woosh", null, 1.0, 0.4) - var strength = clamp(primary_hold_timer * 0.06, 1.5, 9.0) - rod_cast_dist = strength - fish_detect.translation.z = - strength - - var is_valid_fishing_spot = false - if bobber_preview.is_colliding() and bobber_preview.get_collider().is_in_group("valid_water"): - is_valid_fishing_spot = true - - _bobber_cast(rod_cast_dist, bobber_preview.get_collision_point() + Vector3(0, 0.75, 0), is_valid_fishing_spot) - - rod_depth = 0 - - casted_bait = PlayerData.bait_selected - if casted_bait != "" and PlayerData.bait_inv[casted_bait] <= 0: casted_bait = "" - - _exit_animation() - if is_valid_fishing_spot: - animation_data["item_bend"] = 0.3 - retract_splash = true - _enter_animation("rod_cast", false, true, STATES.FISHING) - else : - animation_data["item_bend"] = 0.3 - retract_splash = false - _enter_animation("rod_cast", false, true, STATES.FISHING_CANCEL) - - yield (get_tree().create_timer(0.4), "timeout") - animation_data["item_bend"] = - 0.2 - -func _on_fish_catch_timer_timeout(): - if not controlled: return - - fish_timer.wait_time = rand_range(2.0, 3.0) - fish_timer.start() - - if state != STATES.FISHING: return - var fish_type = "ocean" - var junk_mult = 1.0 - - - fish_zone_data = {"id": - 1, "boost": 0.0} - for zone in fishing_area.get_overlapping_areas(): - if zone.is_in_group("fish_zone"): - fish_zone_data["id"] = zone.id - fish_zone_data["boost"] = zone.chance_boost - junk_mult = zone.junk_mult - if zone.fish_type != "": fish_type = zone.fish_type - - var fish_chance = 0.0 - var base_chance = BAIT_DATA[casted_bait]["catch"] - fish_chance = base_chance - fish_chance += (base_chance * failed_casts) - fish_chance += (base_chance * rod_chance) - fish_chance += fish_zone_data["boost"] * fish_chance - if recent_reel > 0: fish_chance *= 1.1 - if rod_cast_data == "attractive": fish_chance *= 1.3 - if in_rain: fish_chance *= 1.1 - - fish_chance *= catch_drink_boost - print("Fish chance w ", fish_chance, "w type ", fish_type) - - bait_warn -= 1 - if bait_warn <= 0 and fish_chance <= 0.0: - bait_warn = 8 - var text = "" - if casted_bait == "": - text = "[color=#ac0029]You've got no bait attached! You won't catch any fish like that...[/color]" - else : - text = "[color=#ac0029]Seems nothing is going to bite... perhaps your bait isn't for this water...[/color]" - - Network._update_chat(text) - - if randf() > fish_chance: - failed_casts += 0.05 - return - failed_casts = 0.0 - - - var bait_use_chance = 1.0 - if rod_cast_data == "efficient": bait_use_chance = 0.8 - - if randf() < bait_use_chance: PlayerData._use_bait(casted_bait) - else : PlayerData._send_notification("The Efficient Lure saved your bait!") - var max_tier = BAIT_DATA[casted_bait]["max_tier"] - - var double_bait = 0.0 - if ["large", "sparkling", "double"].has(rod_cast_data): double_bait = 0.25 - if randf() < double_bait: - PlayerData._use_bait(casted_bait) - PlayerData._send_notification("Your lure used extra bait...", 1) - - if rod_cast_data == "gold": - for i in 2: PlayerData._use_bait(casted_bait) - PlayerData._send_notification("Your golden lure used extra bait...", 1) - - var treasure_mult = 1.0 - if rod_cast_data == "magnet": treasure_mult = 2.0 - if rod_cast_data == "salty": fish_type = "ocean" - if rod_cast_data == "fresh": fish_type = "lake" - - var force_av_size = false - - if randf() < 0.05 * treasure_mult * junk_mult: - fish_type = "water_trash" - max_tier = 0 - force_av_size = true - - - - - - - - if in_rain and randf() < 0.08: - fish_type = "rain" - - - var rolls = [] - for i in 3: - var roll = Globals._roll_loot_table(fish_type, max_tier) - var s = Globals._roll_item_size(roll) - rolls.append([roll, s]) - - - var reroll_type = "none" - if rod_cast_data == "small": reroll_type = "small" - if rod_cast_data == "sparkling": reroll_type = "tier" - if rod_cast_data == "large": reroll_type = "large" - if rod_cast_data == "gold": reroll_type = "rare" - - var chosen = rolls[0] - for roll in rolls: - match reroll_type: - "none": - chosen = roll - - "small": - if roll[1] < chosen[1]: - chosen = roll - - "large": - if roll[1] > chosen[1]: - chosen = roll - - "tier": - var old_tier = Globals.item_data[chosen[0]]["file"].tier - var new_tier = Globals.item_data[roll[0]]["file"].tier - if new_tier > old_tier: - chosen = roll - - "rare": - var new_rare = Globals.item_data[roll[0]]["file"].rare - if new_rare: - chosen = roll - - var fish_roll = chosen[0] - var size = chosen[1] - - - var quality = PlayerData.ITEM_QUALITIES.NORMAL - var r = randf() - for q in PlayerData.ITEM_QUALITIES.size(): - if BAIT_DATA[casted_bait]["quality"].size() - 1 < q: - print("bait does not support rarity ", q) - break - if randf() < BAIT_DATA[casted_bait]["quality"][q]: - quality = q - print("-------------------------Rolled Quality: ", quality) - - if randf() < 0.02 * treasure_mult: - fish_roll = "treasure_chest" - size = 60.0 - quality = 0 - - var data = Globals.item_data[fish_roll]["file"] - var quality_data = PlayerData.QUALITY_DATA[quality] - - if force_av_size: size = data.average_size - - var diff_mult = clamp(size / data.average_size, 0.7, 1.8) - var difficulty = clamp((data.catch_difficulty * diff_mult * quality_data.diff) + quality_data.bdiff, 1.0, 250.0) - - var xp_mult = size / data.average_size - if xp_mult < 0.15: xp_mult = 1.25 + xp_mult - xp_mult = max(0.5, xp_mult) - var xp_add = ceil(data.obtain_xp * xp_mult * catch_drink_xp * quality_data.worth) - - print("Total Rolls: ", rolls) - print("Roll fish ", fish_roll, " with size ", size, " and diff Mult: ", diff_mult) - - if fish_zone_data["id"] != - 1: - _wipe_actor(fish_zone_data["id"]) - Network._send_actor_action(actor_id, "_wipe_actor", [fish_zone_data["id"]]) - - _enter_state(STATES.FISHING_STRUGGLE) - animation_data["alert"] = true - yield (get_tree().create_timer(1.0), "timeout") - - animation_data["alert"] = false - - var delay_time = 0 - while hud.using_chat: - yield (get_tree().create_timer(0.15), "timeout") - delay_time += 1 - - if delay_time > 200: - _enter_state(STATES.FISHING_CANCEL) - return - - hud._open_minigame("fishing3", {"fish": fish_roll, "rod_type": rod_cast_data, "reel_mult": catch_drink_reel, "quality": quality, "damage": rod_damage, "speed": rod_spd}, difficulty) - var success = yield (hud, "_minigame_finished") - print("SUCCESS: ", success) - if success: - animation_data["caught_item"] = {"id": fish_roll, "size": size} - _enter_state(STATES.FISHING_CANCEL) - yield (self, "_state_change") - - var ref - var catches = 1 - var bonus_text = [] - - if rod_cast_data == "double" and randf() < 0.15: - catches = 2 - bonus_text.append("Your Double Hook doubled the fish!") - - if PlayerData.rod_luck_level > 0 and randf() < 0.15: - bonus_text.append("How lucky! You found a bonus [color=#d57900]Coin Bag[/color] aswell!") - PlayerData._add_item("luck_moneybag", - 1, randi() % 15 + 15, PlayerData.rod_luck_level) - - var tags = [] - - for i in catches: - ref = PlayerData._add_item(fish_roll, - 1, size, quality, tags) - PlayerData._log_item(fish_roll, size, quality) - PlayerData._quest_progress("catch", fish_roll) - PlayerData._quest_progress("catch_type", data.loot_table) - PlayerData._quest_progress("catch_small", PlayerData._get_size_type(fish_roll, size)) - PlayerData._quest_progress("catch_big", PlayerData._get_size_type(fish_roll, size)) - if fish_roll == "treasure_chest": PlayerData._quest_progress("catch_treasure") - if in_rain: PlayerData._quest_progress("catch_rain") - if data.tier == 2: PlayerData._quest_progress("catch_hightier") - xp_buildup += xp_add - - PlayerData._catch_fish() - - _obtain_item(ref, bonus_text) - - if rod_cast_data == "lucky": - var worth = PlayerData._get_item_worth(ref) - var gold = max(1, ceil(worth * rand_range(0.01, 0.1))) - PlayerData.money += gold - PlayerData._send_notification("Your Lucky Lure got you $" + str(gold) + "!") - - if catch_drink_gold_add != Vector2(0, 0): - var gold = max(1, ceil(rand_range(catch_drink_gold_add.x, catch_drink_gold_add.y))) - PlayerData.money += gold - PlayerData._send_notification("Your Catcher's Luck got you $" + str(gold) + "!") - - if catch_drink_gold_percent > 0.0: - var worth = PlayerData._get_item_worth(ref) - var gold = max(1, ceil(rand_range(worth * 0.01, worth * catch_drink_gold_percent))) - PlayerData.money += gold - PlayerData._send_notification("Your Catcher's Luck Ultra got you $" + str(gold) + "!") - - - else : - _enter_state(STATES.FISHING_CANCEL) - -func _wipe_actor(id): - var actor = world._get_actor_by_id(id) - print("Wiping actor ", id, " : ", actor) - if is_instance_valid(actor): - actor._deinstantiate(true) - - -func _shovel(): - _enter_state(STATES.SHOVEL_CAST) - _enter_animation("shovel_dig", false, true, STATES.SHOVEL_STRUGGLE) - -func _shovel_check(): - var mound = false - - var area - for a in shovel_area.get_overlapping_areas(): - if a.is_in_group("mound"): - mound = true - area = a - - if is_instance_valid(area): - var id = area.owner.actor_id - _wipe_actor(id) - Network._send_actor_action(actor_id, "_wipe_actor", [id]) - - if mound: - _enter_animation("shovel_struggle", true, true) - hud._open_minigame("shoveling", {"damage": 5.0}) - var success = yield (hud, "_minigame_finished") - print("SUCCESS: ", success) - if success: - _enter_state(STATES.SHOVEL_CANCEL) - yield (self, "_state_change") - var ref = PlayerData._add_item("spider") - - - _obtain_item(ref) - else : - _enter_state(STATES.SHOVEL_CANCEL) - else : - _enter_state(STATES.SHOVEL_CANCEL) - - -func _cast_net(): - _enter_state(STATES.NET_CAST) - _enter_animation("net_use", false, true, STATES.NET_STRUGGLE) - -func _net_check(): - var bug = false - - var area - for a in net_area.get_overlapping_areas(): - if a.is_in_group("bug"): - bug = true - area = a - - var bug_id = "" - if is_instance_valid(area): - var id = area.owner.actor_id - bug_id = area.owner.bug_id - _wipe_actor(id) - Network._send_actor_action(actor_id, "_wipe_actor", [id]) - - if bug: - _enter_animation("net_struggle", true, true) - hud._open_minigame("shoveling", {"damage": 5.0}) - var success = yield (hud, "_minigame_finished") - print("SUCCESS: ", success) - if success: - _enter_state(STATES.NET_CANCEL) - yield (self, "_state_change") - var size = Globals._roll_item_size(bug_id) - var ref = PlayerData._add_item(bug_id, - 1, size) - - - _obtain_item(ref) - else : - _enter_state(STATES.NET_CANCEL) - else : - _enter_state(STATES.NET_CANCEL) - - - - - - - - - - - - - - -func _toggle_freecam(): - if busy: return - - if not freecamming: - PlayerData._send_notification("entering freecam mode") - freecamming = true - hud.freecamming = true - cam_orbit_node = freecam_anchor - freecam_anchor.global_transform.origin = global_transform.origin - else : - PlayerData._send_notification("exiting freecam mode") - freecamming = false - hud.freecamming = false - cam_orbit_node = null - -func _freecam_input(delta): - if not freecamming: return - - var speed = 4.0 - if Input.is_action_pressed("move_sprint"): - speed = 7.0 - if Input.is_action_pressed("move_sneak"): - speed = 1.0 - var max_dist = 15.0 - var build_dir = Vector3.ZERO - - if Input.is_action_pressed("move_forward"): build_dir -= cam_base.transform.basis.z - if Input.is_action_pressed("move_back"): build_dir += cam_base.transform.basis.z - if Input.is_action_pressed("move_right"): build_dir += cam_base.transform.basis.x - if Input.is_action_pressed("move_left"): build_dir -= cam_base.transform.basis.x - if Input.is_action_pressed("move_up"): build_dir += cam_base.transform.basis.y - if Input.is_action_pressed("move_down"): build_dir -= cam_base.transform.basis.y - - freecam_anchor.global_transform.origin += build_dir * speed * delta - - freecam_anchor.global_transform.origin.x = clamp(freecam_anchor.global_transform.origin.x, global_transform.origin.x - max_dist, global_transform.origin.x + max_dist) - freecam_anchor.global_transform.origin.y = clamp(freecam_anchor.global_transform.origin.y, global_transform.origin.y - max_dist, global_transform.origin.y + max_dist) - freecam_anchor.global_transform.origin.z = clamp(freecam_anchor.global_transform.origin.z, global_transform.origin.z - max_dist, global_transform.origin.z + max_dist) - - - - - -func _create_prop(ref, offset = Vector3(0, 1, 0)): - if not controlled: return - - - for prop in prop_ids: - if prop.ref == ref: - _wipe_actor(prop.id) - prop_ids.erase(prop) - PlayerData._send_notification("clearing prop", 1) - PlayerData.props_placed = prop_ids - PlayerData.emit_signal("_prop_update") - return - - - if $detection_zones / prop_detect.get_overlapping_bodies().size() > 0 or not is_on_floor() or not $detection_zones / prop_ray.is_colliding(): - PlayerData._send_notification("invalid prop placement", 1) - return - - - if prop_ids.size() > 4: - PlayerData._send_notification("prop limit reached", 1) - return - - - var item = PlayerData._find_item_code(ref) - var data = Globals.item_data[item["id"]]["file"] - var ver_offset = Vector3(0, 1.0, 0) * (1.0 - player_scale) - print(ver_offset) - var pos = global_transform.origin + (global_transform.basis.z * - 2.0) - offset + ver_offset - var rot = rotation + Vector3(0, deg2rad(180), 0) - var prop_code = data.prop_code - - - var blacklist = ["island_tiny", "island_med", "island_big"] - if current_zone_owner != - 1: - if blacklist.has(prop_code): - PlayerData._send_notification("this prop cannot be spawned here...", 1) - return - - - var new_id = Network._sync_create_actor(prop_code, pos, current_zone, - 1, Network.STEAM_ID, {"rotation": rot, "current_zone_owner": current_zone_owner}) - prop_ids.append({"id": new_id, "ref": ref, "prop_id": data.action}) - PlayerData.props_placed = prop_ids - PlayerData.emit_signal("_prop_update") - PlayerData._send_notification("prop placed", 0) - - _sync_particle("dust_land", pos, true) - _sync_sfx("poof", pos) - -func _clear_props(): - if prop_ids.size() <= 0: - PlayerData._send_notification("no props to undo", 1) - return - PlayerData._send_notification("undo prop", 0) - _wipe_actor(prop_ids[prop_ids.size() - 1][0]) - prop_ids.remove(prop_ids.size() - 1) - -func _clear_all_props(): - if prop_ids.size() <= 0: - PlayerData._send_notification("no props to clear", 1) - return - - PlayerData._send_notification("clearing all props", 0) - for prop in prop_ids: - _wipe_actor(prop.id) - prop_ids.clear() - PlayerData.props_placed = prop_ids - PlayerData.emit_signal("_prop_update") - -func _item_place_prop(): - if not controlled: return - _create_prop(held_item.ref) - - - - - -func _update_animation_data(): - if animation_data["emote"] != "": - var anim = $body / player_body / AnimationPlayer.get_animation(animation_data["emote"]) - animation_timer += 1 - animation_goal = floor((anim.length * 60) / animation_data["emote_timescale"]) - if animation_timer >= animation_goal and emoting and animation_goal > 0 and not emote_looping: - print("Finished Emoting ", animation_data["emote"], " bufferstate: ", buffer_state) - emit_signal("_animation_finished") - emoting = false - emote_full = false - emote_locked = false - animation_data["emote"] = "" - if buffer_state != - 1: _enter_state(buffer_state) - - animation_data["emoting"] = emoting - animation_data["emote_full"] = emoting and emote_full - animation_data["moving"] = direction != Vector3.ZERO or rot_diff > 0.05 - animation_data["sprinting"] = sprinting and direction != Vector3.ZERO - animation_data["sneaking"] = sneaking and direction != Vector3.ZERO - animation_data["diving"] = diving - animation_data["sitting"] = sitting - animation_data["busy"] = busy and state == STATES.DEFAULT and not emoting - animation_data["land"] = lerp(animation_data["land"], 0.0, 0.04) - animation_data["talking"] = lerp(animation_data["talking"], 0.0, 0.1) - animation_data["recent_reel"] = lerp(animation_data["recent_reel"], recent_reel, 0.2) - animation_data["caught_fish"] = state == STATES.FISHING_STRUGGLE - animation_data["player_scale"] = lerp(animation_data["player_scale"], player_scale, 0.06) - animation_data["player_scale_y"] = lerp(animation_data["player_scale_y"], player_scale_y, 0.06) - animation_data["run_mult"] = 1.15 * boost_mult - animation_data["walk_mult"] = 1.25 if not slow_walking else 0.7 - animation_data["drunk_tier"] = drunk_tier - animation_data["state"] = state - - $emotion_particles / mushroom_trail.emitting = animation_data["mushroom"] - $emotion_particles / drunk_particles.emitting = animation_data["drunk_tier"] > 1 - if is_on_floor(): animation_data["mushroom"] = false - - if not bobber_control: - animation_data["bobber_position"] = Vector3(bobber_hpos.x, bobber_vpos, bobber_hpos.z) - else : - var pos = global_transform.origin + ( - rod_cast_dist * global_transform.basis.z) - pos.y = bobber_vpos + sin(OS.get_ticks_msec() * 0.002) * 0.05 - animation_data["bobber_position"] = lerp(animation_data["bobber_position"], pos, 0.2) - -func _process_animation(): - var anim_lerp = 0.4 - - var emote_type = 0 - if animation_data["emoting"]: emote_type = 1 - if animation_data["emote_full"]: emote_type = 2 - - anim_tree.set("parameters/emote_full/blend_amount", lerp(anim_tree.get("parameters/emote_full/blend_amount"), float(emote_type == 2), anim_lerp)) - if anim_tree.get("parameters/emote_full/blend_amount") < 0.1 and emote_type != 2: anim_tree.set("parameters/emote_full/blend_amount", 0.0) - anim_tree.set("parameters/emote_half/blend_amount", lerp(anim_tree.get("parameters/emote_half/blend_amount"), float(emote_type == 1), anim_lerp)) - if anim_tree.get("parameters/emote_half/blend_amount") < 0.1 and emote_type != 1: anim_tree.set("parameters/emote_half/blend_amount", 0.0) - - anim_tree.set("parameters/arms/blend_amount", lerp(anim_tree.get("parameters/arms/blend_amount"), float( not animation_data["emoting"]), anim_lerp)) - anim_tree.set("parameters/movement/blend_amount", lerp(anim_tree.get("parameters/movement/blend_amount"), float(animation_data["moving"]), anim_lerp)) - anim_tree.set("parameters/run_blend/blend_amount", lerp(anim_tree.get("parameters/run_blend/blend_amount"), float(animation_data["sprinting"]) - float(animation_data["sneaking"]), anim_lerp)) - anim_tree.set("parameters/dive/blend_amount", lerp(anim_tree.get("parameters/dive/blend_amount"), float(animation_data["diving"]), anim_lerp)) - anim_tree.set("parameters/arm_blend/blend_position", float(animation_data["arm_value"])) - anim_tree.set("parameters/sitting/blend_amount", lerp(anim_tree.get("parameters/sitting/blend_amount"), float(animation_data["sitting"]), anim_lerp)) - anim_tree.set("parameters/thinking/blend_amount", lerp(anim_tree.get("parameters/thinking/blend_amount"), float(animation_data["busy"]), anim_lerp)) - anim_tree.set("parameters/land/blend_amount", lerp(anim_tree.get("parameters/land/blend_amount"), float(animation_data["land"]), anim_lerp)) - anim_tree.set("parameters/talking/blend_amount", lerp(anim_tree.get("parameters/talking/blend_amount"), float(animation_data["talking"]), anim_lerp)) - anim_tree.set("parameters/runmodif/scale", animation_data["run_mult"]) - anim_tree.set("parameters/walkmodif/scale", animation_data["walk_mult"]) - anim_tree.set("parameters/emote_time/scale", animation_data["emote_timescale"]) - anim_tree.set("parameters/emote_timeb/scale", animation_data["emote_timescale"]) - - face._show_blush(animation_data["drunk_tier"] > 1) - if animation_data["caught_item"] != caught_item: - caught_item = animation_data["caught_item"] - _update_caught_item(animation_data["caught_item"]) - - if item_scene: - item_scene.item_bend = lerp(item_scene.item_bend, animation_data["item_bend"], 0.4) - bobber_line.end_anchor = item_scene.get_node(item_scene.hotspot_node).global_transform.origin - bobber_line.y_drop = - 1.5 + ((animation_data["recent_reel"] / 15.0) * 0.5) - if animation_data["caught_fish"]: bobber_line.y_drop = 0 - if bobber.visible: bobber.global_transform.origin = animation_data["bobber_position"] + Vector3(0, (0.0 if not animation_data["caught_fish"] else - 0.3), 0) - bobber.visible = animation_data["bobber_visible"] - bobber_line.active = bobber.visible - - - if animation_data["player_scale"] != scale.y: - scale = animation_data["player_scale"] * Vector3.ONE - scale.y *= animation_data["player_scale_y"] - - bobber_line.line_scale = animation_data["player_scale"] - - ripples.visible = animation_data["state"] == STATES.FISHING - var rip_anim = "default" if animation_data["recent_reel"] <= 1.0 else "wake" - if ripples.animation != rip_anim: ripples.animation = rip_anim - - var root = anim_tree.tree_root - var node = root.get_node("emote_anim") - var node_b = root.get_node("emote_anim_b") - if node.animation != animation_data["emote"]: - anim_tree.set("parameters/emote_sync/seek_position", 0.0) - anim_tree.set("parameters/emote_half_sync/seek_position", 0.0) - node.set_animation(animation_data["emote"]) - node_b.set_animation(animation_data["emote"]) - - $"%head_alert".visible = animation_data["alert"] - - tail.sitting = animation_data["sitting"] - tail.diving = animation_data["diving"] - tail.motion = float(animation_data["moving"]) - tail.wagging = animation_data["wagging"] - - - if animation_data["back_bend"] != 0.0: - var pose = skeleton.get_bone_pose(1) - pose = pose.rotated(Vector3(1, 0, 0), animation_data["back_bend"]) - skeleton.set_bone_custom_pose(1, pose) - else : - skeleton.set_bone_custom_pose(1, Transform()) - -func _enter_animation(anim_name, loop = false, _locked = true, state_enter = - 1, full_anim = true, timescale = 1.0): - if anim_name == animation_data["emote"]: return - diving = false - - animation_data["emote_timescale"] = timescale - - - emote_full = full_anim - emote_locked = _locked - emote_looping = loop - buffer_state = state_enter if not emote_looping else - 1 - if emote_looping: _enter_state(state_enter) - animation_data["emote"] = anim_name - animation_timer = 0 - emoting = true - -func _exit_animation(): - emit_signal("_animation_finished") - emoting = false - emote_full = false - emote_locked = false - emote_looping = false - animation_data["emote"] = "" - -func _update_held_item(new): - if new.empty() or held_item == new: return - - held_item = new - var item_data = Globals.item_data[new["id"]]["file"] - var alt_scale_mult = 1.0 - - - item_sprite.texture = item_data.icon.duplicate() if (item_data.show_item and not item_data.show_scene) else null - - - - if is_instance_valid(item_scene): item_scene.queue_free() - item_scene = null - if item_data.show_scene and item_data.item_scene: - item_scene = item_data.item_scene.instance() - hand_bone.add_child(item_scene) - - var scale_mult = 0.07 - clamp(new["size"] * 0.01, 0.01, 0.061) - var item_scale = 1.0 if not item_data.uses_size else new["size"] * scale_mult - item_scale *= alt_scale_mult - item_sprite.scale = Vector3(item_scale, item_scale, item_scale) - - - var y = 0.0 - var offs = 0.0 - var back_bend = 0.0 - if item_data.uses_size: - y = clamp(item_scale * item_scale * 0.08, 0.0, 0.36) - offs = clamp(item_scale * item_scale, 0.0, 16.0) - back_bend = clamp(item_scale * item_scale, 0.0, 55.0) - - item_sprite.translation.y = y - item_sprite.offset.y = item_data.hold_offset + offs - - - $body / player_body / Armature / Skeleton / BoneAttachment / Spatial.rotation_degrees = Vector3(0.0, 0.0, back_bend * 0.7) - - item_sprite.translation.z = 0.0 - item_sprite.vel = 0.0 - item_sprite.mult = clamp(item_scale * 3.5, 0.0, 1.2) if item_data.category == "fish" and item_data.alive else 0.0 - - item_sprite.modulate = Color("#ffffff") - item_sprite.opacity = 1.0 - for child in item_sprite.get_children(): child.emitting = false - - if PlayerData.QUALITY_DATA.has(new["quality"]): - item_sprite.modulate = Color(PlayerData.QUALITY_DATA[new["quality"]]["mod"]) - item_sprite.opacity = PlayerData.QUALITY_DATA[new["quality"]]["op"] - if PlayerData.QUALITY_DATA[new["quality"]]["particle"] > - 1: item_sprite.get_child(PlayerData.QUALITY_DATA[new["quality"]]["particle"]).emitting = true - - animation_data["arm_value"] = item_data.arm_value - animation_data["back_bend"] = deg2rad( - back_bend) - -func _update_caught_item(new): - if new.empty(): - caught_fish.texture = null - return - caught_item = new - - var item_data = Globals.item_data[new["id"]]["file"] - caught_fish.texture = item_data.icon.duplicate() if item_data.show_item else null - - var item_scale = 1.0 if not item_data.uses_size else new["size"] * 0.01 - caught_fish.scale = Vector3(item_scale, item_scale, item_scale) - -func _bobber_cast(dist, end, splash): - bobber_control = false - var height = dist * 0.4 - height += max(0, global_transform.origin.y - end.y) - - end.y -= 1 - - bobber_hpos = global_transform.origin - bobber_vpos = global_transform.origin.y - yield (get_tree().create_timer(0.4), "timeout") - - var tween = get_tree().create_tween() - - tween.set_trans(1) - tween.set_ease(1) - tween.tween_property(self, "bobber_vpos", end.y + height, dist * 0.05) - tween.set_ease(0) - tween.tween_property(self, "bobber_vpos", end.y - (height * 0.2), dist * 0.05) - if splash: - tween.tween_callback(self, "_bobber_splash") - - - tween.set_trans(1) - tween.set_ease(1) - tween.tween_property(self, "bobber_vpos", end.y + (height * 0.1), (dist * 0.05)) - tween.set_ease(0) - tween.tween_property(self, "bobber_vpos", end.y - (height * 0.05), (dist * 0.1)) - - - tween.set_trans(1) - tween.set_ease(1) - tween.tween_property(self, "bobber_vpos", end.y, (dist * 0.1)) - - var htween = get_tree().create_tween() - htween.set_trans(4) - htween.set_ease(1) - htween.tween_property(self, "bobber_hpos", end + (global_transform.basis.z * 0.5), dist * 0.1) - htween.tween_property(self, "bobber_hpos", end + (global_transform.basis.z * 0.2), dist * 0.15) - htween.tween_property(self, "bobber_hpos", end, dist * 0.1) - - yield (htween, "finished") - bobber_control = true - -func _bobber_retract(): - bobber_control = false - bobber_hpos = bobber.global_transform.origin - bobber_vpos = bobber.global_transform.origin.y - - yield (get_tree().create_timer(0.4), "timeout") - - if retract_splash: _bobber_splash("splashb") - var tween = get_tree().create_tween() - tween.set_trans(1) - tween.set_ease(1) - tween.tween_property(self, "bobber_vpos", global_transform.origin.y + 2.0, 0.3) - tween.set_ease(0) - tween.tween_property(self, "bobber_vpos", global_transform.origin.y, 0.3) - - var htween = get_tree().create_tween() - htween.tween_property(self, "bobber_hpos", global_transform.origin, 0.6) - -func _bobber_splash(sfx = "splash"): - _sync_particle("splash", bobber.global_transform.origin, true) - _sync_sfx(sfx, Vector3(bobber_hpos.x, bobber_vpos, bobber_hpos.z)) - - - - - -func _toggle_sit(exit = false): - if not exit: sitting = not sitting - else : sitting = false - -func _play_emote(emote_id, emotion = ""): - if emote_id == "": return - - if emote_id == "sit": - _toggle_sit() - elif not emote_locked: - _enter_animation(emote_id, false, true) - if emotion != "": - _sync_face_emote(emotion) - - - - - -func _change_cosmetics(): - if cosmetic_data == PlayerData.cosmetics_equipped: return - var new = PlayerData.cosmetics_equipped.duplicate() - if not dead_actor: Network._send_actor_action(actor_id, "_update_cosmetics", [new]) - _update_cosmetics(new) - -func _update_cosmetics(data): - var valid = true - for key in PlayerData.FALLBACK_COSM.keys(): - if not data.keys().has(key): - print("missing key ", key) - valid = false - for key in data.keys(): - if not (data[key] is Array): - if not Globals._cosmetic_exists(data[key]): - print("cosm ", data[key], " does not exist") - valid = false - else : - for c in data[key]: - if not Globals._cosmetic_exists(c): - print("cosm ", data[key], " does not exist") - valid = false - - if not valid: data = PlayerData.FALLBACK_COSM.duplicate() - - cosmetic_data = data - - for child in skeleton.get_children(): - if child.is_in_group("cosmetic"): child.queue_free() - - if data.empty(): return - - title.label = str(Network._get_username_from_id(owner_id)) - title.title = Globals.cosmetic_data[data["title"]]["file"].title - - face._setup_face(data) - var species_id = Globals.cosmetic_data[data.species]["file"].cos_internal_id - var species = _create_cosmetic(data["species"], species_id) - _create_cosmetic(data["undershirt"], species_id) - _create_cosmetic(data["overshirt"], species_id) - _create_cosmetic(data["legs"], species_id) - _create_cosmetic(data["hat"], species_id) - for misc in data["accessory"]: _create_cosmetic(misc, species_id) - - - var pattern = Globals.cosmetic_data[data["pattern"]]["file"] - body_mesh.material_override.set_shader_param("texture_albedo", pattern.body_pattern[0]) - - var primary_color = Globals.cosmetic_data[data["primary_color"]]["file"] - var secondary_color = Globals.cosmetic_data[data["secondary_color"]]["file"] if pattern.body_pattern[0] else Globals.cosmetic_data[data["primary_color"]]["file"] - body_mesh.material_override.set_shader_param("albedo", primary_color.main_color) - body_mesh.material_override.set_shader_param("albedo_secondary", secondary_color.main_color) - - - var tail_data = Globals.cosmetic_data[data["tail"]]["file"] - tail._load_tail(tail_data.mesh, primary_color.main_color) - - if species: - species.material_override.set_shader_param("albedo", primary_color.main_color) - species.material_override.set_shader_param("albedo_secondary", secondary_color.main_color) - - match data["species"]: - "species_cat": species.material_override.set_shader_param("texture_albedo", pattern.body_pattern[1]) - "species_dog": species.material_override.set_shader_param("texture_albedo", pattern.body_pattern[2]) - - if not data.keys().has("bobber") or data["bobber"] == "": data["bobber"] = "bobber_default" - var bobber_file = Globals.cosmetic_data[data["bobber"]]["file"] - bobber_mesh.mesh = bobber_file.mesh - bobber_mesh.set_surface_material(0, bobber_file.material) - if bobber_file.secondary_material: bobber_mesh.set_surface_material(1, bobber_file.secondary_material) - if bobber_file.third_material: bobber_mesh.set_surface_material(2, bobber_file.third_material) - -func _create_cosmetic(id, species_id = 0): - if id == "": return - if not Globals.cosmetic_data.keys().has(id): - print("Failed finding cosmetic: ", id) - return - print("Creating Cosmetic: ", id) - var data = Globals.cosmetic_data[id]["file"] - - if data.scene_replace: - var bone_attach = BoneAttachment.new() - skeleton.add_child(bone_attach) - bone_attach.bone_name = "pelvis" - bone_attach.add_to_group("cosmetic") - - var cosm = data.scene_replace.instance() - bone_attach.add_child(cosm) - return cosm - - var cosm = preload("res://Scenes/Entities/Player/cosmetic_node.tscn").instance() - cosm.mesh = data.mesh - if data.species_alt_mesh.size() > 0: - cosm.mesh = data.species_alt_mesh[species_id] - - cosm.skin = data.mesh_skin - - if not data.material: - cosm.material_override = preload("res://Assets/Shaders/player_skins.tres").duplicate() - cosm.material_override.set_shader_param("albedo", data.main_color) - cosm.material_override.set_shader_param("albedo_secondary", data.main_color) - cosm.material_override.set_shader_param("texture_albedo", null) - else : - - cosm.material_override = null - cosm.set_surface_material(0, data.material) - if data.secondary_material: cosm.set_surface_material(1, data.secondary_material) - - cosm.skeleton = skeleton.get_path() - skeleton.add_child(cosm) - return cosm - - - - - - - - - - - - - - - - - - -func _on_step_timer_timeout(): - if not controlled: return - - - if randf() < 0.03 * drunk_tier and drunk_wander_length <= 0: - drunk_wander_length = randi() % 25 + 5 - drunk_wander_dir = Vector3( - rand_range( - 1, 1), - 0.0, - rand_range( - 1, 1)) - - if state == STATES.FISHING_STRUGGLE: - _sync_particle("small_splash", bobber.global_transform.origin, true) - - if recent_reel > 0 and state == STATES.FISHING: - fishing_update.translation.z = - rod_cast_dist - fishing_update.force_raycast_update() - if fishing_update.is_colliding() and not fishing_update.get_collider().is_in_group("valid_water"): - _enter_state(STATES.FISHING_CANCEL) - - if velocity != Vector3.ZERO: - var vol = 1.6 - if sprinting: vol = 2.8 - elif sneaking: vol = 0.3 - - if is_on_floor() and sprinting: _sync_particle("dust_run", Vector3(0, - 0.95, 0)) - - if is_on_floor() and safe_check.is_colliding() and safe_check.get_collision_normal() == Vector3(0, 1, 0) and not gravity_disable: - if death_counter > 0: death_counter -= 1 - last_valid_pos = global_transform.origin - - PlayerData.player_saved_position = global_transform.origin - - - - - -func _message_sent(text): - - var split = text.split(" ") - for s in split: - match s: - ":(", ":[", "D:", ";_;", ";~;", ":C", ":c": _sync_face_emote("sad") - ":)", ":D", ":]": _sync_face_emote("love") - "xD", "!!!", "<3", "xd", "LMAO", "LOL": _sync_face_emote("happy") - ">:(", "D:<", ">:[": _sync_face_emote("angry") - ":/", ":|": _sync_face_emote("flat") - ":3", ":3c", ">:3c", ">:3": _sync_face_emote("cat") - "O.o", "!?!?", "?!?!", ":o", ":O": _sync_face_emote("surprised") - - var bubble = title._create_speech_bubble(text, PlayerData.voice_speed) - bubble.connect("_letter_said", self, "_sync_talk") - Network._send_actor_action(actor_id, "_sync_create_bubble", [text], false) - -func _sync_talk(letter): - var blacklist = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] - if not blacklist.has(letter.to_lower()): return - - animation_data["talking"] = 0.4 - _talk(letter, PlayerData.voice_pitch) - Network._send_actor_action(actor_id, "_talk", [letter, PlayerData.voice_pitch], false) - -func _talk(letter, pitch = 1.5): - if not in_zone or not visible: return - - face._talk() - sound_manager._construct_voice(letter, "NewVoice", pitch) - -func _sync_face_emote(emotion): - _face_emote(emotion) - Network._send_actor_action(actor_id, "_face_emote", [emotion], false) - -func _sync_create_bubble(text): - title._create_speech_bubble(text) - -func _sync_level_bubble(text): - title._create_level_bubble(text) - $emotion_particles / lvl_particles.restart() - $emotion_particles / lvl_particles2.restart() - -func _face_emote(emotion): - face._emote(emotion, 2.4) - - - - - -func _sync_particle(id, offset = Vector3.ZERO, global = false): - _play_particle(id, offset, global) - Network._send_actor_action(actor_id, "_play_particle", [id, offset, global], false) - -func _play_particle(id, offset, global): - if not PARTICLE_DATA.keys().has(id): return - var p = PARTICLE_DATA[id].instance() - add_child(p) - - if not global: - p.translation = offset - else : - p.set_as_toplevel(true) - p.global_transform.origin = offset - - p.emitting = true - yield (get_tree().create_timer(p.lifetime + 0.1), "timeout") - p.queue_free() - - - - - -func _on_water_detect_area_entered(area): - if gravity_disable: return - if area.is_in_group("water"): - _kill() - -func _kill(skip_anim = false): - if not controlled: return - - death_counter += 1 - if death_counter >= 10: - if not skip_anim: PlayerData._send_notification("too many deaths in a row! sending to spawn...", 1) - else : PlayerData._send_notification("returning to spawn", 1) - - world._enter_zone("main_zone", - 1) - PlayerData.player_saved_zone = "main_zone" - PlayerData.player_saved_zone_owner = - 1 - last_valid_pos = world.map.spawn_position.global_transform.origin - death_counter = 0 - - if state == STATES.FISHING or state == STATES.FISHING_CAST or state == STATES.FISHING_CAST: - _enter_state(STATES.FISHING_CANCEL) - - cam_push = 0.0 - gravity_disable = true - - if not skip_anim: - _enter_animation("drown", true, true) - _sync_sfx("drown") - _sync_particle("splash", global_transform.origin, true) - - SceneTransition._fake_scene_change() - yield (SceneTransition, "_finished") - global_transform.origin = last_valid_pos + Vector3(0, 0.5, 0) - yield (get_tree().create_timer(0.3), "timeout") - gravity_disable = false - _enter_state(0) - _exit_animation() - - - - - -func _consume_item(id): - if state != STATES.DEFAULT: return - _enter_state(STATES.EMOTING) - - consume_on_state_change = held_item["ref"] - _enter_animation("drink", false, true, STATES.CONSUME_ITEM, true) - - var sfx = "drink" - - match id: - "growth": player_scale = clamp(player_scale + 0.4, 0.7, 100) - "shrink": player_scale = clamp(player_scale - 0.1, 0.1, 100) - "revert": - player_scale = 1.0 - drunk_timer = max(drunk_timer - 9000, 0) - sfx = "drink_nocap" - "speed": - boost_timer = 18000 - boost_amt = 1.3 - sfx = "drink_nocap" - "speed_burst": - boost_timer = 900 - boost_amt = 4.0 - sfx = "drink_nocap" - "catch": - catch_drink_timer = 18000 - catch_drink_boost = 1.15 - catch_drink_reel = 1.25 - catch_drink_xp = 1.0 - catch_drink_tier = 1 - catch_drink_gold_add = Vector2(1, 10) - catch_drink_gold_percent = 0.0 - "catch_big": - catch_drink_timer = 18000 - catch_drink_boost = 1.3 - catch_drink_reel = 1.45 - catch_drink_xp = 1.0 - catch_drink_tier = 2 - catch_drink_gold_add = Vector2(10, 50) - catch_drink_gold_percent = 0.25 - "catch_deluxe": - catch_drink_timer = 18000 - catch_drink_boost = 1.3 - catch_drink_reel = 1.45 - catch_drink_xp = 1.25 - catch_drink_tier = 3 - catch_drink_gold_add = Vector2(0, 0) - catch_drink_gold_percent = 0.0 - "beer": - drunk_timer += 9000 - drunk_timer = clamp(drunk_timer, 0, 50000) - "beer_big": - drunk_timer += 42000 - drunk_timer = clamp(drunk_timer, 0, 50000) - sfx = "drink_nocap" - - _sync_sfx(sfx) - - - -func _open_chest(rare = false): - if state != STATES.DEFAULT: return - - consume_on_state_change = held_item["ref"] - _enter_state(STATES.CONSUME_ITEM) - - var cosm = PlayerData._get_unowned_cosmetic() - if cosm != null: PlayerData._unlock_cosmetic(cosm) - else : - PlayerData._send_notification("You found 100 dollars inside the chest!") - PlayerData.money += 100 - -func _open_ringbox(): - if state != STATES.DEFAULT: return - - consume_on_state_change = held_item["ref"] - _enter_state(STATES.CONSUME_ITEM) - - if not PlayerData.cosmetics_unlocked.has("accessory_ring"): PlayerData._unlock_cosmetic("accessory_ring") - else : - PlayerData._send_notification("You already have a ring unlocked... Obtained $1000 instead.") - PlayerData.money += 1000 - - - -func _scratch_off(type): - _enter_state(STATES.GUITAR) - hud._open_minigame("scratch_off", {"type": type}) - var _win = yield (hud, "_minigame_finished") - yield (get_tree().create_timer(0.15), "timeout") - _enter_state(STATES.DEFAULT) - - consume_on_state_change = held_item["ref"] - _enter_state(STATES.CONSUME_ITEM) - - if not _win: - _sync_face_emote("angry") - _sync_sfx("rip") - else : - _sync_face_emote("happy") - - - - - -func _mushroom_bounce(): - if not controlled: return - ignore_snap = 10 - var bounce_horz = 16.0 if direction != Vector3.ZERO else 0.0 - var bounce_vert = 32.0 - gravity_vec = Vector3.ZERO - gravity_vec.x += (direction.normalized() * bounce_horz).x - gravity_vec.z += (direction.normalized() * bounce_horz).z - gravity_vec.y += bounce_vert - animation_data["mushroom"] = true - - - - - -func _sync_sfx(id, position = null, pitch = 1.0, delay = 0.0): - if not controlled: return - if delay > 0.0: yield (get_tree().create_timer(delay), "timeout") - - _play_sfx(id, position, pitch) - Network._send_actor_action(actor_id, "_play_sfx", [id, position, pitch], false) - -func _play_sfx(id, position = null, pitch = 1.0): - if not in_zone or not visible: return - sound_manager._play_sound(id, position, pitch) - print("playing sfx ", id) - -func _process_sounds(): - - - - - if $sound_manager / dive_scrape.playing != animation_data["dive_scrape"]: $sound_manager / dive_scrape.playing = animation_data["dive_scrape"] and in_zone - if $sound_manager / reel_slow.stream_paused == animation_data["reel_slow"]: $sound_manager / reel_slow.stream_paused = not animation_data["reel_slow"] and in_zone - if $sound_manager / reel_fast.playing != animation_data["reel_fast"]: $sound_manager / reel_fast.playing = animation_data["reel_fast"] and in_zone - - - - - -func _on_rain_timer_timeout(): - if not controlled: return - - var rain = false - for child in $raincloud_check.get_overlapping_areas(): - if child.is_in_group("rain_cloud"): - rain = true - - if rain != in_rain: - in_rain = rain - PlayerData.emit_signal("_rain_toggle", in_rain) - - if not in_rain: Network.set_rich_presence("#default") - else : Network.set_rich_presence("#rain") - - - - - -func _wag(): - animation_data["wagging"] = not animation_data["wagging"] - -func _paint(size, color): - if not controlled: return - - var in_zone = false - for area in $paint_node / Area.get_overlapping_areas(): - if area.is_in_group("canvas"): in_zone = true - if not in_zone: PlayerData._send_notification("mouse must be on a drawing zone!", 1) - - $paint_node.size = size - $paint_node.color = color - $paint_node.drawing = true - -func _paint_stop(): - if not controlled: return - $paint_node.drawing = false - PlayerData.emit_signal("_chalk_send") - -func _metal_detect_begin(): - pass - -func _metaldetect_update(): - if not controlled or held_item.id == "": - return - - var idata = Globals.item_data[held_item["id"]]["file"] - if not idata.detect_item: - return - - var alert_level = 0 - for b in $detection_zones / metal_detect_far.get_overlapping_bodies(): - if b.is_in_group("metal_spawn"): - if abs(b.global_transform.origin.y - global_transform.origin.y) > 3.5: continue - alert_level = b.global_transform.origin.distance_to(global_transform.origin) - - metal_detect_alert_level = alert_level - - if alert_level > 0: _metal_detect_beep() - -func _metal_detect_beep(): - var new_cd = ceil(max(metal_detect_alert_level * 0.5, 1)) - - if abs(new_cd - metal_detect_alert_cd) > 4: metal_detect_alert_cd = 0 - - metal_detect_alert_cd -= 1 - if metal_detect_alert_cd > 0: return - - metal_detect_alert_cd = new_cd - - var pitch = max(6.0 - metal_detect_alert_level * 0.3, 0.5) - - $metaldetect_dot.modulate.a = 1.0 - if metal_detect_flop: _sync_sfx("md_beep_slowb", null, pitch) - else : _sync_sfx("md_beep_slow", null, pitch) - metal_detect_flop = not metal_detect_flop - -func _on_metal_detect_consume_body_entered(b): - if not controlled or held_item.id == "": return - - var idata = Globals.item_data[held_item["id"]]["file"] - if not idata.detect_item: return - - if b.is_in_group("metal_spawn"): - b._reveal() - -func _on_image_update_timeout(): - if not controlled or dead_actor: return - _update_held_item(held_item) - Network._send_actor_action(actor_id, "_update_held_item", [held_item], false) - -func _real_step(run = false): - if anim_tree.get("parameters/dive/blend_amount") > 0.2 or anim_tree.get("parameters/movement/blend_amount") < 0.8: return - if not is_on_floor(): return - var sfx = "step" if not run else "step_run" - if boost_amt > 1.0 and boost_timer > 1: sfx = "step_fastrun" - _sync_sfx(sfx) - - - -func _play_guitar(): - _enter_state(STATES.GUITAR) - hud._open_minigame("guitar") - var _win = yield (hud, "_minigame_finished") - yield (get_tree().create_timer(0.15), "timeout") - _enter_state(STATES.DEFAULT) - -func _strum_guitar(string, fret, volume): - _sync_strum(string, fret, volume) - Network._send_actor_action(actor_id, "_sync_strum", [string, fret, volume]) - - animation_data["land"] = clamp(animation_data["land"] + 0.06, 0.0, 0.3) - _sync_face_emote("strum") - if randf() < 0.05: - _sync_particle("music") - -func _sync_strum(string, fret, volume): - if not in_zone or not visible: return - $guitar_sounds.get_child(string)._play_fret(fret, false, volume) - -func _hammer_string(string, fret): - _sync_hammer(string, fret) - Network._send_actor_action(actor_id, "_sync_hammer", [string, fret]) - -func _sync_hammer(string, fret): - if not in_zone or not visible: return - $guitar_sounds.get_child(string)._hammer_fret(fret) - -func _bark(): - if not controlled: return - var bark_id = "bark_dog" - bark_id = { - "species_cat": ["bark_cat", "growl_cat", "whine_cat"], - "species_dog": ["bark_dog", "growl_dog", "whine_dog"], - }[PlayerData.cosmetics_equipped.species] - - var type = 0 - if Input.is_action_pressed("move_sneak"): - _sync_face_emote("growl") - type = 1 - elif Input.is_action_pressed("move_walk"): - _sync_face_emote("whine") - type = 2 - else : - _sync_face_emote("bark") - - bark_id = bark_id[type] - _sync_sfx(bark_id) - -func _kiss(): - if not controlled: return - - animation_data["land"] = animation_data["land"] + 0.2 - _sync_face_emote("kiss") - _sync_sfx("kiss") - _sync_particle("kiss") - -func _punch(type = 0): - if not controlled or item_cooldown > 0: return - item_cooldown = 30 - - animation_data["land"] = animation_data["land"] + 1.0 - for b in $detection_zones / punch.get_overlapping_bodies(): - if b.is_in_group("player") and b != self and not b.controlled: - Network._send_P2P_Packet({"type": "player_punch", "from": global_transform.origin, "player": owner_id, "punch_type": type}, str(b.owner_id), 2) - - _sync_face_emote("punch") - _sync_sfx("punch") - _sync_punch() - Network._send_actor_action(actor_id, "_sync_punch") - -func _sync_punch(): - $emotion_particles / punch_particles.restart() - $emotion_particles / punchb_particles.restart() - -func _punched(from, type): - if not controlled: return - - if OptionsMenu.punchable: return - - var dir = (global_transform.origin - from).normalized() - - ignore_snap = 10 - var bounce_horz = 4.0 - var bounce_vert = 8.0 - - match type: - 0: - bounce_horz = 4.0 - bounce_vert = 8.0 - 1: - bounce_horz = 12.0 - bounce_vert = 24.0 - - gravity_vec = Vector3.ZERO - gravity_vec.x += (dir.normalized() * bounce_horz).x - gravity_vec.z += (dir.normalized() * bounce_horz).z - gravity_vec.y += bounce_vert - - _sync_face_emote("angry") - -func _tambourine(): - _sync_sfx("tambourine") - - animation_data["land"] = clamp(animation_data["land"] + 0.14, 0.0, 0.3) - _sync_face_emote("strum") - if randf() < 0.25: - _sync_particle("music") - -func _on_cosmetic_refresh_timeout(): - if not controlled: return - _refresh_cosmetics() - -func _refresh_cosmetics(): - if not controlled: return - yield (get_tree().create_timer(1.0), "timeout") - var new = PlayerData.cosmetics_equipped.duplicate() - if not dead_actor: Network._send_actor_action(actor_id, "_update_cosmetics", [new]) - -func _return_to_spawn(): - if not controlled: return - death_counter = 11 - _kill(true) - -func _item_removal(ref): - print("Sold Item") - if held_item.keys().has("ref") and held_item["ref"] == ref: _equip_item(PlayerData.FALLBACK_ITEM.duplicate()) diff --git a/Scenes/Entities/Player/player.gd b/Scenes/Entities/Player/player.gd deleted file mode 100644 index dd82d68..0000000 --- a/Scenes/Entities/Player/player.gd +++ /dev/null @@ -1,2343 +0,0 @@ -extends Actor - -enum STATES{DEFAULT, BUSY, OBTAIN, EMOTING, FREECAM, FISHING_CHARGE, FISHING_CAST, FISHING, FISHING_CANCEL, FISHING_STRUGGLE, SHOVEL_CAST, SHOVEL_STRUGGLE, SHOVEL_CANCEL, \ -NET_CAST, NET_STRUGGLE, NET_CANCEL, SHOWCASE, CONSUME_ITEM, METAL_DETECTOR, GUITAR, GAMBLING} - -const GRAVITY = 32.0 -const BAIT_DATA = { - "": {"catch": 0.0, "max_tier": 0, "quality": []}, - - "worms": {"catch": 0.06, "max_tier": 1, "quality": [1.0]}, - "cricket": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.05]}, - "leech": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.15, 0.05]}, - "minnow": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.5, 0.25, 0.05]}, - "squid": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.8, 0.45, 0.15, 0.05]}, - "nautilus": {"catch": 0.06, "max_tier": 2, "quality": [1.0, 0.98, 0.75, 0.55, 0.25, 0.05]}, -} -const PARTICLE_DATA = { - "dust_run": preload("res://Scenes/Particles/dust_running.tscn"), - "dust_land": preload("res://Scenes/Particles/dust_land.tscn"), - "splash": preload("res://Scenes/Particles/water_splash.tscn"), - "small_splash": preload("res://Scenes/Particles/small_splash.tscn"), - "music": preload("res://Scenes/Particles/music_particle.tscn"), - "kiss": preload("res://Scenes/Particles/kiss.tscn"), -} - -export (NodePath) var hand_sprite_node -export (NodePath) var hand_bone_node -export var NPC_body = false -export var NPC_cosmetics = {"species": "species_cat", "pattern": "pattern_none", "primary_color": "pcolor_white", "secondary_color": "scolor_tan", "hat": "hat_none", "undershirt": "shirt_none", "overshirt": "overshirt_none", "title": "title_rank_1", "bobber": "bobber_default", "eye": "eye_halfclosed", "nose": "nose_cat", "mouth": "mouth_default", "accessory": [], "tail": "tail_cat"} -export var NPC_name = "NPC Test" -export var NPC_title = "npc title here" - -var camera_zoom = 5.0 - -var direction = Vector3() -var gravity_vec = Vector3() -var dive_vec = Vector3() -var velocity = Vector3() -var player_scale = 1.0 -var player_scale_y = 1.0 - -var cam_orbit_node = null -var cam_follow_node = null -var cam_push = 0.0 -var cam_push_cur = 0.0 -var cam_return = 1.0 -var force_cam_look = false -var mouse_world_pos = Vector3() -var mouse_look = false - -var state = STATES.DEFAULT -var walk_speed = 3.2 -var slow_walk_speed = 1.0 -var sprint_speed = 6.44 -var sneak_speed = 1.3 -var jump_height = 6.0 -var jump_leap = 0.0 -var dive_distance = 9.0 -var accel = 64.0 -var sprinting = false -var slow_walking = false -var sneaking = false -var diving = false -var request_jump = false -var ignore_snap = 0 -var snapped = false -var sitting = false -var locked = false -var busy = false -var in_air = false -var gravity_disable = false -var hud -var int_text = "" -var interact_cooldown = 60 -var xp_buildup = 0 -var showcase_ref - -var held_item = PlayerData.FALLBACK_ITEM -var caught_item = PlayerData.FALLBACK_ITEM -var held_item_weight = 1.0 -var previous_item = 0 -var primary_hold_timer = 0 -var fish_zone_data = {} -var rod_cast_data = "" -var casted_bait = "" -var rod_cast_dist = 0.0 -var rod_depth = 0 -var failed_casts = 0 -var recent_reel = 0.0 -var item_scene = null -var bobber_hpos = Vector3() -var bobber_vpos = 0 -var bobber_control = true -var last_valid_pos = Vector3() -var retract_splash = false -var show_local = false -var bait_warn = 2 -var in_rain = false -var consume_on_state_change = - 1 -var item_cooldown = 0 - -var rod_damage = 1.0 -var rod_spd = 1.0 -var rod_chance = 0.0 - - - -var boost_timer = 0 -var boost_amt = 1.3 -var boost_mult = 1.0 -var catch_drink_timer = 0 -var catch_drink_boost = 1.0 -var catch_drink_reel = 1.0 -var catch_drink_xp = 1.0 -var catch_drink_gold_add = Vector2(0, 0) -var catch_drink_gold_percent = 0.0 -var catch_drink_tier = 0 -var drunk_timer = 0 -var drunk_tier = 0 -var drunk_wander_length = 0 -var drunk_wander_dir = 0 - -var death_counter = 0 -var metal_detect_flop = false -var metal_detect_alert_level = 0 -var metal_detect_alert_cd = 0 - -var emoting = false -var emote_full = false -var emote_locked = false -var emote_looping = false -var animation_timer = 0 -var animation_goal = 99 -var buffer_state = - 1 -var animation_data = { - "moving": false, - "sprinting": false, - "sneaking": false, - "emoting": false, - "emote_full": false, - "diving": false, - "sitting": false, - "alert": false, - "emote": "", - "arm_state": "", - "caught_item": {}, - "arm_value": 0.0, - "item_bend": 0.0, - "busy": false, - "land": 0.0, - "talking": 0.0, - "recent_reel": 0.0, - "bobber_position": Vector3(), - "bobber_visible": false, - "caught_fish": false, - "player_scale": 1.0, - "player_scale_y": 1.0, - "mushroom": false, - "run_mult": 1.0, - "walk_mult": 1.25, - "drunk_tier": 0, - "wagging": false, - "emote_timescale": 1.0, - "back_bend": 0.0, - "dive_scrape": false, - "reel_slow": false, - "reel_fast": false, - "state": state, -} - - - -var custom_held_item = "" - -var cosmetic_data = {} -var selected_build_object -var old_rot = Vector3() -var rot_diff = 0.0 - -var prop_ids = [] -var cam_move = false -var freecamming = false - -onready var cam_base = $cam_base -onready var cam_pivot = $cam_base / cam_pivot -onready var camera = $Camera -onready var camera_point = $cam_base / cam_pivot / SpringArm / camera_point -onready var cam_arm = $cam_base / cam_pivot / SpringArm -onready var body = $body -onready var body_mesh = $body / player_body / Armature / Skeleton / body_main -onready var rot_help = $rot_help -onready var interact_range = $interact_range -onready var anim_tree = $body / AnimationTree -onready var skeleton = $body / player_body / Armature / Skeleton -onready var title = $Viewport / player_label -onready var item_sprite = get_node(hand_sprite_node) -onready var hand_bone = get_node(hand_bone_node) -onready var sound_emit = $sound_emit -onready var face = $body / player_body / Armature / Skeleton / face / player_face -onready var tail = $body / player_body / Armature / Skeleton / tail / holder / tail -onready var freecam_anchor = $camera_freecam_anchor -onready var sound_manager = $sound_manager - -onready var fish_detect = $detection_zones / fishing_detect -onready var fishing_update = $detection_zones / fishing_update -onready var fishing_area = $detection_zones / fishing_detect / fishing_area -onready var fish_timer = $fish_catch_timer -onready var bobber_preview = $bobber_preview -onready var bobber = $bobber -onready var bobber_mesh = $bobber / bobber_mesh -onready var bobber_line = $bobber / line -onready var ripples = $bobber / ripples -onready var caught_fish = $bobber / caught_item - -onready var shovel_area = $detection_zones / shovel_detect -onready var net_area = $detection_zones / net_detect - -onready var safe_check = $safe_check - -onready var lvlparticle = $emotion_particles / lvl_particles -onready var lvlparticleb = $emotion_particles / lvl_particles2 - -signal _animation_finished -signal _primary_release -signal _state_change -signal _menu_closed - - - - - -func _ready(): - add_to_group("player") - rot_help.set_as_toplevel(true) - cam_base.set_as_toplevel(true) - camera.set_as_toplevel(true) - freecam_anchor.set_as_toplevel(true) - anim_tree.tree_root = anim_tree.tree_root.duplicate(true) - _update_cosmetics(cosmetic_data) - title.visible = not dead_actor - - if NPC_body: - camera.queue_free() - remove_from_group("player") - - yield (get_tree(), "idle_frame") - var new = NPC_cosmetics - Network._send_actor_action(actor_id, "_update_cosmetics", [new]) - _update_cosmetics(new) - - yield (get_tree(), "idle_frame") - title.visible = true - title.label = NPC_name - title.title = NPC_title - - -func _setup_controlled(): - if NPC_body: return - - add_to_group("controlled_player") - camera = $Camera - camera.current = true - hud = load("res://Scenes/HUD/playerhud.tscn").instance() - hud.player = self - hud.connect("_player_sit", self, "_toggle_sit") - hud.connect("_play_emote", self, "_play_emote") - hud.connect("_menu_entered", self, "_hud_menu_entered") - hud.connect("_message_sent", self, "_message_sent") - hud.connect("_freecam_toggle", self, "_toggle_freecam") - get_tree().get_root().add_child(hud) - - PlayerData.connect("_clear_all_props", self, "_clear_all_props") - PlayerData.connect("_place_prop", self, "_create_prop") - PlayerData.connect("_play_sfx", self, "_play_sfx") - PlayerData.connect("_play_guitar", self, "_strum_guitar") - PlayerData.connect("_hammer_guitar", self, "_hammer_string") - PlayerData.connect("_return_to_spawn", self, "_return_to_spawn") - PlayerData.connect("_punched", self, "_punched") - PlayerData.connect("_item_removal", self, "_item_removal") - var delayed_update = get_tree().create_timer(1.0).connect("timeout", self, "_change_cosmetics") - - PlayerData.connect("_wag_toggle", self, "_wag") - PlayerData.connect("_kiss", self, "_kiss") - Network.connect("_user_connected", self, "_refresh_cosmetics") - - -func _setup_not_controlled(): - camera = $Camera - camera.queue_free() - - $bobber_preview.visible = false - $local_range.visible = false - $detection_zones / metal_detect_consume.monitoring = false - $detection_zones / metal_detect_consume.monitorable = false - - - $detection_zones / prop_detect.monitoring = false - $detection_zones / metal_detect_far.monitoring = false - $detection_zones / metal_detect.monitoring = false - $detection_zones / metal_detect_close.monitoring = false - $detection_zones / metal_detect_veryclose.monitoring = false - $detection_zones / punch.monitoring = false - $interact_range.monitoring = false - $water_detect.monitoring = false - $raincloud_check.monitoring = false - - - - - -func _physics_process(delta): - _process_animation() - _process_sounds() - - if ( not in_zone != $CollisionShape.disabled): - $CollisionShape.disabled = not in_zone - -func _process(delta): - if controlled: $paint_node._paint_process(delta) - -func _controlled_process(delta): - _get_input() - _process_movement(delta) - _process_timers() - _interact_check() - _update_animation_data() - _camera_update() - - _freecam_input(delta) - - body.visible = camera_zoom > 0.5 or cam_orbit_node != null - current_zone = world.active_zone - current_zone_owner = world.active_zone_owner - - fish_detect.translation.z = - rod_cast_dist - bobber_preview.translation.z = - clamp(primary_hold_timer * 0.06, 1.5, 9.0) - if bobber_preview.is_colliding(): $"%bobber_prev_mesh".global_transform.origin = bobber_preview.get_collision_point() + Vector3(0, 0.05, 0) - bobber_preview.visible = state == STATES.FISHING_CHARGE - - if recent_reel > 0: recent_reel -= 1 - if interact_cooldown > 0: interact_cooldown -= 1 - - animation_data["reel_slow"] = recent_reel > 8 - animation_data["reel_fast"] = state == STATES.FISHING_STRUGGLE - - - if (packet_send_interval == - 1 or Engine.get_physics_frames() % packet_send_interval == 0): - Network._send_actor_animation_update(actor_id, animation_data) - - Network.MESSAGE_ORIGIN = global_transform.origin - $local_range.visible = show_local - - $paint_node.global_transform.origin = mouse_world_pos - $metaldetect_dot.modulate.a = lerp($metaldetect_dot.modulate.a, 0.0, 0.1) - - -func _camera_update(): - cam_push_cur = lerp(cam_push_cur, cam_push * rod_cast_dist, 0.2) - var push = global_transform.basis.z * cam_push_cur - camera_zoom = clamp(camera_zoom, 0.0, 20.0) - - var cam_zoom = camera_zoom - var cam_zoom_lerp = 0.4 - var cam_follow_point = true - var cam_follow_pos = Vector3() - var cam_follow_rot = Vector3() - var sit_add = Vector3(0, - 0.2, 0.0) if sitting else Vector3.ZERO - var cam_base_pos = global_transform.origin + push + sit_add - - var desired_fov = 50 - if sprinting and direction != Vector3.ZERO: - desired_fov += 2 - if boost_timer > 0: desired_fov += 2 * boost_amt - if animation_data["mushroom"]: desired_fov += 10 - - camera.fov = lerp(camera.fov, desired_fov, 0.2) - - if is_instance_valid(cam_orbit_node) and cam_orbit_node.is_visible_in_tree(): - cam_base_pos = cam_orbit_node.global_transform.origin - - if is_instance_valid(cam_follow_node) and cam_follow_node.is_visible_in_tree(): - cam_follow_point = false - cam_follow_pos = cam_follow_node.global_transform.origin - cam_follow_rot = cam_follow_node.global_rotation - - var cam_speed = 0.08 - if cam_follow_point: - cam_return = lerp(cam_return, 1.0, cam_speed * 0.5) - camera.global_transform.origin = lerp(camera.global_transform.origin, camera_point.global_transform.origin, cam_return) - camera.rotation.x = lerp_angle(camera.rotation.x, camera_point.global_rotation.x, cam_return) - camera.rotation.y = lerp_angle(camera.rotation.y, camera_point.global_rotation.y, cam_return) - camera.rotation.z = lerp_angle(camera.rotation.z, camera_point.global_rotation.z, cam_return) - else : - cam_return = 0.0 - camera.global_transform.origin = lerp(camera.global_transform.origin, cam_follow_pos, cam_speed) - camera.rotation.x = lerp_angle(camera.rotation.x, cam_follow_rot.x, cam_speed) - camera.rotation.y = lerp_angle(camera.rotation.y, cam_follow_rot.y, cam_speed) - camera.rotation.z = lerp_angle(camera.rotation.z, cam_follow_rot.z, cam_speed) - - cam_base.global_transform.origin = cam_base_pos - cam_arm.spring_length = lerp(cam_arm.spring_length, cam_zoom, cam_zoom_lerp) - -func _interact_check(): - if not controlled: return - var in_range = false - for area in interact_range.get_overlapping_areas(): - if area.is_in_group("interactable") and area.is_visible_in_tree(): - int_text = area.text - in_range = true - break - if hud: - hud.interact = in_range - hud.int_text = int_text - -func _hud_menu_entered(menu): - if menu == 0: - if not freecamming: - cam_orbit_node = null - cam_follow_node = null - force_cam_look = false - _exit_showcase() - emit_signal("_menu_closed") - -func _process_timers(): - if catch_drink_timer > 0: - catch_drink_timer -= 1 - if catch_drink_timer <= 0: - catch_drink_boost = 1.0 - catch_drink_reel = 1.0 - catch_drink_xp = 1.0 - catch_drink_gold_add = Vector2(0, 0) - catch_drink_gold_percent = 0.0 - - drunk_tier = 0 - if drunk_timer > 0: - drunk_timer -= 1 - if drunk_timer >= 19000: drunk_tier = 3 - elif drunk_timer >= 10000: drunk_tier = 2 - elif drunk_timer > 0: drunk_tier = 1 - else : drunk_tier = 0 - - if item_cooldown > 0: item_cooldown -= 1 - - - - - -func _get_input(): - direction = Vector3.ZERO - - if Input.is_action_just_released("primary_action"): _primary_action_release() - if Input.is_action_pressed("primary_action"): _primary_action_hold() - else : primary_hold_timer = 0 - - if busy: - Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) - return - - if Input.is_action_pressed("secondary_action") or camera_zoom <= 0.0: - if Input.mouse_mode != Input.MOUSE_MODE_CAPTURED: - PlayerData.original_mouse_position = get_tree().get_nodes_in_group("world_viewport")[0].get_mouse_position() - Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) - else : - if Input.mouse_mode != Input.MOUSE_MODE_VISIBLE: - Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) - Input.warp_mouse_position(PlayerData.original_mouse_position) - - if Input.is_action_just_released("zoom_in"): camera_zoom -= 0.5 - if Input.is_action_just_released("zoom_out"): camera_zoom += 0.5 - - if Input.is_action_just_pressed("interact"): _interact() - - if Input.is_action_just_pressed("bind_1"): _equip_hotbar(0) - if Input.is_action_just_pressed("bind_2"): _equip_hotbar(1) - if Input.is_action_just_pressed("bind_3"): _equip_hotbar(2) - if Input.is_action_just_pressed("bind_4"): _equip_hotbar(3) - if Input.is_action_just_pressed("bind_5"): _equip_hotbar(4) - - if Input.is_action_just_pressed("bark"): - _bark() - if Input.is_action_just_pressed("kiss"): - _kiss() - - if locked: return - - - if is_instance_valid(camera): - var camera_cam = camera - var ray_length = 1000 - var mouse_pos = get_tree().get_nodes_in_group("world_viewport")[0].get_mouse_position() / Globals.pixelize_amount - var from = camera_cam.project_ray_origin(mouse_pos) - var to = from + camera_cam.project_ray_normal(mouse_pos) * ray_length - var space_state = get_world().get_direct_space_state() - var result = space_state.intersect_ray(from, to, []) - if result.has("position"): - mouse_world_pos = result["position"] - mouse_world_pos.y = global_transform.origin.y - - if freecamming: return - if Input.is_action_just_pressed("move_jump"): request_jump = true - - mouse_look = false - - if sitting: return - - if Input.is_action_pressed("move_forward"): direction -= cam_base.transform.basis.z - if Input.is_action_pressed("move_back"): direction += cam_base.transform.basis.z - if Input.is_action_pressed("move_right"): direction += cam_base.transform.basis.x - if Input.is_action_pressed("move_left"): direction -= cam_base.transform.basis.x - - if drunk_wander_length > 0: - direction += drunk_wander_dir - drunk_wander_length -= 1 - - mouse_look = Input.is_action_pressed("mouse_look") - - sprinting = not Input.is_action_pressed("move_sneak") and Input.is_action_pressed("move_sprint") - sneaking = Input.is_action_pressed("move_sneak") and not Input.is_action_pressed("move_sprint") - slow_walking = Input.is_action_pressed("move_walk") - - if emote_locked: - request_jump = false - direction = Vector3.ZERO - -func _input(event): - if not controlled: return - - var mouse_sens = OptionsMenu.mouse_sens - var invert = Vector2(1, 1) - if OptionsMenu.mouse_invert == 1: invert.x = - 1 - elif OptionsMenu.mouse_invert == 2: invert.y = - 1 - elif OptionsMenu.mouse_invert == 3: invert = Vector2( - 1, - 1) - - if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: - cam_base.rotation_degrees.y -= event.relative.x * mouse_sens * invert.x - cam_pivot.rotation_degrees.x -= event.relative.y * mouse_sens * invert.y - cam_pivot.rotation_degrees.x = clamp(cam_pivot.rotation_degrees.x, - 80, 80) - -func _unhandled_input(event): - if not controlled: return - - if event.is_action_pressed("primary_action"): _primary_action() - - - - -func _process_movement(delta): - var snap_vec = Vector3(0, - 0.4, 0) - var y_slow = 0.02 - - if is_on_floor() and in_air: - if gravity_vec.y <= - 12.0 and not diving: - diving = true - dive_vec = gravity_vec.length() * - transform.basis.z * 0.2 - player_scale_y = 1.0 - clamp(((abs(gravity_vec.y) / 24.0) * 6.0), 0.0, 0.6) - in_air = false - _sync_particle("dust_land", Vector3(0, - 1, 0)) - _sync_sfx("land") - animation_data["land"] = 0.3 - elif gravity_vec.y < - 6.0: - in_air = true - - player_scale_y = lerp(player_scale_y, 1.0, 0.35) - - if is_on_floor() and ignore_snap <= 0: - y_slow = 0.2 - gravity_vec = get_floor_normal() * - 1.0 - snapped = true - elif snapped and ignore_snap <= 0: - gravity_vec = Vector3.ZERO - snapped = false - else : - snap_vec = Vector3.ZERO - var grav = GRAVITY * Vector3.DOWN * delta - gravity_vec += grav - - if request_jump: - request_jump = false - snap_vec = Vector3.ZERO - if is_on_floor(): - _sync_sfx("jump") - snapped = false - diving = false - gravity_vec = Vector3(0, jump_height, 0) - if sprinting and jump_leap > 0.0: - gravity_vec += - transform.basis.z.normalized() * jump_leap - elif not diving: - _sync_sfx("dive_woosh") - snapped = false - diving = true - dive_vec = - transform.basis.z.normalized() * dive_distance - dive_vec.y = 0 - gravity_vec += Vector3(0, jump_height * 0.5, 0) - _toggle_sit(true) - - if ignore_snap > 0: - snap_vec = Vector3.ZERO - ignore_snap -= 1 - snapped = false - - boost_mult = 1.0 - if boost_timer > 0: - boost_timer -= 1 - boost_mult = boost_amt - - var _speed = walk_speed - if sprinting: _speed = sprint_speed * boost_mult - elif sneaking: _speed = sneak_speed - elif slow_walking: _speed = slow_walk_speed - var _accel = accel if is_on_floor() else accel * 0.35 - - var speed_mult = 1.0 - - - speed_mult = clamp(speed_mult - ((held_item_weight / 25.0) * 0.05), 0.15, 1.0) - - if diving: speed_mult = 0.0 - if gravity_disable: gravity_vec = Vector3.ZERO - - velocity = velocity.move_toward(direction.normalized() * _speed * speed_mult, delta * _accel) - move_and_slide_with_snap(velocity + gravity_vec + dive_vec, snap_vec, Vector3.UP) - - dive_vec = dive_vec.move_toward(Vector3.ZERO, delta * _accel * y_slow) - if not diving: dive_vec = Vector3.ZERO - - rot_help.global_transform.origin = global_transform.origin - - if direction != Vector3.ZERO: - var dir = direction - if diving and dive_vec != Vector3.ZERO: dir = dive_vec.normalized() - - rot_help.look_at(cam_base.global_transform.origin + dir, Vector3.UP) - rotation.y = lerp_angle(rotation.y, rot_help.rotation.y, 0.2) - elif force_cam_look: - rot_help.look_at(camera.global_transform.origin, Vector3.UP) - rotation.y = lerp_angle(rotation.y, rot_help.rotation.y, 0.2) - elif mouse_look and not busy: - rot_help.look_at(mouse_world_pos, Vector3.UP) - rot_diff = abs(rot_help.rotation.y - rotation.y) - rotation.y = lerp_angle(rotation.y, rot_help.rotation.y, 0.2) - - rot_diff = lerp(rot_diff, 0.0, 0.5) - - if diving and dive_vec.length() > 0.4 and is_on_floor(): - - animation_data["dive_scrape"] = true - - if Engine.get_idle_frames() % 4 == 0: - _sync_particle("dust_run", Vector3(0, - 0.8, 0)) - else : - - animation_data["dive_scrape"] = false - - if gravity_vec.y < - 250: - _kill() - - - - -func _enter_state(new_state): - if new_state == - 1: return - - if consume_on_state_change != - 1: - PlayerData._remove_item(consume_on_state_change, false) - consume_on_state_change = - 1 - - state = new_state - emit_signal("_state_change") - cam_push = 0.0 - animation_data["bobber_visible"] = false - - match state: - STATES.DEFAULT: - animation_data["item_bend"] = 0.0 - locked = false - STATES.BUSY: locked = false - STATES.OBTAIN: locked = true - STATES.SHOWCASE: - locked = true - _equip_item(PlayerData._find_item_code(showcase_ref), true, true) - - STATES.FISHING: - cam_push = - 0.3 - locked = true - animation_data["bobber_visible"] = true - PlayerData.emit_signal("_help_update", "hold to reel (SPRINT reels quicker)") - _enter_animation("rod_idle", true) - STATES.FISHING_CANCEL: - animation_data["item_bend"] = 0.1 - cam_push = - 0.3 - locked = true - rod_cast_dist = 0.0 - animation_data["bobber_visible"] = true - PlayerData.emit_signal("_item_equip", held_item.ref) - _bobber_retract() - _enter_animation("rod_retract", false, true, STATES.DEFAULT) - STATES.FISHING_CAST: - cam_push = - 0.3 - animation_data["bobber_visible"] = true - locked = true - STATES.FISHING_CHARGE: - cam_push = 0.0 - locked = false - STATES.FISHING_STRUGGLE: - animation_data["item_bend"] = - 0.7 - cam_push = - 0.3 - animation_data["bobber_visible"] = true - locked = true - _enter_animation("rod_struggle", true) - - STATES.GUITAR: locked = true - - STATES.SHOVEL_CAST: locked = true - STATES.SHOVEL_STRUGGLE: - locked = true - _shovel_check() - STATES.SHOVEL_CANCEL: - locked = true - _enter_animation("shovel_retract", false, true, STATES.DEFAULT) - - STATES.NET_CAST: locked = true - STATES.NET_STRUGGLE: - locked = true - _net_check() - STATES.NET_CANCEL: - locked = true - _enter_animation("net_retract", false, true, STATES.DEFAULT) - - STATES.CONSUME_ITEM: - locked = false - _equip_item({"ref": 0}, true, true) - _enter_state(STATES.DEFAULT) - -func _primary_action(): - match state: - STATES.DEFAULT: - _use_item() - STATES.OBTAIN: - _enter_animation("equip", false, true, 0, false, 1.5) - -func _primary_action_hold(): - primary_hold_timer += 1 - - match state: - STATES.DEFAULT: - return - STATES.FISHING: - _enter_animation("rod_reel", true) - rod_cast_dist -= 0.04 if Input.is_action_pressed("move_sprint") else 0.01 - bobber_control = true - recent_reel = 15 - if rod_cast_dist < 1.5: _enter_state(STATES.FISHING_CANCEL) - -func _primary_action_release(): - emit_signal("_primary_release") - - match state: - STATES.DEFAULT: - _release_item() - STATES.FISHING: - _enter_animation("rod_idle", true) - STATES.METAL_DETECTOR: - _enter_state(STATES.DEFAULT) - - - - - -func _interact(): - if not controlled or interact_cooldown > 0: return - for area in interact_range.get_overlapping_areas(): - if area.is_in_group("interactable") and area.is_visible_in_tree(): - area._activate(self) - interact_cooldown = 60 - return - -func _enter_zone(zone, entrance_id, zone_owner = - 1): - if not controlled: return - world._enter_zone(zone, zone_owner) - PlayerData.player_saved_zone = zone - PlayerData.player_saved_zone_owner = zone_owner - - print("Finding entrance w id: ", entrance_id, " and owner: ", zone_owner) - for entrance in get_tree().get_nodes_in_group("area_entrance"): - print(entrance.entrance_id, ": ", entrance.entrance_owner, " ?") - if entrance.entrance_id == entrance_id and entrance.entrance_owner == zone_owner: - global_transform.origin = entrance.global_transform.origin - last_valid_pos = global_transform.origin - return - - print("Fallback!") - global_transform.origin = world.map.spawn_position.global_transform.origin - world._enter_zone("main_zone", - 1) - PlayerData.player_saved_zone = "main_zone" - PlayerData.player_saved_zone_owner = - 1 - last_valid_pos = global_transform.origin - -func _obtain_item(ref, bonus_text = [], journal_check = true): - old_rot = rotation - showcase_ref = ref - _equip_item({"ref": - 1}, true, true) - _enter_animation("equip", false, false, STATES.SHOWCASE, false, 1.5) - _play_sfx("strum") - - - var data = PlayerData._find_item_code(ref) - var text = "You caught a " + PlayerData._get_item_name(ref) + "! [color=#d5aa73](It's " + str(data["size"]) + "cm!)[/color]\n\n" + str(Globals.item_data[data["id"]]["file"].catch_blurb) - - if journal_check: - var new = true - for type in PlayerData.journal_logs.keys(): - for entry in PlayerData.journal_logs[type].keys(): - if entry == data.id and PlayerData.journal_logs[type][entry].count > 1: - new = false - break - if new: - text = "Woah, a new creature! " + text - - hud.dialogue_text = [text] - if bonus_text != []: hud.dialogue_text.append_array(bonus_text) - hud._change_menu(6) - - force_cam_look = true - yield (get_tree().create_timer(0.1), "timeout") - cam_follow_node = $catch_cam_position - -func _level_up(): - yield (get_tree().create_timer(0.4), "timeout") - var bubble = title._create_level_bubble() - Network._send_actor_action(actor_id, "_sync_level_bubble", [], false) - GlobalAudio._play_sound("jingle_win") - - _play_emote("emote_cheer", "happy") - - $emotion_particles / lvl_particles.restart() - $emotion_particles / lvl_particles2.restart() - -func _exit_showcase(): - if state != STATES.SHOWCASE: return - _exit_animation() - _enter_state(STATES.DEFAULT) - _equip_item(PlayerData._find_item_code(previous_item), false) - get_tree().create_tween().tween_property(self, "rotation", old_rot, 0.3) - - if xp_buildup > 0: - PlayerData._add_xp(ceil(xp_buildup)) - xp_buildup = 0 - -func _equip_hotbar(slot): - if locked or not PlayerData.hotbar.keys().has(slot): return - var ref = PlayerData.hotbar[slot] - _equip_item(PlayerData._find_item_code(ref)) - -func _equip_item(item_data, skip_anim = false, forced = false, set_prev = true): - if set_prev and held_item["ref"] != 0: previous_item = held_item["ref"] - if (state != STATES.DEFAULT and not forced) or held_item["ref"] == item_data["ref"]: return - - if not item_data.keys().has("id") or not Globals.item_data.keys().has(item_data["id"]): - item_data = PlayerData.FALLBACK_ITEM - - PlayerData.emit_signal("_item_equip", item_data["ref"]) - - if not skip_anim: - _sync_sfx("equip") - _enter_state(STATES.BUSY) - _enter_animation("equip", false, false, STATES.DEFAULT, false, 1.5) - yield (self, "_animation_finished") - - - var held_data = item_data.duplicate() - - hud.show_bait = Globals.item_data[item_data["id"]]["file"].show_bait - - var data = Globals.item_data[item_data["id"]]["file"] - held_item_weight = item_data["size"] - if not data.uses_size: held_item_weight = 0.0 - - _update_held_item(held_data) - Network._send_actor_action(actor_id, "_update_held_item", [held_item], false) - -func _use_item(): - if held_item.empty(): return - var item_data = Globals.item_data[held_item["id"]]["file"] - if has_method(item_data.action) and item_data.action != "": - callv(item_data.action, item_data.action_params) - -func _release_item(): - if held_item.empty(): return - var item_data = Globals.item_data[held_item["id"]]["file"] - if has_method(item_data.release_action) and item_data.release_action != "": - call(item_data.release_action) - - - - - - - -func _cast_fishing_rod(): - rod_cast_data = PlayerData.LURE_DATA[PlayerData.lure_selected].effect_id - animation_data["caught_item"] = {} - bait_warn = 1 - - rod_damage = [1, 3, 10, 20, 35, 50][PlayerData.rod_power_level] - rod_spd = [0.0, 0.1, 0.24, 0.4, 0.7, 1.0][PlayerData.rod_speed_level] - rod_chance = [0.0, 0.02, 0.04, 0.06, 0.08, 0.1][PlayerData.rod_chance_level] - - _enter_state(STATES.FISHING_CHARGE) - _enter_animation("rod_wind", true, false, - 1, false) - yield (self, "_primary_release") - if state != STATES.FISHING_CHARGE: return - _enter_state(STATES.FISHING_CAST) - _sync_sfx("woosh", null, 1.0, 0.4) - var strength = clamp(primary_hold_timer * 0.06, 1.5, 9.0) - rod_cast_dist = strength - fish_detect.translation.z = - strength - - var is_valid_fishing_spot = false - if bobber_preview.is_colliding() and bobber_preview.get_collider().is_in_group("valid_water"): - is_valid_fishing_spot = true - - _bobber_cast(rod_cast_dist, bobber_preview.get_collision_point() + Vector3(0, 0.75, 0), is_valid_fishing_spot) - - rod_depth = 0 - - casted_bait = PlayerData.bait_selected - if casted_bait != "" and PlayerData.bait_inv[casted_bait] <= 0: casted_bait = "" - - _exit_animation() - if is_valid_fishing_spot: - animation_data["item_bend"] = 0.3 - retract_splash = true - _enter_animation("rod_cast", false, true, STATES.FISHING) - else : - animation_data["item_bend"] = 0.3 - retract_splash = false - _enter_animation("rod_cast", false, true, STATES.FISHING_CANCEL) - - yield (get_tree().create_timer(0.4), "timeout") - animation_data["item_bend"] = - 0.2 - -func _on_fish_catch_timer_timeout(): - if not controlled: return - - fish_timer.wait_time = rand_range(2.0, 3.0) - fish_timer.start() - - if state != STATES.FISHING: return - var fish_type = "ocean" - var junk_mult = 1.0 - - - fish_zone_data = {"id": - 1, "boost": 0.0} - for zone in fishing_area.get_overlapping_areas(): - if zone.is_in_group("fish_zone"): - fish_zone_data["id"] = zone.id - fish_zone_data["boost"] = zone.chance_boost - junk_mult = zone.junk_mult - if zone.fish_type != "": fish_type = zone.fish_type - - var fish_chance = 0.0 - var base_chance = BAIT_DATA[casted_bait]["catch"] - fish_chance = base_chance - fish_chance += (base_chance * failed_casts) - fish_chance += (base_chance * rod_chance) - fish_chance += fish_zone_data["boost"] * fish_chance - if recent_reel > 0: fish_chance *= 1.1 - if rod_cast_data == "attractive": fish_chance *= 1.3 - if in_rain: fish_chance *= 1.1 - - fish_chance *= catch_drink_boost - print("Fish chance w ", fish_chance, "w type ", fish_type) - - bait_warn -= 1 - if bait_warn <= 0 and fish_chance <= 0.0: - bait_warn = 8 - var text = "" - if casted_bait == "": - text = "[color=#ac0029]You've got no bait attached! You won't catch any fish like that...[/color]" - else : - text = "[color=#ac0029]Seems nothing is going to bite... perhaps your bait isn't for this water...[/color]" - - Network._update_chat(text) - - if randf() > fish_chance: - failed_casts += 0.05 - return - failed_casts = 0.0 - - - var bait_use_chance = 1.0 - if rod_cast_data == "efficient": bait_use_chance = 0.8 - - if randf() < bait_use_chance: PlayerData._use_bait(casted_bait) - else : PlayerData._send_notification("The Efficient Lure saved your bait!") - var max_tier = BAIT_DATA[casted_bait]["max_tier"] - - var double_bait = 0.0 - if ["large", "sparkling", "double"].has(rod_cast_data): double_bait = 0.25 - if randf() < double_bait: - PlayerData._use_bait(casted_bait) - PlayerData._send_notification("Your lure used extra bait...", 1) - - if rod_cast_data == "gold": - for i in 2: PlayerData._use_bait(casted_bait) - PlayerData._send_notification("Your golden lure used extra bait...", 1) - - var treasure_mult = 1.0 - if rod_cast_data == "magnet": treasure_mult = 2.0 - if rod_cast_data == "salty": fish_type = "ocean" - if rod_cast_data == "fresh": fish_type = "lake" - - var force_av_size = false - - if randf() < 0.05 * treasure_mult * junk_mult: - fish_type = "water_trash" - max_tier = 0 - force_av_size = true - - - - - - - - if in_rain and randf() < 0.08: - fish_type = "rain" - - - var rolls = [] - for i in 3: - var roll = Globals._roll_loot_table(fish_type, max_tier) - var s = Globals._roll_item_size(roll) - rolls.append([roll, s]) - - - var reroll_type = "none" - if rod_cast_data == "small": reroll_type = "small" - if rod_cast_data == "sparkling": reroll_type = "tier" - if rod_cast_data == "large": reroll_type = "large" - if rod_cast_data == "gold": reroll_type = "rare" - - var chosen = rolls[0] - for roll in rolls: - match reroll_type: - "none": - chosen = roll - - "small": - if roll[1] < chosen[1]: - chosen = roll - - "large": - if roll[1] > chosen[1]: - chosen = roll - - "tier": - var old_tier = Globals.item_data[chosen[0]]["file"].tier - var new_tier = Globals.item_data[roll[0]]["file"].tier - if new_tier > old_tier: - chosen = roll - - "rare": - var new_rare = Globals.item_data[roll[0]]["file"].rare - if new_rare: - chosen = roll - - var fish_roll = chosen[0] - var size = chosen[1] - - - var quality = PlayerData.ITEM_QUALITIES.NORMAL - var r = randf() - for q in PlayerData.ITEM_QUALITIES.size(): - if BAIT_DATA[casted_bait]["quality"].size() - 1 < q: - print("bait does not support rarity ", q) - break - if randf() < BAIT_DATA[casted_bait]["quality"][q]: - quality = q - print("-------------------------Rolled Quality: ", quality) - - if randf() < 0.02 * treasure_mult: - fish_roll = "treasure_chest" - size = 60.0 - quality = 0 - - var data = Globals.item_data[fish_roll]["file"] - var quality_data = PlayerData.QUALITY_DATA[quality] - - if force_av_size: size = data.average_size - - var diff_mult = clamp(size / data.average_size, 0.7, 1.8) - var difficulty = clamp((data.catch_difficulty * diff_mult * quality_data.diff) + quality_data.bdiff, 1.0, 250.0) - - var xp_mult = size / data.average_size - if xp_mult < 0.15: xp_mult = 1.25 + xp_mult - xp_mult = max(0.5, xp_mult) - var xp_add = ceil(data.obtain_xp * xp_mult * catch_drink_xp * quality_data.worth) - - print("Total Rolls: ", rolls) - print("Roll fish ", fish_roll, " with size ", size, " and diff Mult: ", diff_mult) - - if fish_zone_data["id"] != - 1: - _wipe_actor(fish_zone_data["id"]) - Network._send_actor_action(actor_id, "_wipe_actor", [fish_zone_data["id"]]) - - _enter_state(STATES.FISHING_STRUGGLE) - animation_data["alert"] = true - yield (get_tree().create_timer(1.0), "timeout") - - animation_data["alert"] = false - - var delay_time = 0 - while hud.using_chat: - yield (get_tree().create_timer(0.15), "timeout") - delay_time += 1 - - if delay_time > 200: - _enter_state(STATES.FISHING_CANCEL) - return - - hud._open_minigame("fishing3", {"fish": fish_roll, "rod_type": rod_cast_data, "reel_mult": catch_drink_reel, "quality": quality, "damage": rod_damage, "speed": rod_spd}, difficulty) - var success = yield (hud, "_minigame_finished") - print("SUCCESS: ", success) - if success: - animation_data["caught_item"] = {"id": fish_roll, "size": size} - _enter_state(STATES.FISHING_CANCEL) - yield (self, "_state_change") - - var ref - var catches = 1 - var bonus_text = [] - - if rod_cast_data == "double" and randf() < 0.15: - catches = 2 - bonus_text.append("Your Double Hook doubled the fish!") - - if PlayerData.rod_luck_level > 0 and randf() < 0.15: - bonus_text.append("How lucky! You found a bonus [color=#d57900]Coin Bag[/color] aswell!") - PlayerData._add_item("luck_moneybag", - 1, randi() % 15 + 15, PlayerData.rod_luck_level) - - var tags = [] - - for i in catches: - ref = PlayerData._add_item(fish_roll, - 1, size, quality, tags) - PlayerData._log_item(fish_roll, size, quality) - PlayerData._quest_progress("catch", fish_roll) - PlayerData._quest_progress("catch_type", data.loot_table) - PlayerData._quest_progress("catch_small", PlayerData._get_size_type(fish_roll, size)) - PlayerData._quest_progress("catch_big", PlayerData._get_size_type(fish_roll, size)) - if fish_roll == "treasure_chest": PlayerData._quest_progress("catch_treasure") - if in_rain: PlayerData._quest_progress("catch_rain") - if data.tier == 2: PlayerData._quest_progress("catch_hightier") - xp_buildup += xp_add - - PlayerData._catch_fish() - - _obtain_item(ref, bonus_text) - - if rod_cast_data == "lucky": - var worth = PlayerData._get_item_worth(ref) - var gold = max(1, ceil(worth * rand_range(0.01, 0.1))) - PlayerData.money += gold - PlayerData._send_notification("Your Lucky Lure got you $" + str(gold) + "!") - - if catch_drink_gold_add != Vector2(0, 0): - var gold = max(1, ceil(rand_range(catch_drink_gold_add.x, catch_drink_gold_add.y))) - PlayerData.money += gold - PlayerData._send_notification("Your Catcher's Luck got you $" + str(gold) + "!") - - if catch_drink_gold_percent > 0.0: - var worth = PlayerData._get_item_worth(ref) - var gold = max(1, ceil(rand_range(worth * 0.01, worth * catch_drink_gold_percent))) - PlayerData.money += gold - PlayerData._send_notification("Your Catcher's Luck Ultra got you $" + str(gold) + "!") - - - else : - _enter_state(STATES.FISHING_CANCEL) - -func _wipe_actor(id): - var actor = world._get_actor_by_id(id) - print("Wiping actor ", id, " : ", actor) - if is_instance_valid(actor): - actor._deinstantiate(true) - - -func _shovel(): - _enter_state(STATES.SHOVEL_CAST) - _enter_animation("shovel_dig", false, true, STATES.SHOVEL_STRUGGLE) - -func _shovel_check(): - var mound = false - - var area - for a in shovel_area.get_overlapping_areas(): - if a.is_in_group("mound"): - mound = true - area = a - - if is_instance_valid(area): - var id = area.owner.actor_id - _wipe_actor(id) - Network._send_actor_action(actor_id, "_wipe_actor", [id]) - - if mound: - _enter_animation("shovel_struggle", true, true) - hud._open_minigame("shoveling", {"damage": 5.0}) - var success = yield (hud, "_minigame_finished") - print("SUCCESS: ", success) - if success: - _enter_state(STATES.SHOVEL_CANCEL) - yield (self, "_state_change") - var ref = PlayerData._add_item("spider") - - - _obtain_item(ref) - else : - _enter_state(STATES.SHOVEL_CANCEL) - else : - _enter_state(STATES.SHOVEL_CANCEL) - - -func _cast_net(): - _enter_state(STATES.NET_CAST) - _enter_animation("net_use", false, true, STATES.NET_STRUGGLE) - -func _net_check(): - var bug = false - - var area - for a in net_area.get_overlapping_areas(): - if a.is_in_group("bug"): - bug = true - area = a - - var bug_id = "" - if is_instance_valid(area): - var id = area.owner.actor_id - bug_id = area.owner.bug_id - _wipe_actor(id) - Network._send_actor_action(actor_id, "_wipe_actor", [id]) - - if bug: - _enter_animation("net_struggle", true, true) - hud._open_minigame("shoveling", {"damage": 5.0}) - var success = yield (hud, "_minigame_finished") - print("SUCCESS: ", success) - if success: - _enter_state(STATES.NET_CANCEL) - yield (self, "_state_change") - var size = Globals._roll_item_size(bug_id) - var ref = PlayerData._add_item(bug_id, - 1, size) - - - _obtain_item(ref) - else : - _enter_state(STATES.NET_CANCEL) - else : - _enter_state(STATES.NET_CANCEL) - - - - - - - - - - - - - - -func _toggle_freecam(): - if busy: return - - if not freecamming: - PlayerData._send_notification("entering freecam mode") - freecamming = true - hud.freecamming = true - cam_orbit_node = freecam_anchor - freecam_anchor.global_transform.origin = global_transform.origin - else : - PlayerData._send_notification("exiting freecam mode") - freecamming = false - hud.freecamming = false - cam_orbit_node = null - -func _freecam_input(delta): - if not freecamming: return - - var speed = 4.0 - if Input.is_action_pressed("move_sprint"): - speed = 7.0 - if Input.is_action_pressed("move_sneak"): - speed = 1.0 - var max_dist = 15.0 - var build_dir = Vector3.ZERO - - if Input.is_action_pressed("move_forward"): build_dir -= cam_base.transform.basis.z - if Input.is_action_pressed("move_back"): build_dir += cam_base.transform.basis.z - if Input.is_action_pressed("move_right"): build_dir += cam_base.transform.basis.x - if Input.is_action_pressed("move_left"): build_dir -= cam_base.transform.basis.x - if Input.is_action_pressed("move_up"): build_dir += cam_base.transform.basis.y - if Input.is_action_pressed("move_down"): build_dir -= cam_base.transform.basis.y - - freecam_anchor.global_transform.origin += build_dir * speed * delta - - freecam_anchor.global_transform.origin.x = clamp(freecam_anchor.global_transform.origin.x, global_transform.origin.x - max_dist, global_transform.origin.x + max_dist) - freecam_anchor.global_transform.origin.y = clamp(freecam_anchor.global_transform.origin.y, global_transform.origin.y - max_dist, global_transform.origin.y + max_dist) - freecam_anchor.global_transform.origin.z = clamp(freecam_anchor.global_transform.origin.z, global_transform.origin.z - max_dist, global_transform.origin.z + max_dist) - - - - - -func _create_prop(ref, offset = Vector3(0, 1, 0)): - if not controlled: return - - - for prop in prop_ids: - if prop.ref == ref: - _wipe_actor(prop.id) - prop_ids.erase(prop) - PlayerData._send_notification("clearing prop", 1) - PlayerData.props_placed = prop_ids - PlayerData.emit_signal("_prop_update") - return - - - if $detection_zones / prop_detect.get_overlapping_bodies().size() > 0 or not is_on_floor() or not $detection_zones / prop_ray.is_colliding(): - PlayerData._send_notification("invalid prop placement", 1) - return - - - if prop_ids.size() > 4: - PlayerData._send_notification("prop limit reached", 1) - return - - - var item = PlayerData._find_item_code(ref) - var data = Globals.item_data[item["id"]]["file"] - var ver_offset = Vector3(0, 1.0, 0) * (1.0 - player_scale) - print(ver_offset) - var pos = global_transform.origin + (global_transform.basis.z * - 2.0) - offset + ver_offset - var rot = rotation + Vector3(0, deg2rad(180), 0) - var prop_code = data.prop_code - - - var blacklist = ["island_tiny", "island_med", "island_big"] - if current_zone_owner != - 1: - if blacklist.has(prop_code): - PlayerData._send_notification("this prop cannot be spawned here...", 1) - return - - - var new_id = Network._sync_create_actor(prop_code, pos, current_zone, - 1, Network.STEAM_ID, {"rotation": rot, "current_zone_owner": current_zone_owner}) - prop_ids.append({"id": new_id, "ref": ref, "prop_id": data.action}) - PlayerData.props_placed = prop_ids - PlayerData.emit_signal("_prop_update") - PlayerData._send_notification("prop placed", 0) - - _sync_particle("dust_land", pos, true) - _sync_sfx("poof", pos) - -func _clear_props(): - if prop_ids.size() <= 0: - PlayerData._send_notification("no props to undo", 1) - return - PlayerData._send_notification("undo prop", 0) - _wipe_actor(prop_ids[prop_ids.size() - 1][0]) - prop_ids.remove(prop_ids.size() - 1) - -func _clear_all_props(): - if prop_ids.size() <= 0: - PlayerData._send_notification("no props to clear", 1) - return - - PlayerData._send_notification("clearing all props", 0) - for prop in prop_ids: - _wipe_actor(prop.id) - prop_ids.clear() - PlayerData.props_placed = prop_ids - PlayerData.emit_signal("_prop_update") - -func _item_place_prop(): - if not controlled: return - _create_prop(held_item.ref) - - - - - -func _update_animation_data(): - if animation_data["emote"] != "": - var anim = $body / player_body / AnimationPlayer.get_animation(animation_data["emote"]) - animation_timer += 1 - animation_goal = floor((anim.length * 60) / animation_data["emote_timescale"]) - if animation_timer >= animation_goal and emoting and animation_goal > 0 and not emote_looping: - print("Finished Emoting ", animation_data["emote"], " bufferstate: ", buffer_state) - emit_signal("_animation_finished") - emoting = false - emote_full = false - emote_locked = false - animation_data["emote"] = "" - if buffer_state != - 1: _enter_state(buffer_state) - - animation_data["emoting"] = emoting - animation_data["emote_full"] = emoting and emote_full - animation_data["moving"] = direction != Vector3.ZERO or rot_diff > 0.05 - animation_data["sprinting"] = sprinting and direction != Vector3.ZERO - animation_data["sneaking"] = sneaking and direction != Vector3.ZERO - animation_data["diving"] = diving - animation_data["sitting"] = sitting - animation_data["busy"] = busy and state == STATES.DEFAULT and not emoting - animation_data["land"] = lerp(animation_data["land"], 0.0, 0.04) - animation_data["talking"] = lerp(animation_data["talking"], 0.0, 0.1) - animation_data["recent_reel"] = lerp(animation_data["recent_reel"], recent_reel, 0.2) - animation_data["caught_fish"] = state == STATES.FISHING_STRUGGLE - animation_data["player_scale"] = lerp(animation_data["player_scale"], player_scale, 0.06) - animation_data["player_scale_y"] = lerp(animation_data["player_scale_y"], player_scale_y, 0.06) - animation_data["run_mult"] = 1.15 * boost_mult - animation_data["walk_mult"] = 1.25 if not slow_walking else 0.7 - animation_data["drunk_tier"] = drunk_tier - animation_data["state"] = state - - $emotion_particles / mushroom_trail.emitting = animation_data["mushroom"] - $emotion_particles / drunk_particles.emitting = animation_data["drunk_tier"] > 1 - if is_on_floor(): animation_data["mushroom"] = false - - if not bobber_control: - animation_data["bobber_position"] = Vector3(bobber_hpos.x, bobber_vpos, bobber_hpos.z) - else : - var pos = global_transform.origin + ( - rod_cast_dist * global_transform.basis.z) - pos.y = bobber_vpos + sin(OS.get_ticks_msec() * 0.002) * 0.05 - animation_data["bobber_position"] = lerp(animation_data["bobber_position"], pos, 0.2) - -func _process_animation(): - var anim_lerp = 0.4 - - var emote_type = 0 - if animation_data["emoting"]: emote_type = 1 - if animation_data["emote_full"]: emote_type = 2 - - anim_tree.set("parameters/emote_full/blend_amount", lerp(anim_tree.get("parameters/emote_full/blend_amount"), float(emote_type == 2), anim_lerp)) - if anim_tree.get("parameters/emote_full/blend_amount") < 0.1 and emote_type != 2: anim_tree.set("parameters/emote_full/blend_amount", 0.0) - anim_tree.set("parameters/emote_half/blend_amount", lerp(anim_tree.get("parameters/emote_half/blend_amount"), float(emote_type == 1), anim_lerp)) - if anim_tree.get("parameters/emote_half/blend_amount") < 0.1 and emote_type != 1: anim_tree.set("parameters/emote_half/blend_amount", 0.0) - - anim_tree.set("parameters/arms/blend_amount", lerp(anim_tree.get("parameters/arms/blend_amount"), float( not animation_data["emoting"]), anim_lerp)) - anim_tree.set("parameters/movement/blend_amount", lerp(anim_tree.get("parameters/movement/blend_amount"), float(animation_data["moving"]), anim_lerp)) - anim_tree.set("parameters/run_blend/blend_amount", lerp(anim_tree.get("parameters/run_blend/blend_amount"), float(animation_data["sprinting"]) - float(animation_data["sneaking"]), anim_lerp)) - anim_tree.set("parameters/dive/blend_amount", lerp(anim_tree.get("parameters/dive/blend_amount"), float(animation_data["diving"]), anim_lerp)) - anim_tree.set("parameters/arm_blend/blend_position", float(animation_data["arm_value"])) - anim_tree.set("parameters/sitting/blend_amount", lerp(anim_tree.get("parameters/sitting/blend_amount"), float(animation_data["sitting"]), anim_lerp)) - anim_tree.set("parameters/thinking/blend_amount", lerp(anim_tree.get("parameters/thinking/blend_amount"), float(animation_data["busy"]), anim_lerp)) - anim_tree.set("parameters/land/blend_amount", lerp(anim_tree.get("parameters/land/blend_amount"), float(animation_data["land"]), anim_lerp)) - anim_tree.set("parameters/talking/blend_amount", lerp(anim_tree.get("parameters/talking/blend_amount"), float(animation_data["talking"]), anim_lerp)) - anim_tree.set("parameters/runmodif/scale", animation_data["run_mult"]) - anim_tree.set("parameters/walkmodif/scale", animation_data["walk_mult"]) - anim_tree.set("parameters/emote_time/scale", animation_data["emote_timescale"]) - anim_tree.set("parameters/emote_timeb/scale", animation_data["emote_timescale"]) - - face._show_blush(animation_data["drunk_tier"] > 1) - if animation_data["caught_item"] != caught_item: - caught_item = animation_data["caught_item"] - _update_caught_item(animation_data["caught_item"]) - - if item_scene: - item_scene.item_bend = lerp(item_scene.item_bend, animation_data["item_bend"], 0.4) - bobber_line.end_anchor = item_scene.get_node(item_scene.hotspot_node).global_transform.origin - bobber_line.y_drop = - 1.5 + ((animation_data["recent_reel"] / 15.0) * 0.5) - if animation_data["caught_fish"]: bobber_line.y_drop = 0 - if bobber.visible: bobber.global_transform.origin = animation_data["bobber_position"] + Vector3(0, (0.0 if not animation_data["caught_fish"] else - 0.3), 0) - bobber.visible = animation_data["bobber_visible"] - bobber_line.active = bobber.visible - - - if animation_data["player_scale"] != scale.y: - scale = animation_data["player_scale"] * Vector3.ONE - scale.y *= animation_data["player_scale_y"] - - bobber_line.line_scale = animation_data["player_scale"] - - ripples.visible = animation_data["state"] == STATES.FISHING - var rip_anim = "default" if animation_data["recent_reel"] <= 1.0 else "wake" - if ripples.animation != rip_anim: ripples.animation = rip_anim - - var root = anim_tree.tree_root - var node = root.get_node("emote_anim") - var node_b = root.get_node("emote_anim_b") - if node.animation != animation_data["emote"]: - anim_tree.set("parameters/emote_sync/seek_position", 0.0) - anim_tree.set("parameters/emote_half_sync/seek_position", 0.0) - node.set_animation(animation_data["emote"]) - node_b.set_animation(animation_data["emote"]) - - $"%head_alert".visible = animation_data["alert"] - - tail.sitting = animation_data["sitting"] - tail.diving = animation_data["diving"] - tail.motion = float(animation_data["moving"]) - tail.wagging = animation_data["wagging"] - - - if animation_data["back_bend"] != 0.0: - var pose = skeleton.get_bone_pose(1) - pose = pose.rotated(Vector3(1, 0, 0), animation_data["back_bend"]) - skeleton.set_bone_custom_pose(1, pose) - else : - skeleton.set_bone_custom_pose(1, Transform()) - -func _enter_animation(anim_name, loop = false, _locked = true, state_enter = - 1, full_anim = true, timescale = 1.0): - if anim_name == animation_data["emote"]: return - diving = false - - animation_data["emote_timescale"] = timescale - - - emote_full = full_anim - emote_locked = _locked - emote_looping = loop - buffer_state = state_enter if not emote_looping else - 1 - if emote_looping: _enter_state(state_enter) - animation_data["emote"] = anim_name - animation_timer = 0 - emoting = true - -func _exit_animation(): - emit_signal("_animation_finished") - emoting = false - emote_full = false - emote_locked = false - emote_looping = false - animation_data["emote"] = "" - -func _update_held_item(new): - if new.empty() or held_item == new: return - - held_item = new - var item_data = Globals.item_data[new["id"]]["file"] - var alt_scale_mult = 1.0 - - - item_sprite.texture = item_data.icon.duplicate() if (item_data.show_item and not item_data.show_scene) else null - - - - if is_instance_valid(item_scene): item_scene.queue_free() - item_scene = null - if item_data.show_scene and item_data.item_scene: - item_scene = item_data.item_scene.instance() - hand_bone.add_child(item_scene) - - var scale_mult = 0.07 - clamp(new["size"] * 0.01, 0.01, 0.061) - var item_scale = 1.0 if not item_data.uses_size else new["size"] * scale_mult - item_scale *= alt_scale_mult - item_sprite.scale = Vector3(item_scale, item_scale, item_scale) - - - var y = 0.0 - var offs = 0.0 - var back_bend = 0.0 - if item_data.uses_size: - y = clamp(item_scale * item_scale * 0.08, 0.0, 0.36) - offs = clamp(item_scale * item_scale, 0.0, 16.0) - back_bend = clamp(item_scale * item_scale, 0.0, 55.0) - - item_sprite.translation.y = y - item_sprite.offset.y = item_data.hold_offset + offs - - - $body / player_body / Armature / Skeleton / BoneAttachment / Spatial.rotation_degrees = Vector3(0.0, 0.0, back_bend * 0.7) - - item_sprite.translation.z = 0.0 - item_sprite.vel = 0.0 - item_sprite.mult = clamp(item_scale * 3.5, 0.0, 1.2) if item_data.category == "fish" and item_data.alive else 0.0 - - item_sprite.modulate = Color("#ffffff") - item_sprite.opacity = 1.0 - for child in item_sprite.get_children(): child.emitting = false - - if PlayerData.QUALITY_DATA.has(new["quality"]): - item_sprite.modulate = Color(PlayerData.QUALITY_DATA[new["quality"]]["mod"]) - item_sprite.opacity = PlayerData.QUALITY_DATA[new["quality"]]["op"] - if PlayerData.QUALITY_DATA[new["quality"]]["particle"] > - 1: item_sprite.get_child(PlayerData.QUALITY_DATA[new["quality"]]["particle"]).emitting = true - - animation_data["arm_value"] = item_data.arm_value - animation_data["back_bend"] = deg2rad( - back_bend) - -func _update_caught_item(new): - if new.empty(): - caught_fish.texture = null - return - caught_item = new - - var item_data = Globals.item_data[new["id"]]["file"] - caught_fish.texture = item_data.icon.duplicate() if item_data.show_item else null - - var item_scale = 1.0 if not item_data.uses_size else new["size"] * 0.01 - caught_fish.scale = Vector3(item_scale, item_scale, item_scale) - -func _bobber_cast(dist, end, splash): - bobber_control = false - var height = dist * 0.4 - height += max(0, global_transform.origin.y - end.y) - - end.y -= 1 - - bobber_hpos = global_transform.origin - bobber_vpos = global_transform.origin.y - yield (get_tree().create_timer(0.4), "timeout") - - var tween = get_tree().create_tween() - - tween.set_trans(1) - tween.set_ease(1) - tween.tween_property(self, "bobber_vpos", end.y + height, dist * 0.05) - tween.set_ease(0) - tween.tween_property(self, "bobber_vpos", end.y - (height * 0.2), dist * 0.05) - if splash: - tween.tween_callback(self, "_bobber_splash") - - - tween.set_trans(1) - tween.set_ease(1) - tween.tween_property(self, "bobber_vpos", end.y + (height * 0.1), (dist * 0.05)) - tween.set_ease(0) - tween.tween_property(self, "bobber_vpos", end.y - (height * 0.05), (dist * 0.1)) - - - tween.set_trans(1) - tween.set_ease(1) - tween.tween_property(self, "bobber_vpos", end.y, (dist * 0.1)) - - var htween = get_tree().create_tween() - htween.set_trans(4) - htween.set_ease(1) - htween.tween_property(self, "bobber_hpos", end + (global_transform.basis.z * 0.5), dist * 0.1) - htween.tween_property(self, "bobber_hpos", end + (global_transform.basis.z * 0.2), dist * 0.15) - htween.tween_property(self, "bobber_hpos", end, dist * 0.1) - - yield (htween, "finished") - bobber_control = true - -func _bobber_retract(): - bobber_control = false - bobber_hpos = bobber.global_transform.origin - bobber_vpos = bobber.global_transform.origin.y - - yield (get_tree().create_timer(0.4), "timeout") - - if retract_splash: _bobber_splash("splashb") - var tween = get_tree().create_tween() - tween.set_trans(1) - tween.set_ease(1) - tween.tween_property(self, "bobber_vpos", global_transform.origin.y + 2.0, 0.3) - tween.set_ease(0) - tween.tween_property(self, "bobber_vpos", global_transform.origin.y, 0.3) - - var htween = get_tree().create_tween() - htween.tween_property(self, "bobber_hpos", global_transform.origin, 0.6) - -func _bobber_splash(sfx = "splash"): - _sync_particle("splash", bobber.global_transform.origin, true) - _sync_sfx(sfx, Vector3(bobber_hpos.x, bobber_vpos, bobber_hpos.z)) - - - - - -func _toggle_sit(exit = false): - if not exit: sitting = not sitting - else : sitting = false - -func _play_emote(emote_id, emotion = ""): - if emote_id == "": return - - if emote_id == "sit": - _toggle_sit() - elif not emote_locked: - _enter_animation(emote_id, false, true) - if emotion != "": - _sync_face_emote(emotion) - - - - - -func _change_cosmetics(): - if cosmetic_data == PlayerData.cosmetics_equipped: return - var new = PlayerData.cosmetics_equipped.duplicate() - if not dead_actor: Network._send_actor_action(actor_id, "_update_cosmetics", [new]) - _update_cosmetics(new) - -func _update_cosmetics(data): - var valid = true - for key in PlayerData.FALLBACK_COSM.keys(): - if not data.keys().has(key): - print("missing key ", key) - valid = false - for key in data.keys(): - if not (data[key] is Array): - if not Globals._cosmetic_exists(data[key]): - print("cosm ", data[key], " does not exist") - valid = false - else : - for c in data[key]: - if not Globals._cosmetic_exists(c): - print("cosm ", data[key], " does not exist") - valid = false - - if not valid: data = PlayerData.FALLBACK_COSM.duplicate() - - cosmetic_data = data - - for child in skeleton.get_children(): - if child.is_in_group("cosmetic"): child.queue_free() - - if data.empty(): return - - title.label = str(Network._get_username_from_id(owner_id)) - title.title = Globals.cosmetic_data[data["title"]]["file"].title - - face._setup_face(data) - var species_id = Globals.cosmetic_data[data.species]["file"].cos_internal_id - var species = _create_cosmetic(data["species"], species_id) - _create_cosmetic(data["undershirt"], species_id) - _create_cosmetic(data["overshirt"], species_id) - _create_cosmetic(data["legs"], species_id) - _create_cosmetic(data["hat"], species_id) - for misc in data["accessory"]: _create_cosmetic(misc, species_id) - - - var pattern = Globals.cosmetic_data[data["pattern"]]["file"] - body_mesh.material_override.set_shader_param("texture_albedo", pattern.body_pattern[0]) - - var primary_color = Globals.cosmetic_data[data["primary_color"]]["file"] - var secondary_color = Globals.cosmetic_data[data["secondary_color"]]["file"] if pattern.body_pattern[0] else Globals.cosmetic_data[data["primary_color"]]["file"] - body_mesh.material_override.set_shader_param("albedo", primary_color.main_color) - body_mesh.material_override.set_shader_param("albedo_secondary", secondary_color.main_color) - - - var tail_data = Globals.cosmetic_data[data["tail"]]["file"] - tail._load_tail(tail_data.mesh, primary_color.main_color) - - if species: - species.material_override.set_shader_param("albedo", primary_color.main_color) - species.material_override.set_shader_param("albedo_secondary", secondary_color.main_color) - - match data["species"]: - "species_cat": species.material_override.set_shader_param("texture_albedo", pattern.body_pattern[1]) - "species_dog": species.material_override.set_shader_param("texture_albedo", pattern.body_pattern[2]) - - if not data.keys().has("bobber") or data["bobber"] == "": data["bobber"] = "bobber_default" - var bobber_file = Globals.cosmetic_data[data["bobber"]]["file"] - bobber_mesh.mesh = bobber_file.mesh - bobber_mesh.set_surface_material(0, bobber_file.material) - if bobber_file.secondary_material: bobber_mesh.set_surface_material(1, bobber_file.secondary_material) - if bobber_file.third_material: bobber_mesh.set_surface_material(2, bobber_file.third_material) - -func _create_cosmetic(id, species_id = 0): - if id == "": return - if not Globals.cosmetic_data.keys().has(id): - print("Failed finding cosmetic: ", id) - return - print("Creating Cosmetic: ", id) - var data = Globals.cosmetic_data[id]["file"] - - if data.scene_replace: - var bone_attach = BoneAttachment.new() - skeleton.add_child(bone_attach) - bone_attach.bone_name = "pelvis" - bone_attach.add_to_group("cosmetic") - - var cosm = data.scene_replace.instance() - bone_attach.add_child(cosm) - return cosm - - var cosm = preload("res://Scenes/Entities/Player/cosmetic_node.tscn").instance() - cosm.mesh = data.mesh - if data.species_alt_mesh.size() > 0: - cosm.mesh = data.species_alt_mesh[species_id] - - cosm.skin = data.mesh_skin - - if not data.material: - cosm.material_override = preload("res://Assets/Shaders/player_skins.tres").duplicate() - cosm.material_override.set_shader_param("albedo", data.main_color) - cosm.material_override.set_shader_param("albedo_secondary", data.main_color) - cosm.material_override.set_shader_param("texture_albedo", null) - else : - - cosm.material_override = null - cosm.set_surface_material(0, data.material) - if data.secondary_material: cosm.set_surface_material(1, data.secondary_material) - - cosm.skeleton = skeleton.get_path() - skeleton.add_child(cosm) - return cosm - - - - - - - - - - - - - - - - - - -func _on_step_timer_timeout(): - if not controlled: return - - - if randf() < 0.03 * drunk_tier and drunk_wander_length <= 0: - drunk_wander_length = randi() % 25 + 5 - drunk_wander_dir = Vector3( - rand_range( - 1, 1), - 0.0, - rand_range( - 1, 1)) - - if state == STATES.FISHING_STRUGGLE: - _sync_particle("small_splash", bobber.global_transform.origin, true) - - if recent_reel > 0 and state == STATES.FISHING: - fishing_update.translation.z = - rod_cast_dist - fishing_update.force_raycast_update() - if fishing_update.is_colliding() and not fishing_update.get_collider().is_in_group("valid_water"): - _enter_state(STATES.FISHING_CANCEL) - - if velocity != Vector3.ZERO: - var vol = 1.6 - if sprinting: vol = 2.8 - elif sneaking: vol = 0.3 - - if is_on_floor() and sprinting: _sync_particle("dust_run", Vector3(0, - 0.95, 0)) - - if is_on_floor() and safe_check.is_colliding() and safe_check.get_collision_normal() == Vector3(0, 1, 0) and not gravity_disable: - if death_counter > 0: death_counter -= 1 - last_valid_pos = global_transform.origin - - PlayerData.player_saved_position = global_transform.origin - - - - - -func _message_sent(text): - - var split = text.split(" ") - for s in split: - match s: - ":(", ":[", "D:", ";_;", ";~;", ":C", ":c": _sync_face_emote("sad") - ":)", ":D", ":]": _sync_face_emote("love") - "xD", "!!!", "<3", "xd", "LMAO", "LOL": _sync_face_emote("happy") - ">:(", "D:<", ">:[": _sync_face_emote("angry") - ":/", ":|": _sync_face_emote("flat") - ":3", ":3c", ">:3c", ">:3": _sync_face_emote("cat") - "O.o", "!?!?", "?!?!", ":o", ":O": _sync_face_emote("surprised") - - var bubble = title._create_speech_bubble(text, PlayerData.voice_speed) - bubble.connect("_letter_said", self, "_sync_talk") - Network._send_actor_action(actor_id, "_sync_create_bubble", [text], false) - -func _sync_talk(letter): - var blacklist = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] - if not blacklist.has(letter.to_lower()): return - - animation_data["talking"] = 0.4 - _talk(letter, PlayerData.voice_pitch) - Network._send_actor_action(actor_id, "_talk", [letter, PlayerData.voice_pitch], false) - -func _talk(letter, pitch = 1.5): - if not in_zone or not visible: return - - face._talk() - sound_manager._construct_voice(letter, "NewVoice", pitch) - -func _sync_face_emote(emotion): - _face_emote(emotion) - Network._send_actor_action(actor_id, "_face_emote", [emotion], false) - -func _sync_create_bubble(text): - title._create_speech_bubble(text) - -func _sync_level_bubble(text): - title._create_level_bubble(text) - $emotion_particles / lvl_particles.restart() - $emotion_particles / lvl_particles2.restart() - -func _face_emote(emotion): - face._emote(emotion, 2.4) - - - - - -func _sync_particle(id, offset = Vector3.ZERO, global = false): - _play_particle(id, offset, global) - Network._send_actor_action(actor_id, "_play_particle", [id, offset, global], false) - -func _play_particle(id, offset, global): - if not PARTICLE_DATA.keys().has(id): return - var p = PARTICLE_DATA[id].instance() - add_child(p) - - if not global: - p.translation = offset - else : - p.set_as_toplevel(true) - p.global_transform.origin = offset - - p.emitting = true - yield (get_tree().create_timer(p.lifetime + 0.1), "timeout") - p.queue_free() - - - - - -func _on_water_detect_area_entered(area): - if gravity_disable: return - if area.is_in_group("water"): - _kill() - -func _kill(skip_anim = false): - if not controlled: return - - death_counter += 1 - if death_counter >= 10: - if not skip_anim: PlayerData._send_notification("too many deaths in a row! sending to spawn...", 1) - else : PlayerData._send_notification("returning to spawn", 1) - - world._enter_zone("main_zone", - 1) - PlayerData.player_saved_zone = "main_zone" - PlayerData.player_saved_zone_owner = - 1 - last_valid_pos = world.map.spawn_position.global_transform.origin - death_counter = 0 - - if state == STATES.FISHING or state == STATES.FISHING_CAST or state == STATES.FISHING_CAST: - _enter_state(STATES.FISHING_CANCEL) - - cam_push = 0.0 - gravity_disable = true - - if not skip_anim: - _enter_animation("drown", true, true) - _sync_sfx("drown") - _sync_particle("splash", global_transform.origin, true) - - SceneTransition._fake_scene_change() - yield (SceneTransition, "_finished") - global_transform.origin = last_valid_pos + Vector3(0, 0.5, 0) - yield (get_tree().create_timer(0.3), "timeout") - gravity_disable = false - _enter_state(0) - _exit_animation() - - - - - -func _consume_item(id): - if state != STATES.DEFAULT: return - _enter_state(STATES.EMOTING) - - consume_on_state_change = held_item["ref"] - _enter_animation("drink", false, true, STATES.CONSUME_ITEM, true) - - var sfx = "drink" - - match id: - "growth": player_scale = clamp(player_scale + 0.4, 0.1, 100) - "shrink": player_scale = clamp(player_scale - 0.1, 0.1, 100) - "revert": - player_scale = 1.0 - drunk_timer = max(drunk_timer - 9000, 0) - sfx = "drink_nocap" - "speed": - boost_timer = 18000 - boost_amt = 1.3 - sfx = "drink_nocap" - "speed_burst": - boost_timer = 900 - boost_amt = 4.0 - sfx = "drink_nocap" - "catch": - catch_drink_timer = 18000 - catch_drink_boost = 1.15 - catch_drink_reel = 1.25 - catch_drink_xp = 1.0 - catch_drink_tier = 1 - catch_drink_gold_add = Vector2(1, 10) - catch_drink_gold_percent = 0.0 - "catch_big": - catch_drink_timer = 18000 - catch_drink_boost = 1.3 - catch_drink_reel = 1.45 - catch_drink_xp = 1.0 - catch_drink_tier = 2 - catch_drink_gold_add = Vector2(10, 50) - catch_drink_gold_percent = 0.25 - "catch_deluxe": - catch_drink_timer = 18000 - catch_drink_boost = 1.3 - catch_drink_reel = 1.45 - catch_drink_xp = 1.25 - catch_drink_tier = 3 - catch_drink_gold_add = Vector2(0, 0) - catch_drink_gold_percent = 0.0 - "beer": - drunk_timer += 9000 - drunk_timer = clamp(drunk_timer, 0, 50000) - "beer_big": - drunk_timer += 42000 - drunk_timer = clamp(drunk_timer, 0, 50000) - sfx = "drink_nocap" - - _sync_sfx(sfx) - - - -func _open_chest(rare = false): - if state != STATES.DEFAULT: return - - consume_on_state_change = held_item["ref"] - _enter_state(STATES.CONSUME_ITEM) - - var cosm = PlayerData._get_unowned_cosmetic() - if cosm != null: PlayerData._unlock_cosmetic(cosm) - else : - PlayerData._send_notification("You found 100 dollars inside the chest!") - PlayerData.money += 100 - -func _open_ringbox(): - if state != STATES.DEFAULT: return - - consume_on_state_change = held_item["ref"] - _enter_state(STATES.CONSUME_ITEM) - - if not PlayerData.cosmetics_unlocked.has("accessory_ring"): PlayerData._unlock_cosmetic("accessory_ring") - else : - PlayerData._send_notification("You already have a ring unlocked... Obtained $1000 instead.") - PlayerData.money += 1000 - - - -func _scratch_off(type): - _enter_state(STATES.GUITAR) - hud._open_minigame("scratch_off", {"type": type}) - var _win = yield (hud, "_minigame_finished") - yield (get_tree().create_timer(0.15), "timeout") - _enter_state(STATES.DEFAULT) - - consume_on_state_change = held_item["ref"] - _enter_state(STATES.CONSUME_ITEM) - - if not _win: - _sync_face_emote("angry") - _sync_sfx("rip") - else : - _sync_face_emote("happy") - - - - - -func _mushroom_bounce(): - if not controlled: return - ignore_snap = 10 - var bounce_horz = 16.0 if direction != Vector3.ZERO else 0.0 - var bounce_vert = 32.0 - gravity_vec = Vector3.ZERO - gravity_vec.x += (direction.normalized() * bounce_horz).x - gravity_vec.z += (direction.normalized() * bounce_horz).z - gravity_vec.y += bounce_vert - animation_data["mushroom"] = true - - - - - -func _sync_sfx(id, position = null, pitch = 1.0, delay = 0.0): - if not controlled: return - if delay > 0.0: yield (get_tree().create_timer(delay), "timeout") - - _play_sfx(id, position, pitch) - Network._send_actor_action(actor_id, "_play_sfx", [id, position, pitch], false) - -func _play_sfx(id, position = null, pitch = 1.0): - if not in_zone or not visible: return - sound_manager._play_sound(id, position, pitch) - print("playing sfx ", id) - -func _process_sounds(): - - - - - if $sound_manager / dive_scrape.playing != animation_data["dive_scrape"]: $sound_manager / dive_scrape.playing = animation_data["dive_scrape"] and in_zone - if $sound_manager / reel_slow.stream_paused == animation_data["reel_slow"]: $sound_manager / reel_slow.stream_paused = not animation_data["reel_slow"] and in_zone - if $sound_manager / reel_fast.playing != animation_data["reel_fast"]: $sound_manager / reel_fast.playing = animation_data["reel_fast"] and in_zone - - - - - -func _on_rain_timer_timeout(): - if not controlled: return - - var rain = false - for child in $raincloud_check.get_overlapping_areas(): - if child.is_in_group("rain_cloud"): - rain = true - - if rain != in_rain: - in_rain = rain - PlayerData.emit_signal("_rain_toggle", in_rain) - - if not in_rain: Network.set_rich_presence("#default") - else : Network.set_rich_presence("#rain") - - - - - -func _wag(): - animation_data["wagging"] = not animation_data["wagging"] - -func _paint(size, color): - if not controlled: return - - var in_zone = false - for area in $paint_node / Area.get_overlapping_areas(): - if area.is_in_group("canvas"): in_zone = true - if not in_zone: PlayerData._send_notification("mouse must be on a drawing zone!", 1) - - $paint_node.size = size - $paint_node.color = color - $paint_node.drawing = true - -func _paint_stop(): - if not controlled: return - $paint_node.drawing = false - PlayerData.emit_signal("_chalk_send") - -func _metal_detect_begin(): - pass - -func _metaldetect_update(): - if not controlled or held_item.id == "": - return - - var idata = Globals.item_data[held_item["id"]]["file"] - if not idata.detect_item: - return - - var alert_level = 0 - for b in $detection_zones / metal_detect_far.get_overlapping_bodies(): - if b.is_in_group("metal_spawn"): - if abs(b.global_transform.origin.y - global_transform.origin.y) > 3.5: continue - alert_level = b.global_transform.origin.distance_to(global_transform.origin) - - metal_detect_alert_level = alert_level - - if alert_level > 0: _metal_detect_beep() - -func _metal_detect_beep(): - var new_cd = ceil(max(metal_detect_alert_level * 0.5, 1)) - - if abs(new_cd - metal_detect_alert_cd) > 4: metal_detect_alert_cd = 0 - - metal_detect_alert_cd -= 1 - if metal_detect_alert_cd > 0: return - - metal_detect_alert_cd = new_cd - - var pitch = max(6.0 - metal_detect_alert_level * 0.3, 0.5) - - $metaldetect_dot.modulate.a = 1.0 - if metal_detect_flop: _sync_sfx("md_beep_slowb", null, pitch) - else : _sync_sfx("md_beep_slow", null, pitch) - metal_detect_flop = not metal_detect_flop - -func _on_metal_detect_consume_body_entered(b): - if not controlled or held_item.id == "": return - - var idata = Globals.item_data[held_item["id"]]["file"] - if not idata.detect_item: return - - if b.is_in_group("metal_spawn"): - b._reveal() - -func _on_image_update_timeout(): - if not controlled or dead_actor: return - _update_held_item(held_item) - Network._send_actor_action(actor_id, "_update_held_item", [held_item], false) - -func _real_step(run = false): - if anim_tree.get("parameters/dive/blend_amount") > 0.2 or anim_tree.get("parameters/movement/blend_amount") < 0.8: return - if not is_on_floor(): return - var sfx = "step" if not run else "step_run" - if boost_amt > 1.0 and boost_timer > 1: sfx = "step_fastrun" - _sync_sfx(sfx) - - - -func _play_guitar(): - _enter_state(STATES.GUITAR) - hud._open_minigame("guitar") - var _win = yield (hud, "_minigame_finished") - yield (get_tree().create_timer(0.15), "timeout") - _enter_state(STATES.DEFAULT) - -func _strum_guitar(string, fret, volume): - _sync_strum(string, fret, volume) - Network._send_actor_action(actor_id, "_sync_strum", [string, fret, volume]) - - animation_data["land"] = clamp(animation_data["land"] + 0.06, 0.0, 0.3) - _sync_face_emote("strum") - if randf() < 0.05: - _sync_particle("music") - -func _sync_strum(string, fret, volume): - if not in_zone or not visible: return - $guitar_sounds.get_child(string)._play_fret(fret, false, volume) - -func _hammer_string(string, fret): - _sync_hammer(string, fret) - Network._send_actor_action(actor_id, "_sync_hammer", [string, fret]) - -func _sync_hammer(string, fret): - if not in_zone or not visible: return - $guitar_sounds.get_child(string)._hammer_fret(fret) - -func _bark(): - if not controlled: return - var bark_id = "bark_dog" - bark_id = { - "species_cat": ["bark_cat", "growl_cat", "whine_cat"], - "species_dog": ["bark_dog", "growl_dog", "whine_dog"], - }[PlayerData.cosmetics_equipped.species] - - var type = 0 - if Input.is_action_pressed("move_sneak"): - _sync_face_emote("growl") - type = 1 - elif Input.is_action_pressed("move_walk"): - _sync_face_emote("whine") - type = 2 - else : - _sync_face_emote("bark") - - bark_id = bark_id[type] - _sync_sfx(bark_id) - -func _kiss(): - if not controlled: return - - animation_data["land"] = animation_data["land"] + 0.2 - _sync_face_emote("kiss") - _sync_sfx("kiss") - _sync_particle("kiss") - -func _punch(type = 0): - if not controlled or item_cooldown > 0: return - item_cooldown = 30 - - animation_data["land"] = animation_data["land"] + 1.0 - for b in $detection_zones / punch.get_overlapping_bodies(): - if b.is_in_group("player") and b != self and not b.controlled: - Network._send_P2P_Packet({"type": "player_punch", "from": global_transform.origin, "player": owner_id, "punch_type": type}, str(b.owner_id), 2) - - _sync_face_emote("punch") - _sync_sfx("punch") - _sync_punch() - Network._send_actor_action(actor_id, "_sync_punch") - -func _sync_punch(): - $emotion_particles / punch_particles.restart() - $emotion_particles / punchb_particles.restart() - -func _punched(from, type): - if not controlled: return - - if OptionsMenu.punchable: return - - var dir = (global_transform.origin - from).normalized() - - ignore_snap = 10 - var bounce_horz = 4.0 - var bounce_vert = 8.0 - - match type: - 0: - bounce_horz = 4.0 - bounce_vert = 8.0 - 1: - bounce_horz = 12.0 - bounce_vert = 24.0 - - gravity_vec = Vector3.ZERO - gravity_vec.x += (dir.normalized() * bounce_horz).x - gravity_vec.z += (dir.normalized() * bounce_horz).z - gravity_vec.y += bounce_vert - - _sync_face_emote("angry") - -func _tambourine(): - _sync_sfx("tambourine") - - animation_data["land"] = clamp(animation_data["land"] + 0.14, 0.0, 0.3) - _sync_face_emote("strum") - if randf() < 0.25: - _sync_particle("music") - -func _on_cosmetic_refresh_timeout(): - if not controlled: return - _refresh_cosmetics() - -func _refresh_cosmetics(): - if not controlled: return - yield (get_tree().create_timer(1.0), "timeout") - var new = PlayerData.cosmetics_equipped.duplicate() - if not dead_actor: Network._send_actor_action(actor_id, "_update_cosmetics", [new]) - -func _return_to_spawn(): - if not controlled: return - death_counter = 11 - _kill(true) - -func _item_removal(ref): - print("Sold Item") - if held_item.keys().has("ref") and held_item["ref"] == ref: _equip_item(PlayerData.FALLBACK_ITEM.duplicate())