pyscreeps-arena 0.3.5__py3-none-any.whl → 0.4.0__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.
- pyscreeps_arena/__init__.py +2 -1
- pyscreeps_arena/compiler.py +221 -27
- pyscreeps_arena/core/config.py +1 -1
- pyscreeps_arena/core/const.py +3 -2
- pyscreeps_arena/project.7z +0 -0
- {pyscreeps_arena-0.3.5.dist-info → pyscreeps_arena-0.4.0.dist-info}/METADATA +1 -1
- pyscreeps_arena-0.4.0.dist-info/RECORD +17 -0
- {pyscreeps_arena-0.3.5.dist-info → pyscreeps_arena-0.4.0.dist-info}/WHEEL +1 -1
- {pyscreeps_arena-0.3.5.dist-info → pyscreeps_arena-0.4.0.dist-info}/entry_points.txt +1 -0
- pyscreeps_arena-0.3.5.dist-info/RECORD +0 -17
- {pyscreeps_arena-0.3.5.dist-info → pyscreeps_arena-0.4.0.dist-info}/top_level.txt +0 -0
pyscreeps_arena/__init__.py
CHANGED
|
@@ -7,6 +7,7 @@ def CMD_NewProject():
|
|
|
7
7
|
"""
|
|
8
8
|
cmd:
|
|
9
9
|
pyscreeps-arena [project_path]
|
|
10
|
+
arena [project_path]
|
|
10
11
|
|
|
11
12
|
* 复制"src" "game" "build.py" 到指定目录
|
|
12
13
|
|
|
@@ -14,7 +15,7 @@ def CMD_NewProject():
|
|
|
14
15
|
|
|
15
16
|
"""
|
|
16
17
|
if len(sys.argv) < 2:
|
|
17
|
-
print("Usage: pyarena new [project_path]")
|
|
18
|
+
print("Usage: pyarena new [project_path]\n# or\narena new [project_path]")
|
|
18
19
|
return
|
|
19
20
|
project_path = sys.argv[1]
|
|
20
21
|
if not os.path.exists(project_path):
|
pyscreeps_arena/compiler.py
CHANGED
|
@@ -43,12 +43,12 @@ class Compiler_Const:
|
|
|
43
43
|
|
|
44
44
|
TOTAL_INSERT_AT_HEAD = """
|
|
45
45
|
import { createConstructionSite, findClosestByPath, findClosestByRange, findInRange, findPath, getCpuTime, getDirection, getHeapStatistics, getObjectById, getObjects, getObjectsByPrototype, getRange, getTerrainAt, getTicks,} from 'game/utils';
|
|
46
|
-
import { ConstructionSite, Creep, GameObject, OwnedStructure, Resource, Source, Structure, StructureContainer, StructureExtension, StructureRampart, StructureRoad, StructureSpawn, StructureWall, StructureTower} from 'game/prototypes';
|
|
46
|
+
import { ConstructionSite as GameConstructionSite, Creep as GameCreep, GameObject as GameObjectProto, OwnedStructure, Resource as GameResource, Source as GameSource, Structure as GameStructure, StructureContainer as GameStructureContainer, StructureExtension as GameStructureExtension, StructureRampart as GameStructureRampart, StructureRoad as GameStructureRoad, StructureSpawn as GameStructureSpawn, StructureWall as GameStructureWall, StructureTower as GameStructureTower} from 'game/prototypes';
|
|
47
47
|
import { ATTACK, ATTACK_POWER, BODYPART_COST, BODYPART_HITS, BOTTOM, BOTTOM_LEFT, BOTTOM_RIGHT, BUILD_POWER, CARRY, CARRY_CAPACITY, CONSTRUCTION_COST, CONSTRUCTION_COST_ROAD_SWAMP_RATIO, CONSTRUCTION_COST_ROAD_WALL_RATIO, CONTAINER_CAPACITY, CONTAINER_HITS, CREEP_SPAWN_TIME, DISMANTLE_COST, DISMANTLE_POWER, ERR_BUSY, ERR_FULL, ERR_INVALID_ARGS, ERR_INVALID_TARGET, ERR_NAME_EXISTS, ERR_NOT_ENOUGH_ENERGY, ERR_NOT_ENOUGH_EXTENSIONS, ERR_NOT_ENOUGH_RESOURCES, ERR_NOT_FOUND, ERR_NOT_IN_RANGE, ERR_NOT_OWNER, ERR_NO_BODYPART, ERR_NO_PATH, ERR_TIRED, EXTENSION_ENERGY_CAPACITY, EXTENSION_HITS, HARVEST_POWER, HEAL, HEAL_POWER, LEFT, MAX_CONSTRUCTION_SITES, MAX_CREEP_SIZE, MOVE, OBSTACLE_OBJECT_TYPES, OK, RAMPART_HITS, RAMPART_HITS_MAX, RANGED_ATTACK, RANGED_ATTACK_DISTANCE_RATE, RANGED_ATTACK_POWER, RANGED_HEAL_POWER, REPAIR_COST, REPAIR_POWER, RESOURCES_ALL, RESOURCE_DECAY, RESOURCE_ENERGY, RIGHT, ROAD_HITS, ROAD_WEAROUT, SOURCE_ENERGY_REGEN, SPAWN_ENERGY_CAPACITY, SPAWN_HITS, STRUCTURE_PROTOTYPES, TERRAIN_PLAIN, TERRAIN_SWAMP, TERRAIN_WALL, TOP, TOP_LEFT, TOP_RIGHT, TOUGH, TOWER_CAPACITY, TOWER_COOLDOWN, TOWER_ENERGY_COST, TOWER_FALLOFF, TOWER_FALLOFF_RANGE, TOWER_HITS, TOWER_OPTIMAL_RANGE, TOWER_POWER_ATTACK, TOWER_POWER_HEAL, TOWER_POWER_REPAIR, TOWER_RANGE, WALL_HITS, WALL_HITS_MAX, WORK} from 'game/constants';
|
|
48
48
|
|
|
49
49
|
import {arenaInfo} from "game";
|
|
50
50
|
import {Visual} from "game/visual"
|
|
51
|
-
import {searchPath} from "game/path-finder"
|
|
51
|
+
import {searchPath, CostMatrix} from "game/path-finder"
|
|
52
52
|
"""
|
|
53
53
|
|
|
54
54
|
TOTAL_INSERT_BEFORE_MAIN = """
|
|
@@ -56,22 +56,39 @@ import {searchPath} from "game/path-finder"
|
|
|
56
56
|
|
|
57
57
|
TOTAL_APPEND_ATEND = """
|
|
58
58
|
export var sch = Scheduler();
|
|
59
|
-
var monitor = Monitor(
|
|
59
|
+
var monitor = Monitor(1);
|
|
60
60
|
know.now = 0;
|
|
61
61
|
|
|
62
|
+
StageMachineLogicMeta.__types__ = []; // 清空js首次构造时引入的数据
|
|
62
63
|
__init_my_exists_creep_before_k__();
|
|
64
|
+
let knowCost = 0;
|
|
65
|
+
let monitorCost = 0;
|
|
66
|
+
let stepCost = 0;
|
|
67
|
+
let timeLine = 0;
|
|
63
68
|
export var loop = function () {
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
get.handle();
|
|
70
|
+
know.now = get.now;
|
|
71
|
+
timeLine = get.cpu_us();
|
|
72
|
+
know.handle();
|
|
73
|
+
knowCost = get.cpu_us() - timeLine;
|
|
66
74
|
if (know.now === 1) {
|
|
67
75
|
std.show_welcome();
|
|
68
76
|
init (know);
|
|
77
|
+
|
|
69
78
|
}
|
|
70
79
|
|
|
80
|
+
timeLine = get.cpu_us();
|
|
71
81
|
monitor.handle();
|
|
82
|
+
monitorCost = get.cpu_us() - timeLine;
|
|
83
|
+
for (const creep of get.creeps()){
|
|
84
|
+
creep.handle();
|
|
85
|
+
}
|
|
72
86
|
step (know);
|
|
87
|
+
timeLine = get.cpu_us();
|
|
73
88
|
sch.handle();
|
|
89
|
+
stepCost = get.cpu_us() - timeLine;
|
|
74
90
|
std.show_usage ();
|
|
91
|
+
print("knowCost:", knowCost, "monitorCost:", monitorCost, "stepCost:", stepCost);
|
|
75
92
|
};
|
|
76
93
|
"""
|
|
77
94
|
|
|
@@ -109,42 +126,70 @@ export var loop = function () {
|
|
|
109
126
|
|
|
110
127
|
ARENA_IMPORTS_GETTER = {
|
|
111
128
|
const.ARENA_GREEN: lambda: f"""
|
|
112
|
-
class
|
|
129
|
+
class GameBodyPart{{
|
|
113
130
|
constructor(){{
|
|
114
131
|
}}
|
|
115
132
|
}};
|
|
116
|
-
|
|
133
|
+
class GameAreaEffect{{
|
|
134
|
+
constructor(){{
|
|
135
|
+
}}
|
|
136
|
+
}};
|
|
137
|
+
class GameFlag{{
|
|
138
|
+
constructor(){{
|
|
139
|
+
}}
|
|
140
|
+
}};
|
|
141
|
+
const GameScoreCollector = GameStructureSpawn;
|
|
142
|
+
const RESOURCE_SCORE = "undefined";
|
|
143
|
+
const RESOURCE_SCORE_X = "undefined";
|
|
144
|
+
const RESOURCE_SCORE_Y = "undefined";
|
|
145
|
+
const RESOURCE_SCORE_Z = "undefined";
|
|
117
146
|
""",
|
|
118
147
|
const.ARENA_BLUE: lambda: f"""
|
|
119
|
-
const
|
|
120
|
-
|
|
148
|
+
const GameScoreCollector = GameStructureSpawn;
|
|
149
|
+
class GameAreaEffect{{
|
|
150
|
+
constructor(){{
|
|
151
|
+
}}
|
|
152
|
+
}};
|
|
153
|
+
const RESOURCE_SCORE = "undefined";
|
|
154
|
+
const RESOURCE_SCORE_X = "undefined";
|
|
155
|
+
const RESOURCE_SCORE_Y = "undefined";
|
|
156
|
+
const RESOURCE_SCORE_Z = "undefined";
|
|
157
|
+
import {{ Flag as GameFlag, BodyPart as GameBodyPart}} from 'arena/season_{config.season}/capture_the_flag/{"advanced" if config.level in ["advance", "advanced"] else "basic"}';
|
|
121
158
|
""",
|
|
122
159
|
const.ARENA_RED: lambda: f"""
|
|
123
|
-
class
|
|
160
|
+
class GameBodyPart{{
|
|
124
161
|
constructor(){{
|
|
125
162
|
}}
|
|
126
163
|
}};
|
|
127
|
-
|
|
164
|
+
class GameFlag{{
|
|
165
|
+
constructor(){{
|
|
166
|
+
}}
|
|
167
|
+
}};
|
|
168
|
+
import {{ ScoreCollector as GameScoreCollector, AreaEffect as GameAreaEffect, EFFECT_DAMAGE, EFFECT_FREEZE }} from 'arena/season_{config.season}/collect_and_control/{"advanced" if config.level in ["advance", "advanced"] else "basic"}';
|
|
128
169
|
|
|
129
|
-
import
|
|
130
|
-
|
|
131
|
-
.
|
|
170
|
+
{f"import {{ RESOURCE_SCORE_X, RESOURCE_SCORE_Y, RESOURCE_SCORE_Z }} from 'arena/season_{config.season}/collect_and_control/advanced';" if config.level in ["advance", "advanced"] else 'const RESOURCE_SCORE_X = "undefined"; const RESOURCE_SCORE_Y = "undefined"; const RESOURCE_SCORE_Z = "undefined";'}
|
|
171
|
+
|
|
172
|
+
{"const RESOURCE_SCORE = 'undefined';" if config.level in ["advance", "advanced"] else f"import {{ RESOURCE_SCORE }} from 'arena/season_{config.season}/collect_and_control/basic';"}
|
|
132
173
|
""",
|
|
133
174
|
const.ARENA_GRAY: lambda: f"""
|
|
134
|
-
class
|
|
175
|
+
class GameBodyPart{{
|
|
135
176
|
constructor(){{
|
|
136
177
|
}}
|
|
137
178
|
}};
|
|
138
|
-
|
|
179
|
+
class GameAreaEffect{{
|
|
180
|
+
constructor(){{
|
|
181
|
+
}}
|
|
182
|
+
}};
|
|
183
|
+
const GameScoreCollector = GameStructureSpawn;
|
|
184
|
+
const RESOURCE_SCORE_X = "undefined";
|
|
185
|
+
const RESOURCE_SCORE_Y = "undefined";
|
|
186
|
+
const RESOURCE_SCORE_Z = "undefined";
|
|
187
|
+
let GameFlag = GameStructureSpawn;
|
|
139
188
|
import("game/prototypes")
|
|
140
|
-
.then((module) => {{
|
|
141
|
-
.catch((error) => {{
|
|
189
|
+
.then((module) => {{ GameFlag = module.Flag; }})
|
|
190
|
+
.catch((error) => {{}});
|
|
142
191
|
""",
|
|
143
192
|
}
|
|
144
|
-
ARENA_IMPORTS_NOT_BLUE = ""
|
|
145
|
-
ARENA_IMPORTS_NOT_BLUE1 = """
|
|
146
|
-
import { StructureTower } from 'game/prototypes'
|
|
147
|
-
"""
|
|
148
193
|
|
|
149
194
|
|
|
150
195
|
class Compiler_Utils(Compiler_Const):
|
|
@@ -279,7 +324,7 @@ class Compiler_Utils(Compiler_Const):
|
|
|
279
324
|
return '\n'.join(result) # 将处理后的所有代码行连接成一个字符串,并返回最终结果 | join all processed lines into a string and return
|
|
280
325
|
|
|
281
326
|
def find_chain_import(self, fpath: str, search_dirs: list[str], project_path: str = None, records: dict[str, None] = None) -> list[str]:
|
|
282
|
-
"""
|
|
327
|
+
r"""
|
|
283
328
|
查找文件中的所有import语句,并返回所有import的文件路径 | find all import statements in a file and return the paths of all imported files
|
|
284
329
|
PY_IMPORT_PAT: re.compile(r'\s+from\s+(.+)(?=\s+import)\s+import\s+\*')
|
|
285
330
|
:param fpath: str 目标文件路径 | target file path
|
|
@@ -291,7 +336,7 @@ class Compiler_Utils(Compiler_Const):
|
|
|
291
336
|
if records is None:
|
|
292
337
|
records = {}
|
|
293
338
|
if not os.path.exists(fpath):
|
|
294
|
-
core.error('Compiler.find_chain_import', core.lformat(LOC_FILE_NOT_EXISTS, [fpath]), head='\n', ln=config.language)
|
|
339
|
+
core.error('Compiler.find_chain_import', core.lformat(LOC_FILE_NOT_EXISTS, ["py", fpath]), head='\n', ln=config.language)
|
|
295
340
|
imps = []
|
|
296
341
|
content = self.auto_read(fpath)
|
|
297
342
|
project_path = project_path or os.path.dirname(fpath)
|
|
@@ -337,6 +382,81 @@ class Compiler_Utils(Compiler_Const):
|
|
|
337
382
|
|
|
338
383
|
return imps
|
|
339
384
|
|
|
385
|
+
def find_chain_import2(self, fpath: str, search_dirs: list[str], project_path: str = None, records: dict[str, None] = None) -> list[str]:
|
|
386
|
+
r"""
|
|
387
|
+
查找文件中的所有import语句,并返回所有import的文件路径 | find all import statements in a file and return the paths of all imported files
|
|
388
|
+
PY_IMPORT_PAT: re.compile(r'\s+from\s+(.+)(?=\s+import)\s+import\s+\*')
|
|
389
|
+
:param fpath: str 目标文件路径 | target file path
|
|
390
|
+
:param search_dirs: list[str] 搜索目录 | search directories
|
|
391
|
+
:param project_path=None: str python项目中的概念,指根文件所在的目录。如果不指定,默认使用第一次调用时给定的fpath,并且稍后的递归会全部使用此路径 |
|
|
392
|
+
concept in python-project, refers to the directory where the root file is located. If not specified, the fpath given at the first call is used by default, and all subsequent recursions will use this path
|
|
393
|
+
:param records=None: dict[str, None] 记录已经查找过的文件路径,避免重复查找 | record the file paths that have been searched to avoid duplicate searches
|
|
394
|
+
"""
|
|
395
|
+
if records is None:
|
|
396
|
+
records = {}
|
|
397
|
+
if not os.path.exists(fpath):
|
|
398
|
+
core.error('Compiler.find_chain_import', core.lformat(LOC_FILE_NOT_EXISTS, [fpath]), head='\n', ln=config.language)
|
|
399
|
+
imps = []
|
|
400
|
+
content = self.auto_read(fpath)
|
|
401
|
+
project_path = project_path or os.path.dirname(fpath)
|
|
402
|
+
|
|
403
|
+
# 添加根目录和 src 目录到 search_dirs
|
|
404
|
+
root_dir = os.path.dirname(project_path) # 根目录
|
|
405
|
+
src_dir = os.path.join(root_dir, 'src') # src 目录
|
|
406
|
+
if root_dir not in search_dirs:
|
|
407
|
+
search_dirs = [root_dir] + search_dirs
|
|
408
|
+
if src_dir not in search_dirs:
|
|
409
|
+
search_dirs = [src_dir] + search_dirs
|
|
410
|
+
|
|
411
|
+
for no, line in enumerate(content.split('\n')):
|
|
412
|
+
m = self.PY_IMPORT_PAT.match(line)
|
|
413
|
+
if m:
|
|
414
|
+
target = m.group(1)
|
|
415
|
+
target_path = project_path
|
|
416
|
+
|
|
417
|
+
## 向前定位 | locate forward
|
|
418
|
+
if target.startswith('.'):
|
|
419
|
+
target_path = os.path.dirname(fpath) # 因为使用了相对路径,所以需要先定位到当前文件所在的目录 |
|
|
420
|
+
# because relative path is used, need to locate the directory where the current file is located first
|
|
421
|
+
count = 0
|
|
422
|
+
for c in target:
|
|
423
|
+
if c == '.':
|
|
424
|
+
count += 1
|
|
425
|
+
else:
|
|
426
|
+
break
|
|
427
|
+
if count > 1:
|
|
428
|
+
for _ in range(count - 1):
|
|
429
|
+
target_path = os.path.dirname(target_path)
|
|
430
|
+
|
|
431
|
+
## 向后定位 | locate backward
|
|
432
|
+
while (_idx := target.find('.')) != -1:
|
|
433
|
+
first_name = target[:_idx]
|
|
434
|
+
target_path = os.path.join(target_path, first_name)
|
|
435
|
+
target = target[_idx + 1:]
|
|
436
|
+
|
|
437
|
+
## 检查是否存在 | check if exists
|
|
438
|
+
this_path = os.path.join(target_path, target)
|
|
439
|
+
if os.path.isdir(this_path):
|
|
440
|
+
this_path = os.path.join(this_path, '__init__.py')
|
|
441
|
+
else:
|
|
442
|
+
this_path += '.py'
|
|
443
|
+
|
|
444
|
+
if not os.path.exists(this_path):
|
|
445
|
+
# 如果当前路径不存在,尝试在 search_dirs 中查找
|
|
446
|
+
for search_dir in search_dirs:
|
|
447
|
+
search_path = os.path.join(search_dir, target.replace('.', os.sep)) + ('.py' if not os.path.isdir(this_path) else os.sep + '__init__.py')
|
|
448
|
+
if os.path.exists(search_path):
|
|
449
|
+
this_path = search_path
|
|
450
|
+
break
|
|
451
|
+
else:
|
|
452
|
+
core.error('Compiler.find_chain_import', core.lformat(LOC_CHAIN_FILE_NOT_EXISTS, [fpath, no + 1, this_path]), head='\n', ln=config.language)
|
|
453
|
+
if this_path not in records:
|
|
454
|
+
records[this_path] = None
|
|
455
|
+
tmp = self.find_chain_import(this_path, search_dirs, project_path, records) + [this_path]
|
|
456
|
+
imps.extend(tmp)
|
|
457
|
+
|
|
458
|
+
return imps
|
|
459
|
+
|
|
340
460
|
@staticmethod
|
|
341
461
|
def relist_pyimports_to_jsimports(base_dir:str, pyimps:list[str]) -> list[str]:
|
|
342
462
|
"""
|
|
@@ -352,10 +472,69 @@ class Compiler_Utils(Compiler_Const):
|
|
|
352
472
|
jsimps.append('./' + '.'.join(rel_path_nodes) + '.js')
|
|
353
473
|
return jsimps
|
|
354
474
|
|
|
475
|
+
# ---------- 自定义函数 ---------- #
|
|
476
|
+
@staticmethod
|
|
477
|
+
def stage_recursive_replace(content:str) -> str:
|
|
478
|
+
r"""
|
|
479
|
+
替换'@recursive'为'@recursive(<fname>)', 其中<fname>为被装饰器标记的函数名 |
|
|
480
|
+
Replace '@recursive' with '@recursive(<fname>)', where <fname> is the name of the decorated function.
|
|
481
|
+
|
|
482
|
+
@\s*recursive\s+def\s+([^\s\(]+)
|
|
483
|
+
"""
|
|
484
|
+
return re.sub(r'@\s*recursive(\s+def\s+)([^\s\(]+)', r'@recursive("\2")\1\2', content)
|
|
485
|
+
|
|
486
|
+
@staticmethod
|
|
487
|
+
def process_mate_code(code):
|
|
488
|
+
# 用于存储匹配到的信息
|
|
489
|
+
mate_assignments = []
|
|
490
|
+
# 匹配变量赋值为Mate()的正则表达式,允许变量定义中包含或不包含类型注解
|
|
491
|
+
assign_pattern = re.compile(r'(\w+)\s*(?:\:\s*\w*)?\s*=\s*Mate\s*\(')
|
|
492
|
+
# 匹配类定义的正则表达式
|
|
493
|
+
class_pattern = re.compile(r'class\s+(\w+)')
|
|
494
|
+
# 用于记录当前所在的类名
|
|
495
|
+
current_class = None
|
|
496
|
+
# 将代码按行分割
|
|
497
|
+
lines = code.split('\n')
|
|
498
|
+
# 遍历每一行
|
|
499
|
+
for i, line in enumerate(lines):
|
|
500
|
+
# 匹配类定义
|
|
501
|
+
class_match = class_pattern.match(line)
|
|
502
|
+
if class_match:
|
|
503
|
+
current_class = class_match.group(1)
|
|
504
|
+
# 匹配变量赋值为Mate()
|
|
505
|
+
assign_match = assign_pattern.search(line)
|
|
506
|
+
if assign_match:
|
|
507
|
+
# 检查group(1)前面同一行内是否有#,如果有则忽略
|
|
508
|
+
comment = re.search(r'#', line[:assign_match.start()])
|
|
509
|
+
if comment:
|
|
510
|
+
continue
|
|
511
|
+
variable_name = assign_match.group(1)
|
|
512
|
+
# 存储匹配到的信息
|
|
513
|
+
mate_assignments += [(variable_name, current_class)]
|
|
514
|
+
|
|
515
|
+
output_strings = []
|
|
516
|
+
for variable_name, class_name in mate_assignments:
|
|
517
|
+
output_string = f"# > insert Object.defineProperty ({class_name}, '{variable_name}', property.call ({class_name}, {class_name}.{variable_name}._MateGet_, {class_name}.{variable_name}._MateSet_));"
|
|
518
|
+
output_strings.append(output_string)
|
|
519
|
+
|
|
520
|
+
return code + '\n'.join(output_strings)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
@staticmethod
|
|
524
|
+
def remove_long_docstring(content:str) -> str:
|
|
525
|
+
"""
|
|
526
|
+
移除长注释 | remove long docstring
|
|
527
|
+
"""
|
|
528
|
+
code = re.sub(r'"""[^"]*"""', '', content)
|
|
529
|
+
code = re.sub(r"'''[^']*'''", '', code)
|
|
530
|
+
return code
|
|
531
|
+
|
|
355
532
|
|
|
356
533
|
class CompilerBase(Compiler_Utils):
|
|
357
534
|
|
|
358
|
-
def __init__(self
|
|
535
|
+
def __init__(self):
|
|
536
|
+
src_dir = "src"
|
|
537
|
+
build_dir = "build"
|
|
359
538
|
# check
|
|
360
539
|
if not os.path.exists(src_dir):
|
|
361
540
|
core.error('Compiler.__init__', core.lformat(LOC_FILE_NOT_EXISTS, ['src', src_dir]), head='\n', ln=config.language)
|
|
@@ -418,6 +597,7 @@ class Compiler(CompilerBase):
|
|
|
418
597
|
# 将PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "")插入到文件开头
|
|
419
598
|
content = self.auto_read(fpath)
|
|
420
599
|
content = self.PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "") + content
|
|
600
|
+
# content = self.remove_long_docstring(content) # 移除长注释 | remove long docstring
|
|
421
601
|
|
|
422
602
|
with open(fpath, 'w', encoding='utf-8') as f: # 注意,这里修改的是build目录下的文件,不是源文件 | Note that the file under the build directory is modified here, not the source file
|
|
423
603
|
f.write(content)
|
|
@@ -489,6 +669,13 @@ class Compiler(CompilerBase):
|
|
|
489
669
|
else:
|
|
490
670
|
_pre_sort_[fname] = 65535
|
|
491
671
|
|
|
672
|
+
# ------------------------------------ 自定义:调用process_mate_code ------------------------------------ #
|
|
673
|
+
for fpath in py_fpath:
|
|
674
|
+
content = self.auto_read(fpath)
|
|
675
|
+
content = self.process_mate_code(content) # 调用process_mate_code
|
|
676
|
+
with open(fpath, 'w', encoding='utf-8') as f:
|
|
677
|
+
f.write(content)
|
|
678
|
+
|
|
492
679
|
# ------------------------------------ DEFINE ------------------------------------ #
|
|
493
680
|
# 扫描所有# > define的内容,然后在.py中移除这些行,并记录下来
|
|
494
681
|
# | get all # > define in .py files, and record them
|
|
@@ -562,6 +749,14 @@ class Compiler(CompilerBase):
|
|
|
562
749
|
with open(fpath, 'w', encoding='utf-8') as f:
|
|
563
750
|
f.write(new_content)
|
|
564
751
|
|
|
752
|
+
# ------------------------------------ 自定义:调用stage_recursive_replace ------------------------------------ #
|
|
753
|
+
for fpath in py_fpath:
|
|
754
|
+
content = self.auto_read(fpath)
|
|
755
|
+
content = self.stage_recursive_replace(content) # 调用stage_recursive_replace
|
|
756
|
+
with open(fpath, 'w', encoding='utf-8') as f:
|
|
757
|
+
f.write(content)
|
|
758
|
+
|
|
759
|
+
|
|
565
760
|
core.lprint(GREEN.format('[2/6]'), LOC_DONE, " ", LOC_PREPROCESSING_FINISH, sep="", head="\r", ln=config.language)
|
|
566
761
|
return _imports, _js_imports, _pre_sort_, _pre_define_, _js_replace_
|
|
567
762
|
|
|
@@ -696,9 +891,8 @@ class Compiler(CompilerBase):
|
|
|
696
891
|
"""
|
|
697
892
|
arena_name = const.ARENA_NAMES.get(config.arena, const.ARENA_NAMES['green']) # like green -> spawn_and_swamp
|
|
698
893
|
self.TOTAL_INSERT_AT_HEAD += self.ARENA_IMPORTS_GETTER[arena_name]() # add arena imports
|
|
699
|
-
if config.arena != "blue":
|
|
700
|
-
self.TOTAL_INSERT_AT_HEAD += self.ARENA_IMPORTS_NOT_BLUE
|
|
701
894
|
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"
|
|
895
|
+
total_js += f"const __AUTHOR__ = '{const.AUTHOR}';\nconst __AUTHOR_CN__ = '{const.BILIBILI_NAME}';"
|
|
702
896
|
|
|
703
897
|
core.lprint(WAIT, LOC_GENERATING_TOTAL_MAIN_JS, end="", ln=config.language)
|
|
704
898
|
|
pyscreeps_arena/core/config.py
CHANGED
|
@@ -15,5 +15,5 @@ season = "beta"
|
|
|
15
15
|
language = 'cn'
|
|
16
16
|
# 默认路径: 用户 + ScreepsArena + beta-spawn_and_swamp + main.mjs
|
|
17
17
|
target = None
|
|
18
|
-
TARGET_GETTER = lambda: os.path.join(os.path.expanduser('~'), 'ScreepsArena', f'{season}-{const.ARENA_NAMES.get(arena, "spawn_and_swamp")}', 'main.mjs')
|
|
18
|
+
TARGET_GETTER = lambda: os.path.join(os.path.expanduser('~'), 'ScreepsArena', f'{season}-{const.ARENA_NAMES.get(arena, "spawn_and_swamp")}{"-advanced" if level in ["advance", "advanced"] else ""}', 'main.mjs')
|
|
19
19
|
|
pyscreeps_arena/core/const.py
CHANGED
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
#
|
|
10
10
|
import re
|
|
11
11
|
|
|
12
|
-
VERSION = "0.
|
|
13
|
-
AUTHOR = "
|
|
12
|
+
VERSION = "0.4b0"
|
|
13
|
+
AUTHOR = "●ω<🤍♪"
|
|
14
14
|
STEAM_ID = "1029562896"
|
|
15
15
|
GITHUB_NAME = "EagleBaby"
|
|
16
|
+
BILIBILI_NAME = "我阅读理解一直可以的"
|
|
16
17
|
|
|
17
18
|
ARENA_GREEN = "spawn_and_swamp"
|
|
18
19
|
ARENA_BLUE = "capture_the_flag"
|
pyscreeps_arena/project.7z
CHANGED
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
pyscreeps_arena/__init__.py,sha256=aQvVULggzXzf3INx0Rrlozdk8Aoxe01lU7b5xytK678,862
|
|
2
|
+
pyscreeps_arena/build.py,sha256=DQeGLnID2FjpsWTbnqwt2cOp28olWK68U67bfbFJSOU,177
|
|
3
|
+
pyscreeps_arena/compiler.py,sha256=jpJp85rDhu3I0yN5w04VYwd9S4jx9Nsmedvhexwixu4,51725
|
|
4
|
+
pyscreeps_arena/localization.py,sha256=gBbrNybIJAHlkzeD6maF-ie6RKSwPBbnCNzg_1ge8-c,5656
|
|
5
|
+
pyscreeps_arena/project.7z,sha256=eVA1smGIqMSrnlwhHvr_mbnaFzjihrRd145pWQmfSW0,122127
|
|
6
|
+
pyscreeps_arena/core/__init__.py,sha256=qoP_rx1TpbDLJoTm5via4XPwEPaV1FXr1SYvoVoHGms,41
|
|
7
|
+
pyscreeps_arena/core/basic.py,sha256=DFvyDTsTXf2bQtnS9s254TrkshvRwajaHcvTyVvJyqw,2790
|
|
8
|
+
pyscreeps_arena/core/config.py,sha256=lVk9ynNBDKEkgFnCOsd93w4Q0JiyRPRhTEASLg1KHPw,592
|
|
9
|
+
pyscreeps_arena/core/const.py,sha256=IMYQNBxV8TTAT5n_aO6SKrFE4ybxKl4te3dOza2oGoM,587
|
|
10
|
+
pyscreeps_arena/core/core.py,sha256=3Nty8eLKPNgwnYk_sVNBPrWuKxBXI2od8nfEezsEAZQ,5157
|
|
11
|
+
pyscreeps_arena/core/main.py,sha256=-FNSOEjksNlDfCbUqsjtPSUW8vT3qxEdfzXqT5Tdsik,170
|
|
12
|
+
pyscreeps_arena/core/utils.py,sha256=N9OOkORvrqnJakayaFp9qyS0apWhB9lBK4xyyYkhFdo,215
|
|
13
|
+
pyscreeps_arena-0.4.0.dist-info/METADATA,sha256=aWCqoiPCwmrOahZ2K88pPI_fSuKLgO_d_4IObhCYav8,2079
|
|
14
|
+
pyscreeps_arena-0.4.0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
15
|
+
pyscreeps_arena-0.4.0.dist-info/entry_points.txt,sha256=mLTkJAsgPBEmFkrxNoo3dvb0_dAzSn9jf4Wh09PjdVU,106
|
|
16
|
+
pyscreeps_arena-0.4.0.dist-info/top_level.txt,sha256=l4uLyMR2NOy41ngBMh795jOHTFk3tgYKy64-9cgjVng,16
|
|
17
|
+
pyscreeps_arena-0.4.0.dist-info/RECORD,,
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
pyscreeps_arena/__init__.py,sha256=3O7Oa_IofW8YQYsnrU88SGYNxn-CMR-PpmV8P2hhEhc,800
|
|
2
|
-
pyscreeps_arena/build.py,sha256=DQeGLnID2FjpsWTbnqwt2cOp28olWK68U67bfbFJSOU,177
|
|
3
|
-
pyscreeps_arena/compiler.py,sha256=vitNi05yOzDmhioapJl6VydRBGYlDjwqQGnEwQbCOTQ,42082
|
|
4
|
-
pyscreeps_arena/localization.py,sha256=gBbrNybIJAHlkzeD6maF-ie6RKSwPBbnCNzg_1ge8-c,5656
|
|
5
|
-
pyscreeps_arena/project.7z,sha256=WgobRTq_uG0C-k9kn5kji0ug5sXmLyY6RWr8gMbCMdY,86873
|
|
6
|
-
pyscreeps_arena/core/__init__.py,sha256=qoP_rx1TpbDLJoTm5via4XPwEPaV1FXr1SYvoVoHGms,41
|
|
7
|
-
pyscreeps_arena/core/basic.py,sha256=DFvyDTsTXf2bQtnS9s254TrkshvRwajaHcvTyVvJyqw,2790
|
|
8
|
-
pyscreeps_arena/core/config.py,sha256=U38Z-GiIXPSiAsPKKmOw52AS35Q_tP018H1VUSX6APU,535
|
|
9
|
-
pyscreeps_arena/core/const.py,sha256=veIaT1mEwePm3DqjhnAIRSdJ98djMsN90Uo0qc_nqYM,552
|
|
10
|
-
pyscreeps_arena/core/core.py,sha256=3Nty8eLKPNgwnYk_sVNBPrWuKxBXI2od8nfEezsEAZQ,5157
|
|
11
|
-
pyscreeps_arena/core/main.py,sha256=-FNSOEjksNlDfCbUqsjtPSUW8vT3qxEdfzXqT5Tdsik,170
|
|
12
|
-
pyscreeps_arena/core/utils.py,sha256=N9OOkORvrqnJakayaFp9qyS0apWhB9lBK4xyyYkhFdo,215
|
|
13
|
-
pyscreeps_arena-0.3.5.dist-info/METADATA,sha256=WSRiQfPrKxYhdShprNQeijKM7dwgPeRL4NaMoe2nfSc,2079
|
|
14
|
-
pyscreeps_arena-0.3.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
15
|
-
pyscreeps_arena-0.3.5.dist-info/entry_points.txt,sha256=dqhZN327jfcNypYjEaEJ2t-ABUZ0sVhtDDrD7GiJBfo,67
|
|
16
|
-
pyscreeps_arena-0.3.5.dist-info/top_level.txt,sha256=l4uLyMR2NOy41ngBMh795jOHTFk3tgYKy64-9cgjVng,16
|
|
17
|
-
pyscreeps_arena-0.3.5.dist-info/RECORD,,
|
|
File without changes
|