İlk commit: Stepstead Godot istemci (4.6 Mobile)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jts 2026-07-11 11:31:35 +03:00
commit 6a1706051d
346 changed files with 14415 additions and 0 deletions

151
scripts/event_dialog.gd Normal file
View file

@ -0,0 +1,151 @@
extends Control
## D&D tarzı olay kartı — tam ekran karartma + kart. Seçim → sunucu çözer (d20 + skill).
## Kod ile kurulur, world.gd HUD'a ekler. Node adı "EventDialog".
var _card_title: Label
var _card_image: TextureRect
var _card_text: Label
var _choices_box: VBoxContainer
var _result_box: VBoxContainer
var _result_text: Label
var _check_text: Label
var _continue_btn: Button
func _ready() -> void:
name = "EventDialog"
visible = false
set_anchors_preset(Control.PRESET_FULL_RECT)
_build_ui()
func _build_ui() -> void:
var dim := ColorRect.new()
dim.color = Color(0, 0, 0, 0.65)
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
add_child(dim)
var center := CenterContainer.new()
center.set_anchors_preset(Control.PRESET_FULL_RECT)
add_child(center)
var card := PanelContainer.new()
card.custom_minimum_size = Vector2(560, 0)
var sb := StyleBoxFlat.new()
sb.bg_color = Color(0.13, 0.11, 0.09, 0.98)
sb.border_color = Color(0.75, 0.62, 0.35)
sb.set_border_width_all(2)
sb.set_corner_radius_all(12)
sb.set_content_margin_all(20)
card.add_theme_stylebox_override("panel", sb)
center.add_child(card)
var vbox := VBoxContainer.new()
vbox.add_theme_constant_override("separation", 12)
card.add_child(vbox)
_card_title = Label.new()
_card_title.add_theme_font_size_override("font_size", 22)
_card_title.add_theme_color_override("font_color", Color(0.9, 0.78, 0.5))
_card_title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vbox.add_child(_card_title)
# Olay illüstrasyonu — assets/events/<code>.webp varsa gösterilir
_card_image = TextureRect.new()
_card_image.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
_card_image.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
_card_image.custom_minimum_size = Vector2(0, 280)
_card_image.visible = false
vbox.add_child(_card_image)
_card_text = Label.new()
_card_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
_card_text.add_theme_font_size_override("font_size", 15)
vbox.add_child(_card_text)
_choices_box = VBoxContainer.new()
_choices_box.add_theme_constant_override("separation", 8)
vbox.add_child(_choices_box)
_result_box = VBoxContainer.new()
_result_box.add_theme_constant_override("separation", 8)
_result_box.visible = false
vbox.add_child(_result_box)
_check_text = Label.new()
_check_text.add_theme_font_size_override("font_size", 14)
_check_text.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_result_box.add_child(_check_text)
_result_text = Label.new()
_result_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
_result_text.add_theme_font_size_override("font_size", 15)
_result_box.add_child(_result_text)
_continue_btn = Button.new()
_continue_btn.text = "Devam"
_continue_btn.pressed.connect(func() -> void: visible = false)
_result_box.add_child(_continue_btn)
func show_event(ev: Dictionary) -> void:
_card_title.text = "🎴 %s" % str(ev.get("name", "Olay"))
var img_path := "res://assets/events/%s.webp" % str(ev.get("code", ""))
if ev.has("code") and ResourceLoader.exists(img_path):
_card_image.texture = load(img_path)
_card_image.visible = true
else:
_card_image.visible = false
_card_text.text = str(ev.get("text", ""))
_result_box.visible = false
_choices_box.visible = true
for c in _choices_box.get_children():
c.queue_free()
var choices: Array = ev.get("choices", [])
for i in range(choices.size()):
var ch: Dictionary = choices[i]
var btn := Button.new()
btn.text = str(ch.get("text", "Seçenek %d" % (i + 1)))
btn.pressed.connect(_on_choice.bind(i))
_choices_box.add_child(btn)
visible = true
func _on_choice(index: int) -> void:
for c in _choices_box.get_children():
if c is Button:
(c as Button).disabled = true
var res: Dictionary = await GameState.resolve_event(index)
if not res.ok:
var msg := "Olay çözülemedi"
if res.body is Dictionary and res.body.has("detail"):
msg = str(res.body["detail"])
_result_text.text = "" + msg
_check_text.text = ""
_choices_box.visible = false
_result_box.visible = true
return
var b: Dictionary = res.body
var parts: Array[String] = []
var check: Variant = b.get("skill_check")
if check is Dictionary:
var ok: bool = bool(check.get("success", false))
_check_text.text = "🎲 %d + %d%d%s" % [
int(check.get("roll", 0)), int(check.get("skill_level", 0)),
int(check.get("dc", 0)), "BAŞARILI!" if ok else "BAŞARISIZ"]
_check_text.add_theme_color_override("font_color",
Color(0.5, 0.9, 0.5) if ok else Color(0.95, 0.5, 0.4))
else:
_check_text.text = ""
parts.append(str(b.get("result_text", "")))
var sd := int(b.get("steps_delta", 0))
if sd != 0:
parts.append("%s%d adım" % ["+" if sd > 0 else "", sd])
var gd := int(b.get("gold_delta", 0))
if gd != 0:
parts.append("%s%d 🪙 gold" % ["+" if gd > 0 else "", gd])
var gained: Array = b.get("items_gained", [])
for it in gained:
parts.append("+%d× %s" % [int(it.get("qty", 1)), str(it.get("name", ""))])
var xg: Variant = b.get("xp_gained")
if xg is Dictionary:
parts.append("+%d XP (%s)" % [int(xg.get("xp", 0)), str(xg.get("skill", ""))])
_result_text.text = "\n".join(parts)
_choices_box.visible = false
_result_box.visible = true