1import tkinter as tk
2from tkinter import ttk, messagebox, simpledialog, scrolledtext
3import re
4
5# Funciones para cargar y guardar archivos
6def load_file(file_path):
7 with open(file_path, 'r') as file:
8 return file.read()
9
10def save_file(file_path, content):
11 with open(file_path, 'w') as file:
12 file.write(content)
13
14# Funciones para actualizar el archivo Lua
15def update_file(content, start, end, updated_dict, var_name):
16 updated_entries = []
17 for key, value in updated_dict.items():
18 entries = ', '.join([f"{dir} = {{x = {coords['x']}, y = {coords['y']}}}" for dir, coords in value.items()])
19 updated_entries.append(f"[{key}] = {{{entries}}}")
20 updated_str = f"{var_name} = {{{', '.join(updated_entries)}}}"
21 return content[:start] + updated_str + content[end:]
22
23# Clase principal para la aplicación
24class WingsEditorApp(tk.Tk):
25 def __init__(self):
26 super().__init__()
27 self.title("Wings Editor")
28 self.geometry("1000x800")
29 self.file_path = 'game_wings.lua'
30 self.content = load_file(self.file_path)
31
32 # Pestañas principales
33 self.tab_control = ttk.Notebook(self)
34
35 # Pestañas para cada área
36 self.tabs = {
37 "typesWingedOffSet": ttk.Frame(self.tab_control),
38 "typesWingedMountedOffSet": ttk.Frame(self.tab_control),
39 "WingsOffsets": ttk.Frame(self.tab_control),
40 "WingsMountedOffsets": ttk.Frame(self.tab_control)
41 }
42
43 for name, frame in self.tabs.items():
44 self.tab_control.add(frame, text=name)
45
46 self.tab_control.pack(expand=1, fill="both")
47
48 # Crear widgets y cargar contenido
49 self.tables = {}
50 self.start_end_positions = {}
51
52 for name in ["typesWingedOffSet", "typesWingedMountedOffSet"]:
53 self.tables[name], start, end = self.parse_lua_table(self.content, name)
54 self.start_end_positions[name] = (start, end)
55 self.create_table(self.tabs[name], self.tables[name], name)
56
57 for name in ["WingsOffsets", "WingsMountedOffsets"]:
58 self.tables[name], start, end = self.parse_lua_table(self.content, name)
59 self.start_end_positions[name] = (start, end)
60 self.create_table(self.tabs[name], self.tables[name], name)
61
62 # Botones de acción
63 self.save_button = tk.Button(self, text="Guardar cambios", command=self.save_changes)
64 self.save_button.pack(pady=10)
65
66 # Terminal interna
67 self.terminal = scrolledtext.ScrolledText(self, height=10, state='disabled', bg='black', fg='white', insertbackground='white')
68 self.terminal.pack(fill=tk.BOTH, padx=10, pady=10, expand=True)
69
70 # Función para analizar las tablas Lua
71 def parse_lua_table(self, content, var_name):
72 pattern = re.compile(rf'{var_name}\s*=\s*\{{(.*?)\}}', re.DOTALL)
73 match = pattern.search(content)
74 if match:
75 table_str = match.group(1)
76 start_index = match.start(1)
77 end_index = match.end(1)
78
79 table_dict = {}
80 entry_pattern = re.compile(r'\[(\d+)\]\s*:\s*\{(.*?)\}', re.DOTALL)
81 for entry in entry_pattern.finditer(table_str):
82 key = int(entry.group(1))
83 value_str = entry.group(2).strip()
84 directions = re.findall(r'(\w+)\s*=\s*\{\s*x\s*=\s*(-?\d+),\s*y\s*=\s*(-?\d+)\s*\}', value_str)
85 table_dict[key] = {dir[0]: {'x': int(dir[1]), 'y': int(dir[2])} for dir in directions}
86
87 return table_dict, start_index, end_index
88 return {}, None, None
89
90 # Función para crear la tabla
91 def create_table(self, parent, data, table_name):
92 tree = ttk.Treeview(parent, columns=("x", "y"), show='headings')
93 tree.heading("x", text="X")
94 tree.heading("y", text="Y")
95 tree.pack(expand=True, fill=tk.BOTH)
96
97 for key, value in data.items():
98 for direction, coords in value.items():
99 tree.insert("", "end", values=(direction, coords['x'], coords['y']))
100
101 # Botones de agregar, eliminar y cargar
102 add_button = tk.Button(parent, text="Agregar", command=lambda: self.add_entry(table_name))
103 add_button.pack(pady=5, side=tk.LEFT, padx=5)
104 delete_button = tk.Button(parent, text="Eliminar", command=lambda: self.delete_entry(table_name))
105 delete_button.pack(pady=5, side=tk.LEFT, padx=5)
106 load_button = tk.Button(parent, text="Cargar", command=lambda: self.load_table(table_name))
107 load_button.pack(pady=5, side=tk.LEFT, padx=5)
108
109 # Función para agregar una entrada
110 def add_entry(self, table_name):
111 key = simpledialog.askinteger("Agregar entrada", "Ingrese el ID de la nueva entrada:")
112 if key is not None and key not in self.tables[table_name]:
113 self.tables[table_name][key] = {direction: {'x': 0, 'y': 0} for direction in ["North", "East", "South", "West"]}
114 self.refresh_table(table_name)
115 self.log(f"Entrada {key} agregada en {table_name}.")
116
117 # Función para eliminar una entrada
118 def delete_entry(self, table_name):
119 key = simpledialog.askinteger("Eliminar entrada", "Ingrese el ID de la entrada a eliminar:")
120 if key is not None and key in self.tables[table_name]:
121 del self.tables[table_name][key]
122 self.refresh_table(table_name)
123 self.log(f"Entrada {key} eliminada en {table_name}.")
124
125 # Función para cargar una tabla
126 def load_table(self, table_name):
127 self.tables[table_name], start, end = self.parse_lua_table(self.content, table_name)
128 self.start_end_positions[table_name] = (start, end) # Actualizar posiciones de inicio y fin
129 self.refresh_table(table_name)
130 self.log(f"Tabla {table_name} cargada.")
131
132 # Función para actualizar la tabla
133 def refresh_table(self, table_name):
134 for widget in self.tabs[table_name].winfo_children():
135 widget.destroy()
136 self.create_table(self.tabs[table_name], self.tables[table_name], table_name)
137
138 # Función para guardar los cambios en el archivo
139 def save_changes(self):
140 for name in ["typesWingedOffSet", "typesWingedMountedOffSet"]:
141 updated_dict = self.tables[name]
142 start, end = self.start_end_positions[name]
143 self.content = update_file(self.content, start, end, updated_dict, name)
144
145 for name in ["WingsOffsets", "WingsMountedOffsets"]:
146 updated_dict = self.tables[name]
147 start, end = self.start_end_positions[name]
148 self.content = update_file(self.content, start, end, updated_dict, name)
149
150 save_file(self.file_path, self.content)
151 self.log("Cambios guardados correctamente.")
152
153 # Función para mostrar mensajes en la terminal interna
154 def log(self, message):
155 self.terminal.configure(state='normal')
156 self.terminal.insert(tk.END, message + '\n')
157 self.terminal.configure(state='disabled')
158 self.terminal.yview(tk.END)
159
160if __name__ == "__main__":
161 app = WingsEditorApp()
162 app.mainloop()
163