import streamlit as st # 🌐 Streamlit magic import streamlit.components.v1 as components # πŸ–ΌοΈ Embed custom HTML/JS import os # πŸ“‚ File operations import json # πŸ”„ JSON encoding/decoding import pandas as pd # πŸ“Š DataFrame handling import uuid # πŸ†” Unique IDs import math # βž— Math utils import time # ⏳ Time utilities from gamestate import GameState # πŸ’Ό Shared game‐state singleton # πŸš€ Page setup st.set_page_config(page_title="Infinite World Builder", layout="wide") # πŸ“ Constants for world dimensions & CSV schema SAVE_DIR = "saved_worlds" PLOT_WIDTH = 50.0 # ↔️ Plot width in world units PLOT_DEPTH = 50.0 # ↕️ Plot depth in world units CSV_COLUMNS = [ 'obj_id', 'type', 'pos_x', 'pos_y', 'pos_z', 'rot_x', 'rot_y', 'rot_z', 'rot_order' ] # πŸ—‚οΈ Ensure directory for plots exists os.makedirs(SAVE_DIR, exist_ok=True) # … your existing load_plot_metadata, load_plot_objects, save_plot_data, GameState, etc. … # 🧠 Session state defaults st.session_state.setdefault('selected_object','None') st.session_state.setdefault('new_plot_name','') st.session_state.setdefault('js_save_data_result',None) # πŸ”„ Load everything plots_metadata = load_plot_metadata() all_initial_objects = [] for p in plots_metadata: all_initial_objects += load_plot_objects(p['filename'], p['x_offset'], p['z_offset']) # πŸ–₯️ Sidebar UI with st.sidebar: st.title("πŸ—οΈ World Controls") st.header("πŸ“ Navigate Plots") cols = st.columns(2) i = 0 for p in sorted(plots_metadata, key=lambda x:(x['grid_x'],x['grid_z'])): label = f"➑️ {p['name']} ({p['grid_x']},{p['grid_z']})" if cols[i].button(label, key=f"nav_{p['id']}"): try: from streamlit_js_eval import streamlit_js_eval js = f"teleportPlayer({p['x_offset']+PLOT_WIDTH/2},{p['z_offset']+PLOT_DEPTH/2});" streamlit_js_eval(js_code=js, key=f"tp_{p['id']}") except Exception as e: st.error(f"TP fail: {e}") i = (i+1)%2 st.markdown("---") st.header("🌲 Place Objects") # ←─── HERE: add your four builder‐tool options ────→ opts = [ "None", "Simple House", "Tree", "Rock", "Fence Post", "Cyberpunk City Builder Kit", "POLYGON - Fantasy Kingdom Pack", "HEROIC FANTASY CREATURES FULL PACKΒ VOLΒ 1", "POLYGON - Apocalypse Pack" ] idx = opts.index(st.session_state.selected_object) if st.session_state.selected_object in opts else 0 sel = st.selectbox("Select:", opts, index=idx, key="selected_object_widget") if sel != st.session_state.selected_object: st.session_state.selected_object = sel st.markdown("---") st.header("πŸ’Ύ Save Work") if st.button("πŸ’Ύ Save Current Work", key="save_button"): from streamlit_js_eval import streamlit_js_eval streamlit_js_eval(js_code="getSaveDataAndPosition();", key="js_save_processor") st.rerun() # … the rest of your existing handler for save, and main view injection …