Compare commits
26 Commits
24ffdaba5e
...
ui_fixes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea0f3cfd91 | ||
|
|
53e4afa367 | ||
| 2358dc8b53 | |||
| 185b1b4744 | |||
| e86da0c2bc | |||
|
|
f61668c626 | ||
|
|
ccb410d5d6 | ||
|
|
7dc4d524da | ||
|
|
0e1afcab0c | ||
| 5341fdd3f5 | |||
|
|
d58c31ac65 | ||
|
|
48ba1761e0 | ||
|
|
0ce2cc6b04 | ||
| 8ff14f3455 | |||
| 6da7021a58 | |||
| b87be91521 | |||
|
|
9f3acbccf9 | ||
| d06f693088 | |||
| c2b41d31bf | |||
|
|
be78cf09f7 | ||
| 4aaf8e3fd3 | |||
| dc76181cc0 | |||
| 0f7bb6308a | |||
| a944492dbd | |||
| 15f38c096b | |||
|
|
cc7f819628 |
@@ -87,6 +87,8 @@ const RIVER_NEIGHBOUR_OFFSETS: Dictionary = {
|
||||
@export_range(1, 6, 1) var lamppost_search_radius_cells: int = 3
|
||||
##max allowed distance between lamppost pairs
|
||||
@export var lamppost_max_wire_distance: float = 35.0
|
||||
##minimum horizontal distance between generated wires and the railway centerline
|
||||
@export var lamppost_rail_clearance_distance: float = 4.0
|
||||
##if true wire connections blocked by colliders are discarded
|
||||
@export var lamppost_obstacle_check_enabled: bool = true
|
||||
|
||||
@@ -210,6 +212,17 @@ func _physics_process(_delta: float) -> void:
|
||||
last_pos_train = current_pos
|
||||
_refresh_world(current_pos)
|
||||
|
||||
func generate_initial_world_now() -> void:
|
||||
if rail_path == null or rail_path.train_instance == null:
|
||||
return
|
||||
|
||||
var train_pos = rail_path.train_instance.global_position
|
||||
var current_pos = Vector2i(roundi(train_pos.x / chunk_size), roundi(train_pos.z / chunk_size))
|
||||
last_pos_train = current_pos
|
||||
_rebuild_generation_queue(current_pos)
|
||||
_drain_generation_queue_now()
|
||||
_drain_wire_queue_now()
|
||||
|
||||
func collect_all_chunkinfo(root: Node, list: Array[Node]) -> void:
|
||||
if root == null: return
|
||||
|
||||
@@ -533,6 +546,20 @@ func _drain_generation_queue() -> void:
|
||||
pending_generation_cells.clear()
|
||||
pending_generation_cursor = 0
|
||||
|
||||
func _drain_generation_queue_now() -> void:
|
||||
while pending_generation_cursor < pending_generation_cells.size():
|
||||
var grid_pos: Vector2i = pending_generation_cells[pending_generation_cursor]
|
||||
pending_generation_cursor += 1
|
||||
if board.has(grid_pos):
|
||||
continue
|
||||
|
||||
var is_obstacle = _register_cell_with_ray(grid_pos)
|
||||
if not is_obstacle:
|
||||
_add_compatible_biome(grid_pos)
|
||||
|
||||
pending_generation_cells.clear()
|
||||
pending_generation_cursor = 0
|
||||
|
||||
func _drain_cleanup_queue() -> void:
|
||||
var processed: int = 0
|
||||
var start_usec: int = Time.get_ticks_usec()
|
||||
@@ -593,6 +620,22 @@ func _drain_wire_queue() -> void:
|
||||
pending_wire_cells.clear()
|
||||
pending_wire_cursor = 0
|
||||
|
||||
func _drain_wire_queue_now() -> void:
|
||||
while pending_wire_cursor < pending_wire_cells.size():
|
||||
var grid_pos: Vector2i = pending_wire_cells[pending_wire_cursor]
|
||||
pending_wire_cursor += 1
|
||||
pending_wire_lookup.erase(grid_pos)
|
||||
|
||||
if not board.has(grid_pos):
|
||||
continue
|
||||
if not board[grid_pos].get("have_lamppost", false):
|
||||
continue
|
||||
|
||||
_connect_lamppost_wires(grid_pos)
|
||||
|
||||
pending_wire_cells.clear()
|
||||
pending_wire_cursor = 0
|
||||
|
||||
func _generate_pieces_around_train(center: Vector2i) -> void:
|
||||
for x in range(-eye_line, eye_line + 1):
|
||||
for z in range(-eye_line, eye_line + 1):
|
||||
@@ -1423,6 +1466,25 @@ func _get_wire_sample_point(p1: Vector3, p2: Vector3, t: float) -> Vector3:
|
||||
point.y -= gravity
|
||||
return point
|
||||
|
||||
func _is_wire_too_close_to_rail(p1: Vector3, p2: Vector3) -> bool:
|
||||
if rail_path == null or rail_path.curve == null:
|
||||
return false
|
||||
if lamppost_rail_clearance_distance <= 0.0:
|
||||
return false
|
||||
|
||||
var clearance_sq: float = lamppost_rail_clearance_distance * lamppost_rail_clearance_distance
|
||||
var samples: int = 10
|
||||
for i in range(samples + 1):
|
||||
var t: float = float(i) / float(samples)
|
||||
var wire_point: Vector3 = _get_wire_sample_point(p1, p2, t)
|
||||
var rail_local_point: Vector3 = rail_path.to_local(wire_point)
|
||||
var closest_rail_point: Vector3 = rail_path.to_global(rail_path.curve.get_closest_point(rail_local_point))
|
||||
var horizontal_delta := Vector2(wire_point.x - closest_rail_point.x, wire_point.z - closest_rail_point.z)
|
||||
if horizontal_delta.length_squared() < clearance_sq:
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
func _collect_wire_excluded_rids(root: Node, excluded_rids: Array[RID]) -> void:
|
||||
if root == null:
|
||||
return
|
||||
@@ -1441,6 +1503,9 @@ func _get_wire_excluded_rids(excluded_roots: Array) -> Array[RID]:
|
||||
return excluded_rids
|
||||
|
||||
func _is_wire_path_blocked(p1: Vector3, p2: Vector3, excluded_roots: Array = []) -> bool:
|
||||
if _is_wire_too_close_to_rail(p1, p2):
|
||||
return true
|
||||
|
||||
if not lamppost_obstacle_check_enabled:
|
||||
return false
|
||||
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
extends Path3D
|
||||
|
||||
const STEAM_DISTANCE_STAT: String = "stat_distance_km"
|
||||
const DISTANCE_KM_PER_UNIT: float = 0.01
|
||||
const STATION_STOP_GROUP: StringName = &"railway_station"
|
||||
const TRACK_ZERO_SPACING_FIX_DISTANCE: float = 45.0
|
||||
const TRACK_ZERO_SPACING_BLEND_DISTANCE: float = 18.0
|
||||
const TRACK_ZERO_SPACING_SEARCH_EXTRA: float = 35.0
|
||||
const TRACK_ZERO_SPACING_SEARCH_STEP: float = 0.5
|
||||
const TRACK_ZERO_SPACING_TARGET_RATIO: float = 0.97
|
||||
const TRACK_ZERO_SPACING_MIN_DISTANCE: float = 1.0
|
||||
|
||||
enum TrainStartMode { RANDOM_POSITION, SPECIFIED_STATION, SPECIFIED_POSITION }
|
||||
enum TrainFacingDirection { KEEP_PATH_DIRECTION, LOCOMOTIVE_LEFT, LOCOMOTIVE_RIGHT }
|
||||
|
||||
@export_group("Train")
|
||||
##train speed
|
||||
@@ -32,11 +40,24 @@ const STATION_STOP_GROUP: StringName = &"railway_station"
|
||||
##swing of the train during the ran
|
||||
@export_range(0.0, 1.0) var basic_swing: float = 0.1
|
||||
|
||||
@export_group("Train Start")
|
||||
@export_enum("random_position", "specified_station", "specified_position") var train_start_mode: int = TrainStartMode.RANDOM_POSITION
|
||||
@export_range(0, 64, 1, "or_greater") var train_start_stop_index: int = 1
|
||||
@export var train_start_position: float = 0.0
|
||||
@export var train_start_delay_seconds: float = 0.0
|
||||
@export var train_start_after_delay: bool = true
|
||||
@export var train_start_acceleration_seconds: float = 4.0
|
||||
@export_enum("keep_path_direction", "locomotive_left", "locomotive_right") var train_facing_direction: int = TrainFacingDirection.KEEP_PATH_DIRECTION
|
||||
|
||||
@export_group("Rails Bulding")
|
||||
##if true builds visible rail pieces along the Path3D
|
||||
@export var build_track_visuals: bool = true
|
||||
##distance between sleepers of the rails
|
||||
@export var sleepers_distance: float = 1.0
|
||||
##nodel for the sleeper of the rail
|
||||
@export var sleepers_model: PackedScene
|
||||
##if true add procedural rail bars even when sleepers_model is assigned
|
||||
@export var add_procedural_rails_to_sleepers_model: bool = false
|
||||
|
||||
@export_group("Manual Controls")
|
||||
##max speed
|
||||
@@ -84,19 +105,21 @@ var next_stop_index: int = 0
|
||||
var stop_multiply: float = 1.0
|
||||
var is_restarting: bool = false
|
||||
var tween_restart: Tween
|
||||
var environment_config: EnvironmentConfig
|
||||
var wagon_instances: Array[Node3D] = []
|
||||
var wagon_progress_offsets: Array[float] = []
|
||||
var _pending_steam_distance_km: float = 0.0
|
||||
var _initial_is_inmotion: bool = true
|
||||
var _is_photo_mode_active: bool = false
|
||||
var _train_direction_sign: float = 1.0
|
||||
|
||||
func _ready() -> void:
|
||||
randomize()
|
||||
GameState.on_enable_photo_mode_request.connect(func(): _is_photo_mode_active = true)
|
||||
GameState.on_disable_photo_mode_request.connect(func(): _is_photo_mode_active = false)
|
||||
|
||||
_cache_environment_config()
|
||||
_initial_is_inmotion = is_inmotion
|
||||
|
||||
if curve != null and curve.get_baked_length() > 0:
|
||||
if build_track_visuals:
|
||||
build_rails()
|
||||
build_train()
|
||||
_plan_stops()
|
||||
@@ -105,24 +128,6 @@ func _ready() -> void:
|
||||
else:
|
||||
print("WARNING: Draw Path3D for rails!")
|
||||
|
||||
func _cache_environment_config() -> void:
|
||||
var parent_node: Node = get_parent()
|
||||
if parent_node != null:
|
||||
var day_night_node := parent_node.get_node_or_null("DayNight") as EnvironmentManagerRoot
|
||||
if day_night_node != null:
|
||||
environment_config = day_night_node.environment_config
|
||||
return
|
||||
|
||||
var current_scene: Node = get_tree().current_scene
|
||||
if current_scene == null:
|
||||
return
|
||||
|
||||
for child in current_scene.get_children():
|
||||
var environment_manager := child as EnvironmentManagerRoot
|
||||
if environment_manager != null:
|
||||
environment_config = environment_manager.environment_config
|
||||
return
|
||||
|
||||
func _apply_initial_train_start() -> void:
|
||||
if train_instance == null or curve == null:
|
||||
return
|
||||
@@ -131,37 +136,54 @@ func _apply_initial_train_start() -> void:
|
||||
if total_length <= 0.0:
|
||||
return
|
||||
|
||||
if environment_config != null:
|
||||
match environment_config.train_start_from_random_position:
|
||||
EnvironmentConfig.TrainStartMode.RANDOM_POSITION:
|
||||
match train_start_mode:
|
||||
TrainStartMode.RANDOM_POSITION:
|
||||
train_progress = randf() * total_length
|
||||
_update_next_stop_index_from_progress()
|
||||
EnvironmentConfig.TrainStartMode.SPECIFIED_STATION:
|
||||
TrainStartMode.SPECIFIED_STATION:
|
||||
if stop_offset.is_empty():
|
||||
train_progress = wrapf(train_progress, 0.0, total_length)
|
||||
_update_next_stop_index_from_progress()
|
||||
else:
|
||||
var stop_index: int = clampi(environment_config.train_start_stop_index, 0, stop_offset.size() - 1)
|
||||
var stop_index: int = clampi(train_start_stop_index, 0, stop_offset.size() - 1)
|
||||
train_progress = stop_offset[stop_index]
|
||||
_set_next_stop_index_from_current(stop_index)
|
||||
EnvironmentConfig.TrainStartMode.SPECIFIED_POSITION:
|
||||
train_progress = wrapf(environment_config.train_start_position, 0.0, total_length)
|
||||
_update_next_stop_index_from_progress()
|
||||
else:
|
||||
train_progress = wrapf(train_progress, 0.0, total_length)
|
||||
TrainStartMode.SPECIFIED_POSITION:
|
||||
train_progress = wrapf(train_start_position, 0.0, total_length)
|
||||
_update_next_stop_index_from_progress()
|
||||
|
||||
_apply_train_facing_direction(total_length)
|
||||
_update_next_stop_index_from_progress()
|
||||
_snap_train_to_progress()
|
||||
|
||||
func _apply_train_facing_direction(total_length: float) -> void:
|
||||
_train_direction_sign = 1.0
|
||||
if train_facing_direction == TrainFacingDirection.KEEP_PATH_DIRECTION or curve == null:
|
||||
return
|
||||
if total_length <= 0.0:
|
||||
return
|
||||
|
||||
var center_progress: float = wrapf(train_progress, 0.0, total_length)
|
||||
var center_position: Vector3 = to_global(curve.sample_baked(center_progress, true))
|
||||
var forward_progress: float = wrapf(center_progress + 2.0, 0.0, total_length)
|
||||
var forward_position: Vector3 = to_global(curve.sample_baked(forward_progress, true))
|
||||
var forward_direction: Vector3 = forward_position - center_position
|
||||
if forward_direction.length_squared() <= 0.0001 or is_zero_approx(forward_direction.x):
|
||||
return
|
||||
|
||||
var desired_x_sign: float = -1.0 if train_facing_direction == TrainFacingDirection.LOCOMOTIVE_LEFT else 1.0
|
||||
if forward_direction.x * desired_x_sign < 0.0:
|
||||
_train_direction_sign = -1.0
|
||||
|
||||
if not is_zero_approx(train_speed):
|
||||
train_speed = absf(train_speed) * _train_direction_sign
|
||||
|
||||
func _apply_train_start_delay() -> void:
|
||||
if not _initial_is_inmotion:
|
||||
return
|
||||
|
||||
var should_start_after_delay: bool = true
|
||||
var start_delay_seconds: float = 0.0
|
||||
if environment_config != null:
|
||||
should_start_after_delay = environment_config.train_start_after_delay
|
||||
start_delay_seconds = maxf(environment_config.train_start_delay_seconds, 0.0)
|
||||
var should_start_after_delay: bool = train_start_after_delay
|
||||
var start_delay_seconds: float = maxf(train_start_delay_seconds, 0.0)
|
||||
if start_delay_seconds <= 0.0:
|
||||
if not should_start_after_delay:
|
||||
is_inmotion = false
|
||||
@@ -217,13 +239,9 @@ func _snap_train_to_progress() -> void:
|
||||
|
||||
train_progress = wrapf(train_progress, 0.0, total_length)
|
||||
var center_position: Vector3 = to_global(curve.sample_baked(train_progress, true))
|
||||
var prog_forward: float = wrapf(train_progress + 2.0, 0.0, total_length)
|
||||
var forward_position: Vector3 = to_global(curve.sample_baked(prog_forward, true))
|
||||
|
||||
train_instance.global_position = center_position
|
||||
if center_position.distance_to(forward_position) > 0.01:
|
||||
train_instance.look_at(forward_position, Vector3.UP)
|
||||
train_instance.rotate_y(PI)
|
||||
_orient_vehicle_to_track(train_instance, train_progress, total_length)
|
||||
|
||||
if cameras:
|
||||
cameras.global_position = center_position
|
||||
@@ -245,6 +263,7 @@ func build_rails() -> void:
|
||||
|
||||
var total_length = curve.get_baked_length()
|
||||
var piece_number = int(total_length / sleepers_distance)
|
||||
var should_add_procedural_rails: bool = sleepers_model == null or add_procedural_rails_to_sleepers_model
|
||||
|
||||
for i in range(piece_number):
|
||||
var distance = i * sleepers_distance
|
||||
@@ -276,6 +295,7 @@ func build_rails() -> void:
|
||||
sleeper.material_override = mat_wood
|
||||
rail_piece.add_child(sleeper)
|
||||
|
||||
if should_add_procedural_rails:
|
||||
var rail_sx = MeshInstance3D.new()
|
||||
rail_sx.mesh = mesh_rail
|
||||
rail_sx.material_override = mat_iron
|
||||
@@ -353,12 +373,15 @@ func _has_station_near_position(stop_position: Vector3) -> bool:
|
||||
return false
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if _is_photo_mode_active: return
|
||||
if EnvironmentManagerRoot.is_keyboard_input_blocked(get_tree()):
|
||||
return
|
||||
|
||||
if event is InputEventKey and event.pressed and not event.echo:
|
||||
if event.keycode == KEY_T:
|
||||
_goto_next_stop()
|
||||
if event.is_action_pressed("train_horn"):
|
||||
UIEvents.toot_toot.emit(true)
|
||||
#elif event.keycode == KEY_F:
|
||||
#_test_manual_fireworks()
|
||||
|
||||
@@ -396,13 +419,13 @@ func _physics_process(delta: float) -> void:
|
||||
train_move(delta)
|
||||
|
||||
func input_controls_management(delta: float) -> void:
|
||||
if not is_inmotion: return
|
||||
if EnvironmentManagerRoot.is_keyboard_input_blocked(get_tree()): return
|
||||
if Input.is_action_pressed("ui_up"):
|
||||
if not is_inmotion or _is_photo_mode_active: return
|
||||
if Input.is_action_pressed("train_speed_up"):
|
||||
train_speed += manual_acceleration * delta
|
||||
elif Input.is_action_pressed("ui_down"):
|
||||
elif Input.is_action_pressed("train_speed_down"):
|
||||
train_speed -= manual_acceleration * delta
|
||||
elif Input.is_action_pressed("ui_text_backspace"):
|
||||
elif Input.is_action_pressed("train_stop"):
|
||||
train_speed = 0
|
||||
train_speed = clamp(train_speed, speed_min, speed_max)
|
||||
|
||||
@@ -431,7 +454,10 @@ func train_move(delta: float) -> void:
|
||||
stop_multiply = 1.0
|
||||
|
||||
var current_speed = train_speed * stop_multiply
|
||||
train_progress += current_speed * delta
|
||||
var next_progress: float = train_progress + current_speed * delta
|
||||
var wrapped_forward: bool = current_speed > 0.0 and next_progress >= total_length
|
||||
var wrapped_back: bool = current_speed < 0.0 and next_progress < 0.0
|
||||
train_progress = wrapf(next_progress, 0.0, total_length)
|
||||
_track_steam_distance(abs(current_speed) * delta)
|
||||
|
||||
if enable_stops and stop_offset.size() > 0 and has_valid_stop:
|
||||
@@ -443,11 +469,9 @@ func train_move(delta: float) -> void:
|
||||
train_progress = target_offset
|
||||
_execute_stop(current_speed > 0)
|
||||
|
||||
if train_progress > total_length:
|
||||
train_progress -= total_length
|
||||
if wrapped_forward:
|
||||
if stop_offset.size() > 0: next_stop_index = 0
|
||||
elif train_progress < 0:
|
||||
train_progress += total_length
|
||||
elif wrapped_back:
|
||||
if stop_offset.size() > 0: next_stop_index = stop_offset.size() - 1
|
||||
|
||||
var center_position = to_global(curve.sample_baked(train_progress, true))
|
||||
@@ -458,8 +482,7 @@ func train_move(delta: float) -> void:
|
||||
|
||||
if center_position.distance_to(forward_position) > 0.01:
|
||||
train_instance.global_position = center_position
|
||||
train_instance.look_at(forward_position, Vector3.UP)
|
||||
train_instance.rotate_y(PI)
|
||||
_orient_vehicle_to_track(train_instance, train_progress, total_length)
|
||||
|
||||
if cameras:
|
||||
cameras.global_position = center_position
|
||||
@@ -497,28 +520,7 @@ func _track_steam_distance(distance_units: float) -> void:
|
||||
|
||||
# Always track the global distance in our save file (for UI and persistency)
|
||||
GameState.save_data.total_distance_km += distance_units * DISTANCE_KM_PER_UNIT
|
||||
|
||||
# Steam specific logic
|
||||
if not SteamManager.is_on_steam:
|
||||
return
|
||||
|
||||
_pending_steam_distance_km += distance_units * DISTANCE_KM_PER_UNIT
|
||||
var whole_km: int = int(floor(_pending_steam_distance_km))
|
||||
if whole_km <= 0:
|
||||
return
|
||||
|
||||
_pending_steam_distance_km -= float(whole_km)
|
||||
var total_distance_km: int = StatsManager.get_int(STEAM_DISTANCE_STAT) + whole_km
|
||||
StatsManager.set_int(STEAM_DISTANCE_STAT, total_distance_km)
|
||||
_check_distance_achievements(total_distance_km)
|
||||
StatsManager.store()
|
||||
|
||||
#Check achievements
|
||||
func _check_distance_achievements(total_distance_km: int) -> void:
|
||||
if total_distance_km >= 100:
|
||||
AchievementManager.unlock("ACH_DISTANCE_100")
|
||||
if total_distance_km >= 200:
|
||||
AchievementManager.unlock("ACH_DISTANCE_200")
|
||||
StatsManager.add_distance_km(distance_units * DISTANCE_KM_PER_UNIT)
|
||||
|
||||
func _execute_stop(go_forward: bool = true) -> void:
|
||||
if not _find_next_valid_stop(go_forward):
|
||||
@@ -529,6 +531,8 @@ func _execute_stop(go_forward: bool = true) -> void:
|
||||
stop_multiply = 0.0
|
||||
|
||||
var current_stop_index = next_stop_index
|
||||
StatsManager.add_int("stat_stop_number", 1)
|
||||
StatsManager.store()
|
||||
|
||||
_advance_next_stop_index(go_forward)
|
||||
|
||||
@@ -670,6 +674,10 @@ func _snap_wagons_to_progress(total_length: float = 0.0) -> void:
|
||||
if total_length <= 0.0:
|
||||
return
|
||||
|
||||
var previous_progress: float = wrapf(train_progress, 0.0, total_length)
|
||||
var previous_position: Vector3 = to_global(curve.sample_baked(previous_progress, true))
|
||||
var previous_wagon_offset: float = 0.0
|
||||
|
||||
for i in range(wagon_instances.size()):
|
||||
var wagon: Node3D = wagon_instances[i]
|
||||
if not is_instance_valid(wagon):
|
||||
@@ -679,17 +687,101 @@ func _snap_wagons_to_progress(total_length: float = 0.0) -> void:
|
||||
if i < wagon_progress_offsets.size():
|
||||
wagon_offset = wagon_progress_offsets[i]
|
||||
|
||||
var wagon_progress: float = train_progress - wagon_offset
|
||||
var wagon_progress: float = train_progress - wagon_offset * _train_direction_sign
|
||||
var segment_spacing: float = maxf(wagon_offset - previous_wagon_offset, 0.1)
|
||||
|
||||
var vehicle_progress: float = wrapf(wagon_progress, 0.0, total_length)
|
||||
var center_position: Vector3 = to_global(curve.sample_baked(vehicle_progress, true))
|
||||
var prog_forward: float = wrapf(vehicle_progress + 2.0, 0.0, total_length)
|
||||
var forward_position: Vector3 = to_global(curve.sample_baked(prog_forward, true))
|
||||
var zero_spacing_fix_weight: float = _get_zero_spacing_fix_weight(previous_progress, vehicle_progress, total_length)
|
||||
if zero_spacing_fix_weight > 0.0:
|
||||
var target_distance: float = _get_zero_spacing_target_distance(segment_spacing)
|
||||
var corrected_progress: float = _find_zero_spacing_progress(previous_progress, previous_position, segment_spacing, target_distance, total_length)
|
||||
vehicle_progress = _lerp_progress_on_track(vehicle_progress, corrected_progress, zero_spacing_fix_weight, total_length)
|
||||
center_position = to_global(curve.sample_baked(vehicle_progress, true))
|
||||
|
||||
wagon.global_position = center_position
|
||||
if center_position.distance_to(forward_position) > 0.01:
|
||||
wagon.look_at(forward_position, Vector3.UP)
|
||||
wagon.rotate_y(PI)
|
||||
_orient_vehicle_to_track(wagon, vehicle_progress, total_length)
|
||||
|
||||
previous_progress = vehicle_progress
|
||||
previous_position = center_position
|
||||
previous_wagon_offset = wagon_offset
|
||||
|
||||
func _orient_vehicle_to_track(vehicle: Node3D, progress: float, total_length: float) -> void:
|
||||
if vehicle == null or curve == null or total_length <= 0.0:
|
||||
return
|
||||
|
||||
var center_progress: float = wrapf(progress, 0.0, total_length)
|
||||
var center_position: Vector3 = to_global(curve.sample_baked(center_progress, true))
|
||||
var forward_progress: float = wrapf(center_progress + 2.0 * _train_direction_sign, 0.0, total_length)
|
||||
var forward_position: Vector3 = to_global(curve.sample_baked(forward_progress, true))
|
||||
if center_position.distance_to(forward_position) <= 0.01:
|
||||
return
|
||||
|
||||
vehicle.look_at(forward_position, Vector3.UP)
|
||||
vehicle.rotate_y(PI)
|
||||
|
||||
func _get_zero_spacing_fix_weight(previous_progress: float, vehicle_progress: float, total_length: float) -> float:
|
||||
var distance_to_zero: float = minf(
|
||||
_get_progress_distance_to_zero(previous_progress, total_length),
|
||||
_get_progress_distance_to_zero(vehicle_progress, total_length)
|
||||
)
|
||||
var full_fix_distance: float = maxf(TRACK_ZERO_SPACING_FIX_DISTANCE - TRACK_ZERO_SPACING_BLEND_DISTANCE, 0.0)
|
||||
return 1.0 - smoothstep(full_fix_distance, TRACK_ZERO_SPACING_FIX_DISTANCE, distance_to_zero)
|
||||
|
||||
func _get_progress_distance_to_zero(progress: float, total_length: float) -> float:
|
||||
var wrapped_progress: float = wrapf(progress, 0.0, total_length)
|
||||
return minf(wrapped_progress, total_length - wrapped_progress)
|
||||
|
||||
func _get_zero_spacing_target_distance(segment_spacing: float) -> float:
|
||||
return minf(maxf(segment_spacing * TRACK_ZERO_SPACING_TARGET_RATIO, TRACK_ZERO_SPACING_MIN_DISTANCE), segment_spacing)
|
||||
|
||||
func _find_zero_spacing_progress(previous_progress: float, previous_position: Vector3, segment_spacing: float, minimum_distance: float, total_length: float) -> float:
|
||||
var start_distance: float = minf(minimum_distance, segment_spacing)
|
||||
var best_progress: float = wrapf(previous_progress - start_distance * _train_direction_sign, 0.0, total_length)
|
||||
var search_limit: float = minf(maxf(segment_spacing, minimum_distance) + TRACK_ZERO_SPACING_SEARCH_EXTRA, total_length)
|
||||
var search_distance: float = start_distance
|
||||
var previous_search_distance: float = start_distance
|
||||
|
||||
while search_distance <= search_limit:
|
||||
var candidate_progress: float = wrapf(previous_progress - search_distance * _train_direction_sign, 0.0, total_length)
|
||||
var candidate_position: Vector3 = to_global(curve.sample_baked(candidate_progress, true))
|
||||
best_progress = candidate_progress
|
||||
if previous_position.distance_to(candidate_position) >= minimum_distance:
|
||||
if is_equal_approx(search_distance, start_distance):
|
||||
return candidate_progress
|
||||
|
||||
return _refine_zero_spacing_progress(
|
||||
previous_progress,
|
||||
previous_position,
|
||||
previous_search_distance,
|
||||
search_distance,
|
||||
minimum_distance,
|
||||
total_length
|
||||
)
|
||||
|
||||
previous_search_distance = search_distance
|
||||
search_distance += TRACK_ZERO_SPACING_SEARCH_STEP
|
||||
|
||||
return best_progress
|
||||
|
||||
func _refine_zero_spacing_progress(previous_progress: float, previous_position: Vector3, min_search_distance: float, max_search_distance: float, minimum_distance: float, total_length: float) -> float:
|
||||
var low_distance: float = min_search_distance
|
||||
var high_distance: float = max_search_distance
|
||||
|
||||
for i in range(8):
|
||||
var mid_distance: float = (low_distance + high_distance) * 0.5
|
||||
var mid_progress: float = wrapf(previous_progress - mid_distance, 0.0, total_length)
|
||||
var mid_position: Vector3 = to_global(curve.sample_baked(mid_progress, true))
|
||||
if previous_position.distance_to(mid_position) >= minimum_distance:
|
||||
high_distance = mid_distance
|
||||
else:
|
||||
low_distance = mid_distance
|
||||
|
||||
return wrapf(previous_progress - high_distance, 0.0, total_length)
|
||||
|
||||
func _lerp_progress_on_track(from_progress: float, to_progress: float, weight: float, total_length: float) -> float:
|
||||
var wrapped_delta: float = wrapf(to_progress - from_progress + total_length * 0.5, 0.0, total_length) - total_length * 0.5
|
||||
return wrapf(from_progress + wrapped_delta * clampf(weight, 0.0, 1.0), 0.0, total_length)
|
||||
|
||||
func _get_vehicle_length(vehicle: Node3D) -> float:
|
||||
var bounds: AABB = _get_node_local_bounds(vehicle, vehicle)
|
||||
|
||||
@@ -24,8 +24,6 @@ signal camera_changed(camera: Camera3D)
|
||||
var is_zoomed : bool = false
|
||||
var zoom_tween : Tween
|
||||
|
||||
var is_moving_enabled : bool = true
|
||||
|
||||
var is_cinematic_mode : bool = false
|
||||
var cinematic_timer : float = 0.0
|
||||
var cinematic_index : int = 0
|
||||
@@ -34,6 +32,8 @@ var array_camera : Array[Camera3D] = []
|
||||
var initial_pivot_transformation : Transform3D
|
||||
|
||||
func _ready():
|
||||
UIEvents.change_camera_request.connect(on_change_camera_request)
|
||||
|
||||
if pivot:
|
||||
initial_pivot_transformation = pivot.transform
|
||||
|
||||
@@ -46,83 +46,32 @@ func _ready():
|
||||
if camera_iso:
|
||||
set_camera(camera_iso)
|
||||
|
||||
func sync_zoom(new_size: float, new_fov: float, photo_is_zoomed: bool = false) -> void:
|
||||
if camera_iso:
|
||||
if zoom_tween and zoom_tween.is_valid():
|
||||
zoom_tween.kill()
|
||||
|
||||
camera_iso.size = new_size
|
||||
camera_iso.fov = new_fov
|
||||
|
||||
is_zoomed = photo_is_zoomed
|
||||
|
||||
var target_size = zoom_size if is_zoomed else normal_size
|
||||
if not is_equal_approx(camera_iso.size, target_size):
|
||||
zoom_tween = create_tween()
|
||||
zoom_tween.set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
zoom_tween.tween_property(camera_iso, "size", target_size, zoom_time)
|
||||
zoom_tween.parallel().tween_property(camera_iso, "fov", target_size, zoom_time)
|
||||
|
||||
func set_camera(camera: Camera3D):
|
||||
camera.make_current()
|
||||
emit_signal("camera_changed", camera)
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey and event.pressed and not event.echo:
|
||||
func _process(delta: float) -> void:
|
||||
var current_cam = get_viewport().get_camera_3d()
|
||||
var is_photo_mode = current_cam != null and not current_cam in array_camera
|
||||
|
||||
#R-> Reset isometric camera
|
||||
if event.keycode == KEY_R and is_moving_enabled and pivot:
|
||||
pivot.transform = initial_pivot_transformation
|
||||
print("Isometric camera resetted!")
|
||||
return
|
||||
|
||||
#C-> Toggle cinematic mode
|
||||
if event.keycode == KEY_C:
|
||||
is_cinematic_mode = !is_cinematic_mode
|
||||
if is_cinematic_mode:
|
||||
cinematic_timer = 0.0
|
||||
for i in range(array_camera.size()):
|
||||
if array_camera[i].current:
|
||||
cinematic_index = i
|
||||
break
|
||||
print("Cinematic Mode: enabled")
|
||||
else:
|
||||
print("Cinematic Mode: disabled")
|
||||
return
|
||||
|
||||
#Z-> soft zoom
|
||||
if event.keycode == KEY_Z and camera_iso:
|
||||
is_zoomed = !is_zoomed
|
||||
var target_size = zoom_size if is_zoomed else normal_size
|
||||
|
||||
if zoom_tween and zoom_tween.is_valid():
|
||||
zoom_tween.kill()
|
||||
|
||||
zoom_tween = create_tween()
|
||||
zoom_tween.set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
zoom_tween.tween_property(camera_iso, "size", target_size, zoom_time)
|
||||
return
|
||||
|
||||
#manual controls (1-5)
|
||||
var manual_action = false
|
||||
|
||||
if event.keycode == KEY_1 and camera_iso:
|
||||
set_camera(camera_iso)
|
||||
is_moving_enabled = true
|
||||
manual_action = true
|
||||
|
||||
elif event.keycode == KEY_2 and camera_front:
|
||||
set_camera(camera_front)
|
||||
is_moving_enabled = false
|
||||
manual_action = true
|
||||
|
||||
elif event.keycode == KEY_3 and camera_side1:
|
||||
set_camera(camera_side1)
|
||||
is_moving_enabled = false
|
||||
manual_action = true
|
||||
|
||||
elif event.keycode == KEY_4 and camera_side2:
|
||||
set_camera(camera_side2)
|
||||
is_moving_enabled = false
|
||||
manual_action = true
|
||||
|
||||
elif event.keycode == KEY_5 and camera_top:
|
||||
set_camera(camera_top)
|
||||
is_moving_enabled = false
|
||||
manual_action = true
|
||||
|
||||
if manual_action and is_cinematic_mode:
|
||||
is_cinematic_mode = false
|
||||
print("Cinematic Mode: Disabled")
|
||||
|
||||
if is_moving_enabled and pivot:
|
||||
if event is InputEventMouseMotion and Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
|
||||
pivot.rotate_y(deg_to_rad(-event.relative.x * rotation_speed))
|
||||
|
||||
func _process(delta):
|
||||
if not is_photo_mode:
|
||||
if is_cinematic_mode and array_camera.size() > 0:
|
||||
cinematic_timer += delta
|
||||
if cinematic_timer >= change_camera_time:
|
||||
@@ -130,27 +79,57 @@ func _process(delta):
|
||||
cinematic_index = (cinematic_index + 1) % array_camera.size()
|
||||
var next_cam = array_camera[cinematic_index]
|
||||
set_camera(next_cam)
|
||||
is_moving_enabled = (next_cam == camera_iso)
|
||||
|
||||
if not is_moving_enabled or pivot == null:
|
||||
if camera_iso == null or current_cam != camera_iso:
|
||||
return
|
||||
|
||||
var input_dir = Vector3.ZERO
|
||||
if Input.is_key_pressed(KEY_W): input_dir.z -= 1
|
||||
if Input.is_key_pressed(KEY_S): input_dir.z += 1
|
||||
if Input.is_key_pressed(KEY_A): input_dir.x -= 1
|
||||
if Input.is_key_pressed(KEY_D): input_dir.x += 1
|
||||
if Input.is_action_just_pressed("zoom_in"):
|
||||
if is_zoomed == false:
|
||||
return
|
||||
is_zoomed = false
|
||||
var target_size = normal_size
|
||||
|
||||
if input_dir != Vector3.ZERO:
|
||||
input_dir = input_dir.normalized()
|
||||
if zoom_tween and zoom_tween.is_valid():
|
||||
zoom_tween.kill()
|
||||
|
||||
var forward = pivot.transform.basis.z
|
||||
var right = pivot.transform.basis.x
|
||||
forward.y = 0
|
||||
right.y = 0
|
||||
zoom_tween = create_tween()
|
||||
zoom_tween.set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
zoom_tween.tween_property(camera_iso, "size", target_size, zoom_time)
|
||||
zoom_tween.parallel().tween_property(camera_iso, "fov", target_size, zoom_time)
|
||||
|
||||
forward = forward.normalized()
|
||||
right = right.normalized()
|
||||
elif Input.is_action_just_pressed("zoom_out"):
|
||||
if is_zoomed == true:
|
||||
return
|
||||
is_zoomed = true
|
||||
var target_size = zoom_size
|
||||
|
||||
var motion = (forward * input_dir.z + right * input_dir.x)
|
||||
pivot.position += motion * move_speed * delta
|
||||
if zoom_tween and zoom_tween.is_valid():
|
||||
zoom_tween.kill()
|
||||
|
||||
zoom_tween = create_tween()
|
||||
zoom_tween.set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
zoom_tween.tween_property(camera_iso, "size", target_size, zoom_time)
|
||||
zoom_tween.parallel().tween_property(camera_iso, "fov", target_size, zoom_time)
|
||||
|
||||
func on_change_camera_request(camera_index: int) -> void:
|
||||
var next_cam = array_camera[camera_index]
|
||||
set_camera(next_cam)
|
||||
|
||||
#func _unhandled_input(event: InputEvent) -> void:
|
||||
#var current_cam = get_viewport().get_camera_3d()
|
||||
#var is_photo_mode = current_cam != null and not current_cam in array_camera
|
||||
#if is_photo_mode:
|
||||
#return
|
||||
#
|
||||
#if event is InputEventKey and event.pressed and not event.echo:
|
||||
#match event.keycode:
|
||||
#KEY_1:
|
||||
#if array_camera.size() > 0: set_camera(array_camera[0])
|
||||
#KEY_2:
|
||||
#if array_camera.size() > 1: set_camera(array_camera[1])
|
||||
#KEY_3:
|
||||
#if array_camera.size() > 2: set_camera(array_camera[2])
|
||||
#KEY_4:
|
||||
#if array_camera.size() > 3: set_camera(array_camera[3])
|
||||
#KEY_5:
|
||||
#if array_camera.size() > 4: set_camera(array_camera[4])
|
||||
|
||||
@@ -4,6 +4,15 @@ extends Node3D
|
||||
const NOISE_TEXTURE: Texture2D = preload("res://core/daynight/noise.tres")
|
||||
const WEATHER_SHADER: Material = preload("res://core/daynight/weather_overlay.tres")
|
||||
const DYNAMIC_ENVIRONMENT_UPDATES_PER_FRAME: int = 32 #how many update of the environment (apply materials) will be done per frame
|
||||
const FORCE_WEATHER_MATERIAL_PATH_PARTS: PackedStringArray = [
|
||||
"/chunk/material/field.tres",
|
||||
"/chunk/material/grassflat_chunk.tres",
|
||||
"/chunk/material/path_chunk.tres",
|
||||
"/chunk/material/railway_chunk.tres",
|
||||
"/chunk/material/terrain.tres",
|
||||
"/chunk/prop/house/house.tres",
|
||||
"/chunk/prop/house/house_emissiv.tres",
|
||||
]
|
||||
|
||||
@export var environment_config: EnvironmentConfig
|
||||
|
||||
@@ -157,9 +166,17 @@ func _restore_keyboard_action_events() -> void:
|
||||
_blocked_keyboard_events_by_action.clear()
|
||||
|
||||
func _on_tree_node_added(node: Node) -> void:
|
||||
if node.is_in_group("wind_node") or node.is_in_group("weather_node") or node.is_in_group("weather_vegetables_node"):
|
||||
if _should_queue_dynamic_environment_node(node):
|
||||
_queue_dynamic_environment_node(node)
|
||||
|
||||
func _should_queue_dynamic_environment_node(node: Node) -> bool:
|
||||
if node.is_in_group("wind_node"):
|
||||
return true
|
||||
if node.is_in_group("weather_vegetables_node"):
|
||||
return true
|
||||
|
||||
return node is Node3D
|
||||
|
||||
func _queue_dynamic_environment_node(node: Node) -> void:
|
||||
if not is_instance_valid(node):
|
||||
return
|
||||
@@ -205,7 +222,7 @@ func _apply_dynamic_environment_materials(node: Node) -> void:
|
||||
if node.is_in_group("wind_node"):
|
||||
_apply_wind_noise_to_node(node, NOISE_TEXTURE)
|
||||
|
||||
if node.is_in_group("weather_node") or node.is_in_group("weather_vegetables_node"):
|
||||
if node is Node3D:
|
||||
_apply_weather_overlay_to_node(node, _get_weather_overlay_material(node))
|
||||
|
||||
if _should_ignore_weather_overlay(node):
|
||||
@@ -231,11 +248,9 @@ func _apply_wind_noise_to_node(node: Node, noise_tex: Texture2D) -> void:
|
||||
_apply_wind_noise_to_node(child, noise_tex)
|
||||
|
||||
func ApplyWeatherShaderToMaterials():
|
||||
for node in get_tree().get_nodes_in_group("weather_node"):
|
||||
_apply_weather_overlay_to_node(node, _get_weather_overlay_material(node))
|
||||
|
||||
for node in get_tree().get_nodes_in_group("weather_vegetables_node"):
|
||||
_apply_weather_overlay_to_node(node, _get_weather_overlay_material(node))
|
||||
var current_scene := get_tree().current_scene
|
||||
if current_scene != null:
|
||||
_apply_weather_overlay_to_node(current_scene, _get_weather_overlay_material(current_scene))
|
||||
|
||||
func _get_weather_overlay_material(node: Node) -> Material:
|
||||
if not node.is_in_group("weather_overlay_no_noise"):
|
||||
@@ -255,13 +270,21 @@ func _apply_weather_overlay_to_node(node: Node, material: Material) -> void:
|
||||
return
|
||||
|
||||
if node is GeometryInstance3D:
|
||||
if _should_clear_weather_overlay(node) or _geometry_uses_alpha_texture(node):
|
||||
if _geometry_should_never_receive_weather_overlay(node):
|
||||
node.material_overlay = null
|
||||
elif _should_clear_weather_overlay(node) and not _geometry_forces_weather_overlay(node):
|
||||
node.material_overlay = null
|
||||
elif _geometry_uses_alpha_texture(node) or _geometry_should_skip_weather_overlay(node):
|
||||
node.material_overlay = null
|
||||
else:
|
||||
node.material_overlay = material
|
||||
|
||||
var child_material := _get_weather_overlay_material(node)
|
||||
if child_material == WEATHER_SHADER and material == weather_shader_no_noise:
|
||||
child_material = material
|
||||
|
||||
for child in node.get_children():
|
||||
_apply_weather_overlay_to_node(child, material)
|
||||
_apply_weather_overlay_to_node(child, child_material)
|
||||
|
||||
func _clear_weather_overlay_from_node(node: Node) -> void:
|
||||
if node is GeometryInstance3D:
|
||||
@@ -289,11 +312,99 @@ func _geometry_uses_alpha_texture(node: GeometryInstance3D) -> bool:
|
||||
|
||||
return false
|
||||
|
||||
func _geometry_should_never_receive_weather_overlay(node: GeometryInstance3D) -> bool:
|
||||
if node is GPUParticles3D:
|
||||
return true
|
||||
|
||||
var node_name := String(node.name).to_lower()
|
||||
return node_name.contains("cloud") or node_name.contains("fog") or node_name.contains("godray")
|
||||
|
||||
func _geometry_should_skip_weather_overlay(node: GeometryInstance3D) -> bool:
|
||||
if _geometry_forces_weather_overlay(node):
|
||||
return false
|
||||
if _node_name_indicates_water(node):
|
||||
return true
|
||||
|
||||
var has_material: bool = false
|
||||
var all_materials_ignored: bool = true
|
||||
var material_override := node.material_override
|
||||
if material_override != null:
|
||||
has_material = true
|
||||
all_materials_ignored = all_materials_ignored and _material_ignores_weather_overlay(material_override)
|
||||
|
||||
if node is MeshInstance3D:
|
||||
for surface_index in node.get_surface_override_material_count():
|
||||
var surface_material: Material = node.get_surface_override_material(surface_index)
|
||||
if surface_material == null:
|
||||
continue
|
||||
|
||||
has_material = true
|
||||
all_materials_ignored = all_materials_ignored and _material_ignores_weather_overlay(surface_material)
|
||||
|
||||
if node.mesh:
|
||||
for surface_index in node.mesh.get_surface_count():
|
||||
var mesh_material: Material = node.mesh.surface_get_material(surface_index)
|
||||
if mesh_material == null:
|
||||
continue
|
||||
|
||||
has_material = true
|
||||
all_materials_ignored = all_materials_ignored and _material_ignores_weather_overlay(mesh_material)
|
||||
|
||||
return has_material and all_materials_ignored
|
||||
|
||||
func _geometry_forces_weather_overlay(node: GeometryInstance3D) -> bool:
|
||||
if _material_forces_weather_overlay(node.material_override):
|
||||
return true
|
||||
|
||||
if node is MeshInstance3D:
|
||||
for surface_index in node.get_surface_override_material_count():
|
||||
if _material_forces_weather_overlay(node.get_surface_override_material(surface_index)):
|
||||
return true
|
||||
|
||||
if node.mesh:
|
||||
for surface_index in node.mesh.get_surface_count():
|
||||
if _material_forces_weather_overlay(node.mesh.surface_get_material(surface_index)):
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
func _material_forces_weather_overlay(material: Material) -> bool:
|
||||
if material == null:
|
||||
return false
|
||||
|
||||
var resource_path := material.resource_path.to_lower()
|
||||
for path_part in FORCE_WEATHER_MATERIAL_PATH_PARTS:
|
||||
if resource_path.contains(path_part):
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
func _node_name_indicates_water(node: Node) -> bool:
|
||||
var node_name := String(node.name).to_lower()
|
||||
return node_name.begins_with("water") or node_name.contains("/water")
|
||||
|
||||
func _material_ignores_weather_overlay(material: Material) -> bool:
|
||||
if material == null:
|
||||
return false
|
||||
|
||||
var resource_path := material.resource_path.to_lower()
|
||||
if resource_path.contains("/water") or resource_path.contains("water_"):
|
||||
return true
|
||||
if resource_path.contains("/cloud/") or resource_path.contains("cloud"):
|
||||
return true
|
||||
|
||||
var base_material := material as BaseMaterial3D
|
||||
if base_material != null:
|
||||
return base_material.transparency != BaseMaterial3D.TRANSPARENCY_DISABLED or base_material.albedo_color.a < 0.99
|
||||
|
||||
return false
|
||||
|
||||
func _shader_material_uses_alpha_texture(material: ShaderMaterial) -> bool:
|
||||
if material == null or material.shader == null:
|
||||
return false
|
||||
|
||||
return material.shader.code.find("alpha_texture") != -1
|
||||
var shader_code := material.shader.code
|
||||
return shader_code.find("alpha_texture") != -1 or shader_code.find("ALPHA") != -1 or shader_code.find("opacity") != -1
|
||||
|
||||
func _should_ignore_weather_overlay(node: Node) -> bool:
|
||||
return node.is_in_group("weather_overlay_ignore")
|
||||
@@ -316,8 +427,19 @@ func select_day_time(normalized_time: float) -> void:
|
||||
#24:00 1.0000 3.0
|
||||
|
||||
if normalized_time < environment_config.sunrise:
|
||||
#Sunrise: night → morning
|
||||
day_time = 3.0 + (normalized_time / environment_config.sunrise) * 1.0 # 3.0 → 4.0
|
||||
#Sunrise: stay night → night to alba(afternoon) → alba to morning
|
||||
var part = environment_config.sunrise / 3.0
|
||||
if normalized_time < part:
|
||||
# Stay Night
|
||||
day_time = 3.0
|
||||
elif normalized_time < part * 2.0:
|
||||
# Night to Alba (Afternoon)
|
||||
var t = (normalized_time - part) / part
|
||||
day_time = 3.0 - (t * 1.0) # 3.0 → 2.0
|
||||
else:
|
||||
# Alba (Afternoon) to Morning
|
||||
var t = (normalized_time - part * 2.0) / part
|
||||
day_time = 2.0 - (t * 1.0) # 2.0 → 1.0
|
||||
elif normalized_time < environment_config.day:
|
||||
#Morning: morning → afternoon
|
||||
var t: float = (normalized_time - environment_config.sunrise) / (environment_config.day - environment_config.sunrise)
|
||||
@@ -342,10 +464,17 @@ func _update_clouds_lighting(normalized_time: float) -> void:
|
||||
return
|
||||
|
||||
if normalized_time < environment_config.sunrise:
|
||||
var part = environment_config.sunrise / 3.0
|
||||
if normalized_time < part * 2.0:
|
||||
# NOTTE / PRE-ALBA (Colori scuri, nessun rim light solare)
|
||||
cloud_material.set_shader_parameter("cloud_color", Color("1a1c2e"))
|
||||
cloud_material.set_shader_parameter("shadow_color", Color("0d0e17"))
|
||||
cloud_material.set_shader_parameter("rim_color", Color("000000"))
|
||||
else:
|
||||
# ALBA (uguale al tramonto)
|
||||
cloud_material.set_shader_parameter("cloud_color", Color("fdf3e7"))
|
||||
cloud_material.set_shader_parameter("shadow_color", Color("5c537a"))
|
||||
cloud_material.set_shader_parameter("rim_color", Color("ff9e64"))
|
||||
|
||||
elif normalized_time < environment_config.day:
|
||||
# MATTINA / ALBA (Colori che iniziano a scaldarsi)
|
||||
|
||||
@@ -15,6 +15,8 @@ global uniform float global_snow_melt_speed = 0.1;
|
||||
global uniform float global_snow_amount = 0.0;
|
||||
global uniform vec4 global_snow_color = vec4(0.92, 0.96, 1.0, 1.0);
|
||||
global uniform float global_rain_intensity;
|
||||
const float GRASS_FULL_SNOW_START = 0.58;
|
||||
const float GRASS_FULL_SNOW_END = 0.86;
|
||||
|
||||
// --- PARAMETRI ESTETICI ---
|
||||
uniform bool billboard_enabled = true;
|
||||
@@ -141,13 +143,15 @@ void fragment() {
|
||||
float snow_mask = smoothstep(snow_start, 1.0, top_mask) * snow_amount * snow_visibility;
|
||||
snow_mask *= step(0.01, snow_amount);
|
||||
snow_mask = clamp(snow_mask, 0.0, 1.0);
|
||||
float full_snow_mask = smoothstep(GRASS_FULL_SNOW_START, GRASS_FULL_SNOW_END, snow_amount) * step(0.01, snow_visibility);
|
||||
float final_snow_mask = max(snow_mask, full_snow_mask);
|
||||
|
||||
vec3 snow_base_color = max(snow_color.rgb, global_snow_color.rgb);
|
||||
float snow_light = mix(0.82, 1.0, max(v_shade_factor, 0.35));
|
||||
vec3 shaded_snow = clamp(snow_base_color * snow_light, 0.0, 1.0);
|
||||
|
||||
// Mescoliamo il colore variato con la neve
|
||||
vec3 final_albedo = mix(varied_grass_color, shaded_snow, snow_mask);
|
||||
vec3 final_albedo = mix(varied_grass_color, shaded_snow, final_snow_mask);
|
||||
float rain_int = clamp(global_rain_intensity, 0.0, 1.0);
|
||||
final_albedo *= mix(1.0, 1.0 - wetness_darkening, rain_int);
|
||||
float final_roughness = mix(0.02, 0.005, rain_int);
|
||||
|
||||
@@ -13,6 +13,9 @@ global uniform float global_snow_melt_speed = 0.1;
|
||||
global uniform float global_snow_amount = 0.0;
|
||||
global uniform vec4 global_snow_color;
|
||||
global uniform float global_rain_intensity;
|
||||
const float LEAVES_FULL_SNOW_START = 0.96;
|
||||
const float LEAVES_FULL_SNOW_END = 1.0;
|
||||
const float LEAVES_TOP_SNOW_COVERAGE = 0.75;
|
||||
|
||||
uniform sampler2D wind_noise : filter_linear_mipmap;
|
||||
uniform bool billboard_enabled = true;
|
||||
@@ -108,12 +111,14 @@ void fragment() {
|
||||
float snow_amount = pow(get_snow_progress(), 0.55);
|
||||
|
||||
float top_mask = 1.0 - shifted_uv.y;
|
||||
float snow_mask = smoothstep(1.0 - snow_amount * 1.35, 1.08 - snow_amount * 1.35, top_mask) * snow_visibility;
|
||||
float snow_mask = smoothstep(1.0 - snow_amount * LEAVES_TOP_SNOW_COVERAGE, 1.08 - snow_amount * LEAVES_TOP_SNOW_COVERAGE, top_mask) * snow_visibility;
|
||||
snow_mask *= step(0.01, snow_amount);
|
||||
float full_snow_mask = smoothstep(LEAVES_FULL_SNOW_START, LEAVES_FULL_SNOW_END, snow_amount) * clamp(snow_visibility, 0.0, 1.0);
|
||||
float final_snow_mask = max(snow_mask, full_snow_mask);
|
||||
|
||||
float snow_light = mix(0.82, 1.0, max(v_shade_factor, 0.35));
|
||||
vec3 shaded_snow = clamp(global_snow_color.rgb * snow_light, 0.0, 1.0);
|
||||
vec3 final_albedo = mix(v_final_color, shaded_snow, snow_mask);
|
||||
vec3 final_albedo = mix(v_final_color, shaded_snow, final_snow_mask);
|
||||
|
||||
// Rain wetness: darken and make shinier
|
||||
float rain_int = clamp(global_rain_intensity, 0.0, 1.0);
|
||||
|
||||
@@ -17,6 +17,8 @@ global uniform float global_snow_cap_flatness_end = 0.96;
|
||||
global uniform float global_snow_cap_noise_scale = 0.22;
|
||||
global uniform float global_snow_cap_noise_strength = 0.18;
|
||||
const float SNOW_VISUAL_RESPONSE = 0.55;
|
||||
const float FULL_SNOW_VISUAL_START = 0.58;
|
||||
const float FULL_SNOW_VISUAL_END = 0.86;
|
||||
uniform bool snow_noise_enabled = true;
|
||||
uniform float snow_noise_scale : hint_range(0.01, 1.0) = 0.15;
|
||||
uniform float snow_edge_softness : hint_range(0.01, 0.5) = 0.2;
|
||||
@@ -152,10 +154,12 @@ void fragment() {
|
||||
float flat_accumulation = smoothstep(0.0, 0.35, v_snow_cap_mask) * snow_accumulation;
|
||||
float snow_noise_mask = get_snow_noise_mask(world_pos, snow_progress);
|
||||
float snow_variation = mix(0.75, 1.15, noise_val);
|
||||
float snow_coverage = clamp(mix(snow_progress * 0.35, snow_progress * snow_variation, snow_noise_mask) + flat_accumulation * 0.15, 0.0, 1.0);
|
||||
float snow_coverage = clamp(mix(snow_progress * 0.55, snow_progress * snow_variation, snow_noise_mask) + flat_accumulation * 0.2, 0.0, 1.0);
|
||||
float snow_factor = max(snow_edge * snow_coverage, flat_accumulation);
|
||||
float snow_opacity = clamp(snow_factor, 0.0, 1.0);
|
||||
snow_opacity = max(snow_opacity, flat_accumulation * mix(0.45, 0.9, snow_noise_mask));
|
||||
float full_snow_opacity = snow_edge * smoothstep(FULL_SNOW_VISUAL_START, FULL_SNOW_VISUAL_END, snow_progress);
|
||||
snow_opacity = max(snow_opacity, full_snow_opacity);
|
||||
|
||||
float shade = mix(-snow_color_variation, snow_color_variation, noise_val);
|
||||
vec3 snow_albedo = clamp(global_snow_color.rgb + vec3(shade), 0.0, 1.0);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
class_name EnvironmentConfig
|
||||
extends Resource
|
||||
|
||||
enum TrainStartMode { RANDOM_POSITION, SPECIFIED_STATION, SPECIFIED_POSITION }
|
||||
|
||||
@export_group("Day")
|
||||
@export var start_time: float = 0.0 #start time of the day
|
||||
@export var day_duration: float = 300.0 #Duration of a full day cycle in seconds
|
||||
@@ -157,15 +155,6 @@ enum TrainStartMode { RANDOM_POSITION, SPECIFIED_STATION, SPECIFIED_POSITION }
|
||||
@export var godray_spawn_height: float = 5.0 #Y world position where god rays spawn
|
||||
@export var godray_scale: Vector3 = Vector3(2.0, 6.0, 2.0) #Scale of the god ray mesh
|
||||
|
||||
#Train start settings
|
||||
@export_group("Train Start")
|
||||
@export_enum("random_position", "specified_station", "specified_position") var train_start_from_random_position: int = TrainStartMode.RANDOM_POSITION #Train start mode
|
||||
@export_range(0, 64, 1, "or_greater") var train_start_stop_index: int = 1 #Stop index used for the train start when random start is disabled
|
||||
@export var train_start_position: float = 0.0 #Offset on the rail curve used when train_start_from_random_position is specified_position
|
||||
@export var train_start_delay_seconds: float = 0.0 #Seconds the train waits before starting at game launch
|
||||
@export var train_start_after_delay: bool = true #When enabled the train starts after train_start_delay_seconds, otherwise it stays stopped
|
||||
@export var train_start_acceleration_seconds: float = 4.0 #Seconds used to progressively reach normal train speed after launch
|
||||
|
||||
#Snow settings
|
||||
@export_group("Snow")
|
||||
@export var snow_amount: float = 0.0 #Initial snow coverage amount (0.0 = none, 1.0 = full)
|
||||
|
||||
BIN
core/font/DePixelSchmal.ttf
Normal file
36
core/font/DePixelSchmal.ttf.import
Normal file
@@ -0,0 +1,36 @@
|
||||
[remap]
|
||||
|
||||
importer="font_data_dynamic"
|
||||
type="FontFile"
|
||||
uid="uid://d08lffa62cwe4"
|
||||
path="res://.godot/imported/DePixelSchmal.ttf-8ac33b7cef810a277bf67f13d849d16b.fontdata"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/font/DePixelSchmal.ttf"
|
||||
dest_files=["res://.godot/imported/DePixelSchmal.ttf-8ac33b7cef810a277bf67f13d849d16b.fontdata"]
|
||||
|
||||
[params]
|
||||
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
allow_system_fallback=true
|
||||
force_autohinter=false
|
||||
modulate_color_glyphs=false
|
||||
hinting=1
|
||||
subpixel_positioning=4
|
||||
keep_rounding_remainders=true
|
||||
oversampling=0.0
|
||||
Fallbacks=null
|
||||
fallbacks=[]
|
||||
Compress=null
|
||||
compress=true
|
||||
preload=[]
|
||||
language_support={}
|
||||
script_support={}
|
||||
opentype_features={}
|
||||
BIN
core/font/LTMakeup-Regular.otf
Normal file
36
core/font/LTMakeup-Regular.otf.import
Normal file
@@ -0,0 +1,36 @@
|
||||
[remap]
|
||||
|
||||
importer="font_data_dynamic"
|
||||
type="FontFile"
|
||||
uid="uid://d2vn50t5k7xbk"
|
||||
path="res://.godot/imported/LTMakeup-Regular.otf-3aec1bac2ab646ee8d91792b37ffa3b8.fontdata"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/font/LTMakeup-Regular.otf"
|
||||
dest_files=["res://.godot/imported/LTMakeup-Regular.otf-3aec1bac2ab646ee8d91792b37ffa3b8.fontdata"]
|
||||
|
||||
[params]
|
||||
|
||||
Rendering=null
|
||||
antialiasing=1
|
||||
generate_mipmaps=false
|
||||
disable_embedded_bitmaps=true
|
||||
multichannel_signed_distance_field=false
|
||||
msdf_pixel_range=8
|
||||
msdf_size=48
|
||||
allow_system_fallback=true
|
||||
force_autohinter=false
|
||||
modulate_color_glyphs=false
|
||||
hinting=1
|
||||
subpixel_positioning=4
|
||||
keep_rounding_remainders=true
|
||||
oversampling=0.0
|
||||
Fallbacks=null
|
||||
fallbacks=[]
|
||||
Compress=null
|
||||
compress=true
|
||||
preload=[]
|
||||
language_support={}
|
||||
script_support={}
|
||||
opentype_features={}
|
||||
6
core/font/audio_player_theme.tres
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_resource type="Theme" format=3 uid="uid://dib2yjsuiyhl"]
|
||||
|
||||
[ext_resource type="FontFile" uid="uid://d08lffa62cwe4" path="res://core/font/DePixelSchmal.ttf" id="1_svhk7"]
|
||||
|
||||
[resource]
|
||||
default_font = ExtResource("1_svhk7")
|
||||
6
core/font/tooltip_theme.tres
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_resource type="Theme" format=3 uid="uid://cwqdjc6t31a8i"]
|
||||
|
||||
[ext_resource type="FontFile" uid="uid://d2vn50t5k7xbk" path="res://core/font/LTMakeup-Regular.otf" id="1_itbcg"]
|
||||
|
||||
[resource]
|
||||
default_font = ExtResource("1_itbcg")
|
||||
BIN
core/game_menu/assets/page_2/pg_3.png
Normal file
|
After Width: | Height: | Size: 208 KiB |
40
core/game_menu/assets/page_2/pg_3.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dpsyqpi74dnvu"
|
||||
path="res://.godot/imported/pg_3.png-03cc0909b35fe8817a39820d5cb898ba.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_2/pg_3.png"
|
||||
dest_files=["res://.godot/imported/pg_3.png-03cc0909b35fe8817a39820d5cb898ba.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_2/pg_3_vertical.png
Normal file
|
After Width: | Height: | Size: 195 KiB |
40
core/game_menu/assets/page_2/pg_3_vertical.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://decvm18okiuxw"
|
||||
path="res://.godot/imported/pg_3_vertical.png-c2c3e741e77873e5b55455c2f973c775.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_2/pg_3_vertical.png"
|
||||
dest_files=["res://.godot/imported/pg_3_vertical.png-c2c3e741e77873e5b55455c2f973c775.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_2/pg_3_vertical_2.png
Normal file
|
After Width: | Height: | Size: 309 KiB |
40
core/game_menu/assets/page_2/pg_3_vertical_2.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://nqkwsl05pj6t"
|
||||
path="res://.godot/imported/pg_3_vertical_2.png-733981bb73bbd5adfc0b985312448a48.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_2/pg_3_vertical_2.png"
|
||||
dest_files=["res://.godot/imported/pg_3_vertical_2.png-733981bb73bbd5adfc0b985312448a48.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_2/pg_3_vertical_cs.png
Normal file
|
After Width: | Height: | Size: 343 KiB |
40
core/game_menu/assets/page_2/pg_3_vertical_cs.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://nw420tkucw5p"
|
||||
path="res://.godot/imported/pg_3_vertical_cs.png-2d42ea13986f9679ddedd33b2e463769.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_2/pg_3_vertical_cs.png"
|
||||
dest_files=["res://.godot/imported/pg_3_vertical_cs.png-2d42ea13986f9679ddedd33b2e463769.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_3/barretta_regular.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
40
core/game_menu/assets/page_3/barretta_regular.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://culspkef43qfd"
|
||||
path="res://.godot/imported/barretta_regular.png-004551bd2a59af046ec6f59b14c511df.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/barretta_regular.png"
|
||||
dest_files=["res://.godot/imported/barretta_regular.png-004551bd2a59af046ec6f59b14c511df.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_3/button_1_texture.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
40
core/game_menu/assets/page_3/button_1_texture.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://od0hlvkpilqt"
|
||||
path="res://.godot/imported/button_1_texture.png-c83d07b1c1d4bd7bb3af0cf5e59324e0.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/button_1_texture.png"
|
||||
dest_files=["res://.godot/imported/button_1_texture.png-c83d07b1c1d4bd7bb3af0cf5e59324e0.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_3/button_2_texture.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
40
core/game_menu/assets/page_3/button_2_texture.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bfy6ju4p5uu2t"
|
||||
path="res://.godot/imported/button_2_texture.png-05acc1cdd8e1a7438677073a53d6fc60.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/button_2_texture.png"
|
||||
dest_files=["res://.godot/imported/button_2_texture.png-05acc1cdd8e1a7438677073a53d6fc60.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_3/button_3_texture.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
40
core/game_menu/assets/page_3/button_3_texture.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dxms3ts0qh2t5"
|
||||
path="res://.godot/imported/button_3_texture.png-68d6211a327c46ea2d6803fe08d2ca24.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/button_3_texture.png"
|
||||
dest_files=["res://.godot/imported/button_3_texture.png-68d6211a327c46ea2d6803fe08d2ca24.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_3/play_button_2.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
40
core/game_menu/assets/page_3/play_button_2.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://kuqxyqwqdrq0"
|
||||
path="res://.godot/imported/play_button_2.png-c01ddb1aeca349285eb93a0bb8d21b97.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/play_button_2.png"
|
||||
dest_files=["res://.godot/imported/play_button_2.png-c01ddb1aeca349285eb93a0bb8d21b97.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_3/quit_button_2.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
40
core/game_menu/assets/page_3/quit_button_2.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://diqsj3x0ftdo"
|
||||
path="res://.godot/imported/quit_button_2.png-a64c0ab5cbea6b10b86c94631528b175.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/quit_button_2.png"
|
||||
dest_files=["res://.godot/imported/quit_button_2.png-a64c0ab5cbea6b10b86c94631528b175.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/game_menu/assets/page_3/settings_button_2.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
40
core/game_menu/assets/page_3/settings_button_2.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c010wpjb66cmb"
|
||||
path="res://.godot/imported/settings_button_2.png-5ff07ad2e8705a51cc1173bc788b44c9.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/game_menu/assets/page_3/settings_button_2.png"
|
||||
dest_files=["res://.godot/imported/settings_button_2.png-5ff07ad2e8705a51cc1173bc788b44c9.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@@ -2,21 +2,23 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://bnh1y560h55vc" path="res://core/game_menu/audio_option.gd" id="1_orafl"]
|
||||
[ext_resource type="Texture2D" uid="uid://dirbxw8ii87nv" path="res://core/game_menu/assets/page_3/main_volume_button.png" id="2_vudub"]
|
||||
[ext_resource type="Texture2D" uid="uid://s33pbfshxhb5" path="res://core/game_menu/assets/page_3/button_-1.png" id="3_vf41c"]
|
||||
[ext_resource type="Texture2D" uid="uid://c6kgm3fq8521h" path="res://core/game_menu/assets/page_3/barretta.png" id="4_hduhm"]
|
||||
[ext_resource type="Texture2D" uid="uid://dxms3ts0qh2t5" path="res://core/game_menu/assets/page_3/button_3_texture.png" id="3_f3y2u"]
|
||||
[ext_resource type="Texture2D" uid="uid://bfy6ju4p5uu2t" path="res://core/game_menu/assets/page_3/button_2_texture.png" id="4_tj25j"]
|
||||
[ext_resource type="Texture2D" uid="uid://od0hlvkpilqt" path="res://core/game_menu/assets/page_3/button_1_texture.png" id="5_4fmty"]
|
||||
[ext_resource type="Texture2D" uid="uid://culspkef43qfd" path="res://core/game_menu/assets/page_3/barretta_regular.png" id="6_aax0b"]
|
||||
|
||||
[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_f3y2u"]
|
||||
content_margin_left = 0.0
|
||||
content_margin_right = 0.0
|
||||
content_margin_bottom = 0.0
|
||||
texture = ExtResource("4_hduhm")
|
||||
texture = ExtResource("6_aax0b")
|
||||
texture_margin_top = 23.0
|
||||
|
||||
[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_tj25j"]
|
||||
texture = ExtResource("4_hduhm")
|
||||
texture = ExtResource("6_aax0b")
|
||||
|
||||
[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_4fmty"]
|
||||
texture = ExtResource("4_hduhm")
|
||||
texture = ExtResource("6_aax0b")
|
||||
|
||||
[node name="AudioOption" type="VBoxContainer" unique_id=1509773712]
|
||||
custom_minimum_size = Vector2(280, 117)
|
||||
@@ -40,9 +42,9 @@ stretch_mode = 5
|
||||
[node name="HSlider" type="HSlider" parent="." unique_id=1286896253]
|
||||
process_mode = 3
|
||||
layout_mode = 2
|
||||
theme_override_icons/grabber = ExtResource("3_vf41c")
|
||||
theme_override_icons/grabber_highlight = ExtResource("3_vf41c")
|
||||
theme_override_icons/grabber_disabled = ExtResource("3_vf41c")
|
||||
theme_override_icons/grabber = ExtResource("3_f3y2u")
|
||||
theme_override_icons/grabber_highlight = ExtResource("4_tj25j")
|
||||
theme_override_icons/grabber_disabled = ExtResource("5_4fmty")
|
||||
theme_override_styles/slider = SubResource("StyleBoxTexture_f3y2u")
|
||||
theme_override_styles/grabber_area = SubResource("StyleBoxTexture_tj25j")
|
||||
theme_override_styles/grabber_area_highlight = SubResource("StyleBoxTexture_4fmty")
|
||||
|
||||
@@ -16,11 +16,32 @@ func _ready():
|
||||
$%TextureRect.show()
|
||||
else:
|
||||
$%TextureRect.hide()
|
||||
TweenFX.breathe(self, 1)
|
||||
|
||||
|
||||
func _on_pressed() -> void:
|
||||
if locked:
|
||||
return
|
||||
TweenFX.stop_all(self)
|
||||
scale = Vector2.ONE
|
||||
rotation = 0.0
|
||||
modulate.a = 1.0
|
||||
TweenFX.press_rotate(self)
|
||||
|
||||
|
||||
func _on_mouse_entered() -> void:
|
||||
if locked:
|
||||
return
|
||||
TweenFX.stop_all(self)
|
||||
scale = Vector2.ONE
|
||||
rotation = 0.0
|
||||
modulate.a = 1.0
|
||||
TweenFX.breathe(self, 1)
|
||||
|
||||
|
||||
func _on_mouse_exited() -> void:
|
||||
if locked:
|
||||
return
|
||||
TweenFX.stop_all(self)
|
||||
scale = Vector2.ONE
|
||||
rotation = 0.0
|
||||
modulate.a = 1.0
|
||||
|
||||
@@ -80,4 +80,6 @@ mouse_filter = 2
|
||||
texture = ExtResource("3_jqji0")
|
||||
expand_mode = 1
|
||||
|
||||
[connection signal="mouse_entered" from="." to="." method="_on_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"]
|
||||
[connection signal="pressed" from="." to="." method="_on_pressed"]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
extends Control
|
||||
|
||||
signal settings_requested
|
||||
|
||||
const TRAIN_WHISTLE_STREAM: AudioStream = preload("res://tgcc/train/sounds/train_whistle2.mp3")
|
||||
|
||||
@onready var play_button: Button = $%PlayButton
|
||||
@@ -18,6 +20,7 @@ func _ready() -> void:
|
||||
save_button.pressed.connect(_on_save_button_pressed)
|
||||
quit_button.pressed.connect(_on_quit_button_pressed)
|
||||
resume_button.pressed.connect(func(): UIEvents.resume_game_requested.emit())
|
||||
settings_button.pressed.connect(func(): settings_requested.emit())
|
||||
|
||||
func _on_play_button_pressed() -> void:
|
||||
_play_train_horn()
|
||||
|
||||
@@ -6,19 +6,28 @@ func _ready() -> void:
|
||||
GameState.on_game_resumed.connect(_on_game_resumed)
|
||||
|
||||
func show_page() -> void:
|
||||
var tweens = find_children("*", "ContainerTween", true, false)
|
||||
var tweens: Array[ContainerTween] = []
|
||||
for child in find_children("*", "", true, false):
|
||||
if child is ContainerTween:
|
||||
tweens.append(child)
|
||||
for tween in tweens:
|
||||
tween.start_tween()
|
||||
show()
|
||||
|
||||
|
||||
func hide_page() -> void:
|
||||
var tweens = find_children("*", "ContainerTween", true, false)
|
||||
var tweens: Array[ContainerTween] = []
|
||||
for child in find_children("*", "", true, false):
|
||||
if child is ContainerTween:
|
||||
tweens.append(child)
|
||||
for tween in tweens:
|
||||
tween.stop_tween()
|
||||
hide()
|
||||
|
||||
func _on_game_resumed() -> void:
|
||||
var tweens = find_children("*", "ContainerTween", true, false)
|
||||
var tweens: Array[ContainerTween] = []
|
||||
for child in find_children("*", "", true, false):
|
||||
if child is ContainerTween:
|
||||
tweens.append(child)
|
||||
for tween in tweens:
|
||||
tween.stop_tween()
|
||||
|
||||
@@ -33,7 +33,10 @@ flip_h = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 760.0
|
||||
offset_left = 2.0
|
||||
offset_top = 13.0
|
||||
offset_right = 762.0
|
||||
offset_bottom = 13.0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_sfb5f")
|
||||
|
||||
13
core/game_menu/page_2_right.gd
Normal file
@@ -0,0 +1,13 @@
|
||||
extends "res://core/game_menu/page_interactive.gd"
|
||||
|
||||
@onready var coming_soon_texture = $%ComingSoonTexture
|
||||
|
||||
func on_page_opened() -> void:
|
||||
var anim = coming_soon_texture.texture
|
||||
anim.current_frame = 0
|
||||
anim.pause = false
|
||||
|
||||
func on_page_closed() -> void:
|
||||
var anim = coming_soon_texture.texture as AnimatedTexture
|
||||
anim.pause = true
|
||||
anim.current_frame = 0
|
||||
1
core/game_menu/page_2_right.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://pkvsjrnsteuk
|
||||
@@ -1,9 +1,10 @@
|
||||
[gd_scene format=3 uid="uid://clno1ahv2byng"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://0yyr318wl7co" path="res://core/game_menu/page_interactive.gd" id="1_script"]
|
||||
[ext_resource type="Script" uid="uid://pkvsjrnsteuk" path="res://core/game_menu/page_2_right.gd" id="1_71v1w"]
|
||||
[ext_resource type="Texture2D" uid="uid://xfl3ks4dbfaw" path="res://core/game_menu/assets/page_2/achievements_text.png" id="3_4uwhd"]
|
||||
[ext_resource type="Texture2D" uid="uid://drwe2xcnp8vs1" path="res://core/game_menu/assets/page_2/2_dx.png" id="3_msl27"]
|
||||
[ext_resource type="PackedScene" uid="uid://bvw086glfpcba" path="res://core/game_menu/collectible_gallery.tscn" id="5_w0bcg"]
|
||||
[ext_resource type="Texture2D" uid="uid://nw420tkucw5p" path="res://core/game_menu/assets/page_2/pg_3_vertical_cs.png" id="7_71v1w"]
|
||||
[ext_resource type="Texture2D" uid="uid://bx6gsh5uchkge" path="res://core/game_menu/assets/lock.png" id="8_48jk0"]
|
||||
[ext_resource type="Texture2D" uid="uid://vg5y4qgc26ko" path="res://core/game_menu/assets/page_3/coming_soon_01.png" id="8_71v1w"]
|
||||
[ext_resource type="Texture2D" uid="uid://bmatlcouch6jm" path="res://core/game_menu/assets/page_3/coming_soon_02.png" id="9_g7kul"]
|
||||
@@ -14,6 +15,7 @@
|
||||
|
||||
[sub_resource type="AnimatedTexture" id="AnimatedTexture_0x02d"]
|
||||
frames = 5
|
||||
one_shot = true
|
||||
frame_0/texture = ExtResource("8_71v1w")
|
||||
frame_0/duration = 0.15
|
||||
frame_1/texture = ExtResource("9_g7kul")
|
||||
@@ -35,7 +37,7 @@ offset_bottom = -506.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_script")
|
||||
script = ExtResource("1_71v1w")
|
||||
|
||||
[node name="PageBackground" type="TextureRect" parent="." unique_id=1387851649]
|
||||
layout_mode = 1
|
||||
@@ -56,7 +58,10 @@ anchors_preset = 11
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -760.0
|
||||
offset_left = -149.695
|
||||
offset_top = 22.855
|
||||
offset_right = 610.3054
|
||||
offset_bottom = 22.85498
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
@@ -65,9 +70,9 @@ stretch_mode = 2
|
||||
|
||||
[node name="AchievementsText" type="TextureRect" parent="." unique_id=766898810]
|
||||
layout_mode = 0
|
||||
offset_left = 261.0
|
||||
offset_left = 184.0
|
||||
offset_top = 34.5
|
||||
offset_right = 656.0
|
||||
offset_right = 579.0
|
||||
offset_bottom = 105.5
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_4uwhd")
|
||||
@@ -82,6 +87,7 @@ offset_right = 767.0
|
||||
offset_bottom = 539.5
|
||||
|
||||
[node name="LockTexture" type="TextureRect" parent="." unique_id=535700029]
|
||||
visible = false
|
||||
layout_mode = 0
|
||||
offset_left = 342.0
|
||||
offset_top = 153.5
|
||||
@@ -92,12 +98,25 @@ texture = ExtResource("8_48jk0")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="." unique_id=1942592146]
|
||||
[node name="LockTexture2" type="TextureRect" parent="." unique_id=997767159]
|
||||
layout_mode = 0
|
||||
offset_left = 596.0
|
||||
offset_top = 86.0
|
||||
offset_right = 743.0
|
||||
offset_bottom = 233.0
|
||||
offset_left = 129.0
|
||||
offset_top = 122.0
|
||||
offset_right = 643.0
|
||||
offset_bottom = 482.7
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("7_71v1w")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="ComingSoonTexture" type="TextureRect" parent="." unique_id=1942592146]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_left = 387.99997
|
||||
offset_top = 224.00002
|
||||
offset_right = 708.0
|
||||
offset_bottom = 567.0
|
||||
rotation = -0.05235988
|
||||
texture = SubResource("AnimatedTexture_0x02d")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
@@ -32,17 +32,21 @@ flip_h = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 760.0
|
||||
offset_left = 5.3050003
|
||||
offset_top = 78.795
|
||||
offset_right = 765.305
|
||||
offset_bottom = 78.79498
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_jdqrf")
|
||||
stretch_mode = 2
|
||||
|
||||
[node name="SettingsMenu" parent="." unique_id=1402645746 instance=ExtResource("2_settings")]
|
||||
layout_mode = 0
|
||||
anchors_preset = 0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
layout_mode = 1
|
||||
anchor_left = 0.034210525
|
||||
anchor_top = 0.034843206
|
||||
anchor_right = 0.034210525
|
||||
anchor_bottom = 0.034843206
|
||||
offset_left = 68.0
|
||||
offset_top = 24.5
|
||||
offset_right = 692.0
|
||||
|
||||
@@ -36,7 +36,10 @@ anchors_preset = 11
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -760.0
|
||||
offset_left = -235.0
|
||||
offset_top = 398.0
|
||||
offset_right = 525.0
|
||||
offset_bottom = 398.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
@@ -50,10 +53,10 @@ anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -181.5
|
||||
offset_top = -212.0
|
||||
offset_right = 248.5
|
||||
offset_bottom = 212.0
|
||||
offset_left = -193.5
|
||||
offset_top = -217.0
|
||||
offset_right = 236.5
|
||||
offset_bottom = 207.0
|
||||
|
||||
[node name="PlayButton" parent="OptionMenu/VBoxContainer" parent_id_path=PackedInt32Array(537721615, 508055524) index="0" unique_id=1990327704]
|
||||
visible = false
|
||||
|
||||
@@ -6,9 +6,23 @@ func _ready() -> void:
|
||||
manage_pageflip.connect(_on_manage_pageflip)
|
||||
|
||||
func _on_manage_pageflip(give_control: bool) -> void:
|
||||
var tweens = find_children("*", "ContainerTween", true, false)
|
||||
var tweens: Array[ContainerTween] = []
|
||||
for child in find_children("*", "", true, false):
|
||||
if child is ContainerTween:
|
||||
tweens.append(child)
|
||||
for tween in tweens:
|
||||
if give_control:
|
||||
tween.start_tween()
|
||||
else:
|
||||
tween.stop_tween()
|
||||
else:
|
||||
tween.start_tween()
|
||||
|
||||
if give_control:
|
||||
on_page_closed()
|
||||
else:
|
||||
on_page_opened()
|
||||
|
||||
func on_page_opened() -> void:
|
||||
pass
|
||||
|
||||
func on_page_closed() -> void:
|
||||
pass
|
||||
|
||||
@@ -40,6 +40,7 @@ func _on_color_selected(selected_color_picker: TrainColorPicker, material_index:
|
||||
for i in range(color_pickers.size()):
|
||||
if color_pickers[i] == selected_color_picker:
|
||||
_set_selected_color(i, material_index)
|
||||
AchievementManager.unlock("ACH_CHANGE_TRAIN_COLOR")
|
||||
break
|
||||
|
||||
func _apply_train_color(color: Color, material_index: int, color_index: int = 0) -> void:
|
||||
|
||||
@@ -158,4 +158,8 @@ color = Color(0.9098039, 0.6, 0.5529412, 1)
|
||||
|
||||
[node name="ContainerTween" parent="." unique_id=160227524 node_paths=PackedStringArray("targets") instance=ExtResource("10_i2rs1")]
|
||||
unique_name_in_owner = true
|
||||
targets = [null, NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker1"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker2"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker3"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker4"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker5"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker6"), null]
|
||||
targets = [NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker1"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker2"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker3"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker4"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker5"), NodePath("../TextureRect/MarginContainer/HBoxContainer/ColorPicker6")]
|
||||
|
||||
[node name="ContainerTween2" parent="." unique_id=97219846 node_paths=PackedStringArray("targets") instance=ExtResource("10_i2rs1")]
|
||||
unique_name_in_owner = true
|
||||
targets = [NodePath("../TextureRect2/MarginContainer/HBoxContainer2/ColorPicker7"), NodePath("../TextureRect2/MarginContainer/HBoxContainer2/ColorPicker8"), NodePath("../TextureRect2/MarginContainer/HBoxContainer2/ColorPicker9"), NodePath("../TextureRect2/MarginContainer/HBoxContainer2/ColorPicker10"), NodePath("../TextureRect2/MarginContainer/HBoxContainer2/ColorPicker11"), NodePath("../TextureRect2/MarginContainer/HBoxContainer2/ColorPicker12")]
|
||||
|
||||
@@ -42,16 +42,6 @@ func apply_video_settings() -> void:
|
||||
get_viewport().msaa_3d = msaa_mode
|
||||
get_viewport().msaa_2d = Viewport.MSAA_DISABLED
|
||||
|
||||
func apply_train_colors() -> void:
|
||||
if not save_data.train_color_1.is_empty():
|
||||
var mat1: ShaderMaterial = load("res://tgcc/train/Color1_train.tres")
|
||||
if mat1:
|
||||
mat1.set_shader_parameter("albedo_color", Color(save_data.train_color_1))
|
||||
if not save_data.train_color_2.is_empty():
|
||||
var mat2: ShaderMaterial = load("res://tgcc/train/Color2_train.tres")
|
||||
if mat2:
|
||||
mat2.set_shader_parameter("albedo_color", Color(save_data.train_color_2))
|
||||
|
||||
match save_data.window_mode_index:
|
||||
0:
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN)
|
||||
@@ -78,6 +68,16 @@ func apply_train_colors() -> void:
|
||||
)
|
||||
DisplayServer.window_set_position(screen_center - window_half_size)
|
||||
|
||||
func apply_train_colors() -> void:
|
||||
if not save_data.train_color_1.is_empty():
|
||||
var mat1: ShaderMaterial = load("res://tgcc/train/Color1_train.tres")
|
||||
if mat1:
|
||||
mat1.set_shader_parameter("albedo_color", Color(save_data.train_color_1))
|
||||
if not save_data.train_color_2.is_empty():
|
||||
var mat2: ShaderMaterial = load("res://tgcc/train/Color2_train.tres")
|
||||
if mat2:
|
||||
mat2.set_shader_parameter("albedo_color", Color(save_data.train_color_2))
|
||||
|
||||
#encrypted file + binary serialization (standard)
|
||||
func load_game() -> void:
|
||||
if not FileAccess.file_exists(SAVE_PATH):
|
||||
|
||||
@@ -4,7 +4,7 @@ extends Control
|
||||
@onready var option_menu: Control = $%OptionMenu
|
||||
|
||||
func _ready() -> void:
|
||||
option_menu.settings_button.pressed.connect(_on_settings_button_pressed)
|
||||
option_menu.settings_requested.connect(_on_settings_button_pressed)
|
||||
|
||||
|
||||
func _on_settings_button_pressed() -> void:
|
||||
|
||||
47
core/main_menu/sign.gd
Normal file
@@ -0,0 +1,47 @@
|
||||
extends Node3D
|
||||
|
||||
@export var sub_viewport: SubViewport
|
||||
@onready var quad_cartello = $%QuadSign
|
||||
@onready var coll_shape = $%CollisionShape3D
|
||||
|
||||
func _ready() -> void:
|
||||
sub_viewport.transparent_bg = true
|
||||
|
||||
var mat = StandardMaterial3D.new()
|
||||
mat.albedo_texture = sub_viewport.get_texture()
|
||||
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||
|
||||
#fix color
|
||||
#sub_viewport.use_hdr_2d = false
|
||||
#mat.albedo_texture_force_srgb = true
|
||||
#mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
#mat.albedo_color = Color(0.85, 0.85, 0.85, 1.0)
|
||||
|
||||
quad_cartello.material_override = mat
|
||||
|
||||
coll_shape.shape.size = Vector3(2.0, 2.0, 2.0)
|
||||
coll_shape.position.z = 0.0
|
||||
|
||||
|
||||
func _on_area_3d_input_event(camera: Node, event: InputEvent, event_position: Vector3, normal: Vector3, shape_idx: int) -> void:
|
||||
if event is InputEventMouse:
|
||||
var local_cam = quad_cartello.to_local(camera.global_position)
|
||||
var local_hit = quad_cartello.to_local(event_position)
|
||||
var ray_dir = (local_hit - local_cam).normalized()
|
||||
|
||||
if abs(ray_dir.z) < 0.0001: return
|
||||
|
||||
var t = -local_cam.z / ray_dir.z
|
||||
var exact_pos = local_cam + ray_dir * t
|
||||
|
||||
var uv_x = exact_pos.x + 0.5
|
||||
var uv_y = 0.5 - exact_pos.y
|
||||
if uv_x < 0 or uv_x > 1 or uv_y < 0 or uv_y > 1:
|
||||
return
|
||||
|
||||
var viewport_pos = Vector2(uv_x * sub_viewport.size.x, uv_y * sub_viewport.size.y)
|
||||
var ev2d = event.duplicate()
|
||||
ev2d.position = viewport_pos
|
||||
ev2d.global_position = viewport_pos
|
||||
|
||||
sub_viewport.push_input(ev2d)
|
||||
1
core/main_menu/sign.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://duiqgeista384
|
||||
BIN
core/main_scene_ui/assets/audio_player_background.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
40
core/main_scene_ui/assets/audio_player_background.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dlp62v48tori0"
|
||||
path="res://.godot/imported/audio_player_background.png-1675fa2e75631748d14a166a21ea483f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/main_scene_ui/assets/audio_player_background.png"
|
||||
dest_files=["res://.godot/imported/audio_player_background.png-1675fa2e75631748d14a166a21ea483f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/main_scene_ui/assets/audio_player_empty.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
40
core/main_scene_ui/assets/audio_player_empty.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bgrmy57xhg2gj"
|
||||
path="res://.godot/imported/audio_player_empty.png-1b3b0e9bc78b192baac137114b08b7cd.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/main_scene_ui/assets/audio_player_empty.png"
|
||||
dest_files=["res://.godot/imported/audio_player_empty.png-1b3b0e9bc78b192baac137114b08b7cd.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/main_scene_ui/assets/audio_player_wheel.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
40
core/main_scene_ui/assets/audio_player_wheel.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://s8pp2i6bjkps"
|
||||
path="res://.godot/imported/audio_player_wheel.png-5a27c557d9f373382107e3f2bececfee.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/main_scene_ui/assets/audio_player_wheel.png"
|
||||
dest_files=["res://.godot/imported/audio_player_wheel.png-5a27c557d9f373382107e3f2bececfee.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@@ -1,53 +1,91 @@
|
||||
extends Control
|
||||
|
||||
@export var radio: Radio
|
||||
@export var scroll_speed: float = 60.0
|
||||
@export var wheel_speed: float = -2.0
|
||||
|
||||
@onready var track_label: Label = $%TrackLabel
|
||||
@onready var prev_track_icon_button: Button = $%PrevTrackIconButton
|
||||
@onready var play_pause_icon_button: Button = $%PlayPauseIconButton
|
||||
@onready var next_track_icon_button: Button = $%NextTrackIconButton
|
||||
@onready var increase_volume_icon_button: Button = $%IncreaseVolumeIconButton
|
||||
@onready var decrease_volume_icon_button: Button = $%DecreaseVolumeIconButton
|
||||
@onready var prev_track_button: Button = $%PrevTrackButton
|
||||
@onready var play_track_button: Button = $%PlayTrackButton
|
||||
@onready var pause_track_button: Button = $%PauseTrackButton
|
||||
@onready var next_track_button: Button = $%NextTrackButton
|
||||
@onready var increase_volume_button: Button = $%IncreaseVolumeButton
|
||||
@onready var decrease_volume_button: Button = $%DecreaseVolumeButton
|
||||
@onready var left_wheel: TextureRect = $%LeftWheel
|
||||
@onready var right_wheel: TextureRect = $%RightWheel
|
||||
@onready var background: TextureRect = $%Background
|
||||
|
||||
func _ready() -> void:
|
||||
prev_track_icon_button.pressed.connect(_on_prev_track_icon_button_pressed)
|
||||
play_pause_icon_button.pressed.connect(_on_play_pause_icon_button_pressed)
|
||||
next_track_icon_button.pressed.connect(_on_next_track_icon_button_pressed)
|
||||
increase_volume_icon_button.pressed.connect(_on_increase_volume_icon_button_pressed)
|
||||
decrease_volume_icon_button.pressed.connect(_on_decrease_volume_icon_button_pressed)
|
||||
prev_track_button.pressed.connect(_on_prev_track_button_pressed)
|
||||
play_track_button.pressed.connect(_on_play_track_button_pressed)
|
||||
pause_track_button.pressed.connect(_on_pause_track_button_pressed)
|
||||
next_track_button.pressed.connect(_on_next_track_button_pressed)
|
||||
increase_volume_button.pressed.connect(_on_increase_volume_button_pressed)
|
||||
decrease_volume_button.pressed.connect(_on_decrease_volume_button_pressed)
|
||||
if radio:
|
||||
radio.track_changed.connect(_on_radio_track_changed)
|
||||
if radio.stream and radio.stream.resource_path:
|
||||
track_label.text = radio.stream.resource_path.get_file().get_basename().capitalize()
|
||||
play_pause_icon_button.image = play_pause_icon_button.images[1]
|
||||
else:
|
||||
track_label.text = "Unknown Track"
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if radio and radio.playing and not radio.stream_paused:
|
||||
if left_wheel:
|
||||
left_wheel.rotation += wheel_speed * delta
|
||||
if right_wheel:
|
||||
right_wheel.rotation += wheel_speed * delta
|
||||
|
||||
if track_label and track_label.get_parent_control():
|
||||
track_label.position.x += scroll_speed * delta
|
||||
|
||||
var text_width = track_label.get_minimum_size().x
|
||||
|
||||
var text_left_edge = track_label.position.x + (track_label.size.x - text_width) / 2.0
|
||||
|
||||
if text_left_edge > track_label.get_parent_control().size.x:
|
||||
track_label.position.x = -(track_label.size.x + text_width) / 2.0
|
||||
|
||||
func _on_radio_track_changed(track_name: String) -> void:
|
||||
track_label.text = track_name
|
||||
play_pause_icon_button.image = play_pause_icon_button.images[1]
|
||||
|
||||
func _on_prev_track_icon_button_pressed() -> void:
|
||||
func _play_button_tween() -> void:
|
||||
TweenFX.stop_all(background)
|
||||
background.scale = Vector2.ONE
|
||||
background.rotation = 0.0
|
||||
background.modulate.a = 1.0
|
||||
TweenFX.press_rotate(background)
|
||||
|
||||
func _on_prev_track_button_pressed() -> void:
|
||||
if radio:
|
||||
radio.prev_track()
|
||||
_play_button_tween()
|
||||
|
||||
func _on_play_pause_icon_button_pressed() -> void:
|
||||
func _on_play_track_button_pressed() -> void:
|
||||
if radio:
|
||||
if !radio.stream:
|
||||
radio.next_track()
|
||||
else:
|
||||
radio.unpause()
|
||||
_play_button_tween()
|
||||
|
||||
func _on_pause_track_button_pressed() -> void:
|
||||
if radio:
|
||||
if radio.stream:
|
||||
radio.toggle_pause()
|
||||
else:
|
||||
radio.next_track()
|
||||
var play_pause_index = 0 if radio.stream_paused else 1
|
||||
play_pause_icon_button.image = play_pause_icon_button.images[play_pause_index]
|
||||
radio.pause()
|
||||
_play_button_tween()
|
||||
|
||||
func _on_next_track_icon_button_pressed() -> void:
|
||||
func _on_next_track_button_pressed() -> void:
|
||||
if radio:
|
||||
radio.next_track()
|
||||
_play_button_tween()
|
||||
|
||||
func _on_increase_volume_icon_button_pressed() -> void:
|
||||
func _on_increase_volume_button_pressed() -> void:
|
||||
var current_vol = AudioManager.get_audio_bus_volume("Music", 1.0)
|
||||
AudioManager.set_audio_bus_volume("Music", current_vol + 0.1)
|
||||
_play_button_tween()
|
||||
|
||||
func _on_decrease_volume_icon_button_pressed() -> void:
|
||||
func _on_decrease_volume_button_pressed() -> void:
|
||||
var current_vol = AudioManager.get_audio_bus_volume("Music", 1.0)
|
||||
AudioManager.set_audio_bus_volume("Music", current_vol - 0.1)
|
||||
_play_button_tween()
|
||||
|
||||
@@ -1,132 +1,174 @@
|
||||
[gd_scene format=3 uid="uid://dg4f3v0ukpmay"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c4kekqicrv4m8" path="res://core/main_scene_ui/audio_player.gd" id="1_i2mrl"]
|
||||
[ext_resource type="PackedScene" uid="uid://2tqofxxxnvhv" path="res://core/main_scene_ui/icon_button.tscn" id="1_ucnyb"]
|
||||
[ext_resource type="Theme" uid="uid://bg8megpn77mod" path="res://core/font/main_theme.tres" id="2_0koyu"]
|
||||
[ext_resource type="Texture2D" uid="uid://cqx45c744325t" path="res://core/main_scene_ui/assets/button_audio_previous.png" id="3_netjv"]
|
||||
[ext_resource type="Texture2D" uid="uid://bdnevc7ewu5qe" path="res://core/main_scene_ui/assets/button_audio_play.png" id="4_urwwp"]
|
||||
[ext_resource type="Texture2D" uid="uid://d2ft1kea45hec" path="res://core/main_scene_ui/assets/button_audio_next.png" id="5_0koyu"]
|
||||
[ext_resource type="Texture2D" uid="uid://vx7wa6afj4ri" path="res://core/main_scene_ui/assets/button_audio_pause.png" id="5_urwwp"]
|
||||
[ext_resource type="Texture2D" uid="uid://b0mir57askv7j" path="res://core/main_scene_ui/assets/button_audio_on.png" id="6_xv7rp"]
|
||||
[ext_resource type="Texture2D" uid="uid://dbxhxvvg4s8ru" path="res://core/main_scene_ui/assets/button_audio_off.png" id="7_7ib2x"]
|
||||
[ext_resource type="Texture2D" uid="uid://dlp62v48tori0" path="res://core/main_scene_ui/assets/audio_player_background.png" id="3_e87kc"]
|
||||
[ext_resource type="Texture2D" uid="uid://s8pp2i6bjkps" path="res://core/main_scene_ui/assets/audio_player_wheel.png" id="4_n5r1o"]
|
||||
[ext_resource type="Theme" uid="uid://dib2yjsuiyhl" path="res://core/font/audio_player_theme.tres" id="5_e87kc"]
|
||||
[ext_resource type="Texture2D" uid="uid://bgrmy57xhg2gj" path="res://core/main_scene_ui/assets/audio_player_empty.png" id="10_xv7rp"]
|
||||
|
||||
[node name="AudioPlayer" type="Control" unique_id=425192018]
|
||||
custom_minimum_size = Vector2(241, 179)
|
||||
layout_mode = 3
|
||||
anchor_right = 0.15208334
|
||||
anchor_bottom = 0.10925926
|
||||
anchor_right = 0.12552084
|
||||
anchor_bottom = 0.16574074
|
||||
offset_right = -241.00002
|
||||
offset_bottom = -179.0
|
||||
pivot_offset_ratio = Vector2(0.5, 0.5)
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_i2mrl")
|
||||
scroll_speed = 30.0
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="." unique_id=1300382168]
|
||||
[node name="TextureRect" type="TextureRect" parent="." unique_id=1764222864]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
pivot_offset_ratio = Vector2(0.5, 0.5)
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("10_xv7rp")
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer" unique_id=1923985665]
|
||||
layout_mode = 2
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="TrackLabel" type="Label" parent="HBoxContainer/VBoxContainer" unique_id=1430240022]
|
||||
[node name="Background" type="TextureRect" parent="." unique_id=1772744681]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
theme = ExtResource("2_0koyu")
|
||||
theme_override_font_sizes/font_size = 24
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
pivot_offset_ratio = Vector2(0.5, 0.5)
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("3_e87kc")
|
||||
stretch_mode = 2
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="LeftWheel" type="TextureRect" parent="Background" unique_id=1719200441]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -51.5
|
||||
offset_top = -47.5
|
||||
offset_right = -20.5
|
||||
offset_bottom = -16.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
pivot_offset_ratio = Vector2(0.5, 0.5)
|
||||
texture = ExtResource("4_n5r1o")
|
||||
stretch_mode = 2
|
||||
|
||||
[node name="RightWheel" type="TextureRect" parent="Background" unique_id=960520776]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = 18.5
|
||||
offset_top = -47.5
|
||||
offset_right = 49.5
|
||||
offset_bottom = -16.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
pivot_offset_ratio = Vector2(0.5, 0.5)
|
||||
texture = ExtResource("4_n5r1o")
|
||||
stretch_mode = 2
|
||||
|
||||
[node name="DisplayContainer" type="Control" parent="." unique_id=1280352652]
|
||||
clip_contents = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 7
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -85.5
|
||||
offset_top = -84.0
|
||||
offset_right = 83.5
|
||||
offset_bottom = -52.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
|
||||
[node name="TrackLabel" type="Label" parent="DisplayContainer" unique_id=441671750]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme = ExtResource("5_e87kc")
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "Uknown Track"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="IconButtonsRow" type="HBoxContainer" parent="HBoxContainer/VBoxContainer" unique_id=1734127019]
|
||||
[node name="MarginContainer" type="MarginContainer" parent="." unique_id=1829043318]
|
||||
layout_mode = 1
|
||||
anchors_preset = 12
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = -40.0
|
||||
offset_bottom = -8.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
mouse_filter = 2
|
||||
theme_override_constants/margin_left = 24
|
||||
theme_override_constants/margin_right = 24
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer" unique_id=1300382168]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
mouse_filter = 2
|
||||
theme_override_constants/separation = 0
|
||||
alignment = 1
|
||||
|
||||
[node name="PrevTrackIconButton" parent="HBoxContainer/VBoxContainer/IconButtonsRow" unique_id=1750448019 instance=ExtResource("1_ucnyb")]
|
||||
[node name="PrevTrackButton" type="Button" parent="MarginContainer/HBoxContainer" unique_id=1132927190]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(32, 0)
|
||||
layout_mode = 2
|
||||
image = ExtResource("3_netjv")
|
||||
size_flags_horizontal = 4
|
||||
flat = true
|
||||
|
||||
[node name="Texture" parent="HBoxContainer/VBoxContainer/IconButtonsRow/PrevTrackIconButton" index="0" unique_id=1071359322]
|
||||
anchors_preset = -1
|
||||
offset_left = 116.66667
|
||||
offset_top = 131.3789
|
||||
offset_right = -116.666664
|
||||
offset_bottom = -131.3789
|
||||
texture = ExtResource("3_netjv")
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="PlayPauseIconButton" parent="HBoxContainer/VBoxContainer/IconButtonsRow" unique_id=1533336956 instance=ExtResource("1_ucnyb")]
|
||||
[node name="PlayTrackButton" type="Button" parent="MarginContainer/HBoxContainer" unique_id=445406105]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(32, 0)
|
||||
layout_mode = 2
|
||||
image = ExtResource("4_urwwp")
|
||||
images = Array[Texture]([ExtResource("4_urwwp"), ExtResource("5_urwwp")])
|
||||
size_flags_horizontal = 5
|
||||
flat = true
|
||||
|
||||
[node name="Texture" parent="HBoxContainer/VBoxContainer/IconButtonsRow/PlayPauseIconButton" index="0" unique_id=1071359322]
|
||||
anchors_preset = -1
|
||||
offset_left = 116.66667
|
||||
offset_top = 131.3789
|
||||
offset_right = -116.666664
|
||||
offset_bottom = -131.3789
|
||||
texture = ExtResource("4_urwwp")
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="NextTrackIconButton" parent="HBoxContainer/VBoxContainer/IconButtonsRow" unique_id=2108379455 instance=ExtResource("1_ucnyb")]
|
||||
[node name="NextTrackButton" type="Button" parent="MarginContainer/HBoxContainer" unique_id=1836743157]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(32, 0)
|
||||
layout_mode = 2
|
||||
image = ExtResource("5_0koyu")
|
||||
size_flags_horizontal = 5
|
||||
flat = true
|
||||
|
||||
[node name="Texture" parent="HBoxContainer/VBoxContainer/IconButtonsRow/NextTrackIconButton" index="0" unique_id=1071359322]
|
||||
anchors_preset = -1
|
||||
offset_left = 116.66667
|
||||
offset_top = 131.3789
|
||||
offset_right = -116.666664
|
||||
offset_bottom = -131.3789
|
||||
texture = ExtResource("5_0koyu")
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="VBoxContainer2" type="VBoxContainer" parent="HBoxContainer" unique_id=1843266535]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="IncreaseVolumeIconButton" parent="HBoxContainer/VBoxContainer2" unique_id=1788399963 instance=ExtResource("1_ucnyb")]
|
||||
[node name="PauseTrackButton" type="Button" parent="MarginContainer/HBoxContainer" unique_id=1151045878]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(40, 40)
|
||||
custom_minimum_size = Vector2(32, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 3
|
||||
image = ExtResource("6_xv7rp")
|
||||
size_flags_horizontal = 5
|
||||
flat = true
|
||||
|
||||
[node name="Texture" parent="HBoxContainer/VBoxContainer2/IncreaseVolumeIconButton" index="0" unique_id=1071359322]
|
||||
custom_minimum_size = Vector2(40, 40)
|
||||
offset_left = 106.66667
|
||||
offset_top = 107.01433
|
||||
offset_right = -106.666664
|
||||
offset_bottom = -107.014336
|
||||
texture = ExtResource("6_xv7rp")
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="DecreaseVolumeIconButton" parent="HBoxContainer/VBoxContainer2" unique_id=399629327 instance=ExtResource("1_ucnyb")]
|
||||
[node name="IncreaseVolumeButton" type="Button" parent="MarginContainer/HBoxContainer" unique_id=809451843]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(40, 40)
|
||||
custom_minimum_size = Vector2(32, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
size_flags_vertical = 3
|
||||
image = ExtResource("7_7ib2x")
|
||||
size_flags_horizontal = 5
|
||||
flat = true
|
||||
|
||||
[node name="Texture" parent="HBoxContainer/VBoxContainer2/DecreaseVolumeIconButton" index="0" unique_id=1071359322]
|
||||
custom_minimum_size = Vector2(40, 40)
|
||||
offset_left = 106.66667
|
||||
offset_top = 107.01433
|
||||
offset_right = -106.666664
|
||||
offset_bottom = -107.014336
|
||||
texture = ExtResource("7_7ib2x")
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[editable path="HBoxContainer/VBoxContainer/IconButtonsRow/PrevTrackIconButton"]
|
||||
[editable path="HBoxContainer/VBoxContainer/IconButtonsRow/PlayPauseIconButton"]
|
||||
[editable path="HBoxContainer/VBoxContainer/IconButtonsRow/NextTrackIconButton"]
|
||||
[editable path="HBoxContainer/VBoxContainer2/IncreaseVolumeIconButton"]
|
||||
[editable path="HBoxContainer/VBoxContainer2/DecreaseVolumeIconButton"]
|
||||
[node name="DecreaseVolumeButton" type="Button" parent="MarginContainer/HBoxContainer" unique_id=1399480885]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(32, 0)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 5
|
||||
flat = true
|
||||
|
||||
@@ -12,6 +12,9 @@ class_name IconButton
|
||||
@export var images: Array[Texture]
|
||||
@export var apply_texture_on_selection: bool = true
|
||||
|
||||
@export var enable_tooltip: bool = false
|
||||
@export var tooltip_scene: PackedScene
|
||||
@export var tooltip_image: Texture
|
||||
|
||||
func _ready():
|
||||
if image != null and has_node("%Texture"):
|
||||
@@ -36,3 +39,15 @@ func _on_pressed() -> void:
|
||||
rotation = 0.0
|
||||
modulate.a = 1.0
|
||||
TweenFX.press_rotate(self)
|
||||
|
||||
func _make_custom_tooltip(for_text: String) -> Object:
|
||||
if !enable_tooltip:
|
||||
return null
|
||||
|
||||
var tooltip = tooltip_scene.instantiate()
|
||||
|
||||
tooltip.text = for_text
|
||||
if tooltip_image != null:
|
||||
tooltip.image = tooltip_image
|
||||
|
||||
return tooltip
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://bpbgecvan0a5k" path="res://core/main_scene_ui/icon_button.gd" id="1_r8gxt"]
|
||||
[ext_resource type="Texture2D" uid="uid://bkos5j6dwqcxw" path="res://core/main_scene_ui/assets/button_chrono_night.png" id="3_6q6an"]
|
||||
[ext_resource type="PackedScene" uid="uid://blh7egp5ge16m" path="res://core/tooltips/tooltip.tscn" id="3_60w2f"]
|
||||
[ext_resource type="Texture2D" uid="uid://cbk8ufxb7wdgx" path="res://core/tooltips/assets/tooltip_DX.png" id="4_60w2f"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_r8gxt"]
|
||||
|
||||
@@ -44,6 +46,8 @@ theme_override_styles/disabled_mirrored = SubResource("StyleBoxEmpty_4beq1")
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_cxhgx")
|
||||
script = ExtResource("1_r8gxt")
|
||||
image = ExtResource("3_6q6an")
|
||||
tooltip_scene = ExtResource("3_60w2f")
|
||||
tooltip_image = ExtResource("4_60w2f")
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="Texture" type="TextureRect" parent="." unique_id=1071359322]
|
||||
|
||||
@@ -10,23 +10,28 @@ extends Control
|
||||
@onready var collectible_icon_button: Button = $%CollectibleIconButton
|
||||
@onready var weather_row: HBoxContainer = $%WeatherRow
|
||||
@onready var time_of_day_row: HBoxContainer = $%TimeOfDayRow
|
||||
#@onready var cameras_row: HBoxContainer = $%CamerasRow
|
||||
@onready var photo_mode_texture_panel: Panel = $%PhotoModeTexturePanel
|
||||
@onready var photo_mode_texture_mask: TextureRect = $%PhotoModeTextureMask
|
||||
@onready var photo_mode_black_screen: ColorRect = $%PhotoModeBlackScreen
|
||||
@onready var audio_player: Control = $%AudioPlayer
|
||||
@onready var time_label: Label = $%TimeLabel
|
||||
@onready var dist_label: Label = $%DistLabel
|
||||
@onready var tooltips: HBoxContainer = $%Tooltips
|
||||
|
||||
var _cycle = false
|
||||
var _rain = false
|
||||
var _snow = false
|
||||
var _storm = false
|
||||
var _wind = false
|
||||
var _ui_hidden = false
|
||||
var _photo_mode_mat_tween: Tween
|
||||
var _photo_mode_alpha_tween: Tween
|
||||
var _photo_mode_fold_tween: Tween
|
||||
var _game_menu_base_scale: Vector2
|
||||
|
||||
func _ready() -> void:
|
||||
_game_menu_base_scale = game_menu.scale
|
||||
set_process_input(false)
|
||||
GameState.on_enable_photo_mode_request.connect(_on_enable_photo_mode)
|
||||
GameState.on_disable_photo_mode_request.connect(_on_disable_photo_mode)
|
||||
@@ -53,6 +58,7 @@ func _process(_delta: float) -> void:
|
||||
dist_label.text = "Distance Traveled: %d km" % int(GameState.save_data.total_distance_km)
|
||||
|
||||
func _on_hide_ui_button_pressed() -> void:
|
||||
UIEvents.on_hide_ui_requested.emit()
|
||||
hide_ui()
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
|
||||
await get_tree().create_timer(0.3).timeout
|
||||
@@ -64,17 +70,52 @@ func _input(event: InputEvent) -> void:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
show_ui()
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("toggle_options"):
|
||||
if photo_mode_texture_panel.visible or _ui_hidden:
|
||||
return
|
||||
if game_menu_panel.visible:
|
||||
_on_resume_button_pressed()
|
||||
else:
|
||||
_open_game_menu_on_page(2)
|
||||
elif event.is_action_pressed("hide_ui"):
|
||||
if photo_mode_texture_panel.visible:
|
||||
return
|
||||
if not game_menu_panel.visible:
|
||||
_on_hide_ui_button_pressed()
|
||||
|
||||
func _on_photo_icon_button_pressed() -> void:
|
||||
GameState.on_enable_photo_mode_request.emit()
|
||||
|
||||
func _open_game_menu_on_page(tab_index: int) -> void:
|
||||
if TweenFX.is_playing(game_menu, TweenFX.Animations.FOLD_IN) or TweenFX.is_playing(game_menu, TweenFX.Animations.FOLD_OUT):
|
||||
return
|
||||
GameState.pause_game()
|
||||
game_menu.on_tab_pressed(tab_index, true)
|
||||
game_menu_panel.show()
|
||||
game_menu.scale = Vector2(1, 1)
|
||||
game_menu.scale = _game_menu_base_scale
|
||||
TweenFX.fold_in(game_menu)
|
||||
|
||||
var book = BookAPI.get_current_book()
|
||||
if is_instance_valid(book):
|
||||
for slot in [book.get("_slot_1"), book.get("_slot_2")]:
|
||||
if slot != null and slot.get_child_count() > 0:
|
||||
var node = slot.get_child(-1)
|
||||
if node.has_method("_on_manage_pageflip"):
|
||||
node._on_manage_pageflip(false)
|
||||
|
||||
func _on_resume_button_pressed() -> void:
|
||||
if TweenFX.is_playing(game_menu, TweenFX.Animations.FOLD_IN) or TweenFX.is_playing(game_menu, TweenFX.Animations.FOLD_OUT):
|
||||
return
|
||||
|
||||
var book = BookAPI.get_current_book()
|
||||
if is_instance_valid(book):
|
||||
for slot in [book.get("_slot_1"), book.get("_slot_2")]:
|
||||
if slot != null and slot.get_child_count() > 0:
|
||||
var node = slot.get_child(-1)
|
||||
if node.has_method("_on_manage_pageflip"):
|
||||
node._on_manage_pageflip(true)
|
||||
|
||||
var tween = TweenFX.fold_out(game_menu)
|
||||
await tween.finished
|
||||
game_menu_panel.hide()
|
||||
@@ -95,6 +136,7 @@ func _on_time_of_day_row_on_option_changed(data: String) -> void:
|
||||
pass
|
||||
|
||||
func _on_weather_row_on_option_changed(data: String) -> void:
|
||||
var weather_changed: bool = true
|
||||
match data:
|
||||
"Snow":
|
||||
_snow = !_snow
|
||||
@@ -111,9 +153,10 @@ func _on_weather_row_on_option_changed(data: String) -> void:
|
||||
"Random":
|
||||
pick_random_weather()
|
||||
_:
|
||||
pass
|
||||
weather_changed = false
|
||||
|
||||
AchievementManager.is_unlocked("ACH_CHANGE_METEO")
|
||||
if weather_changed:
|
||||
AchievementManager.unlock("ACH_CHANGE_METEO")
|
||||
|
||||
func pick_random_weather() -> void:
|
||||
var valid_buttons = []
|
||||
@@ -196,7 +239,6 @@ func _on_photo_taken_finished() -> void:
|
||||
|
||||
func _on_choo_choo_button_pressed() -> void:
|
||||
UIEvents.toot_toot.emit(true)
|
||||
AchievementManager.is_unlocked("ACH_CHANGE_TRAIN_COLOR")
|
||||
|
||||
func _set_buttons_mouse_filter(ignore: bool) -> void:
|
||||
var filter = Control.MOUSE_FILTER_IGNORE if ignore else Control.MOUSE_FILTER_STOP
|
||||
@@ -205,20 +247,49 @@ func _set_buttons_mouse_filter(ignore: bool) -> void:
|
||||
buttons.append_array(weather_row.options_icon_buttons)
|
||||
if time_of_day_row and "options_icon_buttons" in time_of_day_row:
|
||||
buttons.append_array(time_of_day_row.options_icon_buttons)
|
||||
#if cameras_row and "options_icon_buttons" in cameras_row:
|
||||
#buttons.append_array(cameras_row.options_icon_buttons)
|
||||
|
||||
for btn in buttons:
|
||||
if btn is Control:
|
||||
btn.mouse_filter = filter
|
||||
if ignore:
|
||||
if btn.tooltip_text != "":
|
||||
btn.set_meta("old_tooltip", btn.tooltip_text)
|
||||
btn.tooltip_text = ""
|
||||
else:
|
||||
if btn.has_meta("old_tooltip"):
|
||||
btn.tooltip_text = btn.get_meta("old_tooltip")
|
||||
|
||||
func hide_ui() -> void:
|
||||
_ui_hidden = true
|
||||
_set_buttons_mouse_filter(true)
|
||||
var hud_elements = [hide_ui_button, weather_row, time_of_day_row, customize_train_button, collectible_icon_button, menu_icon_button, photo_icon_button, audio_player, choo_choo_button, time_label, dist_label]
|
||||
for element in hud_elements:
|
||||
element.visible = false
|
||||
element.visible = true
|
||||
TweenFX.fade_out(element, 0.25)
|
||||
|
||||
func show_ui() -> void:
|
||||
UIEvents.on_show_ui_requested.emit()
|
||||
_ui_hidden = false
|
||||
_set_buttons_mouse_filter(false)
|
||||
var hud_elements = [hide_ui_button, weather_row, time_of_day_row, customize_train_button, collectible_icon_button, menu_icon_button, photo_icon_button, audio_player, choo_choo_button, time_label, dist_label]
|
||||
var hud_elements = [hide_ui_button, weather_row, time_of_day_row, customize_train_button, collectible_icon_button, menu_icon_button, photo_icon_button, audio_player, choo_choo_button, time_label, dist_label, tooltips]
|
||||
for element in hud_elements:
|
||||
element.show()
|
||||
TweenFX.fade_in(element, 0.25)
|
||||
|
||||
func _on_cameras_row_on_option_changed(data: String) -> void:
|
||||
match data:
|
||||
"1":
|
||||
UIEvents.change_camera_request.emit(0)
|
||||
"2":
|
||||
UIEvents.change_camera_request.emit(1)
|
||||
"3":
|
||||
UIEvents.change_camera_request.emit(2)
|
||||
"4":
|
||||
UIEvents.change_camera_request.emit(3)
|
||||
"5":
|
||||
UIEvents.change_camera_request.emit(4)
|
||||
_:
|
||||
pass
|
||||
|
||||
@@ -31,11 +31,15 @@ var initial_local_basis: Basis
|
||||
var is_making_photo = false
|
||||
var captured_image: Image
|
||||
|
||||
var _ui_is_visible = true
|
||||
|
||||
func _ready() -> void:
|
||||
GameState.on_enable_photo_mode_request.connect(enable_photo_mode)
|
||||
GameState.on_disable_photo_mode_request.connect(disable_photo_mode)
|
||||
GameState.on_photo_taken_making.connect(take_photo_async)
|
||||
GameState.on_photo_mode_black_screen_disappeared.connect(_on_photo_mode_black_screen_disappeared)
|
||||
UIEvents.on_show_ui_requested.connect(update_ui_visibility.bind(true))
|
||||
UIEvents.on_hide_ui_requested.connect(update_ui_visibility.bind(false))
|
||||
|
||||
initial_local_pos = position
|
||||
initial_local_basis = basis
|
||||
@@ -49,18 +53,47 @@ func enable_photo_mode() -> void:
|
||||
current_pan = Vector2.ZERO
|
||||
|
||||
if camera:
|
||||
if previous_camera:
|
||||
camera.size = previous_camera.size
|
||||
camera.fov = previous_camera.fov
|
||||
|
||||
if rotation_target and "is_zoomed" in rotation_target:
|
||||
is_zoomed = rotation_target.is_zoomed
|
||||
if "zoom_tween" in rotation_target and rotation_target.zoom_tween and rotation_target.zoom_tween.is_valid():
|
||||
rotation_target.zoom_tween.kill()
|
||||
else:
|
||||
if abs(camera.size - zoom_size) < abs(camera.size - normal_size):
|
||||
is_zoomed = true
|
||||
else:
|
||||
is_zoomed = false
|
||||
|
||||
var target_size = zoom_size if is_zoomed else normal_size
|
||||
if not is_equal_approx(camera.size, target_size):
|
||||
zoom_tween = create_tween()
|
||||
zoom_tween.set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
zoom_tween.tween_property(camera, "size", target_size, zoom_time)
|
||||
zoom_tween.parallel().tween_property(camera, "fov", target_size, zoom_time)
|
||||
|
||||
camera.make_current()
|
||||
|
||||
func disable_photo_mode() -> void:
|
||||
is_active = false
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
if previous_camera:
|
||||
previous_camera.size = camera.size
|
||||
previous_camera.fov = camera.fov
|
||||
|
||||
if rotation_target and rotation_target.has_method("sync_zoom"):
|
||||
rotation_target.sync_zoom(camera.size, camera.fov, is_zoomed)
|
||||
|
||||
previous_camera.make_current()
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventKey and event.pressed and not event.echo:
|
||||
if event.keycode == KEY_Z and camera:
|
||||
is_zoomed = !is_zoomed
|
||||
if event is InputEventMouseButton and event.pressed:
|
||||
if event.button_index == MOUSE_BUTTON_WHEEL_UP and camera:
|
||||
if is_zoomed == false:
|
||||
return
|
||||
is_zoomed = false
|
||||
var target_size = zoom_size if is_zoomed else normal_size
|
||||
|
||||
if zoom_tween and zoom_tween.is_valid():
|
||||
@@ -71,9 +104,39 @@ func _input(event: InputEvent) -> void:
|
||||
zoom_tween.tween_property(camera, "size", target_size, zoom_time)
|
||||
zoom_tween.parallel().tween_property(camera, "fov", target_size, zoom_time)
|
||||
|
||||
elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN and camera:
|
||||
if is_zoomed == true:
|
||||
return
|
||||
is_zoomed = true
|
||||
var target_size = zoom_size if is_zoomed else normal_size
|
||||
|
||||
if zoom_tween and zoom_tween.is_valid():
|
||||
zoom_tween.kill()
|
||||
|
||||
zoom_tween = create_tween()
|
||||
zoom_tween.set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
zoom_tween.tween_property(camera, "size", target_size, zoom_time)
|
||||
zoom_tween.parallel().tween_property(camera, "fov", target_size, zoom_time)
|
||||
|
||||
if is_active:
|
||||
if event.is_action_pressed("exit_photo_mode") and not is_making_photo:
|
||||
GameState.on_disable_photo_mode_request.emit()
|
||||
elif event.is_action_pressed("take_photo"):
|
||||
if not is_making_photo:
|
||||
is_making_photo = true
|
||||
|
||||
GameState.on_photo_taken_prepare.emit()
|
||||
|
||||
await RenderingServer.frame_post_draw
|
||||
captured_image = get_viewport().get_texture().get_image()
|
||||
|
||||
GameState.on_photo_taken_started.emit()
|
||||
|
||||
if event.is_action_pressed("toggle_photo_mode"):
|
||||
if get_tree().paused:
|
||||
return
|
||||
if !_ui_is_visible:
|
||||
return
|
||||
if not is_active:
|
||||
GameState.on_enable_photo_mode_request.emit()
|
||||
else:
|
||||
@@ -83,18 +146,6 @@ func _input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseMotion and is_active:
|
||||
total_yaw -= event.relative.x * rotation_speed
|
||||
|
||||
if event.is_action_pressed("take_photo"):
|
||||
if !is_active or is_making_photo:
|
||||
return
|
||||
is_making_photo = true
|
||||
|
||||
GameState.on_photo_taken_prepare.emit()
|
||||
|
||||
await RenderingServer.frame_post_draw
|
||||
captured_image = get_viewport().get_texture().get_image()
|
||||
|
||||
GameState.on_photo_taken_started.emit()
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if not is_active:
|
||||
return
|
||||
@@ -147,3 +198,6 @@ func take_photo_async() -> void:
|
||||
|
||||
func _on_photo_mode_black_screen_disappeared() -> void:
|
||||
is_making_photo = false
|
||||
|
||||
func update_ui_visibility(ui_is_visible) -> void:
|
||||
_ui_is_visible = ui_is_visible
|
||||
|
||||
@@ -35,6 +35,12 @@ func prev_track():
|
||||
func toggle_pause():
|
||||
stream_paused = !stream_paused
|
||||
|
||||
func pause():
|
||||
stream_paused = true
|
||||
|
||||
func unpause():
|
||||
stream_paused = false
|
||||
|
||||
func stop_radio():
|
||||
stop()
|
||||
stream_paused = false
|
||||
|
||||
@@ -6,6 +6,11 @@ extends Node
|
||||
const KNOWN := [
|
||||
"ACH_CHANGE_METEO",
|
||||
"ACH_CHANGE_TRAIN_COLOR",
|
||||
"ACH_DISTANCE_100",
|
||||
"ACH_DISTANCE_200",
|
||||
"ACH_10_PHOTOS",
|
||||
"ACH_10_TOOTTOOT",
|
||||
"ACH_DISTANCE_1000"
|
||||
]
|
||||
|
||||
#how it works:
|
||||
|
||||
@@ -13,6 +13,13 @@ const KNOWN := [
|
||||
"stat_photo_number",
|
||||
"stat_toottoot_number",
|
||||
]
|
||||
const TIME_PLAYED_STAT: String = "stat_time_played"
|
||||
const DISTANCE_KM_STAT: String = "stat_distance_km"
|
||||
const STATS_STORE_INTERVAL_SECONDS: int = 60
|
||||
|
||||
var _pending_time_played_seconds: float = 0.0
|
||||
var _pending_distance_km: float = 0.0
|
||||
var _stats_store_timer: float = 0.0
|
||||
|
||||
#how it works:
|
||||
#func _on_match_finished(score: int) -> void:
|
||||
@@ -25,10 +32,20 @@ const KNOWN := [
|
||||
|
||||
func _ready() -> void:
|
||||
if not SteamManager.is_on_steam:
|
||||
set_process(false)
|
||||
return
|
||||
|
||||
Steam.user_stats_stored.connect(_on_stats_stored)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_pending_time_played_seconds += delta
|
||||
_stats_store_timer += delta
|
||||
if _stats_store_timer >= STATS_STORE_INTERVAL_SECONDS:
|
||||
_flush_periodic_stats(false)
|
||||
|
||||
func _exit_tree() -> void:
|
||||
_flush_periodic_stats(true)
|
||||
|
||||
func get_int(stat: String) -> int:
|
||||
if not SteamManager.is_on_steam:
|
||||
return 0
|
||||
@@ -62,6 +79,14 @@ func add_int(stat: String, amount: int = 1) -> void:
|
||||
return
|
||||
set_int(stat, get_int(stat) + amount)
|
||||
|
||||
func add_distance_km(distance_km: float) -> void:
|
||||
if not SteamManager.is_on_steam:
|
||||
return
|
||||
if distance_km <= 0.0:
|
||||
return
|
||||
|
||||
_pending_distance_km += distance_km
|
||||
|
||||
func update_avg_rate(stat: String, count_this_session: float, session_length: float) -> void:
|
||||
if not SteamManager.is_on_steam:
|
||||
return
|
||||
@@ -74,6 +99,32 @@ func store() -> void:
|
||||
if not Steam.storeStats():
|
||||
push_error("storeStats failed; data saved locally")
|
||||
|
||||
#periodic stats incrementation; store data every 60 secs
|
||||
func _flush_periodic_stats(force_store: bool) -> void:
|
||||
if not SteamManager.is_on_steam:
|
||||
_pending_time_played_seconds = 0.0
|
||||
_pending_distance_km = 0.0
|
||||
_stats_store_timer = 0.0
|
||||
return
|
||||
|
||||
var has_changes: bool = false
|
||||
|
||||
var whole_seconds: int = int(floor(_pending_time_played_seconds))
|
||||
if whole_seconds > 0:
|
||||
_pending_time_played_seconds -= float(whole_seconds)
|
||||
add_int(TIME_PLAYED_STAT, whole_seconds)
|
||||
has_changes = true
|
||||
|
||||
var whole_km: int = int(floor(_pending_distance_km))
|
||||
if whole_km > 0:
|
||||
_pending_distance_km -= float(whole_km)
|
||||
add_int(DISTANCE_KM_STAT, whole_km)
|
||||
has_changes = true
|
||||
|
||||
_stats_store_timer = 0.0
|
||||
if has_changes and (force_store or whole_seconds > 0 or whole_km > 0):
|
||||
store()
|
||||
|
||||
#Development only: reset stats
|
||||
func reset_all(include_achievements: bool = false) -> void:
|
||||
if not SteamManager.is_on_steam:
|
||||
|
||||
BIN
core/tooltips/assets/camera_1.png
Normal file
|
After Width: | Height: | Size: 522 KiB |
40
core/tooltips/assets/camera_1.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cavfu38w67kv1"
|
||||
path="res://.godot/imported/camera_1.png-6bef811d856883a597fd13243121c269.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/camera_1.png"
|
||||
dest_files=["res://.godot/imported/camera_1.png-6bef811d856883a597fd13243121c269.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/camera_2.png
Normal file
|
After Width: | Height: | Size: 527 KiB |
40
core/tooltips/assets/camera_2.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c4nsxmoh3itat"
|
||||
path="res://.godot/imported/camera_2.png-2350610ab2bb8e3b3a90026f128e8544.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/camera_2.png"
|
||||
dest_files=["res://.godot/imported/camera_2.png-2350610ab2bb8e3b3a90026f128e8544.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/camera_3.png
Normal file
|
After Width: | Height: | Size: 529 KiB |
40
core/tooltips/assets/camera_3.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bbsohagx2646w"
|
||||
path="res://.godot/imported/camera_3.png-ff967b883d8a5166da74f29b1179df2f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/camera_3.png"
|
||||
dest_files=["res://.godot/imported/camera_3.png-ff967b883d8a5166da74f29b1179df2f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/camera_4.png
Normal file
|
After Width: | Height: | Size: 526 KiB |
40
core/tooltips/assets/camera_4.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dry1k7w03167e"
|
||||
path="res://.godot/imported/camera_4.png-43e725f6d4bb1690fa3b306344d9f2c6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/camera_4.png"
|
||||
dest_files=["res://.godot/imported/camera_4.png-43e725f6d4bb1690fa3b306344d9f2c6.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/camera_5.png
Normal file
|
After Width: | Height: | Size: 527 KiB |
40
core/tooltips/assets/camera_5.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://1fsufkfkyti"
|
||||
path="res://.godot/imported/camera_5.png-cca1ded2b7eaa96d84039802746b3bee.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/camera_5.png"
|
||||
dest_files=["res://.godot/imported/camera_5.png-cca1ded2b7eaa96d84039802746b3bee.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/camera_none.png
Normal file
|
After Width: | Height: | Size: 515 KiB |
40
core/tooltips/assets/camera_none.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dsytn6pedo8i"
|
||||
path="res://.godot/imported/camera_none.png-0964d8c8da781e3eeb4296537838b9c0.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/camera_none.png"
|
||||
dest_files=["res://.godot/imported/camera_none.png-0964d8c8da781e3eeb4296537838b9c0.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/exit photo mode.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
40
core/tooltips/assets/exit photo mode.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bx0yto0ah5ffa"
|
||||
path="res://.godot/imported/exit photo mode.png-8a4744e6069ce2a7928d26be53c25d02.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/exit photo mode.png"
|
||||
dest_files=["res://.godot/imported/exit photo mode.png-8a4744e6069ce2a7928d26be53c25d02.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/hide.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
40
core/tooltips/assets/hide.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bniftx6j2h4mu"
|
||||
path="res://.godot/imported/hide.png-673cab8e9d14081efde83510600e74c5.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/hide.png"
|
||||
dest_files=["res://.godot/imported/hide.png-673cab8e9d14081efde83510600e74c5.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/horn.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
40
core/tooltips/assets/horn.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bms10b47ers4c"
|
||||
path="res://.godot/imported/horn.png-d688275340db551ead1e04b98bef039f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/horn.png"
|
||||
dest_files=["res://.godot/imported/horn.png-d688275340db551ead1e04b98bef039f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/photo mode.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
40
core/tooltips/assets/photo mode.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://brujlvboqbd10"
|
||||
path="res://.godot/imported/photo mode.png-5dbff8e6e2d8f4fc4feda1336fb84ebf.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/photo mode.png"
|
||||
dest_files=["res://.godot/imported/photo mode.png-5dbff8e6e2d8f4fc4feda1336fb84ebf.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/take a photo.png
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
40
core/tooltips/assets/take a photo.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://blpprpiha1gaa"
|
||||
path="res://.godot/imported/take a photo.png-a894c87a630557874ac3c24cb0299a43.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/take a photo.png"
|
||||
dest_files=["res://.godot/imported/take a photo.png-a894c87a630557874ac3c24cb0299a43.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/tooltip_1.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
40
core/tooltips/assets/tooltip_1.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d12w3tr36spe8"
|
||||
path="res://.godot/imported/tooltip_1.png-37ffb615aa8cd89f6b904f2ffa077ce8.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/tooltip_1.png"
|
||||
dest_files=["res://.godot/imported/tooltip_1.png-37ffb615aa8cd89f6b904f2ffa077ce8.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/tooltip_2.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
40
core/tooltips/assets/tooltip_2.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bi2tblkgtqnf6"
|
||||
path="res://.godot/imported/tooltip_2.png-c63403f312184a20c0eff2e81f1cdd25.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/tooltip_2.png"
|
||||
dest_files=["res://.godot/imported/tooltip_2.png-c63403f312184a20c0eff2e81f1cdd25.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/tooltip_3.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
40
core/tooltips/assets/tooltip_3.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d160748lbh8j5"
|
||||
path="res://.godot/imported/tooltip_3.png-a097a6ca2e9dd094aba7b4aedee30fbe.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://core/tooltips/assets/tooltip_3.png"
|
||||
dest_files=["res://.godot/imported/tooltip_3.png-a097a6ca2e9dd094aba7b4aedee30fbe.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
core/tooltips/assets/tooltip_4.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |