From aaf246d873ff4ae7f80c187df41c97b0f4975027 Mon Sep 17 00:00:00 2001 From: Yogi Wiguna Date: Mon, 9 Mar 2026 17:49:50 +0800 Subject: [PATCH] feat: Introduce core game systems for special tile effects, power-up management, player movement, and initial UI screens. --- launcher/server/version.json | 26 ++++++++++++++++++--- scenes/boot_screen.tscn | 2 +- scenes/player.gd | 10 +++++++- scenes/ui/login_screen.tscn | 2 +- scripts/managers/game_update_manager.gd | 4 ++-- scripts/managers/player_movement_manager.gd | 6 ++--- scripts/managers/powerup_manager.gd | 6 ++++- scripts/managers/special_tiles_manager.gd | 13 +++++++---- version.txt | 2 +- 9 files changed, 54 insertions(+), 17 deletions(-) diff --git a/launcher/server/version.json b/launcher/server/version.json index 6957499..96940e9 100644 --- a/launcher/server/version.json +++ b/launcher/server/version.json @@ -1,8 +1,28 @@ { - "latest_version": "1.0.0", - "minimum_launcher_version": "1.0.0", - "minimum_app_version": "1.0.0", + "latest_version": "0.9.0", + "minimum_launcher_version": "0.9.0", + "minimum_app_version": "0.9.0", "releases": [ + { + "version": "0.9.0", + "date": "2026-03-09", + "pck_windows": { + "url": "https://your-host.com/releases/tekton-local-0.9.0-windows.pck", + "size": 52428800, + "checksum_md5": "", + "checksum_sha256": "" + }, + "changelog": [ + "Power-up spawning before countdown in Stop n Go", + "Fixed safe zone visuals persistence", + "Unified Game Over freeze for bots and players", + "Added wall overlap protection for spawned tiles", + "Restricted bot tile collection to current standing tile", + "Improved door visibility in Tekton Doors mode", + "Fixed knock logic when carrying a Tekton" + ], + "required": true + }, { "version": "1.0.0", "date": "2025-12-10", diff --git a/scenes/boot_screen.tscn b/scenes/boot_screen.tscn index 85f3acc..86e0119 100644 --- a/scenes/boot_screen.tscn +++ b/scenes/boot_screen.tscn @@ -127,5 +127,5 @@ grow_horizontal = 0 grow_vertical = 0 theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 0.6) theme_override_font_sizes/font_size = 12 -text = "v1.0.0" +text = "v0.9.0" horizontal_alignment = 2 diff --git a/scenes/player.gd b/scenes/player.gd index c69a059..2bcca8f 100644 --- a/scenes/player.gd +++ b/scenes/player.gd @@ -2241,6 +2241,10 @@ var is_knock_mode: bool = false # Yellow mode for knocking Tekton func enter_attack_mode(): if not is_multiplayer_authority(): return + if is_invisible: + NotificationManager.send_message(self , "Cannot enter Attack Mode while in Ghost mode!", NotificationManager.MessageType.WARNING) + return + is_attack_mode = true is_knock_mode = false # Mutually exclusive NotificationManager.send_message(self , "Attack Mode ACTIVATED (Red)", NotificationManager.MessageType.POWERUP) @@ -2249,6 +2253,10 @@ func enter_attack_mode(): func enter_knock_mode(): if not is_multiplayer_authority(): return + if is_invisible: + NotificationManager.send_message(self , "Cannot enter Knock Mode while in Ghost mode!", NotificationManager.MessageType.WARNING) + return + is_knock_mode = true is_attack_mode = false # Mutually exclusive NotificationManager.send_message(self , "Knock Mode ACTIVATED (Yellow)", NotificationManager.MessageType.POWERUP) @@ -2289,7 +2297,7 @@ func sync_bump(target_pos: Vector2i, is_soft: bool = false): tween.tween_property(self, "global_position", original_pos, duration).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN) func knock_tekton(): - if not is_multiplayer_authority() or is_frozen or is_stop_frozen: + if not is_multiplayer_authority() or is_frozen or is_stop_frozen or is_invisible: return # Requirement: Full Powerup Bar (or we are already in knock mode) diff --git a/scenes/ui/login_screen.tscn b/scenes/ui/login_screen.tscn index 1ff3133..b1fc571 100644 --- a/scenes/ui/login_screen.tscn +++ b/scenes/ui/login_screen.tscn @@ -241,5 +241,5 @@ grow_horizontal = 0 grow_vertical = 0 theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 0.6) theme_override_font_sizes/font_size = 11 -text = "v1.0.0" +text = "v0.9.0" horizontal_alignment = 2 diff --git a/scripts/managers/game_update_manager.gd b/scripts/managers/game_update_manager.gd index cf002a1..dbd7777 100644 --- a/scripts/managers/game_update_manager.gd +++ b/scripts/managers/game_update_manager.gd @@ -22,8 +22,8 @@ const IOS_STORE_URL := "https://apps.apple.com/app/tekton/id123456789" enum Platform { WINDOWS, LINUX, MACOS, ANDROID, IOS, WEB } # State -var current_version: String = "1.0.0" -var latest_version: String = "1.0.0" +var current_version: String = "0.9.0" +var latest_version: String = "0.9.0" var manifest_data: Dictionary = {} var http_request: HTTPRequest var download_request: HTTPRequest diff --git a/scripts/managers/player_movement_manager.gd b/scripts/managers/player_movement_manager.gd index 757440d..636bd3d 100644 --- a/scripts/managers/player_movement_manager.gd +++ b/scripts/managers/player_movement_manager.gd @@ -156,10 +156,10 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool: NotificationManager.send_message(player, "Target is Immune!", NotificationManager.MessageType.WARNING) return false - # === NEW LOGIC: Only allow push if in ATTACK MODE === - if not player.get("is_attack_mode"): + # === NEW LOGIC: Only allow push if in ATTACK MODE and NOT GHOST === + if not player.get("is_attack_mode") or player.get("is_invisible"): # Standard bumping effect (Visual only) - print("[Move] Push blocked: Not in attack mode (%s trying to push %s)" % [player.name, other_player.name]) + print("[Move] Push blocked: Not in attack mode or is Ghost (%s trying to push %s)" % [player.name, other_player.name]) if _can_rpc(): player.rpc("sync_bump", target_pos, true) # Soft bump elif player.has_method("sync_bump"): diff --git a/scripts/managers/powerup_manager.gd b/scripts/managers/powerup_manager.gd index 89ec02c..7ae6677 100644 --- a/scripts/managers/powerup_manager.gd +++ b/scripts/managers/powerup_manager.gd @@ -155,11 +155,15 @@ func use_special_effect() -> bool: if not can_use_special(): return false - # Restriction: Cannot use attack mode while carrying a Tekton + # Restriction: Cannot use attack mode while carrying a Tekton or in Ghost mode if player.is_carrying_tekton: NotificationManager.send_message(player, "Cannot enter Attack Mode while carrying a Tekton!", NotificationManager.MessageType.WARNING) return false + if player.get("is_invisible"): + NotificationManager.send_message(player, "Cannot enter Attack Mode while in Ghost mode!", NotificationManager.MessageType.WARNING) + return false + # Enable Attack Mode explicitly player.is_attack_mode = true # Do NOT consume boost here. Boost acts as "fuel" for the attacks. diff --git a/scripts/managers/special_tiles_manager.gd b/scripts/managers/special_tiles_manager.gd index 2462cff..4e41af8 100644 --- a/scripts/managers/special_tiles_manager.gd +++ b/scripts/managers/special_tiles_manager.gd @@ -34,7 +34,7 @@ func get_skill_affected_area(effect: int, center_pos: Vector2i) -> Array[Vector2 match effect: SpecialEffect.AREA_FREEZE: - # Preview 3 blocks ahead of current hover (if we ever re-enable targeting) + # Preview 2 blocks ahead of current hover (if we ever re-enable targeting) area.append(center_pos) SpecialEffect.BLOCK_FLOOR: @@ -190,6 +190,11 @@ func activate_effect(effect: int, target_player: Node3D = null): print("PowerUp %s on cooldown." % SpecialEffect.keys()[effect]) return + # Check Attack Mode Restriction + if player.get("is_attack_mode") and effect == SpecialEffect.INVISIBLE_MODE: + NotificationManager.send_message(player, "Cannot enter Ghost mode while in Attack Mode!", NotificationManager.MessageType.WARNING) + return + # Check Carrying Restriction if player.get("is_carrying_tekton") and effect != SpecialEffect.FASTER_SPEED: NotificationManager.send_message(player, "Cannot use this power while carrying a Tekton!", NotificationManager.MessageType.WARNING) @@ -250,9 +255,9 @@ func _execute_area_freeze(target_pos: Vector2i = Vector2i.ZERO): if center_pos == Vector2i.ZERO: # Calculate distance ahead based on Level - # Gap of 3 floors = 4 tiles ahead - # Gap of 5 floors = 6 tiles ahead - var distance = 4 if current_lvl < 5 else 6 + # Gap of 2 floors = 3 tiles ahead + # Gap of 4 floors = 5 tiles ahead + var distance = 3 if current_lvl < 5 else 5 var movement = player.movement_manager if movement and movement.current_move_direction != Vector2i.ZERO: diff --git a/version.txt b/version.txt index 3eefcb9..ac39a10 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.0 +0.9.0