Files
Original/code/world.gd

206 lines
6.4 KiB
GDScript3
Raw Permalink Normal View History

2026-05-09 17:39:45 +02:00
extends Area2D
# GLOBAL CFG
@onready var fade_rect: ColorRect = get_node("../Fader/ColorRect")
func fade_out(duration := 1.0):
fade_rect.visible = true
fade_rect.modulate.a = 0.0
var tween = get_tree().create_tween()
tween.tween_property(fade_rect, "modulate:a", 1.0, duration)
func fade_in(duration := 1.0):
fade_rect.visible = true
fade_rect.modulate.a = 1.0
var tween = get_tree().create_tween()
tween.tween_property(fade_rect, "modulate:a", 0.0, duration)
tween.tween_callback(Callable(self, "_on_fade_in_complete"))
func wait(seconds: float) -> void:
await get_tree().create_timer(seconds).timeout
func _on_fade_in_complete():
fade_rect.visible = false
const scalef = 3;
const textsize = 16;
func load_json(path: String): # stolen from reddit then updated to godot 4 lmao
var file := FileAccess.open(path, FileAccess.READ)
var content = file.get_as_text()
file.close()
var parsed_json = JSON.parse_string(content)
return parsed_json
func loadstring(path: String): # stolen from reddit then updated to godot 4 lmao
var file := FileAccess.open(path, FileAccess.READ)
var content = file.get_as_text()
file.close()
return content
var rng = RandomNumberGenerator.new()
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
await fade_in(1.0)
get_node("../Player").set_meta("can_walk",true)
for child in get_children(): child.queue_free()
var root = get_node("../")
var world = load_json("res://worlds/"+self.get_meta("world")+".json");
if world.has("mapscript"):
var script = loadstring("res://worlds/"+self.get_meta("world")+".lua")
get_node("../LuaEnv").reset_env()
get_node("../LuaEnv").run_script(script,self)
var assetcfg = load_json("res://assetcfg.json")
var texturespace = root.get_meta("resourcepack");
var worldassemble = {};
var plr = get_node("../Player")
plr.position = Vector2(world["pspawn"]["w"]*(16*scalef),world["pspawn"]["h"]*(16*scalef))
for y in range(world["height"]+1):
for x in range(world["width"]+1):
if not worldassemble.has(y):
worldassemble[y] = {}
worldassemble[y][x] = {"thing":world["fill"],"action":"none"}
for modifier in world["features"]:
var x = int(modifier["w"])
var y = int(modifier["h"])
worldassemble[y][x] = modifier["t"]
# assuming this script extends Node2D or Area2D that builds the world
for y in range(worldassemble.size()):
for x in range(worldassemble[y].size()):
var along = worldassemble[y][x]
var walpole = along["thing"]
var cfg = assetcfg[walpole]
# combine base data from cfg and instance-specific data from along
var tile_type = along.get("action", cfg.get("action", "default"))
var is_collidable = along.get("collidable", cfg.get("collidable", false))
var tex_path = "res://%s/text/%s" % [texturespace, cfg["textname"]]
var tex = load(tex_path)
# --- choose node type
var tile_node: Node2D
if tile_type == "tp":
tile_node = Area2D.new() # teleporter
elif is_collidable:
tile_node = StaticBody2D.new() # solid
else:
tile_node = Area2D.new() # non-collidable sensor/decor
add_child(tile_node)
tile_node.position = Vector2(x * (scalef * textsize), y * (scalef * textsize))
tile_node.name = "tile_%s_%s" % [x, y]
tile_node.set_meta("collidable", is_collidable)
# --- sprite
var sprite = Sprite2D.new()
sprite.texture = tex
sprite.scale = Vector2(scalef, scalef)
tile_node.add_child(sprite)
# optional random rotation
if cfg.get("allowRandRot", false):
sprite.rotation_degrees = 90 * rng.randi_range(0, 3)
# --- collision shape for solids and sensors
if is_collidable or tile_type == "tp":
var col = CollisionShape2D.new()
var shape = RectangleShape2D.new()
shape.size = Vector2(16 * scalef, 16 * scalef)
col.shape = shape
col.position = Vector2.ZERO
tile_node.add_child(col)
# --- teleporter setup
if tile_type == "tp":
var target_world = along.get("target_world", cfg.get("target_world", "default"))
tile_node.set_meta("world", target_world)
tile_node.connect("body_entered", Callable(self, "_on_tp_entered").bind(tile_node))
_add_world_borders(world["width"], world["height"])
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func _on_tp_entered(body: Node, source: Node) -> void:
if not body.is_in_group("player"):
return
print("Teleport triggered by:", body.name)
await fade_out(1.0)
get_node("../Player").set_meta("can_walk",false)
await wait(1.0)
if body.has_method("set_velocity"):
body.set_velocity(Vector2.ZERO)
if source.has_meta("world"):
var new_world = source.get_meta("world")
print("Teleporting to world:", new_world)
set_meta("world", new_world)
call_deferred("_ready") # safely rebuild
else:
print("⚠️ Teleporter node has no 'world' meta set!")
func _add_world_borders(width: int, height: int) -> void:
var border_thickness = 32.0 * scalef
var w_px = width * (textsize * scalef)
var h_px = height * (textsize * scalef)
var positions = {
"top": Vector2(w_px / 2, -border_thickness / 2),
"bottom": Vector2(w_px / 2, h_px + border_thickness / 2),
"left": Vector2(-border_thickness / 2, h_px / 2),
"right": Vector2(w_px + border_thickness / 2, h_px / 2)
}
for name in positions.keys():
var wall = StaticBody2D.new()
wall.name = "border_%s" % name
var shape = RectangleShape2D.new()
if name in ["top", "bottom"]:
shape.size = Vector2(w_px + border_thickness, border_thickness)
else:
shape.size = Vector2(border_thickness, h_px + border_thickness)
var col = CollisionShape2D.new()
col.shape = shape
wall.position = positions[name]
wall.add_child(col)
add_child(wall)
@onready var label: RichTextLabel = null
@onready var uitypebox: ColorRect = null
var typing_speed := 0.03 # seconds between characters
var typing = false # to prevent overlapping animations
func ui_showmesg(t: String) -> void:
label = get_node("../UI/bg/RichTextLabel")
uitypebox = get_node("../UI/bg")
if typing:
return # skip if already typing (optional safeguard)
uitypebox.visible = true
typing = true
print(label, " valid? ", is_instance_valid(label))
label.text = t
label.visible_characters = 0
await _type_text(t)
await wait(4)
label = get_node("../UI/bg/RichTextLabel")
uitypebox = get_node("../UI/bg")
label.visible_characters = 0
uitypebox.visible = false
typing = false
func _type_text(t: String) -> void:
var i := 0
while i < t.length():
i += 1
label.visible_characters = i
await wait(typing_speed)