4747 st .sidebar .warning (f"**{ w ['type' ]} [{ w ['name' ]} ]**: { w ['msg' ]} " )
4848
4949
50- def edit_list (data_list , key_prefix ):
50+ def edit_list (data_list , key_prefix , item_pool = None ):
51+ if item_pool is None :
52+ item_pool = [it ["Name" ] for i in [manager .unified_data ["items" ]] for it in i ]
53+
5154 to_delete = None
5255 for i , entry in enumerate (data_list ):
5356 col1 , col2 , col3 = st .columns ([3 , 2 , 1 ])
5457 with col1 :
55- # Safely find index of current item
56- item_names = [it ["Name" ] for i in [manager .unified_data ["items" ]] for it in i ]
5758 current_index = 0
58- if entry ["Item" ] in item_names :
59- current_index = item_names .index (entry ["Item" ])
59+ if entry ["Item" ] in item_pool :
60+ current_index = item_pool .index (entry ["Item" ])
6061
61- new_name = st .selectbox (f"Item { i } " , item_names , index = current_index , key = f"{ key_prefix } _name_{ i } " )
62+ new_name = st .selectbox (f"Item { i } " , item_pool , index = current_index , key = f"{ key_prefix } _name_{ i } " )
6263 entry ["Item" ] = new_name
6364
6465 with col2 :
@@ -73,41 +74,75 @@ def edit_list(data_list, key_prefix):
7374 st .rerun ()
7475
7576 if st .button ("➕ Add Entry" , key = f"{ key_prefix } _add" ):
76- data_list .append ({"Item" : manager . unified_data [ "items" ][ 0 ][ "Name" ], "Quantity" : 1 })
77+ data_list .append ({"Item" : item_pool [ 0 ], "Quantity" : 1 })
7778 st .rerun ()
7879
79- def edit_dict_list ( data_dict , key_prefix , label_name = "Stat" ):
80+ def edit_recipes ( recipes , key_prefix ):
8081 to_delete = None
81- keys = list (data_dict .keys ())
82- for i , key in enumerate (keys ):
83- col1 , col2 , col3 = st .columns ([3 , 2 , 1 ])
84- with col1 :
85- stat_names = [s ["Name" ] for s in manager .unified_data ["stats" ]]
86- current_index = 0
87- if key in stat_names :
88- current_index = stat_names .index (key )
89-
90- new_key = st .selectbox (f"{ label_name } { i } " , stat_names , index = current_index , key = f"{ key_prefix } _key_{ i } " )
91- if new_key != key :
92- data_dict [new_key ] = data_dict .pop (key )
93- st .rerun ()
82+ item_names = [i ["Name" ] for i in manager .unified_data ["items" ]]
83+ for i , recipe in enumerate (recipes ):
84+ with st .container (border = True ):
85+ col1 , col2 , col3 , col4 , col5 = st .columns ([2 , 1 , 2 , 1 , 0.5 ])
86+ with col1 :
87+ recipe ["InputItem" ] = st .selectbox ("In" , item_names , index = item_names .index (recipe ["InputItem" ]) if recipe ["InputItem" ] in item_names else 0 , key = f"{ key_prefix } _in_{ i } " )
88+ with col2 :
89+ recipe ["InputQuantity" ] = st .number_input ("Qty" , value = recipe ["InputQuantity" ], min_value = 1 , key = f"{ key_prefix } _in_q_{ i } " )
90+ with col3 :
91+ recipe ["OutputItem" ] = st .selectbox ("Out" , item_names , index = item_names .index (recipe ["OutputItem" ]) if recipe ["OutputItem" ] in item_names else 0 , key = f"{ key_prefix } _out_{ i } " )
92+ with col4 :
93+ recipe ["OutputQuantity" ] = st .number_input ("Qty" , value = recipe ["OutputQuantity" ], min_value = 1 , key = f"{ key_prefix } _out_q_{ i } " )
94+ with col5 :
95+ if st .button ("🗑️" , key = f"{ key_prefix } _del_{ i } " ):
96+ to_delete = i
97+
98+ if to_delete is not None :
99+ recipes .pop (to_delete )
100+ st .rerun ()
101+
102+ if st .button ("➕ Add Recipe" , key = f"{ key_prefix } _add" ):
103+ recipes .append ({"InputItem" : item_names [0 ], "InputQuantity" : 1 , "OutputItem" : item_names [0 ], "OutputQuantity" : 1 })
104+ st .rerun ()
105+
106+ def edit_cadence_abilities (abilities_list , key_prefix ):
107+ to_delete = None
108+ all_ability_names = [a ["Name" ] for a in manager .unified_data ["abilities" ]]
109+ stat_names = [s ["Name" ] for s in manager .unified_data ["stats" ]]
110+
111+ for i , ab_entry in enumerate (abilities_list ):
112+ with st .container (border = True ):
113+ col1 , col2 , col3 = st .columns ([3 , 2 , 1 ])
114+ with col1 :
115+ # The nested structure is {"Ability": {"Name": "...", "Description": "..."}, "Requirements": [...], "PrimaryStat": "..."}
116+ current_ab_name = ab_entry ["Ability" ]["Name" ]
117+ new_ab_name = st .selectbox (f"Ability { i } " , all_ability_names , index = all_ability_names .index (current_ab_name ) if current_ab_name in all_ability_names else 0 , key = f"{ key_prefix } _ab_{ i } " )
94118
95- with col2 :
96- data_dict [new_key ] = st .number_input (f"Value { i } " , value = data_dict [new_key ], key = f"{ key_prefix } _val_{ i } " )
119+ if new_ab_name != current_ab_name :
120+ source_ab = next (a for a in manager .unified_data ["abilities" ] if a ["Name" ] == new_ab_name )
121+ ab_entry ["Ability" ]["Name" ] = source_ab ["Name" ]
122+ ab_entry ["Ability" ]["Description" ] = source_ab ["Description" ]
97123
98- with col3 :
99- if st .button ("🗑️" , key = f"{ key_prefix } _del_{ i } " ):
100- to_delete = key
101-
124+ with col2 :
125+ ab_entry ["PrimaryStat" ] = st .selectbox (f"Stat { i } " , stat_names , index = stat_names .index (ab_entry ["PrimaryStat" ]) if ab_entry ["PrimaryStat" ] in stat_names else 0 , key = f"{ key_prefix } _stat_{ i } " )
126+
127+ with col3 :
128+ if st .button ("🗑️ Remove Ability" , key = f"{ key_prefix } _del_{ i } " ):
129+ to_delete = i
130+
131+ st .write ("**Requirements**" )
132+ edit_list (ab_entry ["Requirements" ], f"{ key_prefix } _req_{ i } " )
133+
102134 if to_delete is not None :
103- del data_dict [to_delete ]
135+ abilities_list .pop (to_delete )
136+ st .rerun ()
137+
138+ if st .button ("➕ Add Ability to Cadence" , key = f"{ key_prefix } _add" ):
139+ source_ab = manager .unified_data ["abilities" ][0 ]
140+ abilities_list .append ({
141+ "Ability" : {"Name" : source_ab ["Name" ], "Description" : source_ab ["Description" ]},
142+ "Requirements" : [],
143+ "PrimaryStat" : "Magic"
144+ })
104145 st .rerun ()
105-
106- if st .button (f"➕ Add { label_name } " , key = f"{ key_prefix } _add" ):
107- available = [s ["Name" ] for s in manager .unified_data ["stats" ] if s ["Name" ] not in data_dict ]
108- if available :
109- data_dict [available [0 ]] = 1
110- st .rerun ()
111146
112147# --- Page Rendering ---
113148
@@ -133,6 +168,11 @@ def edit_dict_list(data_dict, key_prefix, label_name="Stat"):
133168 new_item .update ({"DurationSeconds" : 10 , "Type" : "Single" , "Requirements" : [], "Rewards" : [], "PrimaryStat" : "Vitality" , "RequiredStats" : {}, "StatRewards" : {}, "Requires" : [], "UnlocksCadences" : []})
134169 elif page == "Items" :
135170 new_item .update ({"ItemType" : "Material" , "Augments" : []})
171+ elif page == "Cadences" :
172+ new_item .update ({"Abilities" : []})
173+ elif page == "Refinements" :
174+ new_item = {"Name" : "New Refinement" , "PrimaryStat" : "Strength" , "Recipes" : []}
175+
136176 manager .unified_data [page .lower ()].append (new_item )
137177 st .rerun ()
138178
@@ -142,9 +182,13 @@ def edit_dict_list(data_dict, key_prefix, label_name="Stat"):
142182 with st .form (f"edit_{ page } _{ selected_name } " ):
143183 st .subheader (f"Editing: { selected_name } " )
144184
145- name = st .text_input ("Name" , item ["Name" ])
146- description = st .text_area ("Description" , item .get ("Description" , "" ))
147-
185+ if page != "Refinements" : # Refinements use 'Ability' as name, handled in data_io
186+ name = st .text_input ("Name" , item ["Name" ])
187+ description = st .text_area ("Description" , item .get ("Description" , "" ))
188+ else :
189+ name = st .selectbox ("Ability Base" , [a ["Name" ] for a in manager .unified_data ["abilities" ]], index = [a ["Name" ] for a in manager .unified_data ["abilities" ]].index (item ["Name" ]) if item ["Name" ] in [a ["Name" ] for a in manager .unified_data ["abilities" ]] else 0 )
190+ description = "" # Not used for refinements
191+
148192 if page == "Quests" :
149193 col1 , col2 , col3 = st .columns (3 )
150194 with col1 :
@@ -158,25 +202,26 @@ def edit_dict_list(data_dict, key_prefix, label_name="Stat"):
158202 st .subheader ("Unlocks & Dependencies" )
159203 requires = st .multiselect ("Prerequisite Quests" , [q ["Name" ] for q in manager .unified_data ["quests" ] if q ["Name" ] != name ], default = item ["Requires" ])
160204 unlocks_c = st .multiselect ("Unlocks Cadences" , [c ["Name" ] for c in manager .unified_data ["cadences" ]], default = item ["UnlocksCadences" ])
161-
162- # Complex nested data (Requirements/Rewards) are hard in standard Streamlit forms
163- # so we'll just show them as JSON for now or implement outside form
164- st .info ("Requirements and Rewards are managed below the form for technical reasons." )
165205
166- if page == "Items" :
206+ elif page == "Items" :
167207 i_type = st .selectbox ("Type" , ["Material" , "Currency" , "Consumable" , "Spell" , "KeyItem" ], index = ["Material" , "Currency" , "Consumable" , "Spell" , "KeyItem" ].index (item ["ItemType" ]))
208+
209+ elif page == "Refinements" :
210+ stat = st .selectbox ("Primary Stat" , [s ["Name" ] for s in manager .unified_data ["stats" ]], index = [s ["Name" ] for s in manager .unified_data ["stats" ]].index (item ["PrimaryStat" ]))
168211
169212 if st .form_submit_button ("Update Basic Info" ):
170213 item ["Name" ] = name
171- item ["Description" ] = description
214+ if "Description" in item : item ["Description" ] = description
172215 if page == "Quests" :
173216 item ["DurationSeconds" ] = duration
174217 item ["Type" ] = q_type
175218 item ["PrimaryStat" ] = stat
176219 item ["Requires" ] = requires
177220 item ["UnlocksCadences" ] = unlocks_c
178- if page == "Items" :
221+ elif page == "Items" :
179222 item ["ItemType" ] = i_type
223+ elif page == "Refinements" :
224+ item ["PrimaryStat" ] = stat
180225 st .success ("Updated basic info in memory." )
181226 st .rerun ()
182227
@@ -193,8 +238,20 @@ def edit_dict_list(data_dict, key_prefix, label_name="Stat"):
193238
194239 st .subheader ("📈 Stat Rewards" )
195240 edit_dict_list (item ["StatRewards" ], "rew_stat" )
241+
242+ elif page == "Cadences" :
243+ st .subheader ("⚡ Abilities" )
244+ edit_cadence_abilities (item ["Abilities" ], "cad_ab" )
245+
246+ elif page == "Refinements" :
247+ st .subheader ("🧪 Recipes" )
248+ edit_recipes (item ["Recipes" ], "ref_rec" )
249+
250+ elif page == "Abilities" :
251+ st .info ("Abilities themselves are simple Name/Description. Use the Cadence page to assign them and define requirements." )
196252
197253 if st .button ("🔥 Delete Entity" , type = "secondary" ):
198254 manager .unified_data [page .lower ()].remove (item )
199255 st .warning (f"Deleted { selected_name } from memory." )
200256 st .rerun ()
257+
0 commit comments