Files
modbison/scripts/world_briefing_modal.gd

231 lines
7.5 KiB
GDScript

class_name WorldBriefingModal
extends Control
## World Briefing Card (Trust & Safety / Safe Worlds).
##
## Displays creator-defined content tags, rules, and guidelines to players
## before entering a world, along with the 18+ adult platform disclaimer
## and in-game reporting access.
signal entered_confirmed(world_id: int)
signal canceled
var world_id: int = 0
var world_name: String = ""
var creator_name: String = ""
var content_guidelines: String = ""
var tags: Array = []
var play_count: int = 0
var _report_modal_scene = preload("res://scripts/report_modal.gd")
func _init() -> void:
name = "WorldBriefingModal"
set_anchors_preset(Control.PRESET_FULL_RECT)
func setup_world_data(
p_world_id: int,
p_name: String,
p_creator: String = "",
p_guidelines: String = "",
p_tags: Array = [],
p_plays: int = 0
) -> void:
world_id = p_world_id
world_name = p_name
creator_name = p_creator
content_guidelines = p_guidelines
tags = p_tags
play_count = p_plays
var title_lbl: Label = find_child("TitleLabel", true, false) as Label
if title_lbl != null:
title_lbl.text = world_name if not world_name.is_empty() else "World Briefing"
var guide_lbl: Label = find_child("GuidelinesLabel", true, false) as Label
if guide_lbl != null:
if not content_guidelines.strip_edges().is_empty():
guide_lbl.text = content_guidelines.strip_edges()
else:
guide_lbl.text = "The creator has not specified custom rules for this world. Standard ModBison community conduct rules apply."
func _ready() -> void:
mouse_filter = Control.MOUSE_FILTER_STOP
var overlay := ColorRect.new()
overlay.color = Color(0, 0, 0, 0.75)
overlay.set_anchors_preset(Control.PRESET_FULL_RECT)
add_child(overlay)
var center := CenterContainer.new()
center.set_anchors_preset(Control.PRESET_FULL_RECT)
add_child(center)
var panel := PanelContainer.new()
panel.custom_minimum_size = Vector2(520, 0)
var style := StyleBoxFlat.new()
style.bg_color = Color(0.14, 0.16, 0.2, 1.0)
style.border_color = Color(0.3, 0.6, 0.9, 1.0)
style.set_border_width_all(2)
style.set_corner_radius_all(10)
style.content_margin_left = 24
style.content_margin_right = 24
style.content_margin_top = 20
style.content_margin_bottom = 20
panel.add_theme_stylebox_override("panel", style)
center.add_child(panel)
var vbox := VBoxContainer.new()
vbox.add_theme_constant_override("separation", 12)
panel.add_child(vbox)
# Title & Creator
var title_lbl := Label.new()
title_lbl.name = "TitleLabel"
title_lbl.text = world_name if not world_name.is_empty() else "World Briefing"
title_lbl.add_theme_font_size_override("font_size", 22)
title_lbl.add_theme_color_override("font_color", Color(1.0, 0.95, 0.4))
title_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vbox.add_child(title_lbl)
if not creator_name.is_empty():
var creator_lbl := Label.new()
creator_lbl.text = "Built by @%s • %d plays" % [creator_name, play_count]
creator_lbl.add_theme_font_size_override("font_size", 12)
creator_lbl.add_theme_color_override("font_color", Color(0.7, 0.7, 0.7))
creator_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
vbox.add_child(creator_lbl)
# Content Tags Badges
if tags.size() > 0:
var tags_hbox := HBoxContainer.new()
tags_hbox.alignment = BoxContainer.ALIGNMENT_CENTER
tags_hbox.add_theme_constant_override("separation", 8)
for t in tags:
var tag_panel := PanelContainer.new()
var tag_style := StyleBoxFlat.new()
tag_style.bg_color = Color(0.2, 0.3, 0.45, 0.8)
tag_style.set_corner_radius_all(4)
tag_style.content_margin_left = 8
tag_style.content_margin_right = 8
tag_style.content_margin_top = 4
tag_style.content_margin_bottom = 4
tag_panel.add_theme_stylebox_override("panel", tag_style)
var t_label := Label.new()
t_label.text = "#" + str(t)
t_label.add_theme_font_size_override("font_size", 11)
t_label.add_theme_color_override("font_color", Color(0.85, 0.9, 1.0))
tag_panel.add_child(t_label)
tags_hbox.add_child(tag_panel)
vbox.add_child(tags_hbox)
var sep1 := HSeparator.new()
vbox.add_child(sep1)
# World Guidelines / Rules Section
var guide_hdr := Label.new()
guide_hdr.text = "World Rules & Creator Guidelines:"
guide_hdr.add_theme_font_size_override("font_size", 13)
guide_hdr.add_theme_color_override("font_color", Color(0.4, 0.85, 1.0))
vbox.add_child(guide_hdr)
var guide_panel := PanelContainer.new()
var g_style := StyleBoxFlat.new()
g_style.bg_color = Color(0.08, 0.1, 0.12, 1.0)
g_style.set_corner_radius_all(6)
g_style.content_margin_left = 12
g_style.content_margin_right = 12
g_style.content_margin_top = 10
g_style.content_margin_bottom = 10
guide_panel.add_theme_stylebox_override("panel", g_style)
var guide_text := Label.new()
guide_text.name = "GuidelinesLabel"
if not content_guidelines.strip_edges().is_empty():
guide_text.text = content_guidelines.strip_edges()
else:
guide_text.text = "The creator has not specified custom rules for this world. Standard ModBison community conduct rules apply."
guide_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
guide_text.add_theme_font_size_override("font_size", 12)
guide_text.add_theme_color_override("font_color", Color(0.85, 0.85, 0.85))
guide_panel.add_child(guide_text)
vbox.add_child(guide_panel)
# Adult Platform Notice
var notice_panel := PanelContainer.new()
var n_style := StyleBoxFlat.new()
n_style.bg_color = Color(0.18, 0.12, 0.05, 0.7)
n_style.border_color = Color(0.8, 0.6, 0.2, 0.8)
n_style.set_border_width_all(1)
n_style.set_corner_radius_all(6)
n_style.content_margin_left = 12
n_style.content_margin_right = 12
n_style.content_margin_top = 8
n_style.content_margin_bottom = 8
notice_panel.add_theme_stylebox_override("panel", n_style)
var notice_text := Label.new()
notice_text.name = "DisclaimerLabel"
notice_text.text = "⚠️ ModBison is an 18+ community. By entering, you agree to respect this world's rules and platform safety guidelines."
notice_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
notice_text.add_theme_font_size_override("font_size", 11)
notice_text.add_theme_color_override("font_color", Color(1.0, 0.85, 0.5))
notice_panel.add_child(notice_text)
vbox.add_child(notice_panel)
# Action Buttons Row
var btn_row := HBoxContainer.new()
btn_row.alignment = BoxContainer.ALIGNMENT_END
btn_row.add_theme_constant_override("separation", 10)
var report_btn := Button.new()
report_btn.name = "ReportButton"
report_btn.text = "🚩 Report World"
report_btn.add_theme_color_override("font_color", Color(1.0, 0.4, 0.4))
report_btn.pressed.connect(_on_report_world_pressed)
btn_row.add_child(report_btn)
var spacer := Control.new()
spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
btn_row.add_child(spacer)
var cancel_btn := Button.new()
cancel_btn.name = "CancelButton"
cancel_btn.text = "Cancel"
cancel_btn.pressed.connect(_on_cancel_pressed)
btn_row.add_child(cancel_btn)
var enter_btn := Button.new()
enter_btn.name = "EnterButton"
enter_btn.text = "Enter World"
enter_btn.add_theme_color_override("font_color", Color(0.4, 1.0, 0.5))
enter_btn.pressed.connect(_on_enter_pressed)
btn_row.add_child(enter_btn)
vbox.add_child(btn_row)
func _on_enter_pressed() -> void:
entered_confirmed.emit(world_id)
queue_free()
func _on_cancel_pressed() -> void:
canceled.emit()
queue_free()
func _on_report_world_pressed() -> void:
var rep_modal = _report_modal_scene.new()
rep_modal.setup_report("world", world_id, world_name)
get_parent().add_child(rep_modal)
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel"):
get_viewport().set_input_as_handled()
_on_cancel_pressed()