Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions scripts/fish.gd
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ mDifficulty, mMin_weight, mMax_weight, price_weight_multiplier, mType, weight_mu
self.type = mType
self.is_shiny = mIs_shiny

# In infinite mode, scale down fish prices significantly past 600m depth
if GameState.is_infinite() and abs(mStart_position.y) > 600:
var depth_factor = abs(mStart_position.y) - 600
# Scale down price more aggressively the deeper you go
# At 700m: 0.5x, at 800m: 0.25x, at 1000m: 0.1x, etc.
var scale_factor = max(0.1, 1.0 - (depth_factor / 400.0))
self.price = round(self.price * scale_factor)

scale = get_scale_for_weight(mMax_weight, mMin_weight, weight)

if self.is_shiny:
Expand Down
108 changes: 97 additions & 11 deletions scripts/game_state.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ signal inventory_updated

#DEFINITIONS
enum Stage {SURFACE, DEEP, DEEPER, SUPERDEEP, HOT, LAVA, VOID}
enum GameMode {NORMAL, INTRO_MISSION}
enum GameMode {NORMAL, INTRO_MISSION, INFINITE}
var depthStageMap = {
0: Stage.SURFACE,
100: Stage.DEEP,
Expand All @@ -15,7 +15,7 @@ var depthStageMap = {
600: Stage.VOID
}

enum Upgrade {CARGO_SIZE, DEPTH_RESISTANCE, PICKAXE_UNLOCKED, VERT_SPEED, HOR_SPEED, LAMP_UNLOCKED, AK47, DUALAK47, HARPOON, HARPOON_ROTATION, INVENTORY_MANAGEMENT, SURFACE_BUOY, INVENTORY_SAVE, DRONE_SELLING}
enum Upgrade {CARGO_SIZE, DEPTH_RESISTANCE, PICKAXE_UNLOCKED, VERT_SPEED, HOR_SPEED, LAMP_UNLOCKED, AK47, DUALAK47, HARPOON, HARPOON_ROTATION, INVENTORY_MANAGEMENT, SURFACE_BUOY, INVENTORY_SAVE, DRONE_SELLING, SUBMARINE_COLOR, DRONE_COLOR}
var upgradeCosts = {
Upgrade.CARGO_SIZE: 25,
Upgrade.DEPTH_RESISTANCE: 50,
Expand All @@ -30,7 +30,9 @@ var upgradeCosts = {
Upgrade.INVENTORY_MANAGEMENT: 400,
Upgrade.SURFACE_BUOY: 1000,
Upgrade.INVENTORY_SAVE: 250,
Upgrade.DRONE_SELLING: 300
Upgrade.DRONE_SELLING: 300,
Upgrade.SUBMARINE_COLOR: 50000,
Upgrade.DRONE_COLOR: 30000
}

var maxUpgrades = {
Expand All @@ -47,7 +49,9 @@ var maxUpgrades = {
Upgrade.INVENTORY_MANAGEMENT: 1,
Upgrade.SURFACE_BUOY: 1,
Upgrade.INVENTORY_SAVE: 1,
Upgrade.DRONE_SELLING: 1
Upgrade.DRONE_SELLING: 1,
Upgrade.SUBMARINE_COLOR: 10,
Upgrade.DRONE_COLOR: 10
}

#STATE
Expand All @@ -65,7 +69,9 @@ var upgrades = {
Upgrade.INVENTORY_MANAGEMENT: 0,
Upgrade.SURFACE_BUOY: 0,
Upgrade.INVENTORY_SAVE: 0,
Upgrade.DRONE_SELLING: 0
Upgrade.DRONE_SELLING: 0,
Upgrade.SUBMARINE_COLOR: 0,
Upgrade.DRONE_COLOR: 0
}
var depth = 0
var maxDepthReached = 0
Expand All @@ -91,17 +97,15 @@ var is_first_time_player = true
var intro_mission_completed = false
var friend_death_position: Vector3 = Vector3.ZERO
var boss_encountered = false # Flag to track if player has seen the boss for the first time
var infinite_mode_enabled = false # Flag to track if infinite mode is active

func _ready():
# Connect to inventory's methods to emit the inventory_updated signal
inventory.connect_signals_to_gamestate(self)

# automatically start intro mission for first-time players (if enabled)
if enable_intro_mission and is_first_time_player and not intro_mission_completed:
start_intro_mission()
else:
# If intro mission is disabled, initialize normal mode
start_normal_mode()
# Show game mode selection UI
await get_tree().process_frame
show_game_mode_selection()

func _process(_delta):
# Ensure game is not paused during intro mission
Expand All @@ -125,6 +129,11 @@ func setDepth(d: int):
var snapped_depth = snapped(d, 100)
var new_stage = Stage.SURFACE # Default to SURFACE for shallow depths

# In infinite mode, continue using VOID stage past 600m
if infinite_mode_enabled and d > 600:
playerInStage = Stage.VOID
return

# Sort depth thresholds and find the highest one that we meet or exceed
var sorted_depths = depthStageMap.keys()
sorted_depths.sort()
Expand Down Expand Up @@ -267,6 +276,83 @@ func reset_upgrades():
func is_intro() -> bool:
return current_game_mode == GameMode.INTRO_MISSION

func is_infinite() -> bool:
return infinite_mode_enabled

func start_infinite_mode():
print("Starting infinite mode")
infinite_mode_enabled = true
current_game_mode = GameMode.INFINITE
is_first_time_player = false
intro_mission_completed = true
boss_encountered = false

# Reset game state for infinite mode
death_screen = false
paused = false
health = 100
isDocked = false

# Set player to surface level
playerInStage = Stage.SURFACE
depth = 0
maxDepthReached = 0

# Initialize Boss system
Boss.boss_spawned = false
Boss.boss_defeated_permanently = false
Boss.boss_dialog_displayed = true
Boss.boss_dialog_section = Boss.BossDialogSections.TUTORIAL1
Boss.boss_dialog_index = 0
Boss.boss_health = Boss.boss_max_health

# Wait for player node to be available, then set position to surface
await get_tree().process_frame
if player_node:
player_node.position = Vector3(-8, 0, 0.33) # Surface position

# Reset tree pause state
get_tree().paused = false

print("Infinite mode setup complete")

func show_game_mode_selection():
"""Show the game mode selection UI"""
# Only show if we haven't started a game mode yet
if current_game_mode != GameMode.NORMAL and current_game_mode != GameState.GameMode.INFINITE:
var ui_node = get_node_or_null("/root/Node3D/UI")
if ui_node:
# Check if game mode selection already exists
var mode_selection = ui_node.find_child("GameModeSelection", true, false)
if not mode_selection:
# Create game mode selection UI
mode_selection = load("res://scripts/ui/game_mode_selection.gd").new()
mode_selection.name = "GameModeSelection"
mode_selection.mode_selected.connect(_on_game_mode_selected)
ui_node.add_child(mode_selection)

mode_selection.show_menu()
else:
# Fallback: start intro mission if UI not found
if enable_intro_mission and is_first_time_player and not intro_mission_completed:
start_intro_mission()
else:
start_normal_mode()
else:
# Game mode already selected, don't show selection
pass

func _on_game_mode_selected(mode: GameState.GameMode):
"""Handle game mode selection"""
if mode == GameMode.NORMAL:
# For normal mode, check if we should start intro mission
if enable_intro_mission and is_first_time_player and not intro_mission_completed:
start_intro_mission()
else:
start_normal_mode()
elif mode == GameMode.INFINITE:
start_infinite_mode()

func start_normal_mode():
print("Starting normal mode")
current_game_mode = GameMode.NORMAL
Expand Down
55 changes: 45 additions & 10 deletions scripts/level.gd
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func _process(_delta: float) -> void:
if camera and camera.has_method("change_section_environment"):
camera.change_section_environment(GameState.Stage.HOT)

if player.position.y < (lastSpawned) && GameState.current_game_mode == GameState.GameMode.NORMAL:
if player.position.y < (lastSpawned) && (GameState.current_game_mode == GameState.GameMode.NORMAL || GameState.current_game_mode == GameState.GameMode.INFINITE):
spawnNewSection(lastSpawned - sectionHeight)
if GameState.maxDepthReached > Boss.boss_spawn_height && Boss.boss_spawned == false && Boss.boss_defeated_permanently == false:
var boss_spawn_loc = (GameState.maxDepthReached * -1) - 25
Expand Down Expand Up @@ -146,22 +146,57 @@ func spawn_intro_mission_sections():
func spawnNewSection(mPosition: float):
var newSection = section.instantiate()
newSection.position.y = mPosition
var i = snapped(-mPosition, 100)
i = min(i, GameState.depthStageMap.keys()[len(GameState.depthStageMap.keys())-1])
newSection.sectionType = GameState.depthStageMap[i]
newSection.lastSectionType = last_section_type

# Give section a meaningful name based on its type and depth
var depth_meters = int(abs(mPosition))
var stage_name = GameState.Stage.keys()[GameState.depthStageMap[i]]
newSection.name = "Section_%s_%dm" % [stage_name, depth_meters]

# Handle infinite mode - continue with VOID stage past 600m
if GameState.is_infinite() and depth_meters > 600:
newSection.sectionType = GameState.Stage.VOID
# Use previous section type for proper transitions
if last_section_type == GameState.Stage.VOID:
newSection.lastSectionType = GameState.Stage.VOID
else:
# Transition from LAVA to VOID
newSection.lastSectionType = GameState.Stage.LAVA
newSection.name = "Section_VOID_%dm" % depth_meters
else:
# Normal section generation - ensure no gaps
var i = snapped(-mPosition, 100)
# Ensure we don't exceed the maximum depth threshold
var max_depth_key = GameState.depthStageMap.keys()[len(GameState.depthStageMap.keys())-1]
i = min(i, max_depth_key)

# Find the appropriate stage for this depth
var sorted_depths = GameState.depthStageMap.keys()
sorted_depths.sort()
var selected_stage = GameState.Stage.SURFACE

# Find the highest threshold we meet or exceed
for depth_threshold in sorted_depths:
if i >= depth_threshold:
selected_stage = GameState.depthStageMap[depth_threshold]

newSection.sectionType = selected_stage
# Set last section type for proper transitions
# If this is the first section or we're at a transition point, use previous
if last_section_type == GameState.Stage.SURFACE and selected_stage != GameState.Stage.SURFACE:
# First transition - use SURFACE as last
newSection.lastSectionType = GameState.Stage.SURFACE
else:
# Use the previous section type for continuity
newSection.lastSectionType = last_section_type

# Give section a meaningful name based on its type and depth
var stage_name = GameState.Stage.keys()[selected_stage]
newSection.name = "Section_%s_%dm" % [stage_name, depth_meters]

# Update lastSpawned BEFORE adding to scene to prevent gaps
lastSpawned = mPosition
GameState.fishes_lower_boarder = lastSpawned - sectionHeight/2 - 1
if mPosition <= -50:
newSection.setDepth(mPosition * -1)
add_child(newSection)
last_section_type = GameState.depthStageMap[i]
# Update last_section_type AFTER adding section
last_section_type = newSection.sectionType

func spawnBoss(mPosition: float):
print("Spawn boss", mPosition)
Expand Down
69 changes: 68 additions & 1 deletion scripts/player.gd
Original file line number Diff line number Diff line change
Expand Up @@ -669,9 +669,27 @@ func activate_selling_drone():
drone.scale = Vector3(0.5, 0.5, 0.5) # Make it a bit smaller than regular fish
get_parent().add_child(drone)

# Apply drone color if upgrade is purchased
var drone_color_level = GameState.upgrades[GameState.Upgrade.DRONE_COLOR]
var drone_color = Color(0.8, 0.8, 0.2) # Default golden color
if drone_color_level > 0:
var colors = [
Color(1.0, 0.2, 0.2), # Red
Color(0.2, 1.0, 0.2), # Green
Color(0.2, 0.2, 1.0), # Blue
Color(1.0, 1.0, 0.2), # Yellow
Color(1.0, 0.2, 1.0), # Magenta
Color(0.2, 1.0, 1.0), # Cyan
Color(1.0, 0.5, 0.2), # Orange
Color(0.5, 0.2, 1.0), # Purple
Color(1.0, 0.8, 0.2), # Gold
Color(0.8, 0.8, 0.8), # Silver
]
drone_color = colors[min(drone_color_level - 1, colors.size() - 1)]

# Create visual effect for the drone
var particles = $dronefart.duplicate()
particles.color = Color(0.8, 0.8, 0.2) # Give it a golden color
particles.color = drone_color
drone.add_child(particles)
particles.emitting = true

Expand Down Expand Up @@ -870,4 +888,53 @@ func switch_to_normal_submarine():
# Reset upgrades to normal (will be handled by GameState.complete_intro_mission)
# No need to reset here since that function handles the upgrade reset

# Apply cosmetic color if upgrade is purchased
apply_submarine_color()

print("Normal submarine appearance restored")

func apply_submarine_color():
"""Apply cosmetic color to submarine based on upgrade level"""
# Don't apply color during intro mission (friend submarine)
if GameState.is_intro() or is_friend_submarine:
return

var color_level = GameState.upgrades[GameState.Upgrade.SUBMARINE_COLOR]
if color_level == 0:
return # No color upgrade

# Define color palette for different levels
var colors = [
Color(1.0, 0.2, 0.2), # Red
Color(0.2, 1.0, 0.2), # Green
Color(0.2, 0.2, 1.0), # Blue
Color(1.0, 1.0, 0.2), # Yellow
Color(1.0, 0.2, 1.0), # Magenta
Color(0.2, 1.0, 1.0), # Cyan
Color(1.0, 0.5, 0.2), # Orange
Color(0.5, 0.2, 1.0), # Purple
Color(1.0, 0.8, 0.2), # Gold
Color(0.8, 0.8, 0.8), # Silver
]

var selected_color = colors[min(color_level - 1, colors.size() - 1)]

# Apply color to submarine material
if has_node("Pivot/SmFishSubmarine"):
var submarine_mesh = $Pivot/SmFishSubmarine
var material = submarine_mesh.get_surface_override_material(0)

if material == null:
# Create a new material if none exists
material = StandardMaterial3D.new()
# Try to load original textures
material.albedo_texture = load("res://textures/sub/SM_FishSubmarine_initialShadingGroup_BaseColor.png")
material.metallic_texture = load("res://textures/sub/SM_FishSubmarine_initialShadingGroup_Metallic.png")
material.roughness_texture = load("res://textures/sub/SM_FishSubmarine_initialShadingGroup_Roughness.png")
material.normal_texture = load("res://textures/sub/SM_FishSubmarine_initialShadingGroup_Normal.png")
material.height_texture = load("res://textures/sub/SM_FishSubmarine_initialShadingGroup_Height.png")

# Apply color tint
material.albedo_color = selected_color
submarine_mesh.set_surface_override_material(0, material)
print("Applied submarine color level ", color_level, ": ", selected_color)
6 changes: 5 additions & 1 deletion scripts/strings.gd
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ var upgradeNames = {
GameState.Upgrade.SURFACE_BUOY: "Emergency Buoy",
GameState.Upgrade.INVENTORY_SAVE: "Inventory Insurance",
GameState.Upgrade.DRONE_SELLING: "Remote Selling Drone",
GameState.Upgrade.SUBMARINE_COLOR: "Submarine Color",
GameState.Upgrade.DRONE_COLOR: "Drone Color",
}

var boss_dialog_lines = {
Expand Down Expand Up @@ -58,5 +60,7 @@ var upgradeDescriptions = {
GameState.Upgrade.INVENTORY_MANAGEMENT: "Automatically replaces less valuable fish with more expensive ones when your inventory is full.",
GameState.Upgrade.SURFACE_BUOY: "Provides an emergency buoy that quickly returns you to the surface when you press B.",
GameState.Upgrade.INVENTORY_SAVE: "Insures your inventory, preventing loss of collected fish when you die.",
GameState.Upgrade.DRONE_SELLING: "Deploys a drone that sells your inventory remotely when you press Q, without returning to dock."
GameState.Upgrade.DRONE_SELLING: "Deploys a drone that sells your inventory remotely when you press Q, without returning to dock.",
GameState.Upgrade.SUBMARINE_COLOR: "Changes the color of your submarine. Each level unlocks a new color variant. Only affordable by exploring the depths below the boss!",
GameState.Upgrade.DRONE_COLOR: "Changes the color of your selling drone. Each level unlocks a new color variant. Only affordable by exploring the depths below the boss!"
}
Loading