· 4 months ago · Jun 05, 2025, 10:45 PM
1import tkinter as tk
2from tkinter import ttk, scrolledtext, messagebox
3import csv
4import random
5import os
6
7class MagicItemGenerator:
8 def __init__(self):
9 self.root = tk.Tk()
10 self.root.title("Arcane Treasury Generator")
11 self.root.geometry("1000x800")
12 self.root.configure(bg='#1a0f0a')
13
14 # Data storage
15 self.item_tables = {}
16 self.all_items = []
17 self.total_items = 0
18
19 # Store last generation info for reroll functionality
20 self.last_generation = {
21 'category': None,
22 'table_id': None,
23 'items': [],
24 'available': False
25 }
26
27 # Store current item for enhancement
28 self.current_item = {
29 'name': None,
30 'original_name': None,
31 'category': None,
32 'table': None,
33 'available': False,
34 'ee_count': 0, # Track EE enhancements applied
35 'quirks_count': 0 # Track Quirks enhancements applied
36 }
37
38 # Load CSV data
39 self.load_csv_data()
40
41 # Create GUI
42 self.create_gui()
43
44 def load_csv_data(self):
45 """Load all CSV files with exact matching names"""
46 table_files = [
47 ('A', 'Table_A.csv', 'Magical Liquids'),
48 ('B', 'Table_B.csv', 'Scrolls'),
49 ('C', 'Table_C.csv', 'Rings'),
50 ('D', 'Table_D.csv', 'Rods'),
51 ('E', 'Table_E.csv', 'Staves'),
52 ('F', 'Table_F.csv', 'Wands'),
53 ('G', 'Table_G.csv', 'Books'),
54 ('H', 'Table_H.csv', 'Gems & Jewelry'),
55 ('I', 'Table_I.csv', 'Clothing'),
56 ('J', 'Table_J.csv', 'Boots & Gloves'),
57 ('K', 'Table_K.csv', 'Girdles & Helmets'),
58 ('L', 'Table_L.csv', 'Bags & Bottles'),
59 ('M', 'Table_M.csv', 'Dust & Stones'),
60 ('N', 'Table_N.csv', 'Household Items'),
61 ('O', 'Table_O.csv', 'Musical Instruments'),
62 ('P', 'Table_P.csv', 'Weird Stuff'),
63 ('Q', 'Table_Q.csv', 'Humorous Items'),
64 ('R1', 'Table_R1.csv', 'Armor and Shields'),
65 ('R2', 'Table_R2.csv', 'Armor and Shields'),
66 ('R3', 'Table_R3.csv', 'Armor and Shields'),
67 ('S1', 'Table_S1.csv', 'Weapons'),
68 ('S2', 'Table_S2.csv', 'Weapons'),
69 ('S3', 'Table_S3.csv', 'Weapons'),
70 ('T', 'Table_T.csv', 'Final Items'),
71 ('1', 'Table_1.csv', 'Main Category Table'),
72 # Enhancement tables
73 ('EE', 'EE_Table.csv', 'Enchanted Enhancements'),
74 ('QE', 'QE_Table.csv', 'Quirk Effects'),
75 ('QP', 'QP_Table.csv', 'Quirks Present'),
76 ('AE', 'AE_Table.csv', 'Aquatic Enhancements'),
77 ('RE', 'RE_Table.csv', 'Racial Enhancements'),
78 ]
79
80 print("Loading CSV files...")
81
82 for table_id, filename, category in table_files:
83 file_path = os.path.join('data', 'tables', filename)
84 if os.path.exists(file_path):
85 print(f"✓ Found: {filename}")
86 try:
87 with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
88 reader = csv.DictReader(f)
89 items = []
90
91 for row in reader:
92 item_name = None
93 roll_from = None
94 roll_to = None
95
96 # Find item name - expanded column search for enhancement tables
97 for col in ['Item Discovered', 'Generic Magic Weapon', 'Item', 'Magical Item Category', 'd100 Roll', 'Type', 'Effect', 'Quirks Present', 'Variant', 'Race']:
98 if col in row and row[col] and row[col].strip():
99 item_name = str(row[col]).strip()
100 break
101
102 # Special handling for Table_S2
103 if table_id == 'S2':
104 for col in ['Roll From', 'Roll (Low)', 'Roll Low']:
105 if col in row and row[col] is not None and str(row[col]).strip():
106 try:
107 roll_from = int(row[col])
108 break
109 except ValueError:
110 pass
111
112 for col in ['Roll to', 'Roll To', 'Roll (High)', 'Roll High']:
113 if col in row and row[col] is not None and str(row[col]).strip():
114 try:
115 roll_to = int(row[col])
116 break
117 except ValueError:
118 pass
119
120 if not item_name and roll_from is not None:
121 wpn_adj = row.get('Wpn Adj', '')
122 wpn_xp = row.get('Wpn XP Val', '')
123 gp_val = row.get('GP Value', '')
124
125 if wpn_adj is not None and str(wpn_adj).strip() != '':
126 wpn_adj_val = int(wpn_adj)
127 if wpn_adj_val > 0:
128 item_name = f"+{wpn_adj_val} enhancement, {wpn_xp} XP, {gp_val} GP"
129 elif wpn_adj_val < 0:
130 item_name = f"{wpn_adj_val} cursed, {wpn_xp} XP, {gp_val} GP"
131 else:
132 item_name = f"normal weapon, {wpn_xp} XP, {gp_val} GP"
133
134 # Special handling for R2
135 elif table_id == 'R2' and not item_name:
136 ac_adj = row.get('AC Adj', '')
137 xp_val = row.get('XP Value', '')
138 gp_val = row.get('GP Value', '')
139 if ac_adj and str(ac_adj).strip():
140 if float(ac_adj) > 0:
141 item_name = f"+{ac_adj} AC bonus, {xp_val} XP, {gp_val} GP"
142 elif float(ac_adj) < 0:
143 item_name = f"{ac_adj} AC penalty, {xp_val} XP, {gp_val} GP"
144 else:
145 item_name = f"normal armor, {xp_val} XP, {gp_val} GP"
146
147 # Standard roll range parsing
148 if table_id != 'S2' and roll_from is None:
149 for col in ['Roll From', 'Roll (Low)', 'Roll Low', 'Roll low', 'Low Roll', 'd100 Roll']:
150 if col in row and row[col] and str(row[col]).strip():
151 try:
152 roll_from = int(row[col])
153 break
154 except ValueError:
155 if '-' in str(row[col]):
156 parts = str(row[col]).split('-')
157 if len(parts) == 2:
158 try:
159 roll_from = int(parts[0])
160 break
161 except ValueError:
162 pass
163
164 for col in ['Roll To', 'Roll (High)', 'Roll High', 'Roll high', 'High Roll', 'Roll to']:
165 if col in row and row[col] and str(row[col]).strip():
166 try:
167 roll_to = int(row[col])
168 break
169 except ValueError:
170 pass
171
172 if roll_from is not None and roll_to is None:
173 for col in ['d100 Roll']:
174 if col in row and row[col] and '-' in str(row[col]):
175 parts = str(row[col]).split('-')
176 if len(parts) == 2:
177 try:
178 roll_to = int(parts[1])
179 break
180 except ValueError:
181 pass
182
183 if item_name and item_name != '' and roll_from is not None:
184 item = {
185 'name': item_name,
186 'roll_from': roll_from,
187 'roll_to': roll_to if roll_to is not None else roll_from,
188 'category': category,
189 'table': table_id
190 }
191
192 if table_id == '1':
193 item['Magical Item Category'] = row.get('Magical Item Category', '')
194 item['Tables'] = row.get('Tables', '')
195
196 items.append(item)
197 self.all_items.append(item)
198
199 self.item_tables[table_id] = {
200 'category': category,
201 'items': items,
202 'filename': filename
203 }
204
205 self.total_items += len(items)
206 print(f" Loaded {len(items)} items from {category}")
207
208 except Exception as e:
209 print(f" Error reading {filename}: {e}")
210
211 else:
212 print(f"✗ Missing: {filename}")
213
214 print(f"\nTotal items loaded: {self.total_items}")
215 print(f"Tables loaded: {len(self.item_tables)}")
216
217 def has_enhancement_symbols(self, item_name):
218 """Check if item has enhancement symbols"""
219 name = item_name.strip()
220 if name.startswith('**') and name.endswith('**'):
221 return False
222 symbols = '*#%@&^$'
223 return any(s in name for s in symbols)
224
225 def is_reroll_item(self, item_name):
226 """Check if item has enhancement symbols"""
227 return self.has_enhancement_symbols(item_name)
228
229 def is_unique_artifact(self, item_name):
230 """Check if item is **unique** artifact"""
231 name = item_name.strip()
232 return name.startswith('**') and name.endswith('**')
233
234 def clean_unique_name(self, item_name):
235 """Remove ** markers from unique artifacts"""
236 if self.is_unique_artifact(item_name):
237 return item_name.strip('*')
238 return item_name
239
240 def parse_enhancement_symbols(self, item_name):
241 """Parse all enhancement symbols from item name"""
242 symbols = {
243 'reroll': '*' in item_name,
244 'enchanted': '#' in item_name,
245 'aquatic': '%' in item_name,
246 'quirks': '@' in item_name,
247 'racial': '&' in item_name,
248 'no_duplicate': '^' in item_name,
249 'weapon_enhancement': '$' in item_name
250 }
251
252 # Get base name without symbols
253 base_name = item_name
254 for symbol in '*#%@&^$':
255 base_name = base_name.replace(symbol, '')
256 symbols['base_name'] = base_name.strip()
257
258 return symbols
259
260 def process_enhanced_item(self, item_name, source_table, applied_enhancements=None, max_enhancements=3):
261 """Process item with enhancement symbols"""
262 if applied_enhancements is None:
263 applied_enhancements = []
264
265 processing_log = []
266
267 # Check for unique artifacts first
268 if self.is_unique_artifact(item_name):
269 clean_name = self.clean_unique_name(item_name)
270 processing_log.append(f"✨ Unique artifact: {item_name} → {clean_name}")
271 return clean_name, processing_log, applied_enhancements
272
273 # Parse enhancement symbols
274 symbols = self.parse_enhancement_symbols(item_name)
275 base_name = symbols['base_name']
276
277 # SPECIAL CASE: If this is "Racial Enhancements" and RE table is empty, skip entirely
278 if base_name == "Racial Enhancements" and ('RE' not in self.item_tables or not self.item_tables['RE']['items']):
279 processing_log.append(f"👥 Racial Enhancement for: {base_name}")
280 processing_log.append(f"⚠️ RE table is empty - skipping racial enhancement completely")
281 # Return just the base item without the racial enhancement
282 return "", processing_log, applied_enhancements
283
284 # Track current item for building final name
285 current_item = base_name
286
287 # Handle reroll for base item - BUILD THE CHAIN WITH LIMIT
288 if symbols['reroll']:
289 reroll_result, base_log = self.roll_for_base_item_chain(source_table, applied_enhancements)
290 processing_log.extend(base_log)
291
292 # Combine base name with reroll chain
293 if reroll_result != base_name and reroll_result:
294 current_item = f"{base_name} + {reroll_result}"
295 else:
296 current_item = base_name
297
298 # Handle weapon enhancement first ($ symbol)
299 if symbols['weapon_enhancement']:
300 enhanced_item, weapon_log = self.process_weapon_enhancement(current_item, applied_enhancements)
301 processing_log.extend(weapon_log)
302 return enhanced_item, processing_log, applied_enhancements
303
304 # Handle other enhancements (max 3 total)
305 if len(applied_enhancements) < max_enhancements:
306 # Enchanted Enhancements (#)
307 if symbols['enchanted']:
308 enhanced_item, ee_log, applied_enhancements = self.process_enchanted_enhancement(current_item, applied_enhancements, max_enhancements)
309 processing_log.extend(ee_log)
310 current_item = enhanced_item
311
312 # Aquatic (%)
313 if symbols['aquatic']:
314 enhancement_name = "Aquatic"
315 if symbols['no_duplicate'] and enhancement_name in applied_enhancements:
316 processing_log.append(f"🚫 {enhancement_name} already applied, skipping")
317 else:
318 enhanced_item, aquatic_log = self.process_aquatic_enhancement(current_item)
319 processing_log.extend(aquatic_log)
320 current_item = enhanced_item
321 if symbols['no_duplicate']:
322 applied_enhancements.append(enhancement_name)
323
324 # Quirks (@)
325 if symbols['quirks']:
326 enhanced_item, quirk_log = self.process_quirks_enhancement(current_item)
327 processing_log.extend(quirk_log)
328 current_item = enhanced_item
329
330 # Racial (&)
331 if symbols['racial']:
332 # Check if RE table is available
333 if 'RE' not in self.item_tables or not self.item_tables['RE']['items']:
334 processing_log.append(f"👥 Racial Enhancement for: {current_item}")
335 processing_log.append(f"⚠️ RE table is empty - skipping racial enhancement")
336 # Don't modify current_item, just skip the enhancement
337 else:
338 enhanced_item, racial_log = self.process_racial_enhancement(current_item)
339 processing_log.extend(racial_log)
340 current_item = enhanced_item
341 else:
342 processing_log.append(f"🚫 Max enhancements ({max_enhancements}) reached")
343
344 return current_item, processing_log, applied_enhancements
345
346 def apply_manual_ee_enhancement(self, base_item_name, applied_enhancements=None, max_enhancements=3):
347 """Manually apply EE enhancement to any item - allow up to 3 EE enhancements total"""
348 if applied_enhancements is None:
349 applied_enhancements = []
350
351 processing_log = []
352
353 # Apply EE enhancement
354 enhanced_item, ee_log, updated_enhancements = self.process_enchanted_enhancement(
355 base_item_name, [], max_enhancements # Start fresh for each manual application
356 )
357 processing_log.extend(ee_log)
358
359 return enhanced_item, processing_log, updated_enhancements
360
361 def apply_manual_quirks_enhancement(self, base_item_name):
362 """Manually apply Quirks enhancement to any item"""
363 processing_log = []
364
365 # Apply Quirks enhancement
366 enhanced_item, quirks_log = self.process_quirks_enhancement(base_item_name)
367 processing_log.extend(quirks_log)
368
369 return enhanced_item, processing_log
370
371 def roll_for_base_item_chain(self, source_table, applied_enhancements):
372 """Roll same table for base item and build enhancement chain"""
373 log = []
374 enhancement_chain = []
375 seen_enhancements = set() # Track duplicate enhancements for ^ symbol
376
377 if source_table not in self.item_tables:
378 log.append(f"⚠️ Source table {source_table} not available")
379 return "Unknown Item", log
380
381 table_items = self.item_tables[source_table]['items']
382 if not table_items:
383 log.append(f"⚠️ Source table {source_table} is empty")
384 return "Unknown Item", log
385
386 attempts = 0
387 max_attempts = 15 # Increased to handle ^ symbol rerolls
388
389 while attempts < max_attempts:
390 base_item_data = random.choice(table_items)
391 base_roll = random.randint(base_item_data['roll_from'], base_item_data['roll_to'])
392 base_name = base_item_data['name']
393
394 log.append(f" → Base item roll: {base_roll} → {base_name}")
395
396 # Parse the enhancement symbols
397 if self.has_enhancement_symbols(base_name):
398 symbols = self.parse_enhancement_symbols(base_name)
399 clean_name = symbols['base_name']
400
401 # Check for no_duplicate (^) symbol
402 if symbols['no_duplicate']:
403 # Check if we've already seen this enhancement type (case-insensitive)
404 enhancement_type = clean_name.lower().strip()
405 if enhancement_type in seen_enhancements:
406 log.append(f" 🚫 Duplicate enhancement '{clean_name}' blocked by ^ symbol, rerolling...")
407 attempts += 1
408 continue # Reroll to get a different enhancement
409 else:
410 seen_enhancements.add(enhancement_type)
411 log.append(f" ✅ New enhancement '{clean_name}' allowed by ^ symbol")
412
413 # Process the enhancement symbols first, then add to chain
414 processed_enhancement = clean_name
415
416 # Handle specific enhancement symbols
417 if symbols['quirks']:
418 processed_enhancement, quirk_log = self.process_quirks_enhancement(clean_name)
419 log.extend([f" {line}" for line in quirk_log])
420 elif symbols['aquatic']:
421 processed_enhancement, aquatic_log = self.process_aquatic_enhancement(clean_name)
422 log.extend([f" {line}" for line in aquatic_log])
423 elif symbols['racial']:
424 # Check if RE table is available before processing
425 if 'RE' not in self.item_tables or not self.item_tables['RE']['items']:
426 log.append(f" 👥 Racial Enhancement for: {clean_name}")
427 log.append(f" ⚠️ RE table is empty - skipping racial enhancement")
428 log.append(f" → Racial enhancement failed, skipping from chain")
429 attempts += 1
430 continue # Skip this enhancement and try again
431 else:
432 processed_enhancement, racial_log = self.process_racial_enhancement(clean_name)
433 log.extend([f" {line}" for line in racial_log])
434 else:
435 # For other symbols like ^ (no duplicate), just use clean name
436 processed_enhancement = clean_name
437
438 enhancement_chain.append(processed_enhancement)
439
440 # If it has reroll symbol, continue the chain
441 if symbols['reroll']:
442 log.append(f" → Base item has enhancements, continuing chain...")
443 attempts += 1
444 continue # Keep rolling to build the chain
445 else:
446 # No reroll symbol, end the chain
447 break
448 else:
449 # Regular item, end the chain
450 enhancement_chain.append(base_name)
451 break
452
453 attempts += 1
454
455 # Check if we hit max attempts due to ^ symbol conflicts
456 if attempts >= max_attempts:
457 log.append(f"⚠️ Max attempts reached due to ^ symbol duplicate prevention")
458
459 # Build final result from chain
460 if enhancement_chain:
461 final_result = " + ".join(enhancement_chain)
462 return final_result, log
463 else:
464 # Fallback
465 log.append(f"⚠️ Chain building failed, using simple item")
466 simple_items = [item for item in table_items if not self.has_enhancement_symbols(item['name'])]
467 if simple_items:
468 fallback = random.choice(simple_items)
469 return fallback['name'], log
470 else:
471 return table_items[0]['name'], log
472
473 def apply_manual_quirks_enhancement(self, base_item_name):
474 """Manually apply Quirks enhancement to any item"""
475 processing_log = []
476
477 # Apply Quirks enhancement
478 enhanced_item, quirks_log = self.process_quirks_enhancement(base_item_name)
479 processing_log.extend(quirks_log)
480
481 return enhanced_item, processing_log
482
483 def manual_quirks_enhancement(self):
484 """Manually apply Quirks enhancement to the current item"""
485 if not self.current_item['available']:
486 messagebox.showwarning("No Item Available",
487 "Please generate an item first before applying Quirks enhancement!")
488 return
489
490 # Check if max Quirks enhancements reached (3 max)
491 if self.current_item['quirks_count'] >= 3:
492 messagebox.showwarning("Max Quirks Enhancements Reached",
493 "This item already has 3 quirks enhancements (maximum allowed)!")
494 return
495
496 if 'QP' not in self.item_tables or 'QE' not in self.item_tables:
497 missing_tables = []
498 if 'QP' not in self.item_tables:
499 missing_tables.append('QP_Table.csv')
500 if 'QE' not in self.item_tables:
501 missing_tables.append('QE_Table.csv')
502 messagebox.showerror("Quirks Tables Missing",
503 f"Quirks tables not loaded: {', '.join(missing_tables)}")
504 return
505
506 # Get the CURRENT item (which may already have enhancements)
507 current_item_name = self.current_item['name']
508
509 # Apply FRESH Quirks enhancement to the current item
510 enhanced_item, processing_log = self.apply_manual_quirks_enhancement(current_item_name)
511
512 # Update current item with new enhancement and increment counter
513 self.current_item['name'] = enhanced_item
514 self.current_item['quirks_count'] += 1
515
516 # Display results
517 self.result_text.insert(tk.END, "\n" + "="*60 + "\n")
518 self.insert_formatted_text(f"🎭 **QUIRKS ENHANCEMENT #{self.current_item['quirks_count']} APPLIED** 🎭\n", "title")
519 self.result_text.insert(tk.END, "="*60 + "\n\n")
520
521 self.result_text.insert(tk.END, f"🎯 Item Before: {current_item_name}\n")
522 self.result_text.insert(tk.END, f"📈 Quirks Count: {self.current_item['quirks_count']}/3 maximum\n")
523 self.result_text.insert(tk.END, f"📋 Quirks Processing Log:\n")
524 for i, log_entry in enumerate(processing_log, 1):
525 self.result_text.insert(tk.END, f" {i}. {log_entry}\n")
526
527 self.result_text.insert(tk.END, f"\n")
528 self.insert_formatted_text(f"🎭 **NEW QUIRKY RESULT: {enhanced_item}** 🎭\n\n", "humorous")
529
530 # Show remaining enhancement capacity
531 remaining_ee = 3 - self.current_item['ee_count']
532 remaining_quirks = 3 - self.current_item['quirks_count']
533
534 if remaining_quirks > 0:
535 self.result_text.insert(tk.END, f"🎭 {remaining_quirks} more quirks enhancements available!\n")
536 else:
537 self.result_text.insert(tk.END, f"🚫 Maximum quirks enhancements (3) reached!\n")
538
539 if remaining_ee > 0:
540 self.result_text.insert(tk.END, f"⭐ {remaining_ee} EE enhancements still available!\n")
541 else:
542 self.result_text.insert(tk.END, f"🚫 Maximum EE enhancements (3) reached!\n")
543
544 self.result_text.insert(tk.END, f"🎲 Or generate a new item to start fresh.\n\n")
545
546 # Update button states after applying enhancement
547 if self.current_item['ee_count'] >= 3:
548 self.ee_enhance_btn.config(state=tk.DISABLED)
549 if self.current_item['quirks_count'] >= 3:
550 self.quirks_enhance_btn.config(state=tk.DISABLED)
551
552 self.result_text.see(tk.END)
553 """Manually apply EE enhancement to any item"""
554 if applied_enhancements is None:
555 applied_enhancements = []
556
557 processing_log = []
558
559 # Check if we can add more enhancements
560 if len(applied_enhancements) >= max_enhancements:
561 processing_log.append(f"🚫 Max enhancements ({max_enhancements}) reached")
562 return base_item_name, processing_log, applied_enhancements
563
564 # Apply EE enhancement
565 enhanced_item, ee_log, updated_enhancements = self.process_enchanted_enhancement(
566 base_item_name, applied_enhancements, max_enhancements
567 )
568 processing_log.extend(ee_log)
569
570 return enhanced_item, processing_log, updated_enhancements
571
572 def roll_for_base_item(self, source_table, applied_enhancements):
573 """Roll same table for base item"""
574 log = []
575 enhancement_chain = [] # Track all enhancements in the chain
576
577 if source_table not in self.item_tables:
578 log.append(f"⚠️ Source table {source_table} not available")
579 return "Unknown Item", log
580
581 table_items = self.item_tables[source_table]['items']
582 if not table_items:
583 log.append(f"⚠️ Source table {source_table} is empty")
584 return "Unknown Item", log
585
586 attempts = 0
587 max_attempts = 10
588
589 while attempts < max_attempts:
590 base_item_data = random.choice(table_items)
591 base_roll = random.randint(base_item_data['roll_from'], base_item_data['roll_to'])
592 base_name = base_item_data['name']
593
594 log.append(f" → Base item roll: {base_roll} → {base_name}")
595
596 # If base item also has enhancements, process it first
597 if self.has_enhancement_symbols(base_name) or self.is_unique_artifact(base_name):
598 log.append(f" → Base item has enhancements, processing...")
599
600 # Parse the current enhancement and add to chain
601 symbols = self.parse_enhancement_symbols(base_name)
602 clean_name = symbols['base_name']
603 enhancement_chain.append(clean_name)
604
605 # Process the enhancement symbols
606 if symbols['reroll']:
607 # Recursive call to get more enhancements
608 processed_base, base_process_log = self.roll_for_base_item(source_table, applied_enhancements.copy())
609 log.extend([f" {line}" for line in base_process_log])
610
611 # If the processed base contains multiple parts, add them all
612 if " + " in processed_base:
613 parts = processed_base.split(" + ")
614 enhancement_chain.extend(parts)
615 else:
616 enhancement_chain.append(processed_base)
617
618 # Build the full enhancement chain
619 final_result = " + ".join(enhancement_chain)
620 return final_result, log
621 else:
622 return base_name, log
623
624 attempts += 1
625
626 # Fallback
627 log.append(f"⚠️ Too many enhancement loops, using simple item")
628 simple_items = [item for item in table_items if not self.has_enhancement_symbols(item['name'])]
629 if simple_items:
630 fallback = random.choice(simple_items)
631 return fallback['name'], log
632 else:
633 return table_items[0]['name'], log
634
635 def process_weapon_enhancement(self, base_item, applied_enhancements):
636 """Process weapon enhancement ($)"""
637 log = [f"💰 Weapon Enhancement triggered for: {base_item}"]
638
639 if 'S2' not in self.item_tables:
640 log.append("⚠️ S2 table not available")
641 return base_item, log
642
643 s2_items = self.item_tables['S2']['items']
644 s2_item = random.choice(s2_items)
645 s2_roll = random.randint(s2_item['roll_from'], s2_item['roll_to'])
646 log.append(f" → S2 Enhancement roll: {s2_roll} → {s2_item['name']}")
647
648 enhanced_name = f"{base_item} + {s2_item['name']}"
649 log.append(f"🔗 Weapon enhanced: {enhanced_name}")
650 return enhanced_name, log
651
652 def process_enchanted_enhancement(self, base_item, applied_enhancements, max_enhancements):
653 """Process enchanted enhancement (#)"""
654 log = [f"⭐ Enchanted Enhancement for: {base_item}"]
655
656 if 'EE' not in self.item_tables:
657 log.append("⚠️ EE table not available")
658 return base_item, log, applied_enhancements
659
660 if len(applied_enhancements) >= max_enhancements:
661 log.append(f"🚫 Max enhancements reached")
662 return base_item, log, applied_enhancements
663
664 ee_items = self.item_tables['EE']['items']
665 if not ee_items:
666 log.append("⚠️ EE table is empty")
667 return base_item, log, applied_enhancements
668
669 ee_item = random.choice(ee_items)
670 ee_roll = random.randint(ee_item['roll_from'], ee_item['roll_to'])
671 log.append(f" → EE roll: {ee_roll} → {ee_item['name']}")
672
673 # Process the EE result (it might have its own symbols)
674 if self.has_enhancement_symbols(ee_item['name']) or self.is_unique_artifact(ee_item['name']):
675 processed_enhancement, ee_process_log, applied_enhancements = self.process_enhanced_item(ee_item['name'], 'EE', applied_enhancements, max_enhancements)
676 log.extend([f" {line}" for line in ee_process_log])
677
678 # If processing returned empty string (failed racial enhancement), don't add it
679 if processed_enhancement:
680 enhanced_name = f"{base_item} + {processed_enhancement}"
681 else:
682 enhanced_name = base_item
683 else:
684 enhanced_name = f"{base_item} + {ee_item['name']}"
685
686 log.append(f"🔗 EE enhanced: {enhanced_name}")
687 return enhanced_name, log, applied_enhancements
688
689 def process_aquatic_enhancement(self, base_item):
690 """Process aquatic enhancement (%)"""
691 log = [f"🌊 Aquatic Enhancement for: {base_item}"]
692
693 if 'AE' not in self.item_tables:
694 log.append("⚠️ AE table not available")
695 return base_item, log
696
697 ae_items = self.item_tables['AE']['items']
698 ae_item = random.choice(ae_items)
699 ae_roll = random.randint(ae_item['roll_from'], ae_item['roll_to'])
700 log.append(f" → AE roll: {ae_roll} → {ae_item['name']}")
701
702 enhanced_name = f"{base_item} + {ae_item['name']}"
703 log.append(f"🔗 Aquatic enhanced: {enhanced_name}")
704 return enhanced_name, log
705
706 def process_quirks_enhancement(self, base_item):
707 """Process quirks enhancement (@)"""
708 log = [f"🎭 Quirks Enhancement for: {base_item}"]
709
710 if 'QP' not in self.item_tables or 'QE' not in self.item_tables:
711 log.append("⚠️ QP or QE table not available")
712 return base_item, log
713
714 # Roll QP for number of quirks
715 qp_items = self.item_tables['QP']['items']
716 qp_item = random.choice(qp_items)
717 qp_roll = random.randint(qp_item['roll_from'], qp_item['roll_to'])
718 log.append(f" → QP roll: {qp_roll} → {qp_item['name']}")
719
720 # Determine number of quirks
721 quirk_count = 1
722 quirks_text = qp_item['name'].lower()
723 if 'one quirk' in quirks_text:
724 quirk_count = 1
725 elif 'two quirk' in quirks_text:
726 quirk_count = 2
727 elif 'three quirk' in quirks_text:
728 quirk_count = 3
729
730 # Roll QE for each quirk
731 quirks = []
732 qe_items = self.item_tables['QE']['items']
733 for i in range(quirk_count):
734 qe_item = random.choice(qe_items)
735 qe_roll = random.randint(qe_item['roll_from'], qe_item['roll_to'])
736 quirks.append(qe_item['name'])
737 log.append(f" → QE Quirk {i+1}: {qe_roll} → {qe_item['name']}")
738
739 quirk_text = " | ".join(quirks)
740 enhanced_name = f"{base_item} with Quirks[{quirk_text}]"
741 log.append(f"🔗 Quirky: {enhanced_name}")
742 return enhanced_name, log
743
744 def process_racial_enhancement(self, base_item):
745 """Process racial enhancement (&)"""
746 log = [f"👥 Racial Enhancement for: {base_item}"]
747
748 if 'RE' not in self.item_tables:
749 log.append("⚠️ RE table not loaded - check if RE_Table.csv exists")
750 log.append(f"📋 Available tables: {list(self.item_tables.keys())}")
751 return base_item, log
752
753 re_items = self.item_tables['RE']['items']
754 if not re_items:
755 log.append("⚠️ RE table is loaded but contains 0 items")
756 log.append(f"📋 RE table info: {self.item_tables['RE']}")
757 return base_item, log
758
759 re_item = random.choice(re_items)
760 re_roll = random.randint(re_item['roll_from'], re_item['roll_to'])
761
762 # Get the race name from the RE table item and clean it
763 race_name = re_item['name'].replace('^', '').strip() # Remove ^ symbol from race name
764 log.append(f" → RE roll: {re_roll} → {race_name}")
765
766 # Create enhanced name with racial designation - just use the race name
767 enhanced_name = f"{race_name}"
768 log.append(f"🔗 Racial enhanced: {enhanced_name}")
769 return enhanced_name, log
770
771 def is_weapon_enchantment(self, item_name):
772 """Check if item ends with dollar sign for weapon enhancement"""
773 return item_name.strip().endswith('$')
774
775 def select_armor_table(self):
776 """Always return R1 to start armor progression"""
777 return 'R1'
778 def select_weapon_table(self):
779 """Always return S1 to start weapon progression"""
780 return 'S1'
781 def get_main_category_from_table1(self, roll):
782 """Get category from Table 1 based on d100 roll"""
783 if '1' not in self.item_tables:
784 return self.get_fallback_category(roll)
785
786 table1_items = self.item_tables['1']['items']
787
788 for item in table1_items:
789 roll_range = str(item['name']).strip()
790 category = item.get('Magical Item Category', '').strip()
791
792 if not category:
793 continue
794
795 if roll_range == "20-Jan":
796 if 1 <= roll <= 20:
797 return category
798 elif roll_range == "78-00":
799 if 78 <= roll <= 100:
800 return category
801 elif '-' in roll_range:
802 parts = roll_range.split('-')
803 if len(parts) == 2:
804 try:
805 range_start, range_end = int(parts[0]), int(parts[1])
806 if range_start <= roll <= range_end:
807 return category
808 except ValueError:
809 continue
810 else:
811 try:
812 if int(roll_range) == roll:
813 return category
814 except ValueError:
815 continue
816
817 return self.get_fallback_category(roll)
818
819 def get_fallback_category(self, roll):
820 """Fallback category mapping if Table 1 fails"""
821 if roll <= 20: return "Magical Liquids"
822 elif roll <= 35: return "Scrolls"
823 elif roll <= 40: return "Rings"
824 elif roll == 41: return "Rods"
825 elif roll == 42: return "Staves"
826 elif roll <= 45: return "Wands"
827 elif roll == 46: return "Books"
828 elif roll <= 48: return "Gems & Jewelry"
829 elif roll <= 50: return "Clothing"
830 elif roll <= 52: return "Boots & Gloves"
831 elif roll == 53: return "Girdles & Helmets"
832 elif roll <= 55: return "Bags & Bottles"
833 elif roll == 56: return "Dust & Stones"
834 elif roll == 57: return "Household Items"
835 elif roll == 58: return "Musical Instruments"
836 elif roll <= 60: return "Weird Stuff"
837 elif roll == 61: return "Humorous Items"
838 elif roll <= 77: return "Armor and Shields"
839 else: return "Weapons"
840
841 def get_category_items(self, category_name):
842 """Get items for a category"""
843 if "🎲 Random" in category_name:
844 return None, None
845 elif "🌟 Legendary Artifacts" in category_name:
846 if 'T' in self.item_tables:
847 return self.item_tables['T']['items'], 'T'
848 else:
849 return [], 'T (Missing)'
850 elif "🛡️ Armor and Shields" in category_name or "Armor and Shields" in category_name:
851 table_id = self.select_armor_table()
852 if table_id in self.item_tables:
853 return self.item_tables[table_id]['items'], table_id
854 else:
855 armor_items = []
856 for tid in ['R1', 'R2', 'R3']:
857 if tid in self.item_tables:
858 armor_items.extend(self.item_tables[tid]['items'])
859 return armor_items, 'R1-R3'
860 elif "⚔️ Weapons" in category_name or "Weapons" in category_name:
861 table_id = self.select_weapon_table()
862 if table_id in self.item_tables:
863 return self.item_tables[table_id]['items'], table_id
864 else:
865 weapon_items = []
866 for tid in ['S1', 'S2', 'S3']:
867 if tid in self.item_tables:
868 weapon_items.extend(self.item_tables[tid]['items'])
869 return weapon_items, 'S1-S3'
870 else:
871 if '(' in category_name and ')' in category_name:
872 base_category = category_name.split('(')[0].strip()
873 base_category = ''.join(char for char in base_category if char.isalnum() or char.isspace() or char in ['&']).strip()
874 else:
875 base_category = category_name
876
877 category_items = []
878 used_tables = []
879 for table_id, table_data in self.item_tables.items():
880 if table_data['category'] == base_category:
881 category_items.extend(table_data['items'])
882 used_tables.append(table_id)
883
884 table_desc = '+'.join(used_tables) if len(used_tables) > 1 else (used_tables[0] if used_tables else 'Unknown')
885 return category_items, table_desc
886
887 def get_item_color_tag(self, item):
888 """Determine the color tag for an item"""
889 category = item.get('category', '').lower()
890 item_name = item['name'].lower()
891
892 is_enhanced = any(keyword in item_name for keyword in [
893 '+', 'enhanced', 'magical', 'enchanted', 'cursed', 'blessed',
894 'holy', 'unholy', 'legendary', 'artifact', 'relic', 'ancient'
895 ])
896
897 if item.get('table') == 'T':
898 return "legendary"
899
900 if is_enhanced:
901 return "enhanced"
902
903 if 'weapon' in category:
904 return "weapons"
905 elif 'armor' in category and 'shields' in category:
906 return "armor"
907 elif 'liquid' in category or 'potion' in category:
908 return "potions"
909 elif 'scroll' in category or 'book' in category:
910 return "scrolls"
911 elif 'ring' in category or 'gem' in category or 'jewelry' in category:
912 return "jewelry"
913 elif 'wand' in category or 'staff' in category or 'staves' in category or 'rod' in category:
914 return "implements"
915 elif 'clothing' in category or 'boots' in category or 'gloves' in category or 'girdles' in category or 'helmet' in category:
916 return "clothing"
917 elif 'bag' in category or 'bottle' in category:
918 return "containers"
919 elif 'humorous' in category:
920 return "humorous"
921 else:
922 return "misc"
923
924 def format_item_result(self, item, is_final=False):
925 """Format item results with discovery text and color coding"""
926 category = item.get('category', '').lower()
927 item_name = item['name'].lower()
928
929 is_enhanced = any(keyword in item_name for keyword in [
930 '+', 'enhanced', 'magical', 'enchanted', 'cursed', 'blessed',
931 'holy', 'unholy', 'legendary', 'artifact', 'relic', 'ancient'
932 ])
933
934 if 'weapon' in category:
935 icon = "⚔️"
936 if is_enhanced:
937 discovery_words = ["LEGENDARY BLADE DISCOVERED", "ENCHANTED WEAPON UNEARTHED", "MYSTICAL ARMAMENT REVEALED"]
938 else:
939 discovery_words = ["WEAPON FOUND", "BLADE DISCOVERED", "ARMAMENT LOCATED"]
940 elif 'armor' in category:
941 icon = "🛡️"
942 if is_enhanced:
943 discovery_words = ["LEGENDARY PROTECTION DISCOVERED", "ENCHANTED ARMOR UNEARTHED", "MYSTICAL WARD REVEALED"]
944 else:
945 discovery_words = ["ARMOR FOUND", "PROTECTION DISCOVERED", "DEFENSIVE GEAR LOCATED"]
946 elif 'ring' in category:
947 icon = "💍"
948 if is_enhanced:
949 discovery_words = ["RING OF POWER DISCOVERED", "ENCHANTED BAND UNEARTHED", "MYSTICAL CIRCLET REVEALED"]
950 else:
951 discovery_words = ["RING FOUND", "BAND DISCOVERED", "CIRCLET LOCATED"]
952 elif 'liquid' in category:
953 icon = "🧪"
954 if is_enhanced:
955 discovery_words = ["POWERFUL ELIXIR DISCOVERED", "ENCHANTED BREW UNEARTHED", "MYSTICAL POTION REVEALED"]
956 else:
957 discovery_words = ["POTION FOUND", "ELIXIR DISCOVERED", "BREW LOCATED"]
958 else:
959 icon = "✨"
960 if is_enhanced:
961 discovery_words = ["LEGENDARY ARTIFACT DISCOVERED", "ENCHANTED RELIC UNEARTHED", "MYSTICAL TREASURE REVEALED"]
962 else:
963 discovery_words = ["MAGIC ITEM FOUND", "TREASURE DISCOVERED", "ARTIFACT LOCATED"]
964
965 if is_final:
966 if is_enhanced:
967 discovery_words = ["🏆 LEGENDARY ARTIFACT UNEARTHED 🏆", "🏆 ULTIMATE TREASURE REVEALED 🏆"]
968 icon = "🏆"
969 else:
970 discovery_words = ["🎯 TREASURE DISCOVERED 🎯", "🎯 MAGIC ITEM FOUND 🎯"]
971 icon = "🎯"
972
973 discovery_text = random.choice(discovery_words)
974 return f"{icon} **{discovery_text}: {item['name']}** {icon}", self.get_item_color_tag(item)
975
976 def generate_item_from_category(self, category_items, category_name, max_rerolls=3):
977 """Generate an item from a category"""
978 all_rolls = []
979 final_items = []
980
981 for attempt in range(max_rerolls + 1):
982 item = random.choice(category_items)
983 item_roll = random.randint(item['roll_from'], item['roll_to'])
984
985 roll_info = f"Roll {attempt + 1}: {item_roll} → {item['name']}"
986 all_rolls.append(roll_info)
987
988 if self.is_weapon_enchantment(item['name']):
989 all_rolls.append(f" ↳ ⚔️ Weapon Enhancements$ trigger - rolling ONCE on S3 + ONCE on S2!")
990
991 if 'S3' in self.item_tables and len(self.item_tables['S3']['items']) > 0:
992 s3_items = self.item_tables['S3']['items']
993 normal_s3_items = [x for x in s3_items if not self.is_reroll_item(x['name']) and not self.is_weapon_enchantment(x['name'])]
994 if normal_s3_items:
995 s3_item = random.choice(normal_s3_items)
996 else:
997 s3_item = random.choice(s3_items)
998
999 s3_roll = random.randint(s3_item['roll_from'], s3_item['roll_to'])
1000 all_rolls.append(f" → S3 Special Weapon roll: {s3_roll} → {s3_item['name']}")
1001
1002 if 'S2' in self.item_tables and len(self.item_tables['S2']['items']) > 0:
1003 s2_items = self.item_tables['S2']['items']
1004 s2_item = random.choice(s2_items)
1005 s2_roll = random.randint(s2_item['roll_from'], s2_item['roll_to'])
1006 all_rolls.append(f" → S2 Enhancement roll: {s2_roll} → {s2_item['name']}")
1007
1008 enhanced_weapon = {
1009 'name': f"{s3_item['name']} + {s2_item['name']}",
1010 'category': 'Enhanced Special Weapons',
1011 'table': 'S3+S2',
1012 'roll_from': s3_item['roll_from'],
1013 'roll_to': s3_item['roll_to'],
1014 'base_weapon': s3_item['name'],
1015 'enhancement': s2_item['name']
1016 }
1017 final_items.append(enhanced_weapon)
1018 else:
1019 final_items.append(s3_item)
1020 all_rolls.append(f" ↳ ⚠️ S2 table not available, using S3 weapon only")
1021 else:
1022 all_rolls.append(f" ↳ ⚠️ S3 table not available for Weapon Enhancements$")
1023 final_items.append(item)
1024
1025 break
1026
1027 elif self.is_reroll_item(item['name']):
1028 # Handle enhancement symbols using the new system
1029 if self.has_enhancement_symbols(item['name']) or self.is_unique_artifact(item['name']):
1030 all_rolls.append(f" ↳ ⭐ Enhancement symbols detected - processing...")
1031 final_item_name, processing_log, _ = self.process_enhanced_item(item['name'], item['table'])
1032 all_rolls.extend([f" {log}" for log in processing_log])
1033
1034 enhanced_item = {
1035 'name': final_item_name,
1036 'category': item['category'],
1037 'table': item['table'],
1038 'roll_from': item['roll_from'],
1039 'roll_to': item['roll_to'],
1040 'original_name': item['name']
1041 }
1042 final_items.append(enhanced_item)
1043 break
1044 else:
1045 # Old asterisk reroll system for compatibility
1046 if attempt < max_rerolls:
1047 all_rolls.append(f" ↳ ⭐ Enhancement trigger - rolling twice MORE on {category_name} table!")
1048
1049 for sub_roll in range(2):
1050 attempts = 0
1051 while attempts < 5:
1052 sub_item = random.choice(category_items)
1053 sub_item_roll = random.randint(sub_item['roll_from'], sub_item['roll_to'])
1054
1055 if not self.is_reroll_item(sub_item['name']) and not self.is_weapon_enchantment(sub_item['name']):
1056 all_rolls.append(f" → Sub-roll {sub_roll + 1}: {sub_item_roll} → {sub_item['name']}")
1057 final_items.append(sub_item)
1058 break
1059 else:
1060 all_rolls.append(f" → Sub-roll {sub_roll + 1}: {sub_item_roll} → {sub_item['name']} (rerolling...)")
1061 attempts += 1
1062
1063 if attempts >= 5:
1064 fallback_items = [x for x in category_items if not self.is_reroll_item(x['name']) and not self.is_weapon_enchantment(x['name'])]
1065 if fallback_items:
1066 fallback_item = random.choice(fallback_items)
1067 else:
1068 fallback_item = random.choice(category_items)
1069 all_rolls.append(f" → Fallback: Using {fallback_item['name']}")
1070 final_items.append(fallback_item)
1071
1072 break
1073 else:
1074 all_rolls.append(" ↳ ⚠️ Max rerolls reached - treating as regular item")
1075 final_items.append(item)
1076 break
1077 else:
1078 final_items.append(item)
1079
1080 if item['table'] == 'R1':
1081 if item['roll_from'] >= 953:
1082 all_rolls.append(f" R1 Roll: {item['roll_from']}-{item['roll_to']} → {item['name']}")
1083 if 'R3' in self.item_tables:
1084 r3_items = self.item_tables['R3']['items']
1085 r3_item = random.choice(r3_items)
1086 r3_roll = random.randint(r3_item['roll_from'], r3_item['roll_to'])
1087 all_rolls.append(f" → R3 Special Armor roll: {r3_roll} → {r3_item['name']}")
1088 final_items[-1] = r3_item
1089 break
1090 elif 'R2' in self.item_tables:
1091 r2_items = self.item_tables['R2']['items']
1092 r2_item = random.choice(r2_items)
1093 r2_roll = random.randint(r2_item['roll_from'], r2_item['roll_to'])
1094 all_rolls.append(f" → R2 Enhancement roll: {r2_roll} → {r2_item['name']}")
1095 combined_item = {
1096 'name': f"{item['name']} + {r2_item['name']}",
1097 'category': item['category'],
1098 'table': 'R1+R2',
1099 'roll_from': item['roll_from'],
1100 'roll_to': item['roll_to']
1101 }
1102 final_items[-1] = combined_item
1103 break
1104 elif item['table'] == 'S1':
1105 if item['roll_from'] >= 975:
1106 all_rolls.append(f" S1 Roll: {item['roll_from']}-{item['roll_to']} → {item['name']}")
1107 if 'S3' in self.item_tables:
1108 s3_items = self.item_tables['S3']['items']
1109 s3_item = random.choice(s3_items)
1110 s3_roll = random.randint(s3_item['roll_from'], s3_item['roll_to'])
1111 all_rolls.append(f" → S3 Special Weapon roll: {s3_roll} → {s3_item['name']}")
1112 final_items[-1] = s3_item
1113 break
1114 elif 'S2' in self.item_tables:
1115 s2_items = self.item_tables['S2']['items']
1116 s2_item = random.choice(s2_items)
1117 s2_roll = random.randint(s2_item['roll_from'], s2_item['roll_to'])
1118 all_rolls.append(f" → S2 Enhancement roll: {s2_roll} → {s2_item['name']}")
1119 combined_item = {
1120 'name': f"{item['name']} + {s2_item['name']}",
1121 'category': item['category'],
1122 'table': 'S1+S2',
1123 'roll_from': item['roll_from'],
1124 'roll_to': item['roll_to']
1125 }
1126 final_items[-1] = combined_item
1127 break
1128 adjustment_table = 'R2' if item['table'] == 'R1' else 'S2'
1129 if adjustment_table in self.item_tables and len(self.item_tables[adjustment_table]['items']) > 0:
1130 all_rolls.append(f" ↳ 🎯 Generic item - rolling on {adjustment_table} for magical properties!")
1131
1132 adj_items = self.item_tables[adjustment_table]['items']
1133 adj_item = random.choice(adj_items)
1134 adj_roll = random.randint(adj_item['roll_from'], adj_item['roll_to'])
1135
1136 all_rolls.append(f" → Adjustment roll: {adj_roll} → {adj_item['name']}")
1137
1138 combined_item = {
1139 'name': f"{item['name']} + {adj_item['name']}",
1140 'category': item['category'],
1141 'table': f"{item['table']}+{adjustment_table}",
1142 'roll_from': item['roll_from'],
1143 'roll_to': item['roll_to'],
1144 'adjustment': adj_item['name']
1145 }
1146
1147 final_items[-1] = combined_item
1148 else:
1149 all_rolls.append(f" ↳ ⚠️ Adjustment table {adjustment_table} not found or empty!")
1150
1151 break
1152
1153 return final_items, all_rolls
1154
1155 def create_gui(self):
1156 """Create the GUI interface"""
1157 bg_dark = '#1a0f0a'
1158 bg_medium = '#2c1810'
1159 gold = '#ffd700'
1160 silver = '#c0c0c0'
1161 copper = '#cd853f'
1162 red = '#8b0000'
1163 green = '#228b22'
1164
1165 self.root.configure(bg=bg_dark)
1166
1167 # Title
1168 title_frame = tk.Frame(self.root, bg=bg_dark, pady=15)
1169 title_frame.pack(pady=20, fill=tk.X)
1170
1171 title_label = tk.Label(title_frame,
1172 text="⚔️ 🧙♂️ ENHANCED ARCANE TREASURY GENERATOR 🧙♂️ ⚔️",
1173 font=('Georgia', 20, 'bold'),
1174 fg=gold,
1175 bg=bg_dark,
1176 relief=tk.RAISED,
1177 bd=3)
1178 title_label.pack()
1179
1180 subtitle_label = tk.Label(title_frame,
1181 text="🗝️ Ancient Tables of Wondrous Items • Enhanced Symbols Active • Est. 1974 🗝️",
1182 font=('Georgia', 11, 'italic'),
1183 fg=silver,
1184 bg=bg_dark)
1185 subtitle_label.pack(pady=(5, 0))
1186
1187 # Separator
1188 separator_frame = tk.Frame(self.root, bg=copper, height=3)
1189 separator_frame.pack(fill=tk.X, padx=50, pady=10)
1190
1191 # Status
1192 self.status_label = tk.Label(self.root,
1193 text=f"📚 {self.total_items} Magical Items • 📜 {len(self.item_tables)} Ancient Tables • ⚡ Enhancement Systems Ready",
1194 font=('Georgia', 10, 'bold'),
1195 fg=green,
1196 bg=bg_dark)
1197 self.status_label.pack(pady=10)
1198
1199 # Control panel
1200 control_frame = tk.Frame(self.root, bg=bg_medium, relief=tk.RAISED, bd=2)
1201 control_frame.pack(pady=20, padx=20, fill=tk.X)
1202
1203 control_title = tk.Label(control_frame,
1204 text="🎲 DIVINATION CONTROLS 🎲",
1205 font=('Georgia', 14, 'bold'),
1206 fg=gold,
1207 bg=bg_medium)
1208 control_title.pack(pady=10)
1209
1210 # Main buttons frame
1211 button_frame = tk.Frame(control_frame, bg=bg_medium)
1212 button_frame.pack(pady=15)
1213
1214 self.generate_btn = tk.Button(button_frame,
1215 text="🔮 CONJURE MAGIC ITEM 🔮",
1216 font=('Georgia', 14, 'bold'),
1217 bg='#654321',
1218 fg=gold,
1219 activebackground='#8b4513',
1220 activeforeground=gold,
1221 command=self.generate_item,
1222 padx=25,
1223 pady=12,
1224 relief=tk.RAISED,
1225 bd=3,
1226 cursor='hand2')
1227 self.generate_btn.pack(side=tk.LEFT, padx=15)
1228
1229 self.reroll_btn = tk.Button(button_frame,
1230 text="🌀 DIVINE AGAIN 🌀",
1231 font=('Georgia', 11, 'bold'),
1232 bg=red,
1233 fg=gold,
1234 activebackground='#a52a2a',
1235 activeforeground=gold,
1236 command=self.reroll_same_table,
1237 padx=15,
1238 pady=10,
1239 relief=tk.RAISED,
1240 bd=2,
1241 cursor='hand2')
1242 self.reroll_btn.pack(side=tk.LEFT, padx=10)
1243
1244 # NEW: Manual EE Enhancement button
1245 self.ee_enhance_btn = tk.Button(button_frame,
1246 text="⭐ ADD EE ENHANCEMENT ⭐",
1247 font=('Georgia', 11, 'bold'),
1248 bg='#4a90e2',
1249 fg=gold,
1250 activebackground='#5ba0f2',
1251 activeforeground=gold,
1252 command=self.manual_ee_enhancement,
1253 padx=15,
1254 pady=10,
1255 relief=tk.RAISED,
1256 bd=2,
1257 cursor='hand2',
1258 state=tk.DISABLED) # Disabled until item is generated
1259 self.ee_enhance_btn.pack(side=tk.LEFT, padx=10)
1260
1261 # NEW: Manual Quirks Enhancement button
1262 self.quirks_enhance_btn = tk.Button(button_frame,
1263 text="🎭 ADD QUIRKS 🎭",
1264 font=('Georgia', 11, 'bold'),
1265 bg='#9c27b0',
1266 fg=gold,
1267 activebackground='#ba68c8',
1268 activeforeground=gold,
1269 command=self.manual_quirks_enhancement,
1270 padx=15,
1271 pady=10,
1272 relief=tk.RAISED,
1273 bd=2,
1274 cursor='hand2',
1275 state=tk.DISABLED) # Disabled until item is generated
1276 self.quirks_enhance_btn.pack(side=tk.LEFT, padx=10)
1277
1278 self.test_btn = tk.Button(button_frame,
1279 text="🧪 TEST ENHANCEMENTS 🧪",
1280 font=('Georgia', 11, 'bold'),
1281 bg='#4a90e2',
1282 fg=gold,
1283 activebackground='#5ba0f2',
1284 activeforeground=gold,
1285 command=self.test_enhancement_system,
1286 padx=15,
1287 pady=10,
1288 relief=tk.RAISED,
1289 bd=2,
1290 cursor='hand2')
1291 self.test_btn.pack(side=tk.LEFT, padx=10)
1292 self.test_btn.pack_forget()
1293
1294 # Category selection
1295 category_frame = tk.Frame(control_frame, bg=bg_medium)
1296 category_frame.pack(pady=15)
1297
1298 category_title = tk.Label(category_frame,
1299 text="📖 TOME SELECTION 📖",
1300 font=('Georgia', 12, 'bold'),
1301 fg=copper,
1302 bg=bg_medium)
1303 category_title.pack(pady=(0, 5))
1304
1305 selection_frame = tk.Frame(category_frame, bg=bg_medium)
1306 selection_frame.pack()
1307
1308 category_label = tk.Label(selection_frame,
1309 text="🗂️ Category:",
1310 font=('Georgia', 11, 'bold'),
1311 fg=silver,
1312 bg=bg_medium)
1313 category_label.pack(side=tk.LEFT, padx=(0, 10))
1314
1315 # Create dropdown options
1316 categories = ["🎲 Random (Table 1 → All Tables)"]
1317
1318 if 'T' in self.item_tables:
1319 t_count = len(self.item_tables['T']['items'])
1320 categories.append(f"🌟 Legendary Artifacts (Table T) - {t_count} items")
1321
1322 category_mappings = {
1323 'Magical Liquids': 'A',
1324 'Scrolls': 'B',
1325 'Rings': 'C',
1326 'Rods': 'D',
1327 'Staves': 'E',
1328 'Wands': 'F',
1329 'Books': 'G',
1330 'Gems & Jewelry': 'H',
1331 'Clothing': 'I',
1332 'Boots & Gloves': 'J',
1333 'Girdles & Helmets': 'K',
1334 'Bags & Bottles': 'L',
1335 'Dust & Stones': 'M',
1336 'Household Items': 'N',
1337 'Musical Instruments': 'O',
1338 'Weird Stuff': 'P',
1339 'Humorous Items': 'Q',
1340 'Armor and Shields': 'R1/R2/R3',
1341 'Weapons': 'S1/S2/S3'
1342 }
1343
1344 for category_name in sorted(category_mappings.keys()):
1345 table_ref = category_mappings[category_name]
1346
1347 item_count = 0
1348 if category_name in ['Armor and Shields', 'Weapons']:
1349 if category_name == 'Armor and Shields':
1350 for tid in ['R1', 'R2', 'R3']:
1351 if tid in self.item_tables:
1352 item_count += len(self.item_tables[tid]['items'])
1353 else:
1354 for tid in ['S1', 'S2', 'S3']:
1355 if tid in self.item_tables:
1356 item_count += len(self.item_tables[tid]['items'])
1357 else:
1358 for table_id, table_data in self.item_tables.items():
1359 if table_data['category'] == category_name:
1360 item_count += len(table_data['items'])
1361
1362 if category_name == 'Armor and Shields':
1363 categories.append(f"🛡️ {category_name} (Tables {table_ref}) - {item_count} items")
1364 elif category_name == 'Weapons':
1365 categories.append(f"⚔️ {category_name} (Tables {table_ref}) - {item_count} items")
1366 elif 'Magical Liquids' in category_name:
1367 categories.append(f"🧪 {category_name} (Table {table_ref}) - {item_count} items")
1368 elif 'Scrolls' in category_name:
1369 categories.append(f"📜 {category_name} (Table {table_ref}) - {item_count} items")
1370 elif 'Rings' in category_name:
1371 categories.append(f"💍 {category_name} (Table {table_ref}) - {item_count} items")
1372 elif 'Books' in category_name:
1373 categories.append(f"📚 {category_name} (Table {table_ref}) - {item_count} items")
1374 elif 'Gems' in category_name or 'Jewelry' in category_name:
1375 categories.append(f"💎 {category_name} (Table {table_ref}) - {item_count} items")
1376 elif any(word in category_name for word in ['Clothing', 'Boots', 'Gloves', 'Girdles', 'Helmets']):
1377 categories.append(f"👕 {category_name} (Table {table_ref}) - {item_count} items")
1378 elif any(word in category_name for word in ['Wand', 'Staves', 'Rods']):
1379 categories.append(f"🪄 {category_name} (Table {table_ref}) - {item_count} items")
1380 elif 'Bags' in category_name or 'Bottles' in category_name:
1381 categories.append(f"🎒 {category_name} (Table {table_ref}) - {item_count} items")
1382 elif 'Humorous' in category_name:
1383 categories.append(f"🤡 {category_name} (Table {table_ref}) - {item_count} items")
1384 elif 'Musical' in category_name:
1385 categories.append(f"🎵 {category_name} (Table {table_ref}) - {item_count} items")
1386 elif 'Weird' in category_name:
1387 categories.append(f"👽 {category_name} (Table {table_ref}) - {item_count} items")
1388 else:
1389 categories.append(f"✨ {category_name} (Table {table_ref}) - {item_count} items")
1390
1391 # Initialize dropdown with Random as default
1392 self.category_var = tk.StringVar(value="🎲 Random (Table 1 → All Tables)")
1393
1394 style = ttk.Style()
1395 style.theme_use('clam')
1396 style.configure('Fantasy.TCombobox',
1397 fieldbackground='#3d2818',
1398 background='#654321',
1399 foreground='white',
1400 arrowcolor='gold')
1401
1402 category_combo = ttk.Combobox(selection_frame,
1403 textvariable=self.category_var,
1404 values=categories,
1405 state="readonly",
1406 width=50,
1407 font=('Georgia', 10),
1408 style='Fantasy.TCombobox')
1409 category_combo.pack(side=tk.LEFT, padx=5)
1410
1411 # Results
1412 results_title_frame = tk.Frame(self.root, bg=bg_dark)
1413 results_title_frame.pack(fill=tk.X, padx=20, pady=(20, 0))
1414
1415 results_title = tk.Label(results_title_frame,
1416 text="📜 DIVINATION RESULTS 📜",
1417 font=('Georgia', 14, 'bold'),
1418 fg=gold,
1419 bg=bg_dark)
1420 results_title.pack()
1421
1422 # Results frame
1423 result_frame = tk.Frame(self.root, bg=bg_medium, relief=tk.SUNKEN, bd=3)
1424 result_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
1425
1426 # Text display
1427 self.result_text = scrolledtext.ScrolledText(result_frame,
1428 font=('Consolas', 11),
1429 bg='#0f0f23',
1430 fg='#e6d690',
1431 insertbackground=gold,
1432 selectbackground='#4a4a4a',
1433 selectforeground=gold,
1434 wrap=tk.WORD,
1435 height=18,
1436 relief=tk.SUNKEN,
1437 bd=2,
1438 padx=10,
1439 pady=10)
1440 self.result_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
1441
1442 # Color-coded text formatting
1443 self.result_text.tag_config("bold", font=('Consolas', 11, 'bold'), foreground=gold)
1444 self.result_text.tag_config("italic", font=('Consolas', 11, 'italic'), foreground=silver)
1445 self.result_text.tag_config("title", font=('Consolas', 14, 'bold'), foreground=gold)
1446 self.result_text.tag_config("category", font=('Consolas', 10), foreground=copper)
1447 self.result_text.tag_config("dice", font=('Consolas', 10), foreground='#87CEEB')
1448
1449 # Item type colors (all bold by default)
1450 self.result_text.tag_config("weapons", font=('Consolas', 12, 'bold'), foreground='#FF6B6B')
1451 self.result_text.tag_config("armor", font=('Consolas', 12, 'bold'), foreground='#4ECDC4')
1452 self.result_text.tag_config("potions", font=('Consolas', 12, 'bold'), foreground='#45B7D1')
1453 self.result_text.tag_config("scrolls", font=('Consolas', 12, 'bold'), foreground='#F9CA24')
1454 self.result_text.tag_config("jewelry", font=('Consolas', 12, 'bold'), foreground='#F0932B')
1455 self.result_text.tag_config("implements", font=('Consolas', 12, 'bold'), foreground='#9C88FF')
1456 self.result_text.tag_config("clothing", font=('Consolas', 12, 'bold'), foreground='#6C5CE7')
1457 self.result_text.tag_config("containers", font=('Consolas', 12, 'bold'), foreground='#A29BFE')
1458 self.result_text.tag_config("misc", font=('Consolas', 12, 'bold'), foreground='#FD79A8')
1459 self.result_text.tag_config("humorous", font=('Consolas', 12, 'bold'), foreground='#00B894')
1460 self.result_text.tag_config("legendary", font=('Consolas', 14, 'bold'), foreground='#FFD700')
1461 self.result_text.tag_config("enhanced", font=('Consolas', 12, 'bold'), foreground='#00FFFF')
1462
1463 # Welcome message
1464 self.insert_formatted_text("🌟 Welcome, brave adventurer, to the Enhanced Arcane Treasury Generator! 🌟\n\n")
1465 self.insert_formatted_text("📿 **MYSTICAL ENHANCEMENTS FULLY ACTIVATED** 📿\n")
1466 self.insert_formatted_text("⚡ All Enhancement Symbols: * # % @ & ^ $ **item**\n")
1467 self.insert_formatted_text("🔮 * = Reroll same table and combine\n")
1468 self.insert_formatted_text("⭐ # = Roll Enchanted Enhancements table\n")
1469 self.insert_formatted_text("🌊 % = Roll Aquatic Enhancement table\n")
1470 self.insert_formatted_text("🎭 @ = Roll Quirks tables (QP → QE)\n")
1471 self.insert_formatted_text("👥 & = Roll Racial Enhancement table\n")
1472 self.insert_formatted_text("🚫 ^ = No duplicates of this enhancement type\n")
1473 self.insert_formatted_text("💰 $ = Weapon Enhancement (S2 table)\n")
1474 self.insert_formatted_text("✨ **item** = Unique artifacts (no processing)\n\n")
1475
1476 enhancement_count = sum(1 for table in ['EE', 'QE', 'QP', 'AE', 'RE'] if table in self.item_tables)
1477 self.insert_formatted_text("🔮 **Ready to generate authentic enhanced magical items!** 🔮\n\n")
1478 self.insert_formatted_text(f"📚 **Arcane Database:** {self.total_items:,} magical items across {len(self.item_tables)} mystical tables\n")
1479 self.insert_formatted_text(f"🎯 **Enhancement Tables:** {enhancement_count}/5 systems loaded\n")
1480 self.insert_formatted_text("⭐ **NEW FEATURE:** Manual EE Enhancement - enhance ANY item with Enchanted Enhancements!\n")
1481 self.insert_formatted_text("🎭 **NEW FEATURE:** Manual Quirks Enhancement - add quirks to ANY item!\n\n")
1482 self.insert_formatted_text("🌙 May the ancient symbols guide your rolls, adventurer! 🌙\n")
1483
1484 # Add hover effects
1485 self.add_hover_effects()
1486
1487 def add_hover_effects(self):
1488 """Add hover effects to buttons"""
1489 def on_enter_main(e):
1490 self.generate_btn.config(bg='#8b4513', fg='#ffffff')
1491
1492 def on_leave_main(e):
1493 self.generate_btn.config(bg='#654321', fg='#ffd700')
1494
1495 def on_enter_reroll(e):
1496 self.reroll_btn.config(bg='#a52a2a', fg='#ffffff')
1497
1498 def on_leave_reroll(e):
1499 self.reroll_btn.config(bg='#8b0000', fg='#ffd700')
1500
1501 def on_enter_ee(e):
1502 if self.ee_enhance_btn['state'] == tk.NORMAL:
1503 self.ee_enhance_btn.config(bg='#5ba0f2', fg='#ffffff')
1504
1505 def on_leave_ee(e):
1506 if self.ee_enhance_btn['state'] == tk.NORMAL:
1507 self.ee_enhance_btn.config(bg='#4a90e2', fg='#ffd700')
1508
1509 def on_enter_quirks(e):
1510 if self.quirks_enhance_btn['state'] == tk.NORMAL:
1511 self.quirks_enhance_btn.config(bg='#ba68c8', fg='#ffffff')
1512
1513 def on_leave_quirks(e):
1514 if self.quirks_enhance_btn['state'] == tk.NORMAL:
1515 self.quirks_enhance_btn.config(bg='#9c27b0', fg='#ffd700')
1516 if self.ee_enhance_btn['state'] == tk.NORMAL:
1517 self.ee_enhance_btn.config(bg='#5ba0f2', fg='#ffffff')
1518
1519 def on_leave_ee(e):
1520 if self.ee_enhance_btn['state'] == tk.NORMAL:
1521 self.ee_enhance_btn.config(bg='#4a90e2', fg='#ffd700')
1522
1523 def on_enter_test(e):
1524 self.test_btn.config(bg='#5ba0f2', fg='#ffffff')
1525
1526 def on_leave_test(e):
1527 self.test_btn.config(bg='#4a90e2', fg='#ffd700')
1528
1529 self.generate_btn.bind("<Enter>", on_enter_main)
1530 self.generate_btn.bind("<Leave>", on_leave_main)
1531 self.reroll_btn.bind("<Enter>", on_enter_reroll)
1532 self.reroll_btn.bind("<Leave>", on_leave_reroll)
1533 self.ee_enhance_btn.bind("<Enter>", on_enter_ee)
1534 self.ee_enhance_btn.bind("<Leave>", on_leave_ee)
1535 self.quirks_enhance_btn.bind("<Enter>", on_enter_quirks)
1536 self.quirks_enhance_btn.bind("<Leave>", on_leave_quirks)
1537 self.test_btn.bind("<Enter>", on_enter_test)
1538 self.test_btn.bind("<Leave>", on_leave_test)
1539
1540 def insert_formatted_text(self, text, tag=None):
1541 """Insert text with formatting and color tags"""
1542 if '**' in text and tag and tag in ["weapons", "armor", "potions", "scrolls", "jewelry", "implements", "clothing", "containers", "misc", "humorous", "legendary", "enhanced"]:
1543 # For colored item text, don't split on ** since the color tags already include bold
1544 self.result_text.insert(tk.END, text.replace('**', ''), tag)
1545 elif '**' in text:
1546 # Regular bold formatting
1547 parts = text.split('**')
1548 for i, part in enumerate(parts):
1549 if i % 2 == 1: # Odd indices are bold
1550 self.result_text.insert(tk.END, part, "bold")
1551 else:
1552 if tag:
1553 self.result_text.insert(tk.END, part, tag)
1554 else:
1555 self.result_text.insert(tk.END, part)
1556 else:
1557 # No bold formatting, just apply the tag
1558 self.result_text.insert(tk.END, text, tag)
1559
1560 def manual_ee_enhancement(self):
1561 """Manually apply EE enhancement to the current item"""
1562 print("DEBUG: EE Enhancement button clicked")
1563
1564 if not self.current_item['available']:
1565 print("DEBUG: No current item available")
1566 messagebox.showwarning("No Item Available",
1567 "Please generate an item first before applying EE enhancement!")
1568 return
1569
1570 # Check if max EE enhancements reached (3 max)
1571 if self.current_item['ee_count'] >= 3:
1572 messagebox.showwarning("Max EE Enhancements Reached",
1573 "This item already has 3 EE enhancements (maximum allowed)!")
1574 return
1575
1576 if 'EE' not in self.item_tables:
1577 print("DEBUG: EE table not found")
1578 messagebox.showerror("EE Table Missing",
1579 "Enchanted Enhancements table (EE_Table.csv) is not loaded!")
1580 return
1581
1582 print(f"DEBUG: Current item: {self.current_item}")
1583
1584 # Get the CURRENT item (which may already have enhancements)
1585 current_item_name = self.current_item['name']
1586 print(f"DEBUG: Current item name: {current_item_name}")
1587
1588 try:
1589 # Apply FRESH EE enhancement to the current item
1590 enhanced_item, processing_log, applied_enhancements = self.apply_manual_ee_enhancement(current_item_name)
1591 print(f"DEBUG: Enhanced item: {enhanced_item}")
1592
1593 # Update current item with new enhancement and increment counter
1594 self.current_item['name'] = enhanced_item
1595 self.current_item['ee_count'] += 1
1596
1597 # Display results
1598 self.result_text.insert(tk.END, "\n" + "="*60 + "\n")
1599 self.insert_formatted_text(f"⭐ **EE ENHANCEMENT #{self.current_item['ee_count']} APPLIED** ⭐\n", "title")
1600 self.result_text.insert(tk.END, "="*60 + "\n\n")
1601
1602 self.result_text.insert(tk.END, f"🎯 Item Before: {current_item_name}\n")
1603 self.result_text.insert(tk.END, f"📈 EE Count: {self.current_item['ee_count']}/3 maximum\n")
1604 self.result_text.insert(tk.END, f"📋 Enhancement Processing Log:\n")
1605 for i, log_entry in enumerate(processing_log, 1):
1606 self.result_text.insert(tk.END, f" {i}. {log_entry}\n")
1607
1608 self.result_text.insert(tk.END, f"\n")
1609 self.insert_formatted_text(f"✨ **NEW ENHANCED RESULT: {enhanced_item}** ✨\n\n", "enhanced")
1610
1611 self.result_text.insert(tk.END, f"🔧 Applied Enhancements: {applied_enhancements}\n")
1612
1613 # Show remaining enhancement capacity
1614 remaining_ee = 3 - self.current_item['ee_count']
1615 remaining_quirks = 3 - self.current_item['quirks_count']
1616
1617 if remaining_ee > 0:
1618 self.result_text.insert(tk.END, f"⭐ {remaining_ee} more EE enhancements available!\n")
1619 else:
1620 self.result_text.insert(tk.END, f"🚫 Maximum EE enhancements (3) reached!\n")
1621
1622 if remaining_quirks > 0:
1623 self.result_text.insert(tk.END, f"🎭 {remaining_quirks} quirks enhancements still available!\n")
1624 else:
1625 self.result_text.insert(tk.END, f"🚫 Maximum quirks enhancements (3) reached!\n")
1626
1627 self.result_text.insert(tk.END, f"🎲 Or generate a new item to start fresh.\n\n")
1628
1629 # Update button states after applying enhancement
1630 if self.current_item['ee_count'] >= 3:
1631 self.ee_enhance_btn.config(state=tk.DISABLED)
1632 if self.current_item['quirks_count'] >= 3:
1633 self.quirks_enhance_btn.config(state=tk.DISABLED)
1634
1635 self.result_text.see(tk.END)
1636 print("DEBUG: EE Enhancement completed successfully")
1637
1638 except Exception as e:
1639 print(f"DEBUG: Error in EE enhancement: {str(e)}")
1640 import traceback
1641 traceback.print_exc()
1642 messagebox.showerror("Enhancement Error", f"An error occurred: {str(e)}")
1643
1644 def generate_item(self):
1645 """Generate a random magic item"""
1646 if not self.all_items:
1647 self.result_text.insert(tk.END, "\n❌ No items loaded! Check your CSV files.\n")
1648 return
1649
1650 selected_category = self.category_var.get()
1651
1652 if selected_category.startswith("🎲 Random"):
1653 main_table_roll = random.randint(1, 100)
1654 category = self.get_main_category_from_table1(main_table_roll)
1655 category_items, table_used = self.get_category_items(category)
1656 final_items, all_rolls = self.generate_item_from_category(category_items, category)
1657
1658 dice_info = f"🎲 Table 1 Roll: {main_table_roll} → {category} (Table {table_used})\n"
1659 dice_info += f"🎲 {category} Rolls:\n"
1660 for roll in all_rolls:
1661 dice_info += f" {roll}\n"
1662
1663 actual_category = category
1664 actual_items = category_items
1665
1666 else:
1667 category_items, table_used = self.get_category_items(selected_category)
1668
1669 if category_items:
1670 if "🌟 Legendary Artifacts" in selected_category:
1671 clean_category = "Legendary Artifacts"
1672 elif '(' in selected_category:
1673 clean_category = selected_category.split('(')[0].strip()
1674 clean_category = ''.join(char for char in clean_category if char.isalpha() or char.isspace()).strip()
1675 else:
1676 clean_category = selected_category
1677
1678 final_items, all_rolls = self.generate_item_from_category(category_items, clean_category)
1679
1680 dice_info = f"🎲 {clean_category} Rolls (Table {table_used}):\n"
1681 for roll in all_rolls:
1682 dice_info += f" {roll}\n"
1683
1684 actual_category = clean_category
1685 actual_items = category_items
1686 else:
1687 self.result_text.insert(tk.END, f"\n❌ No items found in category: {selected_category}\n")
1688 return
1689
1690 # Display results
1691 self.result_text.insert(tk.END, "\n" + "="*60 + "\n")
1692 self.insert_formatted_text(f"🔮 **MYSTICAL DIVINATION COMPLETE** 🔮\n", "title")
1693 self.result_text.insert(tk.END, "="*60 + "\n\n")
1694
1695 self.result_text.insert(tk.END, dice_info + "\n", "dice")
1696
1697 if len(final_items) == 1:
1698 item = final_items[0]
1699
1700 # Store current item for EE enhancement
1701 self.current_item = {
1702 'name': item['name'],
1703 'original_name': item['name'], # Store original for fresh EE enhancements
1704 'category': item['category'],
1705 'table': item['table'],
1706 'available': True,
1707 'ee_count': 0, # Reset enhancement counters
1708 'quirks_count': 0
1709 }
1710
1711 # Enable EE enhancement button
1712 # Enable buttons based on remaining enhancement capacity
1713 if self.current_item['ee_count'] < 3:
1714 self.ee_enhance_btn.config(state=tk.NORMAL)
1715 else:
1716 self.ee_enhance_btn.config(state=tk.DISABLED)
1717
1718 if self.current_item['quirks_count'] < 3:
1719 self.quirks_enhance_btn.config(state=tk.NORMAL)
1720 else:
1721 self.quirks_enhance_btn.config(state=tk.DISABLED)
1722 # Enable Quirks enhancement button
1723 self.quirks_enhance_btn.config(state=tk.NORMAL)
1724
1725 self.last_generation = {
1726 'category': actual_category,
1727 'table_id': item['table'],
1728 'items': actual_items,
1729 'available': True
1730 }
1731
1732 if "🌟 Legendary Artifacts" in selected_category or actual_category == "Legendary Artifacts":
1733 self.result_text.insert(tk.END, f"🌟 Category: LEGENDARY ARTIFACTS\n", "category")
1734 self.result_text.insert(tk.END, f"📋 Table: T (Ancient Artifacts of Power)\n", "category")
1735 self.result_text.insert(tk.END, f"🎲 Range: {item['roll_from']}-{item['roll_to']}\n", "category")
1736 self.result_text.insert(tk.END, f"⚡ Power Level: MAXIMUM\n\n", "category")
1737
1738 legendary_discoveries = [
1739 "🌟 ARTIFACT OF COSMIC POWER UNEARTHED 🌟",
1740 "🌟 LEGENDARY RELIC OF THE ANCIENTS DISCOVERED 🌟",
1741 "🌟 ULTIMATE TREASURE OF THE AGES REVEALED 🌟",
1742 "🌟 MYTHICAL ARTIFACT OF UNTOLD POWER FOUND 🌟"
1743 ]
1744 legendary_text = random.choice(legendary_discoveries)
1745 self.insert_formatted_text(f"{legendary_text}: {item['name']}\n\n", "legendary")
1746
1747 self.result_text.insert(tk.END, f"💎 Behold! A true artifact of legend has been revealed!\n")
1748 self.result_text.insert(tk.END, f"🔮 Use '🌀 DIVINE AGAIN' to discover another legendary relic!\n")
1749 self.result_text.insert(tk.END, f"⭐ Use 'ADD EE ENHANCEMENT' to further enhance this legendary artifact!\n\n")
1750 else:
1751 self.result_text.insert(tk.END, f"📖 Category: {item['category']}\n", "category")
1752 self.result_text.insert(tk.END, f"📋 Table: {item['table']}\n", "category")
1753 self.result_text.insert(tk.END, f"🎲 Range: {item['roll_from']}-{item['roll_to']}\n\n", "category")
1754
1755 formatted_item, color_tag = self.format_item_result(item, is_final=True)
1756 self.insert_formatted_text(f"{formatted_item}\n\n", color_tag)
1757
1758 self.result_text.insert(tk.END, f"💡 Seek different treasure? Use '🌀 DIVINE AGAIN' for another {item['category']} item!\n")
1759 self.result_text.insert(tk.END, f"⭐ Want to enhance this item? Use 'ADD EE ENHANCEMENT' to apply Enchanted Enhancements!\n\n")
1760 else:
1761 # Multiple items - store the first one for enhancement
1762 if final_items:
1763 self.current_item = {
1764 'name': final_items[0]['name'],
1765 'original_name': final_items[0]['name'], # Store original for fresh EE enhancements
1766 'category': final_items[0]['category'],
1767 'table': final_items[0]['table'],
1768 'available': True,
1769 'ee_count': 0, # Reset enhancement counters
1770 'quirks_count': 0
1771 }
1772 # Enable buttons based on remaining enhancement capacity
1773 if self.current_item['ee_count'] < 3:
1774 self.ee_enhance_btn.config(state=tk.NORMAL)
1775 else:
1776 self.ee_enhance_btn.config(state=tk.DISABLED)
1777
1778 if self.current_item['quirks_count'] < 3:
1779 self.quirks_enhance_btn.config(state=tk.NORMAL)
1780 else:
1781 self.quirks_enhance_btn.config(state=tk.DISABLED)
1782 self.quirks_enhance_btn.config(state=tk.NORMAL)
1783
1784 self.insert_formatted_text(f"⚡ **ENHANCEMENT CASCADE TRIGGERED** ⚡\n\n", "title")
1785 self.result_text.insert(tk.END, f"🔗 Combined magical energies detected:\n")
1786 for i, item in enumerate(final_items, 1):
1787 formatted_item, color_tag = self.format_item_result(item)
1788 self.insert_formatted_text(f" {i}. {formatted_item}\n", color_tag)
1789
1790 self.result_text.insert(tk.END, f"\n🧙♂️ **DM's Forge:** Combine these {len(final_items)} magical essences into ONE ultimate artifact!\n")
1791 self.result_text.insert(tk.END, f"⭐ **Enhancement Available:** You can enhance the first item ({final_items[0]['name']}) with EE!\n\n")
1792
1793 if final_items:
1794 self.last_generation = {
1795 'category': actual_category,
1796 'table_id': final_items[0]['table'].split('+')[0],
1797 'items': actual_items,
1798 'available': True
1799 }
1800
1801 self.result_text.see(tk.END)
1802
1803 def reroll_same_table(self):
1804 """Reroll on the same table"""
1805 if not self.last_generation['available']:
1806 self.result_text.insert(tk.END, "\n❌ No previous generation to reroll! Generate an item first.\n\n")
1807 self.result_text.see(tk.END)
1808 return
1809
1810 category = self.last_generation['category']
1811 table_id = self.last_generation['table_id']
1812 category_items = self.last_generation['items']
1813
1814 self.result_text.insert(tk.END, "\n" + "="*60 + "\n")
1815 self.result_text.insert(tk.END, f"🔄 REROLLING ON SAME TABLE 🔄\n")
1816 self.result_text.insert(tk.END, "="*60 + "\n\n")
1817 self.result_text.insert(tk.END, f"🎯 Rerolling on: {category} (Table {table_id})\n")
1818 self.result_text.insert(tk.END, f"📊 Available items: {len(category_items)}\n\n")
1819
1820 final_items, all_rolls = self.generate_item_from_category(category_items, category)
1821
1822 dice_info = f"🎲 {category} Reroll:\n"
1823 for roll in all_rolls:
1824 dice_info += f" {roll}\n"
1825
1826 self.result_text.insert(tk.END, f"{dice_info}\n")
1827
1828 if len(final_items) == 1:
1829 item = final_items[0]
1830
1831 # Update current item for EE enhancement
1832 self.current_item = {
1833 'name': item['name'],
1834 'original_name': item.get('original_name', item['name']), # Preserve original if it exists
1835 'category': item['category'],
1836 'table': item['table'],
1837 'available': True,
1838 'ee_count': 0, # Reset enhancement counters for rerolls
1839 'quirks_count': 0
1840 }
1841 self.ee_enhance_btn.config(state=tk.NORMAL)
1842
1843 self.result_text.insert(tk.END, f"📜 Category: {item['category']}\n")
1844 self.result_text.insert(tk.END, f"🎯 Table: {item['table']}\n")
1845 self.result_text.insert(tk.END, f"🎲 Range: {item['roll_from']}-{item['roll_to']}\n\n")
1846 self.insert_formatted_text(f"✨ **REROLL RESULT: {item['name']}** ✨\n\n", self.get_item_color_tag(item))
1847
1848 self.last_generation['table_id'] = item['table']
1849
1850 self.result_text.insert(tk.END, f"💡 Still not right? Click '🌀 DIVINE AGAIN' again!\n")
1851 self.result_text.insert(tk.END, f"⭐ Want to enhance? Use 'ADD EE ENHANCEMENT'!\n\n")
1852 else:
1853 # Multiple items - update current item to first one
1854 if final_items:
1855 self.current_item = {
1856 'name': final_items[0]['name'],
1857 'original_name': final_items[0].get('original_name', final_items[0]['name']), # Preserve original
1858 'category': final_items[0]['category'],
1859 'table': final_items[0]['table'],
1860 'available': True
1861 }
1862 self.ee_enhance_btn.config(state=tk.NORMAL)
1863
1864 self.result_text.insert(tk.END, f"🔄 ENHANCED REROLL RESULT:\n\n")
1865 for i, item in enumerate(final_items, 1):
1866 self.insert_formatted_text(f" ✨ **{i}. {item['name']}**\n", self.get_item_color_tag(item))
1867 self.result_text.insert(tk.END, f"\n💡 Combine these {len(final_items)} items into ONE enhanced item!\n")
1868 self.result_text.insert(tk.END, f"⭐ **Enhancement Available:** You can enhance the first item with EE!\n\n")
1869
1870 self.result_text.see(tk.END)
1871
1872 def test_enhancement_system(self):
1873 """Test the enhancement system with real items from random tables"""
1874 self.result_text.insert(tk.END, "\n" + "="*80 + "\n")
1875 self.result_text.insert(tk.END, "🧪 ENHANCEMENT SYSTEM TEST 🧪\n")
1876 self.result_text.insert(tk.END, "="*80 + "\n\n")
1877
1878 self.result_text.insert(tk.END, "📋 **ENHANCED SYMBOL SYSTEM:**\n")
1879 self.result_text.insert(tk.END, "* = Reroll same table and combine\n")
1880 self.result_text.insert(tk.END, "# = Roll EE table\n")
1881 self.result_text.insert(tk.END, "% = Roll AE table\n")
1882 self.result_text.insert(tk.END, "@ = Roll QP→QE tables\n")
1883 self.result_text.insert(tk.END, "& = Roll RE table\n")
1884 self.result_text.insert(tk.END, "^ = Select item, however, No duplicates if selected again reroll\n")
1885 self.result_text.insert(tk.END, "$ = Weapon enhancement\n")
1886 self.result_text.insert(tk.END, "**item** = Unique artifacts\n")
1887 self.result_text.insert(tk.END, "⭐ MANUAL EE = Apply EE enhancement to ANY item\n\n")
1888
1889 # TEST SCENARIO #1: Test Manual EE Enhancement
1890 self.result_text.insert(tk.END, "🎯 **TEST SCENARIO #1 - MANUAL EE ENHANCEMENT**\n")
1891 self.result_text.insert(tk.END, "Apply manual EE enhancement to a simple item\n\n")
1892
1893 try:
1894 # Find a simple item without symbols
1895 simple_items = []
1896 for table_id, table_data in self.item_tables.items():
1897 if table_id not in ['EE', 'QE', 'QP', 'AE', 'RE', '1']: # Skip enhancement and main tables
1898 for item in table_data['items']:
1899 if not self.has_enhancement_symbols(item['name']) and not self.is_unique_artifact(item['name']):
1900 simple_items.append((table_id, item))
1901
1902 if simple_items:
1903 chosen_table, chosen_item = random.choice(simple_items)
1904 base_name = chosen_item['name']
1905 self.result_text.insert(tk.END, f"🎲 TEST ITEM: '{base_name}' from Table {chosen_table}\n")
1906
1907 # Apply manual EE enhancement
1908 enhanced_item, processing_log, applied_enhancements = self.apply_manual_ee_enhancement(base_name)
1909
1910 self.result_text.insert(tk.END, f"✅ ENHANCED RESULT: {enhanced_item}\n")
1911 self.result_text.insert(tk.END, f"📋 PROCESSING LOG:\n")
1912 for i, log_entry in enumerate(processing_log, 1):
1913 self.result_text.insert(tk.END, f" {i}. {log_entry}\n")
1914 self.result_text.insert(tk.END, f"🔧 Applied Enhancements: {applied_enhancements}\n")
1915 else:
1916 self.result_text.insert(tk.END, "❌ NO simple items found for testing\n")
1917
1918 except Exception as e:
1919 self.result_text.insert(tk.END, f"❌ ERROR: {str(e)}\n")
1920
1921 self.result_text.insert(tk.END, "\n" + "="*60 + "\n\n")
1922
1923 # TEST SCENARIO #2: Find real "Enchanted Enhancements*#" items
1924 self.result_text.insert(tk.END, "🎯 **TEST SCENARIO #2**\n")
1925 self.result_text.insert(tk.END, "Find random table containing 'Enchanted Enhancements*#' and test it\n\n")
1926
1927 try:
1928 # Search all tables for items with "Enchanted Enhancements*#"
1929 ee_star_hash_items = []
1930 for table_id, table_data in self.item_tables.items():
1931 for item in table_data['items']:
1932 if 'enchanted enhancements' in item['name'].lower() and '*#' in item['name']:
1933 ee_star_hash_items.append((table_id, item))
1934
1935 if ee_star_hash_items:
1936 # Pick a random one
1937 chosen_table, chosen_item = random.choice(ee_star_hash_items)
1938 self.result_text.insert(tk.END, f"🎲 FOUND: '{chosen_item['name']}' in Table {chosen_table}\n")
1939 self.result_text.insert(tk.END, f"📋 Roll range: {chosen_item['roll_from']}-{chosen_item['roll_to']}\n")
1940
1941 # Process it
1942 result, log, enhancements = self.process_enhanced_item(chosen_item['name'], chosen_table)
1943
1944 self.result_text.insert(tk.END, f"✅ FINAL RESULT: {result}\n")
1945 self.result_text.insert(tk.END, f"📋 PROCESSING LOG:\n")
1946 for i, log_entry in enumerate(log, 1):
1947 self.result_text.insert(tk.END, f" {i}. {log_entry}\n")
1948 self.result_text.insert(tk.END, f"🔧 Applied Enhancements: {enhancements}\n")
1949 else:
1950 self.result_text.insert(tk.END, "❌ NO 'Enchanted Enhancements*#' items found in any table\n")
1951
1952 except Exception as e:
1953 self.result_text.insert(tk.END, f"❌ ERROR: {str(e)}\n")
1954
1955 self.result_text.insert(tk.END, "\n" + "="*60 + "\n\n")
1956
1957 # Enhancement table status
1958 self.result_text.insert(tk.END, "📊 **ENHANCEMENT TABLE STATUS:**\n")
1959 enhancement_tables = ['EE', 'QE', 'QP', 'AE', 'RE']
1960 loaded_count = 0
1961 for table_id in enhancement_tables:
1962 if table_id in self.item_tables:
1963 count = len(self.item_tables[table_id]['items'])
1964 self.result_text.insert(tk.END, f" ✅ {table_id}: {count} items loaded\n")
1965 loaded_count += 1
1966 else:
1967 self.result_text.insert(tk.END, f" ❌ {table_id}: NOT LOADED\n")
1968
1969 self.result_text.insert(tk.END, f"\n🎯 **STATUS:** {loaded_count}/{len(enhancement_tables)} enhancement tables operational\n")
1970
1971 if loaded_count >= 1: # At least EE table for manual enhancement
1972 self.result_text.insert(tk.END, f"🎉 **MANUAL EE ENHANCEMENT READY!**\n")
1973 else:
1974 self.result_text.insert(tk.END, f"⚠️ **EE table missing - manual enhancement unavailable**\n")
1975
1976 self.result_text.insert(tk.END, f"\n🧪 **Test scenarios complete! Manual EE enhancement system operational.**\n")
1977 self.result_text.see(tk.END)
1978
1979 def run(self):
1980 """Start the application"""
1981 self.root.mainloop()
1982
1983if __name__ == "__main__":
1984 print("🎲 Starting Enhanced Arcane Treasury Generator...")
1985 app = MagicItemGenerator()
1986 app.run()