pyscreeps-arena 0.5.9.0__py3-none-any.whl → 0.5.9a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,6 @@ import shutil
8
8
  import chardet
9
9
  import subprocess
10
10
  import pyperclip
11
- import datetime
12
11
  from colorama import Fore
13
12
  from typing import List, Optional, Tuple, Union
14
13
 
@@ -53,7 +52,6 @@ def replace_src_prefix(file_list):
53
52
  # """
54
53
  # return PYFILE_PRAGMA_INSERTS + "\n" + content
55
54
  class Compiler_Const:
56
- CALLED_FUNCTIONS = ['behavior', 'sequence', 'selector', 'parallel', 'listen']
57
55
  PROTO_DEFINES_DIRS = ["builtin", "library"]
58
56
  FILE_STRONG_REPLACE = {
59
57
  "std": {
@@ -110,14 +108,14 @@ export var loop = function () {
110
108
  if (know.now === 1) {
111
109
  std.show_welcome();
112
110
  init (know);
113
-
111
+
114
112
  }
115
113
  step (know);
116
114
  timeLine = get.cpu_us();
117
115
  if (get._SCH_FLAG) sch.handle();
118
116
  stepCost = get.cpu_us() - timeLine;
119
117
  std.show_usage ();
120
- print("knowCost:", knowCost, "monitorCost:", monitorCost, "stepCost:", stepCost);
118
+ print("knowCost:", knowCost, "monitorCost:", monitorCost, "stepCost:", stepCost);
121
119
  if (know.draw) know.draw();
122
120
  };
123
121
  """
@@ -650,82 +648,6 @@ class Compiler_Utils(Compiler_Const):
650
648
 
651
649
  return result
652
650
 
653
- @staticmethod
654
- def stage_called_replace(caller_name: str, content: str) -> str:
655
- """
656
- 移除 '@<caller_name>(...)' 装饰器行,并在文末添加对应的 _<caller_name>Login 调用。
657
-
658
- 对于类方法: _<caller_name>Login("ClassName", "method_name", a, b, ...)
659
- 对于普通函数: _<caller_name>Login("", "function_name", a, b, ...)
660
- """
661
- calls_to_add = []
662
- deletions = []
663
-
664
- # 1. 收集所有类定义的位置和缩进
665
- class_pattern = re.compile(r'^(\s*)class\s+(\w+)', re.MULTILINE)
666
- classes = [(m.start(), len(m.group(1)), m.group(2))
667
- for m in class_pattern.finditer(content)]
668
-
669
- # 2. 查找所有 @<caller_name>(...) 装饰器(支持多行参数)
670
- decorator_pattern = re.compile(
671
- r'^\s*@\s*' + re.escape(caller_name) + r'\s*\((.*?)\)\s*$\n?',
672
- re.MULTILINE | re.DOTALL
673
- )
674
-
675
- for dec_match in decorator_pattern.finditer(content):
676
- dec_start = dec_match.start()
677
- dec_end = dec_match.end()
678
- # 提取装饰器的参数
679
- params_str = dec_match.group(1).strip()
680
-
681
- # 查找接下来的函数定义(跳过可能的空行)
682
- after_decorator = content[dec_end:]
683
- func_match = re.search(r'^(\s*)def\s+([^\s\(]+)', after_decorator, re.MULTILINE)
684
-
685
- if not func_match:
686
- continue
687
-
688
- func_indent_len = len(func_match.group(1))
689
- func_name = func_match.group(2)
690
-
691
- # 3. 确定类名:查找装饰器前最近的、缩进小于函数缩进的类
692
- class_name = ""
693
- for cls_pos, cls_indent_len, cls_name in reversed(classes):
694
- if cls_pos < dec_match.start() and func_indent_len > cls_indent_len:
695
- class_name = cls_name
696
- break
697
-
698
- # 4. 处理参数,保持参数的格式
699
- # 移除参数中的换行和多余空格,保持参数列表的格式
700
- params = []
701
- if params_str:
702
- # 简单处理参数,保持引号内的内容不变
703
- # 这里可以根据需要进行更复杂的参数解析
704
- params = [p.strip() for p in params_str.split(',') if p.strip()]
705
-
706
- # 构建参数部分的字符串
707
- params_part = ""
708
- if params:
709
- params_part = ", " + ", ".join(params)
710
-
711
- # 5. 记录删除位置和调用信息
712
- deletions.append((dec_start, dec_end))
713
- calls_to_add.append(f'_{caller_name}Login("{class_name}", "{func_name}"{params_part})')
714
-
715
- # 6. 应用删除(倒序避免位置偏移)
716
- if not deletions:
717
- return content
718
-
719
- result = content
720
- for start, end in sorted(deletions, key=lambda x: x[0], reverse=True):
721
- result = result[:start] + result[end:]
722
-
723
- # 7. 在文末添加调用
724
- if calls_to_add:
725
- result = '\n'.join(calls_to_add) + '\n' + result
726
-
727
- return result
728
-
729
651
  @staticmethod
730
652
  def process_mate_code(code):
731
653
  # 用于存储匹配到的信息
@@ -999,8 +921,6 @@ class Compiler(CompilerBase):
999
921
 
1000
922
  # 将PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "")插入到文件开头
1001
923
  content = self.auto_read(fpath)
1002
- # 移除"""$..."""代码块
1003
- content = re.sub(r'"""\$[\s\S]*?"""', '', content)
1004
924
  content = self.PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "") + content
1005
925
  # content = self.remove_long_docstring(content) # 移除长注释 | remove long docstring
1006
926
 
@@ -1157,13 +1077,10 @@ class Compiler(CompilerBase):
1157
1077
  with open(fpath, 'w', encoding='utf-8') as f:
1158
1078
  f.write(new_content)
1159
1079
 
1160
- # ------------------------------------ 自定义:调用stage_recursive_replace和stage_called_replace ------------------------------------ #
1080
+ # ------------------------------------ 自定义:调用stage_recursive_replace ------------------------------------ #
1161
1081
  for fpath in py_fpath:
1162
1082
  content = self.auto_read(fpath)
1163
1083
  content = self.stage_recursive_replace(content) # 调用stage_recursive_replace
1164
- # 调用stage_called_replace处理四个装饰器
1165
- for caller in self.CALLED_FUNCTIONS:
1166
- content = self.stage_called_replace(caller, content)
1167
1084
  with open(fpath, 'w', encoding='utf-8') as f:
1168
1085
  f.write(content)
1169
1086
 
@@ -1300,22 +1217,12 @@ class Compiler(CompilerBase):
1300
1217
  :param min_js_files: list[str] # .min.js文件路径列表
1301
1218
  :return: str
1302
1219
  """
1303
- arena_name = const.ARENA_NAMES.get(config.arena, const.ARENA_NAMES["green"]) # like green -> spawn_and_swamp
1220
+ arena_name = const.ARENA_NAMES.get(config.arena, const.ARENA_NAMES['green']) # like green -> spawn_and_swamp
1304
1221
  self.TOTAL_INSERT_AT_HEAD += self.ARENA_IMPORTS_GETTER[arena_name]() # add arena imports
1305
- current_time = datetime.datetime.now()
1306
- timestamp_ms = int(current_time.timestamp() * 1000)
1307
- timestring = current_time.strftime("%Y-%m-%d %H:%M")
1308
-
1309
- total_js = f"""const __VERSION__ = '{const.VERSION}';
1310
- const __PYTHON_VERSION__ = '{python_version_info}';""" + self.TOTAL_INSERT_AT_HEAD + f"""
1311
- export var LANGUAGE = '{config.language}';
1312
- """
1313
-
1314
- total_js += f"export var TIMESTAMP = {timestamp_ms};\n"
1315
- total_js += f"export var TIMESTRING = '{timestring}';\n"
1316
- total_js += f"""const __AUTHOR__ = '{const.AUTHOR}';
1317
- const __AUTHOR_CN__ = '{const.BILIBILI_NAME}';"""
1222
+ total_js = f"const __VERSION__ = '{const.VERSION}';\nconst __PYTHON_VERSION__ = '{python_version_info}';" + self.TOTAL_INSERT_AT_HEAD + f"\nexport var LANGUAGE = '{config.language}';\n"
1223
+ total_js += f"const __AUTHOR__ = '{const.AUTHOR}';\nconst __AUTHOR_CN__ = '{const.BILIBILI_NAME}';"
1318
1224
 
1225
+ # 添加.min.js文件的import语句
1319
1226
  if min_js_files:
1320
1227
  for min_js_path in min_js_files:
1321
1228
  min_js_filename = os.path.basename(min_js_path)
@@ -1435,6 +1342,14 @@ const __AUTHOR_CN__ = '{const.BILIBILI_NAME}';"""
1435
1342
  dir_path = os.path.dirname(mjs_path)
1436
1343
  build_dir_path = os.path.dirname(build_main_mjs)
1437
1344
 
1345
+ # 复制.min.js文件到目标目录
1346
+ for min_js_path in min_js_files:
1347
+ min_js_filename = os.path.basename(min_js_path)
1348
+ # 复制到build目录
1349
+ shutil.copy(min_js_path, os.path.join(build_dir_path, min_js_filename))
1350
+ # 复制到最终导出目录
1351
+ shutil.copy(min_js_path, os.path.join(dir_path, min_js_filename))
1352
+
1438
1353
  # 生成total_js,传入.min.js文件列表
1439
1354
  total_js = imports + "\n" + self.generate_total_js(
1440
1355
  replace_src_prefix(modules), imps, sorts, self.FILE_STRONG_REPLACE, reps, min_js_files
@@ -1450,14 +1365,6 @@ const __AUTHOR_CN__ = '{const.BILIBILI_NAME}';"""
1450
1365
  with open(mjs_path, 'w', encoding='utf-8') as f:
1451
1366
  f.write(total_js)
1452
1367
 
1453
- # 复制.min.js文件到目标目录
1454
- for min_js_path in min_js_files:
1455
- min_js_filename = os.path.basename(min_js_path)
1456
- # 复制到build目录
1457
- shutil.copy(min_js_path, os.path.join(build_dir_path, min_js_filename))
1458
- # 复制到最终导出目录
1459
- shutil.copy(min_js_path, os.path.join(dir_path, min_js_filename))
1460
-
1461
1368
  core.lprint(GREEN.format('[6/6]'), LOC_DONE, " ", LOC_EXPORTING_TOTAL_MAIN_JS_FINISH, sep="", head="\r", ln=config.language)
1462
1369
 
1463
1370
  if mjs_path != build_main_mjs:
@@ -1515,7 +1422,7 @@ if __name__ == '__main__':
1515
1422
  # compiler.compile()
1516
1423
  # compiler.clean()
1517
1424
  test = """
1518
-
1425
+
1519
1426
  def patrolling(self, c: Creep):
1520
1427
  e = self.center.nearest(k.civilian.enemies, 5)
1521
1428
  if e:
@@ -1525,6 +1432,6 @@ def patrolling(self, c: Creep):
1525
1432
  ):
1526
1433
  case True: c.move(e, SWAMP_MOTION)
1527
1434
  case False: c.move(self.bpos, SWAMP_MOTION)
1528
-
1435
+
1529
1436
  """
1530
1437
  print(f"res=\n{Compiler.convert_match_to_if(test)}")
@@ -9,7 +9,7 @@
9
9
  #
10
10
  import re
11
11
 
12
- VERSION = "0.5.9.0"
12
+ VERSION = "0.5.9a0"
13
13
  AUTHOR = "●ω<🤍♪"
14
14
  STEAM_ID = "1029562896"
15
15
  GITHUB_NAME = "EagleBaby"
Binary file
@@ -4,13 +4,11 @@
4
4
  """
5
5
  import sys
6
6
  import os
7
- import json
8
7
  from pathlib import Path
9
8
  from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
10
9
  QHBoxLayout, QLabel, QLineEdit, QPushButton,
11
- QFileDialog, QMessageBox, QComboBox, QStackedWidget)
12
- from pyscreeps_arena.ui.qprefabs.qprefabs import QPrefabsManager
13
- from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty
10
+ QFileDialog, QMessageBox, QComboBox)
11
+ from PyQt6.QtCore import Qt
14
12
  from PyQt6.QtGui import QFont
15
13
  from PyQt6.QtGui import QIcon
16
14
  from pyscreeps_arena.core import const
@@ -18,307 +16,36 @@ from pyscreeps_arena.ui.rs_icon import get_pixmap
18
16
  from pyscreeps_arena.afters import ToConfigAfter, ToEmptyAfter, ToPrefabAfter, ToCustomAfter
19
17
  from PyQt6.QtWidgets import QRadioButton, QGroupBox
20
18
 
21
- # Language mapping
22
- LANG = {
23
- 'cn': {
24
- 'window_title': 'PyScreeps Arena - 项目创建器',
25
- 'title': 'PyScreeps Arena',
26
- 'version': '版本: {0}',
27
- 'author': '作者: {0}',
28
- 'github': 'GitHub: {0}',
29
- 'project_name': '项目名称:',
30
- 'name_placeholder': '输入项目名称...',
31
- 'save_location': '保存位置:',
32
- 'path_placeholder': '选择项目保存位置...',
33
- 'browse': '浏览...',
34
- 'language': '语 言:',
35
- 'arena': '竞技场:',
36
- 'difficulty': '难 度:',
37
- 'empty': '空白 (Empty)',
38
- 'basic': '基础 (Basic)',
39
- 'prefab': '预设 (Prefab)',
40
- 'pi': '预设继承 (P&&I)',
41
- 'create_project': '创建项目',
42
- 'cancel': '取消',
43
- 'path_exists': '路径已存在',
44
- 'path_exists_message': "路径 '{0}' 已存在。\n是否继续?",
45
- 'success': '成功',
46
- 'success_message': "项目 '{0}' 创建成功!\n路径: {1}",
47
- 'error': '错误',
48
- 'error_message': '项目创建失败:\n{0}',
49
- 'select_location': '选择项目保存位置',
50
- 'next_page': '下一页',
51
- 'previous_page': '上一页',
52
- },
53
- 'en': {
54
- 'window_title': 'PyScreeps Arena - Project Creator',
55
- 'title': 'PyScreeps Arena',
56
- 'version': 'Version: {0}',
57
- 'author': 'Author: {0}',
58
- 'github': 'GitHub: {0}',
59
- 'project_name': 'Project Name:',
60
- 'name_placeholder': 'Enter project name...',
61
- 'save_location': 'Save Location:',
62
- 'path_placeholder': 'Select project save location...',
63
- 'browse': 'Browse...',
64
- 'language': 'Language:',
65
- 'arena': 'Arena:',
66
- 'difficulty': 'Difficulty:',
67
- 'empty': 'Empty',
68
- 'basic': 'Basic',
69
- 'prefab': 'Prefab',
70
- 'pi': 'Prefab & Inherit',
71
- 'create_project': 'Create Project',
72
- 'cancel': 'Cancel',
73
- 'path_exists': 'Path Exists',
74
- 'path_exists_message': "Path '{0}' already exists.\nContinue anyway?",
75
- 'success': 'Success',
76
- 'success_message': "Project '{0}' created successfully!\nPath: {1}",
77
- 'error': 'Error',
78
- 'error_message': 'Failed to create project:\n{0}',
79
- 'select_location': 'Select Project Save Location',
80
- 'next_page': 'Next Page',
81
- 'previous_page': 'Previous',
82
- }
83
- }
84
19
 
85
20
 
86
-
87
- class QProjectBody(QWidget):
88
- """Project creation body widget"""
89
-
90
- # Signals
91
- projectCreated = pyqtSignal(str, str) # (project_name, project_path)
92
- projectCancelled = pyqtSignal()
93
- languageChanged = pyqtSignal(str) # (language_code)
94
-
95
- def __init__(self, parent=None):
96
- super().__init__(parent)
21
+ class ProjectCreatorUI(QMainWindow):
22
+ def __init__(self):
23
+ super().__init__()
97
24
  self._proj_name = ""
98
25
  self._proj_path = ""
99
26
  self._init_ui()
100
-
101
- def lang(self, key, *args):
102
- """Get translation for the current language"""
103
- # Get language code from combo box data
104
- lang = self._lang_combo.currentData() or 'cn'
105
-
106
- if lang not in LANG:
107
- lang = 'cn'
108
- return LANG[lang][key].format(*args)
109
-
110
- def _get_settings_path(self):
111
- """Get cross-platform settings file path"""
112
- # Get user's home directory
113
- home_dir = os.path.expanduser("~")
114
-
115
- # Create settings directory if it doesn't exist
116
- settings_dir = os.path.join(home_dir, ".psaui")
117
- os.makedirs(settings_dir, exist_ok=True)
118
-
119
- # Return settings file path
120
- return os.path.join(settings_dir, "psaui.json")
121
-
122
- def _save_settings(self):
123
- """Save settings to psaui.json"""
124
- settings = {
125
- "language": self._lang_combo.currentIndex(),
126
- "path": self._path_input.text()
127
- }
128
-
129
- try:
130
- settings_path = self._get_settings_path()
131
- with open(settings_path, 'w', encoding='utf-8') as f:
132
- json.dump(settings, f, indent=2, ensure_ascii=False)
133
- except Exception as e:
134
- print(f"Error saving settings: {e}")
135
-
136
- def _load_settings(self):
137
- """Load settings from psaui.json if it exists"""
138
- try:
139
- settings_path = self._get_settings_path()
140
- if os.path.exists(settings_path):
141
- with open(settings_path, 'r', encoding='utf-8') as f:
142
- settings = json.load(f)
143
-
144
- # Load language setting
145
- if "language" in settings:
146
- language_index = settings["language"]
147
- if 0 <= language_index < self._lang_combo.count():
148
- self._lang_combo.setCurrentIndex(language_index)
149
-
150
- # Load path setting
151
- if "path" in settings and settings["path"]:
152
- self._path_input.setText(settings["path"])
153
- self._proj_path = settings["path"]
154
- except Exception as e:
155
- print(f"Error loading settings: {e}")
156
-
157
- def _update_language_options(self):
158
- """Update language combo box options based on current language"""
159
- # Get current language
160
- lang_text = self._lang_combo.currentText()
161
- current_lang = lang_text.split('(')[1].strip(')') if '(' in lang_text else 'cn'
162
-
163
- # Save current index
164
- current_index = self._lang_combo.currentIndex()
165
-
166
- # Disconnect signal to avoid recursion
167
- self._lang_combo.currentTextChanged.disconnect(self._update_language)
168
-
169
- # Clear existing items
170
- self._lang_combo.clear()
171
-
172
- # Add items based on current language
173
- if current_lang == 'en':
174
- # In English mode, show only language codes
175
- self._lang_combo.addItems(["cn", "en"])
176
- else:
177
- # In Chinese mode, show full language names
178
- self._lang_combo.addItems(["中文 (cn)", "英文 (en)"])
179
-
180
- # Restore current index
181
- if current_index < self._lang_combo.count():
182
- self._lang_combo.setCurrentIndex(current_index)
183
-
184
- # Reconnect signal
185
- self._lang_combo.currentTextChanged.connect(self._update_language)
186
-
187
- def _update_language(self):
188
- """Update all UI elements to use the current language"""
189
- # Get current language code
190
- current_lang = self._lang_combo.currentData() or 'cn'
191
-
192
- # Update window title
193
- self.setWindowTitle(self.lang('window_title'))
194
-
195
- # Update title
196
- self._title_label.setText(self.lang('title'))
197
-
198
- # Update info labels
199
- self._version_label.setText(self.lang('version', const.VERSION))
200
- self._author_label.setText(self.lang('author', const.AUTHOR))
201
- self._github_label.setText(self.lang('github', const.GITHUB_NAME))
202
-
203
- # Update input labels and placeholders
204
- current_lang = self._lang_combo.currentData() or 'cn'
205
- if current_lang == 'en':
206
- self._name_label.setText('Name:')
207
- else:
208
- self._name_label.setText(self.lang('project_name'))
209
- self._name_input.setPlaceholderText(self.lang('name_placeholder'))
210
- self._path_label.setText(self.lang('save_location'))
211
- self._path_input.setPlaceholderText(self.lang('path_placeholder'))
212
-
213
- # Update buttons
214
- self._browse_btn.setText(self.lang('browse'))
215
- if hasattr(self, '_create_btn'):
216
- self._create_btn.setText(self.lang('create_project'))
217
- if hasattr(self, '_cancel_btn'):
218
- self._cancel_btn.setText(self.lang('cancel'))
219
-
220
- # Update config labels
221
- self._lang_label.setText(self.lang('language'))
222
- self._arena_label.setText(self.lang('arena'))
223
- self._level_label.setText(self.lang('difficulty'))
224
-
225
- # Update radio buttons
226
- self._empty_radio.setText(self.lang('empty'))
227
- self._basic_radio.setText(self.lang('basic'))
228
- self._prefab_radio.setText(self.lang('prefab'))
229
- self._pi_radio.setText(self.lang('pi'))
230
-
231
- # Update language combo box items based on current language
232
- if current_lang == 'en':
233
- # In English mode, show only language codes
234
- self._lang_combo.blockSignals(True)
235
- current_index = self._lang_combo.currentIndex()
236
- self._lang_combo.clear()
237
- self._lang_combo.addItem("cn", "cn")
238
- self._lang_combo.addItem("en", "en")
239
- self._lang_combo.setCurrentIndex(current_index)
240
- self._lang_combo.blockSignals(False)
241
-
242
- # Update arena combo box items
243
- self._arena_combo.blockSignals(True)
244
- current_arena_index = self._arena_combo.currentIndex()
245
- self._arena_combo.clear()
246
- self._arena_combo.addItem("gray", "gray")
247
- self._arena_combo.addItem("green", "green")
248
- self._arena_combo.addItem("blue", "blue")
249
- self._arena_combo.addItem("red", "red")
250
- self._arena_combo.setCurrentIndex(current_arena_index)
251
- self._arena_combo.blockSignals(False)
252
-
253
- # Update level combo box items
254
- self._level_combo.blockSignals(True)
255
- current_level_index = self._level_combo.currentIndex()
256
- self._level_combo.clear()
257
- self._level_combo.addItem("basic", "basic")
258
- self._level_combo.addItem("advanced", "advanced")
259
- self._level_combo.setCurrentIndex(current_level_index)
260
- self._level_combo.blockSignals(False)
261
- else:
262
- # In Chinese mode, show full language names
263
- self._lang_combo.blockSignals(True)
264
- current_index = self._lang_combo.currentIndex()
265
- self._lang_combo.clear()
266
- self._lang_combo.addItem("中文 (cn)", "cn")
267
- self._lang_combo.addItem("英文 (en)", "en")
268
- self._lang_combo.setCurrentIndex(current_index)
269
- self._lang_combo.blockSignals(False)
270
-
271
- # Update arena combo box items
272
- self._arena_combo.blockSignals(True)
273
- current_arena_index = self._arena_combo.currentIndex()
274
- self._arena_combo.clear()
275
- self._arena_combo.addItem("灰色 (gray)", "gray")
276
- self._arena_combo.addItem("绿色 (green)", "green")
277
- self._arena_combo.addItem("蓝色 (blue)", "blue")
278
- self._arena_combo.addItem("红色 (red)", "red")
279
- self._arena_combo.setCurrentIndex(current_arena_index)
280
- self._arena_combo.blockSignals(False)
281
-
282
- # Update level combo box items
283
- self._level_combo.blockSignals(True)
284
- current_level_index = self._level_combo.currentIndex()
285
- self._level_combo.clear()
286
- self._level_combo.addItem("基础 (basic)", "basic")
287
- self._level_combo.addItem("高级 (advanced)", "advanced")
288
- self._level_combo.setCurrentIndex(current_level_index)
289
- self._level_combo.blockSignals(False)
290
-
291
- # Save settings after language change
292
- self._save_settings()
293
27
 
294
28
  def _init_ui(self):
295
29
  """初始化UI界面"""
30
+ self.setWindowTitle("PyScreeps Arena - 项目创建器")
31
+ self.setWindowIcon(QIcon(get_pixmap()))
296
32
  self.setFixedSize(500, 580)
297
33
 
298
- # 主布局
299
- layout = QVBoxLayout(self)
34
+ # 主窗口部件
35
+ central_widget = QWidget()
36
+ self.setCentralWidget(central_widget)
37
+ layout = QVBoxLayout(central_widget)
300
38
  layout.setSpacing(15)
301
- # 减小左右边距,保持上下边距
302
- layout.setContentsMargins(15, 15, 15, 30)
303
-
304
- # 创建项目创建页面
305
- self._project_page = QWidget()
306
- self._project_layout = QVBoxLayout(self._project_page)
307
- self._project_layout.setSpacing(15)
308
- self._project_layout.setContentsMargins(0, 0, 0, 0)
309
-
310
- # 创建堆叠容器
311
- self._stacked_widget = QStackedWidget()
312
- layout.addWidget(self._stacked_widget)
39
+ layout.setContentsMargins(30, 30, 30, 30)
313
40
 
314
41
  # 标题
315
- self._title_label = QLabel("PyScreeps Arena")
316
- self._title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
42
+ title = QLabel("PyScreeps Arena")
43
+ title.setAlignment(Qt.AlignmentFlag.AlignCenter)
317
44
  title_font = QFont()
318
45
  title_font.setPointSize(18)
319
46
  title_font.setBold(True)
320
- self._title_label.setFont(title_font)
321
- self._project_layout.addWidget(self._title_label)
47
+ title.setFont(title_font)
48
+ layout.addWidget(title)
322
49
 
323
50
  # 项目信息
324
51
  info_widget = QWidget()
@@ -326,27 +53,27 @@ class QProjectBody(QWidget):
326
53
  info_layout.setSpacing(8)
327
54
 
328
55
  # 版本信息
329
- self._version_label = QLabel(f"版本: {const.VERSION}")
330
- self._version_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
331
- info_layout.addWidget(self._version_label)
56
+ version_label = QLabel(f"版本: {const.VERSION}")
57
+ version_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
58
+ info_layout.addWidget(version_label)
332
59
 
333
60
  # 作者信息
334
- self._author_label = QLabel(f"作者: {const.AUTHOR}")
335
- self._author_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
336
- info_layout.addWidget(self._author_label)
61
+ author_label = QLabel(f"作者: {const.AUTHOR}")
62
+ author_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
63
+ info_layout.addWidget(author_label)
337
64
 
338
65
  # GitHub信息
339
- self._github_label = QLabel(f"GitHub: {const.GITHUB_NAME}")
340
- self._github_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
341
- info_layout.addWidget(self._github_label)
66
+ github_label = QLabel(f"GitHub: {const.GITHUB_NAME}")
67
+ github_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
68
+ info_layout.addWidget(github_label)
342
69
 
343
- self._project_layout.addWidget(info_widget)
70
+ layout.addWidget(info_widget)
344
71
 
345
72
  # 分隔线
346
73
  separator = QLabel("─" * 50)
347
74
  separator.setAlignment(Qt.AlignmentFlag.AlignCenter)
348
75
  separator.setStyleSheet("color: #ccc;")
349
- self._project_layout.addWidget(separator)
76
+ layout.addWidget(separator)
350
77
 
351
78
  # 项目输入区域
352
79
  input_widget = QWidget()
@@ -355,20 +82,20 @@ class QProjectBody(QWidget):
355
82
 
356
83
  # 项目名称输入
357
84
  name_layout = QHBoxLayout()
358
- self._name_label = QLabel("项目名称:")
359
- self._name_label.setFixedWidth(80)
85
+ name_label = QLabel("项目名称:")
86
+ name_label.setFixedWidth(80)
360
87
  self._name_input = QLineEdit()
361
88
  self._name_input.setPlaceholderText("输入项目名称...")
362
89
  self._name_input.textChanged.connect(self._on_name_changed)
363
90
  self._name_input.returnPressed.connect(self._create_project)
364
- name_layout.addWidget(self._name_label)
91
+ name_layout.addWidget(name_label)
365
92
  name_layout.addWidget(self._name_input)
366
93
  input_layout.addLayout(name_layout)
367
94
 
368
95
  # 项目路径输入
369
96
  path_layout = QHBoxLayout()
370
- self._path_label = QLabel("保存位置:")
371
- self._path_label.setFixedWidth(80)
97
+ path_label = QLabel("保存位置:")
98
+ path_label.setFixedWidth(80)
372
99
  self._path_input = QLineEdit()
373
100
  self._path_input.setPlaceholderText("选择项目保存位置...")
374
101
  self._path_input.setReadOnly(True)
@@ -377,23 +104,23 @@ class QProjectBody(QWidget):
377
104
  if os.path.exists(desktop_path):
378
105
  self._path_input.setText(desktop_path)
379
106
  self._proj_path = desktop_path
380
- path_layout.addWidget(self._path_label)
107
+ path_layout.addWidget(path_label)
381
108
  path_layout.addWidget(self._path_input)
382
109
 
383
110
  # 浏览按钮
384
- self._browse_btn = QPushButton("浏览...")
385
- self._browse_btn.setFixedWidth(80)
386
- self._browse_btn.clicked.connect(self._browse_path)
387
- path_layout.addWidget(self._browse_btn)
111
+ browse_btn = QPushButton("浏览...")
112
+ browse_btn.setFixedWidth(60)
113
+ browse_btn.clicked.connect(self._browse_path)
114
+ path_layout.addWidget(browse_btn)
388
115
 
389
116
  input_layout.addLayout(path_layout)
390
- self._project_layout.addWidget(input_widget)
117
+ layout.addWidget(input_widget)
391
118
 
392
119
  # 分隔线
393
120
  separator2 = QLabel("─" * 50)
394
121
  separator2.setAlignment(Qt.AlignmentFlag.AlignCenter)
395
122
  separator2.setStyleSheet("color: #ccc;")
396
- self._project_layout.addWidget(separator2)
123
+ layout.addWidget(separator2)
397
124
 
398
125
  # 配置选项区域(左右布局)
399
126
  config_container = QWidget()
@@ -407,43 +134,34 @@ class QProjectBody(QWidget):
407
134
 
408
135
  # 语言选择
409
136
  lang_layout = QHBoxLayout()
410
- self._lang_label = QLabel("语 言:")
411
- self._lang_label.setFixedWidth(80)
137
+ lang_label = QLabel("语 言:")
138
+ lang_label.setFixedWidth(80)
412
139
  self._lang_combo = QComboBox()
413
- # 语言选项
414
- self._lang_combo.addItem("中文 (cn)", "cn")
415
- self._lang_combo.addItem("英文 (en)", "en")
140
+ self._lang_combo.addItems(["中文 (cn)", "英文 (en)"])
416
141
  self._lang_combo.setCurrentIndex(0)
417
- self._lang_combo.currentIndexChanged.connect(self._update_language)
418
- lang_layout.addWidget(self._lang_label)
142
+ lang_layout.addWidget(lang_label)
419
143
  lang_layout.addWidget(self._lang_combo)
420
144
  left_config_layout.addLayout(lang_layout)
421
145
 
422
146
  # 竞技场选择
423
147
  arena_layout = QHBoxLayout()
424
- self._arena_label = QLabel("竞技场:")
425
- self._arena_label.setFixedWidth(80)
148
+ arena_label = QLabel("竞技场:")
149
+ arena_label.setFixedWidth(80)
426
150
  self._arena_combo = QComboBox()
427
- # 竞技场选项
428
- self._arena_combo.addItem("灰色 (gray)", "gray")
429
- self._arena_combo.addItem("绿色 (green)", "green")
430
- self._arena_combo.addItem("蓝色 (blue)", "blue")
431
- self._arena_combo.addItem("红色 (red)", "red")
151
+ self._arena_combo.addItems(["灰色 (gray)", "绿色 (green)", "蓝色 (blue)", "红色 (red)"])
432
152
  self._arena_combo.setCurrentIndex(0)
433
- arena_layout.addWidget(self._arena_label)
153
+ arena_layout.addWidget(arena_label)
434
154
  arena_layout.addWidget(self._arena_combo)
435
155
  left_config_layout.addLayout(arena_layout)
436
156
 
437
157
  # 难度级别选择
438
158
  level_layout = QHBoxLayout()
439
- self._level_label = QLabel("难 度:")
440
- self._level_label.setFixedWidth(80)
159
+ level_label = QLabel("难 度:")
160
+ level_label.setFixedWidth(80)
441
161
  self._level_combo = QComboBox()
442
- # 难度选项
443
- self._level_combo.addItem("基础 (basic)", "basic")
444
- self._level_combo.addItem("高级 (advanced)", "advanced")
162
+ self._level_combo.addItems(["基础 (basic)", "高级 (advanced)"])
445
163
  self._level_combo.setCurrentIndex(0)
446
- level_layout.addWidget(self._level_label)
164
+ level_layout.addWidget(level_label)
447
165
  level_layout.addWidget(self._level_combo)
448
166
  left_config_layout.addLayout(level_layout)
449
167
 
@@ -476,22 +194,7 @@ class QProjectBody(QWidget):
476
194
 
477
195
  config_container_layout.addWidget(right_config_widget)
478
196
 
479
- self._project_layout.addWidget(config_container)
480
-
481
- self._project_layout.addStretch()
482
-
483
- # 加载设置
484
- self._load_settings()
485
-
486
- # 创建预制件管理器页面
487
- self._prefabs_page = QPrefabsManager()
488
-
489
- # 添加页面到堆叠容器
490
- self._stacked_widget.addWidget(self._project_page)
491
- self._stacked_widget.addWidget(self._prefabs_page)
492
-
493
- # 连接堆叠容器的页面变化信号
494
- self._stacked_widget.currentChanged.connect(self._on_page_changed)
197
+ layout.addWidget(config_container)
495
198
 
496
199
  # 按钮区域
497
200
  button_layout = QHBoxLayout()
@@ -499,95 +202,36 @@ class QProjectBody(QWidget):
499
202
 
500
203
  # 创建按钮
501
204
  self._create_btn = QPushButton("创建项目")
502
- self._create_btn.setFixedSize(120, 35)
503
- self._create_btn.clicked.connect(self._on_next_or_create)
205
+ self._create_btn.setFixedSize(100, 35)
206
+ self._create_btn.clicked.connect(self._create_project)
504
207
  self._create_btn.setEnabled(False)
505
208
  self._create_btn.setDefault(True)
506
209
  button_layout.addWidget(self._create_btn)
507
210
 
508
211
  # 取消按钮
509
- self._cancel_btn = QPushButton("取消")
510
- self._cancel_btn.setFixedSize(80, 35)
511
- self._cancel_btn.clicked.connect(self._on_previous_or_cancel)
512
- button_layout.addWidget(self._cancel_btn)
212
+ cancel_btn = QPushButton("取消")
213
+ cancel_btn.setFixedSize(80, 35)
214
+ cancel_btn.clicked.connect(self.close)
215
+ button_layout.addWidget(cancel_btn)
513
216
 
514
- # 添加按钮区域到主布局
515
217
  layout.addLayout(button_layout)
516
-
517
- # 初始更新语言
518
- # 延迟调用,确保所有UI元素都已创建
519
- self._update_language()
520
-
521
- # 初始更新按钮文本
522
- self._update_button_texts()
218
+ layout.addStretch()
523
219
 
524
220
  def _on_name_changed(self, text):
525
221
  """项目名称改变时的处理"""
526
222
  self._proj_name = text.strip()
527
223
  self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
528
-
529
- def _on_cancel(self):
530
- """Handle cancel button click"""
531
- self.projectCancelled.emit()
532
- # Exit the application when cancel is clicked
533
- QApplication.quit()
534
-
535
- def _on_next_or_create(self):
536
- """Handle next or create button click"""
537
- current_index = self._stacked_widget.currentIndex()
538
- max_index = self._stacked_widget.count() - 1
539
-
540
- if current_index < max_index:
541
- # Go to next page
542
- self._stacked_widget.setCurrentIndex(current_index + 1)
543
- else:
544
- # Create project
545
- self._create_project()
546
-
547
- def _on_previous_or_cancel(self):
548
- """Handle previous or cancel button click"""
549
- current_index = self._stacked_widget.currentIndex()
550
-
551
- if current_index > 0:
552
- # Go to previous page
553
- self._stacked_widget.setCurrentIndex(current_index - 1)
554
- else:
555
- # Cancel
556
- self._on_cancel()
557
-
558
- def _on_page_changed(self, index):
559
- """Handle page changed signal"""
560
- self._update_button_texts()
561
-
562
- def _update_button_texts(self):
563
- """Update button texts based on current page index"""
564
- current_index = self._stacked_widget.currentIndex()
565
- max_index = self._stacked_widget.count() - 1
566
-
567
- # Update create/next button
568
- if current_index < max_index:
569
- self._create_btn.setText(self.lang('next_page'))
570
- else:
571
- self._create_btn.setText(self.lang('create_project'))
572
-
573
- # Update cancel/previous button
574
- if current_index == 0:
575
- self._cancel_btn.setText(self.lang('cancel'))
576
- else:
577
- self._cancel_btn.setText(self.lang('previous_page'))
578
224
 
579
225
  def _browse_path(self):
580
226
  """浏览选择路径"""
581
227
  current_path = self._path_input.text() or os.path.expanduser("~")
582
228
  path = QFileDialog.getExistingDirectory(
583
- self, self.lang('select_location'), current_path
229
+ self, "选择项目保存位置", current_path
584
230
  )
585
231
  if path:
586
232
  self._path_input.setText(path)
587
233
  self._proj_path = path
588
234
  self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
589
- # Save settings after path change
590
- self._save_settings()
591
235
 
592
236
  def _create_project(self):
593
237
  """创建项目"""
@@ -600,8 +244,8 @@ class QProjectBody(QWidget):
600
244
  # 检查路径是否已存在
601
245
  if os.path.exists(full_path):
602
246
  reply = QMessageBox.question(
603
- self, self.lang('path_exists'),
604
- self.lang('path_exists_message', full_path),
247
+ self, "路径已存在",
248
+ f"路径 '{full_path}' 已存在。\n是否继续?",
605
249
  QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
606
250
  )
607
251
  if reply != QMessageBox.StandardButton.Yes:
@@ -612,22 +256,15 @@ class QProjectBody(QWidget):
612
256
  self._extract_project_template(full_path)
613
257
 
614
258
  QMessageBox.information(
615
- self, self.lang('success'),
616
- self.lang('success_message', self._proj_name, full_path)
259
+ self, "成功",
260
+ f"项目 '{self._proj_name}' 创建成功!\n路径: {full_path}"
617
261
  )
618
-
619
- # 处理预制件
620
- self._process_prefabs(full_path)
621
-
622
- self.projectCreated.emit(self._proj_name, full_path)
623
-
624
- # 成功创建项目后关闭程序
625
- QApplication.quit()
262
+ self.close()
626
263
 
627
264
  except Exception as e:
628
265
  QMessageBox.critical(
629
- self, self.lang('error'),
630
- self.lang('error_message', str(e))
266
+ self, "错误",
267
+ f"项目创建失败:\n{str(e)}"
631
268
  )
632
269
 
633
270
  def _extract_project_template(self, target_path):
@@ -650,9 +287,14 @@ class QProjectBody(QWidget):
650
287
  print(f"[DEBUG] 项目模板已解压到: {target_path}") # 调试输出
651
288
 
652
289
  # 获取用户选择的配置
653
- lang = self._lang_combo.currentData() or 'cn'
654
- arena = self._arena_combo.currentData() or 'gray'
655
- level = self._level_combo.currentData() or 'basic'
290
+ lang_text = self._lang_combo.currentText()
291
+ lang = lang_text.split('(')[1].strip(')')
292
+
293
+ arena_text = self._arena_combo.currentText()
294
+ arena = arena_text.split('(')[1].strip(')')
295
+
296
+ level_text = self._level_combo.currentText()
297
+ level = level_text.split('(')[1].strip(')')
656
298
 
657
299
  # 调用配置方法
658
300
  ToConfigAfter(path=target_path, language=lang, arena=arena, level=level)
@@ -672,268 +314,6 @@ class QProjectBody(QWidget):
672
314
  print(f"[DEBUG] 执行预设继承模式配置")
673
315
  ToPrefabAfter(path=target_path)
674
316
  ToCustomAfter(path=target_path)
675
-
676
- # Properties
677
- @pyqtProperty(str, constant=False)
678
- def projectName(self) -> str:
679
- """Get project name"""
680
- return self._proj_name
681
-
682
- @projectName.setter
683
- def projectName(self, value: str):
684
- """Set project name"""
685
- self._proj_name = value.strip()
686
- self._name_input.setText(self._proj_name)
687
- self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
688
-
689
- @pyqtProperty(str, constant=False)
690
- def projectPath(self) -> str:
691
- """Get project path"""
692
- return self._proj_path
693
-
694
- @projectPath.setter
695
- def projectPath(self, value: str):
696
- """Set project path"""
697
- self._proj_path = value
698
- self._path_input.setText(self._proj_path)
699
- self._create_btn.setEnabled(bool(self._proj_name and self._proj_path))
700
-
701
- @pyqtProperty(str, constant=False)
702
- def language(self) -> str:
703
- """Get current language code"""
704
- return self._lang_combo.currentData() or 'cn'
705
-
706
- @language.setter
707
- def language(self, value: str):
708
- """Set language code"""
709
- if value == 'cn':
710
- self._lang_combo.setCurrentIndex(0)
711
- elif value == 'en':
712
- self._lang_combo.setCurrentIndex(1)
713
-
714
- def _process_prefabs(self, project_path: str):
715
- """
716
- Process selected prefabs: copy them to src directory, handle naming conflicts,
717
- and add import statements to main.py
718
-
719
- Args:
720
- project_path: Path to the newly created project
721
- """
722
- print(f"Processing prefabs for project: {project_path}")
723
-
724
- # Check if QPrefabsManager exists and has selected prefabs
725
- if hasattr(self, '_prefabs_page'):
726
- # Get selected prefabs as list
727
- selected_prefabs = self._prefabs_page.selectedPrefabs
728
- print(f"Selected prefabs: {selected_prefabs}")
729
-
730
- if selected_prefabs:
731
- # Convert to dict format using list_to_dict method
732
- prefabs_dict = self._prefabs_page.list_to_dict(selected_prefabs)
733
- print(f"Prefabs dict: {prefabs_dict}")
734
-
735
- # Create src directory if it doesn't exist
736
- src_dir = os.path.join(project_path, 'src')
737
- os.makedirs(src_dir, exist_ok=True)
738
- print(f"Src directory: {src_dir}")
739
-
740
- # Get existing directory names in src
741
- existing_dirs = [d for d in os.listdir(src_dir) if os.path.isdir(os.path.join(src_dir, d))]
742
- print(f"Existing dirs in src: {existing_dirs}")
743
-
744
- # Process each prefab
745
- imported_modules = []
746
-
747
- for name, path in prefabs_dict.items():
748
- # Clean directory name: replace non-alphanumeric and non-underscore characters with underscore
749
- clean_name = ''.join(c if c.isalnum() or c == '_' else '_' for c in name)
750
-
751
- # Handle naming conflicts
752
- final_name = clean_name
753
- i = 2
754
- while final_name in existing_dirs:
755
- final_name = f"{clean_name}_{i}"
756
- i += 1
757
-
758
- # Add to existing_dirs to avoid conflicts with subsequent prefabs
759
- existing_dirs.append(final_name)
760
-
761
- # Target directory path
762
- target_dir = os.path.join(src_dir, final_name)
763
-
764
- # Copy directory from path to target_dir
765
- import shutil
766
- try:
767
- shutil.copytree(path, target_dir)
768
- imported_modules.append(final_name)
769
- print(f"Copied prefab {name} to {target_dir}")
770
- except Exception as e:
771
- print(f"Error copying prefab {name}: {e}")
772
-
773
- # Add import statements to main.py
774
- if imported_modules:
775
- main_py_path = os.path.join(project_path, 'src', 'main.py')
776
- print(f"Main.py path: {main_py_path}")
777
- if os.path.exists(main_py_path):
778
- # Read main.py content
779
- with open(main_py_path, 'r', encoding='utf-8') as f:
780
- content = f.read()
781
- print(f"Main.py content:\n{content}")
782
-
783
- # Find the end of import statements
784
- import_end = 0
785
- lines = content.split('\n')
786
- # Iterate through all lines to find the last import statement
787
- for i, line in enumerate(lines):
788
- if line.strip().startswith('from ') or line.strip().startswith('import '):
789
- import_end = i + 1
790
- elif import_end > 0 and line.strip() == '':
791
- # Keep moving past empty lines after imports
792
- import_end = i + 1
793
- elif import_end > 0 and line.strip() != '':
794
- # Stop when we reach non-empty, non-import line
795
- break
796
- # If no imports found, add at the beginning
797
- print(f"Import end position: {import_end}")
798
-
799
- # Add import statements
800
- import_lines = []
801
- for module in imported_modules:
802
- import_lines.append(f"from {module} import *")
803
- print(f"Import lines to add: {import_lines}")
804
-
805
- # Process the content to properly format imports
806
- # First, separate the content into import section and code section
807
- import_section = []
808
- code_section = []
809
- in_imports = True
810
-
811
- for line in lines:
812
- if in_imports:
813
- if line.strip().startswith('from ') or line.strip().startswith('import '):
814
- import_section.append(line.strip())
815
- elif line.strip() == '':
816
- # Skip empty lines in import section
817
- pass
818
- else:
819
- # Reached end of imports
820
- in_imports = False
821
- code_section.append(line)
822
- else:
823
- # Add all other lines to code section
824
- code_section.append(line)
825
-
826
- # Add new imports to import section
827
- import_section.extend(import_lines)
828
-
829
- # Create properly formatted content
830
- # Join imports without empty lines between them
831
- import_text = '\n'.join(import_section)
832
- # Join code section as is
833
- code_text = '\n'.join(code_section)
834
- # Combine with exactly two empty lines between imports and code
835
- new_content = import_text + '\n\n\n' + code_text
836
- print(f"New main.py content:\n{new_content}")
837
-
838
- # Write back to main.py
839
- with open(main_py_path, 'w', encoding='utf-8') as f:
840
- f.write(new_content)
841
-
842
- print(f"Added import statements for {len(imported_modules)} modules to main.py")
843
-
844
- # Verify the changes
845
- with open(main_py_path, 'r', encoding='utf-8') as f:
846
- verify_content = f.read()
847
- print(f"Verified main.py content:\n{verify_content}")
848
- else:
849
- print(f"Main.py not found at {main_py_path}")
850
- else:
851
- print("No modules to import")
852
- else:
853
- print("No selected prefabs")
854
- else:
855
- print("No QPrefabsManager found")
856
-
857
-
858
- class ProjectCreatorUI(QMainWindow):
859
- """Project creator main window"""
860
-
861
- def __init__(self):
862
- super().__init__()
863
- self._init_ui()
864
-
865
- def _init_ui(self):
866
- """Initialize main window"""
867
- self.setWindowTitle("PyScreeps Arena - Project Wizard")
868
- self.setWindowIcon(QIcon(get_pixmap()))
869
-
870
- # Create central widget
871
- central_widget = QWidget()
872
- self.setCentralWidget(central_widget)
873
-
874
- # Create main layout
875
- layout = QVBoxLayout(central_widget)
876
- layout.setContentsMargins(10, 10, 10, 10)
877
-
878
- # Create project body widget
879
- self._project_body = QProjectBody()
880
-
881
- # Connect signals
882
- self._project_body.projectCreated.connect(self._on_project_created)
883
- self._project_body.projectCancelled.connect(self._on_project_cancelled)
884
- self._project_body.languageChanged.connect(self._on_language_changed)
885
-
886
- # Add project body to layout
887
- layout.addWidget(self._project_body)
888
-
889
- # Set window size
890
- self.setFixedSize(550, 650)
891
-
892
- def _on_project_created(self, project_name: str, project_path: str):
893
- """Handle project created signal"""
894
- print(f"Project created: {project_name} at {project_path}")
895
- # You can add additional handling here if needed
896
-
897
- def _on_project_cancelled(self):
898
- """Handle project cancelled signal"""
899
- print("Project creation cancelled")
900
- # You can add additional handling here if needed
901
-
902
- def _on_language_changed(self, language_code: str):
903
- """Handle language changed signal"""
904
- print(f"Language changed to: {language_code}")
905
- # You can add additional handling here if needed
906
-
907
- # Properties to expose project body properties
908
- @pyqtProperty(str, constant=False)
909
- def projectName(self) -> str:
910
- """Get project name"""
911
- return self._project_body.projectName
912
-
913
- @projectName.setter
914
- def projectName(self, value: str):
915
- """Set project name"""
916
- self._project_body.projectName = value
917
-
918
- @pyqtProperty(str, constant=False)
919
- def projectPath(self) -> str:
920
- """Get project path"""
921
- return self._project_body.projectPath
922
-
923
- @projectPath.setter
924
- def projectPath(self, value: str):
925
- """Set project path"""
926
- self._project_body.projectPath = value
927
-
928
- @pyqtProperty(str, constant=False)
929
- def language(self) -> str:
930
- """Get current language code"""
931
- return self._project_body.language
932
-
933
- @language.setter
934
- def language(self, value: str):
935
- """Set language code"""
936
- self._project_body.language = value
937
317
 
938
318
 
939
319
  def run_project_creator():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscreeps-arena
3
- Version: 0.5.9.0
3
+ Version: 0.5.9a0
4
4
  Summary: Python api|interface to play game: Screeps: Arena.
5
5
  Author-email: 2229066748@qq.com
6
6
  Maintainer: Eagle'sBaby
@@ -1,8 +1,8 @@
1
1
  pyscreeps_arena/__init__.py,sha256=GWrCpZnrzPwbBzhNqk8gTvV4VSwkP2DbxK8lR0E_SzY,3223
2
2
  pyscreeps_arena/build.py,sha256=DQeGLnID2FjpsWTbnqwt2cOp28olWK68U67bfbFJSOU,177
3
- pyscreeps_arena/compiler.py,sha256=sddY_09Nvq0Ts86lmjLlsKOT0b-EWnhsKK04oIRvnDc,70671
3
+ pyscreeps_arena/compiler.py,sha256=RdJNwEvWOzS36UhwM6wxK2_bV2JtMBaNg6dLotVKj2k,66843
4
4
  pyscreeps_arena/localization.py,sha256=Dr0G6n8DvT6syfC0urqwjccYpEPEfcwYyJx3f9s-6a8,6031
5
- pyscreeps_arena/project.7z,sha256=PSWXjm7FpLRWzlx_dMUaVXRtJ8gFFXQkaQKUO6RueFw,580860
5
+ pyscreeps_arena/project.7z,sha256=yl-JXQwkItO8EkDrITPLSBU3krG4Hz6-z6PjDPl2Xpk,581577
6
6
  pyscreeps_arena/afters/__init__.py,sha256=Ze8NKQoMEzIJ3WlyR8Jhhdq21gSXJUtGoINzB8iaQyE,254
7
7
  pyscreeps_arena/afters/after_config.py,sha256=Tw8Qry0KAM3hDasmXArKoS1crPuwfiAfWiEeAcKrPdo,2455
8
8
  pyscreeps_arena/afters/after_custom.py,sha256=pgI5xkY4X7w_NHFufQ5PUGxpCrv9Ayw6VWFwVJCHLFw,3226
@@ -11,7 +11,7 @@ pyscreeps_arena/afters/after_prefab.py,sha256=H_2LJbr_7e2yCtxWStxze259-py3TXQlyP
11
11
  pyscreeps_arena/core/__init__.py,sha256=qoP_rx1TpbDLJoTm5via4XPwEPaV1FXr1SYvoVoHGms,41
12
12
  pyscreeps_arena/core/basic.py,sha256=DFvyDTsTXf2bQtnS9s254TrkshvRwajaHcvTyVvJyqw,2790
13
13
  pyscreeps_arena/core/config.py,sha256=x_JhVHlVZqB3qA7UyACVnwZjg2gZU-BIs49UxZzwCoE,637
14
- pyscreeps_arena/core/const.py,sha256=XyypqtmbRI4bXv4NviZ-G-9UegCpPUgjPKKAWbgWGmA,590
14
+ pyscreeps_arena/core/const.py,sha256=VP43eR7T0YugXN9wm5WQQF7yME6Q2yA50x9gnEUcp9U,590
15
15
  pyscreeps_arena/core/core.py,sha256=3Nty8eLKPNgwnYk_sVNBPrWuKxBXI2od8nfEezsEAZQ,5157
16
16
  pyscreeps_arena/core/main.py,sha256=-FNSOEjksNlDfCbUqsjtPSUW8vT3qxEdfzXqT5Tdsik,170
17
17
  pyscreeps_arena/core/utils.py,sha256=N9OOkORvrqnJakayaFp9qyS0apWhB9lBK4xyyYkhFdo,215
@@ -20,7 +20,7 @@ pyscreeps_arena/ui/__init__.py,sha256=rxSx5ZPxMNUVokvYgOmGkxHInFUVVYh9InSbbvkgo2
20
20
  pyscreeps_arena/ui/creeplogic_edit.py,sha256=XlO4aoH48UyWhQQAejyLY57yukpn9BzS0w9QXMMOeeg,314
21
21
  pyscreeps_arena/ui/map_render.py,sha256=dS7iL5ywEwlhGEOiif0G9up3bpPI4p20o07mbnDaSD8,30414
22
22
  pyscreeps_arena/ui/mapviewer.py,sha256=AWv9loznosIJaQC5L5szRms_zDetDiHXIsY2EEpRNB8,293
23
- pyscreeps_arena/ui/project_ui.py,sha256=eQMngywySlFbSHOMbi0mrsanGzI2lNZiWg_92_fChxQ,39188
23
+ pyscreeps_arena/ui/project_ui.py,sha256=6LTwRHqfyb1R2ry13Xtq41vCANEJL96-hqXposNr81M,12580
24
24
  pyscreeps_arena/ui/rs_icon.py,sha256=5v8YdTv2dds4iAp9x3MXpqB_5XIOYd0uPqaq83ZNySM,22496
25
25
  pyscreeps_arena/ui/qcreeplogic/__init__.py,sha256=FVuJ6TZyDh5WnkYlHjCWjEKGPBWl27LzqIAab-4aeuI,75
26
26
  pyscreeps_arena/ui/qcreeplogic/model.py,sha256=_Ba5jbHcFsKQ1el36UcCnXGUimvvWSRHgzo979SpVzs,2833
@@ -45,8 +45,8 @@ pyscreeps_arena/ui/qmapv/test_simple_array.py,sha256=hPnLXcFrn6I1X4JXFM3RVpBPhU_
45
45
  pyscreeps_arena/ui/qrecipe/__init__.py,sha256=2Guvr9k5kGkZboiVC0aNF4u48LRbmcCm2dqOhEF52Tw,59
46
46
  pyscreeps_arena/ui/qrecipe/model.py,sha256=s3lr_DXtsBgt8bVg1_wLz-dX88QKi77mNkqM5VJsGwE,13200
47
47
  pyscreeps_arena/ui/qrecipe/qrecipe.py,sha256=z57VLmlpMripdpGtVCkKR0csJQhw5-WpocZK5l2xTVg,39398
48
- pyscreeps_arena-0.5.9.0.dist-info/METADATA,sha256=YVlVorfH88HdKb0Hl1BxtqpUD66dYBk1LXRtbL6lW0Y,2356
49
- pyscreeps_arena-0.5.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
50
- pyscreeps_arena-0.5.9.0.dist-info/entry_points.txt,sha256=pnpuPPadwQsxQPaR1rXzUo0fUvhOcC7HTHlf7TYXr7M,141
51
- pyscreeps_arena-0.5.9.0.dist-info/top_level.txt,sha256=l4uLyMR2NOy41ngBMh795jOHTFk3tgYKy64-9cgjVng,16
52
- pyscreeps_arena-0.5.9.0.dist-info/RECORD,,
48
+ pyscreeps_arena-0.5.9a0.dist-info/METADATA,sha256=WO8MT9aDrX2NK1eOY2UyHPflms4IeaY0ZtUur_yhUPQ,2356
49
+ pyscreeps_arena-0.5.9a0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
50
+ pyscreeps_arena-0.5.9a0.dist-info/entry_points.txt,sha256=pnpuPPadwQsxQPaR1rXzUo0fUvhOcC7HTHlf7TYXr7M,141
51
+ pyscreeps_arena-0.5.9a0.dist-info/top_level.txt,sha256=l4uLyMR2NOy41ngBMh795jOHTFk3tgYKy64-9cgjVng,16
52
+ pyscreeps_arena-0.5.9a0.dist-info/RECORD,,