feat: Introduce core game systems for special tile effects, power-up management, player movement, and initial UI screens.

This commit is contained in:
Yogi Wiguna
2026-03-09 17:49:50 +08:00
parent 0fb1397d11
commit aaf246d873
9 changed files with 54 additions and 17 deletions
+23 -3
View File
@@ -1,8 +1,28 @@
{ {
"latest_version": "1.0.0", "latest_version": "0.9.0",
"minimum_launcher_version": "1.0.0", "minimum_launcher_version": "0.9.0",
"minimum_app_version": "1.0.0", "minimum_app_version": "0.9.0",
"releases": [ "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", "version": "1.0.0",
"date": "2025-12-10", "date": "2025-12-10",
+1 -1
View File
@@ -127,5 +127,5 @@ grow_horizontal = 0
grow_vertical = 0 grow_vertical = 0
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 0.6) theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 0.6)
theme_override_font_sizes/font_size = 12 theme_override_font_sizes/font_size = 12
text = "v1.0.0" text = "v0.9.0"
horizontal_alignment = 2 horizontal_alignment = 2
+9 -1
View File
@@ -2241,6 +2241,10 @@ var is_knock_mode: bool = false # Yellow mode for knocking Tekton
func enter_attack_mode(): func enter_attack_mode():
if not is_multiplayer_authority(): return 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_attack_mode = true
is_knock_mode = false # Mutually exclusive is_knock_mode = false # Mutually exclusive
NotificationManager.send_message(self , "Attack Mode ACTIVATED (Red)", NotificationManager.MessageType.POWERUP) NotificationManager.send_message(self , "Attack Mode ACTIVATED (Red)", NotificationManager.MessageType.POWERUP)
@@ -2249,6 +2253,10 @@ func enter_attack_mode():
func enter_knock_mode(): func enter_knock_mode():
if not is_multiplayer_authority(): return 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_knock_mode = true
is_attack_mode = false # Mutually exclusive is_attack_mode = false # Mutually exclusive
NotificationManager.send_message(self , "Knock Mode ACTIVATED (Yellow)", NotificationManager.MessageType.POWERUP) 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) tween.tween_property(self, "global_position", original_pos, duration).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN)
func knock_tekton(): 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 return
# Requirement: Full Powerup Bar (or we are already in knock mode) # Requirement: Full Powerup Bar (or we are already in knock mode)
+1 -1
View File
@@ -241,5 +241,5 @@ grow_horizontal = 0
grow_vertical = 0 grow_vertical = 0
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 0.6) theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 0.6)
theme_override_font_sizes/font_size = 11 theme_override_font_sizes/font_size = 11
text = "v1.0.0" text = "v0.9.0"
horizontal_alignment = 2 horizontal_alignment = 2
+2 -2
View File
@@ -22,8 +22,8 @@ const IOS_STORE_URL := "https://apps.apple.com/app/tekton/id123456789"
enum Platform { WINDOWS, LINUX, MACOS, ANDROID, IOS, WEB } enum Platform { WINDOWS, LINUX, MACOS, ANDROID, IOS, WEB }
# State # State
var current_version: String = "1.0.0" var current_version: String = "0.9.0"
var latest_version: String = "1.0.0" var latest_version: String = "0.9.0"
var manifest_data: Dictionary = {} var manifest_data: Dictionary = {}
var http_request: HTTPRequest var http_request: HTTPRequest
var download_request: HTTPRequest var download_request: HTTPRequest
+3 -3
View File
@@ -156,10 +156,10 @@ func try_push(target_pos: Vector2i, direction: Vector2i) -> bool:
NotificationManager.send_message(player, "Target is Immune!", NotificationManager.MessageType.WARNING) NotificationManager.send_message(player, "Target is Immune!", NotificationManager.MessageType.WARNING)
return false return false
# === NEW LOGIC: Only allow push if in ATTACK MODE === # === NEW LOGIC: Only allow push if in ATTACK MODE and NOT GHOST ===
if not player.get("is_attack_mode"): if not player.get("is_attack_mode") or player.get("is_invisible"):
# Standard bumping effect (Visual only) # 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(): if _can_rpc():
player.rpc("sync_bump", target_pos, true) # Soft bump player.rpc("sync_bump", target_pos, true) # Soft bump
elif player.has_method("sync_bump"): elif player.has_method("sync_bump"):
+5 -1
View File
@@ -155,11 +155,15 @@ func use_special_effect() -> bool:
if not can_use_special(): if not can_use_special():
return false 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: if player.is_carrying_tekton:
NotificationManager.send_message(player, "Cannot enter Attack Mode while carrying a Tekton!", NotificationManager.MessageType.WARNING) NotificationManager.send_message(player, "Cannot enter Attack Mode while carrying a Tekton!", NotificationManager.MessageType.WARNING)
return false 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 # Enable Attack Mode explicitly
player.is_attack_mode = true player.is_attack_mode = true
# Do NOT consume boost here. Boost acts as "fuel" for the attacks. # Do NOT consume boost here. Boost acts as "fuel" for the attacks.
+9 -4
View File
@@ -34,7 +34,7 @@ func get_skill_affected_area(effect: int, center_pos: Vector2i) -> Array[Vector2
match effect: match effect:
SpecialEffect.AREA_FREEZE: 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) area.append(center_pos)
SpecialEffect.BLOCK_FLOOR: SpecialEffect.BLOCK_FLOOR:
@@ -190,6 +190,11 @@ func activate_effect(effect: int, target_player: Node3D = null):
print("PowerUp %s on cooldown." % SpecialEffect.keys()[effect]) print("PowerUp %s on cooldown." % SpecialEffect.keys()[effect])
return 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 # Check Carrying Restriction
if player.get("is_carrying_tekton") and effect != SpecialEffect.FASTER_SPEED: 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) 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: if center_pos == Vector2i.ZERO:
# Calculate distance ahead based on Level # Calculate distance ahead based on Level
# Gap of 3 floors = 4 tiles ahead # Gap of 2 floors = 3 tiles ahead
# Gap of 5 floors = 6 tiles ahead # Gap of 4 floors = 5 tiles ahead
var distance = 4 if current_lvl < 5 else 6 var distance = 3 if current_lvl < 5 else 5
var movement = player.movement_manager var movement = player.movement_manager
if movement and movement.current_move_direction != Vector2i.ZERO: if movement and movement.current_move_direction != Vector2i.ZERO:
+1 -1
View File
@@ -1 +1 @@
1.0.0 0.9.0