Skip to content

Commit fe291d4

Browse files
authored
Merge pull request #248 from mathsman5133/th17
Th17 - New Th, Troop, Spell, Hero, & Equipment
2 parents a1e6965 + c5b7c19 commit fe291d4

25 files changed

+104547
-242585
lines changed

coc/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
SOFTWARE.
2323
"""
2424

25-
__version__ = "3.7.2"
25+
__version__ = "3.8.0"
2626

2727
from .abc import BasePlayer, BaseClan
2828
from .clans import RankedClan, Clan

coc/abc.py

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -193,20 +193,22 @@ def __eq__(self, other):
193193
def __hash__(self):
194194
return hash((self.__name, self.__level, self.__village, self.__is_active))
195195

196+
196197
@classmethod
197-
def _load_json_meta(cls, json_meta, id, name, lab_to_townhall):
198+
def _load_json_meta(cls, json_meta: dict, id, name: str, lab_to_townhall):
198199
cls.id = int(id)
199200
cls.name = name
200201
cls.lab_to_townhall = lab_to_townhall
201202

202-
cls.range = try_enum(UnitStat, json_meta.get("AttackRange"))
203-
cls.dps = try_enum(UnitStat, json_meta.get("DPS"))
204-
cls.ground_target = _get_maybe_first(json_meta, "GroundTargets",
205-
default=True)
206-
cls.hitpoints = try_enum(UnitStat, json_meta.get("Hitpoints"))
203+
levels_available = [key for key in json_meta.keys() if key.isnumeric()]
204+
205+
cls.ground_target = json_meta.get("GroundTargets", True)
206+
cls.range = try_enum(UnitStat, [json_meta.get(level).get("AttackRange") for level in levels_available])
207+
cls.dps = try_enum(UnitStat, [json_meta.get(level).get("DPS") for level in levels_available])
208+
cls.hitpoints = try_enum(UnitStat, [json_meta.get(level).get("Hitpoints") for level in levels_available])
207209

208210
# get production building
209-
production_building = json_meta.get("ProductionBuilding", [None])[0] if json_meta.get("ProductionBuilding") else None
211+
production_building = json_meta.get("ProductionBuilding")
210212
if production_building == "Barrack":
211213
cls.is_elixir_troop = True
212214
elif production_building == "Dark Elixir Barrack":
@@ -226,75 +228,79 @@ def _load_json_meta(cls, json_meta, id, name, lab_to_townhall):
226228

227229
# without production_building, it is a hero
228230
if not production_building:
229-
laboratory_levels = json_meta.get("LaboratoryLevel")
231+
laboratory_levels = [json_meta.get(level).get("LaboratoryLevel") for level in levels_available]
230232
else:
231-
# it is a troop or spell or siege
232233
prod_unit = buildings.get(production_building)
233234
if production_building in ("SiegeWorkshop", "Spell Forge", "Mini Spell Factory",
234235
"Dark Elixir Barrack", "Barrack", "Barrack2"):
235-
min_prod_unit_level = json_meta.get("BarrackLevel", [None, ])[0]
236+
min_prod_unit_level = json_meta.get("BarrackLevel", None)
236237
# there are some special troops, which have no BarrackLevel attribute
237238
if not min_prod_unit_level:
238-
laboratory_levels = json_meta.get("LaboratoryLevel")
239+
laboratory_levels = [json_meta.get(level).get("LaboratoryLevel") for level in levels_available]
239240
else:
240-
# get the min th level were we can unlock by the required level of the production building
241-
min_th_level = [th for i, th in
242-
enumerate(prod_unit["TownHallLevel"], start=1)
243-
if i == min_prod_unit_level]
241+
#get the townhall level of the spot where prod building level is equal to the one of the unit
242+
min_th_level = prod_unit.get(str(min_prod_unit_level)).get("TownHallLevel", 0)
244243
# map the min th level to a lab level
245-
[first_lab_level] = [lab_level for lab_level, th_level in
246-
lab_to_townhall.items()
247-
if th_level in min_th_level]
244+
[first_lab_level] = [lab_level for lab_level, th_level in lab_to_townhall.items() if th_level == min_th_level]
248245
# the first_lab_level is the lowest possible (there are some inconsistencies with siege machines)
249246
# To handle them properly, replacing all lab_level lower than first_lab_level with first_lab_level
250247
laboratory_levels = []
251-
for lab_level in json_meta.get("LaboratoryLevel"):
248+
for lab_level in [json_meta.get(level).get("LaboratoryLevel", 1) for level in levels_available]:
252249
laboratory_levels.append(max(lab_level, first_lab_level))
250+
251+
252+
253+
253254
elif production_building == "Pet Shop":
254-
min_prod_unit_level = json_meta.get("LaboratoryLevel", [None, ])[0]
255-
# there are some special troops, which have no BarrackLevel attribute
255+
min_prod_unit_level = json_meta.get("1").get("LaboratoryLevel")
256256

257257
# get the min th level were we can unlock by the required level of the production building
258-
min_th_level = [th for i, th in
259-
enumerate(prod_unit["TownHallLevel"], start=1)
260-
if i == min_prod_unit_level]
258+
min_th_level = prod_unit.get(str(min_prod_unit_level)).get("TownHallLevel", 0)
259+
261260
# map the min th level to a lab level
262-
[first_lab_level] = [lab_level for lab_level, th_level in
263-
lab_to_townhall.items()
264-
if th_level in min_th_level]
261+
[first_lab_level] = [lab_level for lab_level, th_level in lab_to_townhall.items() if th_level == min_th_level]
265262
# the first_lab_level is the lowest possible (there are some inconsistencies with siege machines)
266263
# To handle them properly, replacing all lab_level lower than first_lab_level with first_lab_level
267264
laboratory_levels = []
268-
for lab_level in json_meta.get("LaboratoryLevel"):
265+
for lab_level in [json_meta.get(level).get("LaboratoryLevel") for level in levels_available]:
269266
laboratory_levels.append(max(lab_level, first_lab_level))
267+
270268
else:
271269
return
272270

273271
cls.lab_level = try_enum(UnitStat, laboratory_levels)
274-
cls.housing_space = _get_maybe_first(json_meta, "HousingSpace", default=0)
275-
cls.speed = try_enum(UnitStat, json_meta.get("Speed"))
272+
cls.housing_space = json_meta.get("HousingSpace", 0)
273+
274+
cls.speed = try_enum(UnitStat, [json_meta.get(level).get("Speed") for level in levels_available])
276275
cls.level = cls.dps and UnitStat(range(1, len(cls.dps) + 1))
277276

278-
# all 3
279-
cls.upgrade_cost = try_enum(UnitStat, json_meta.get("UpgradeCost"))
280-
cls.upgrade_resource = Resource(value=json_meta["UpgradeResource"][0])
281-
cls.upgrade_time = try_enum(UnitStat,
282-
[TimeDelta(hours=hours) for hours in
283-
json_meta.get("UpgradeTimeH", [])])
277+
cls.upgrade_cost = try_enum(UnitStat, [json_meta.get(level).get("UpgradeCost") for level in levels_available])
278+
cls.upgrade_resource = Resource(value=json_meta.get("UpgradeResource"))
279+
upgrade_times = [
280+
TimeDelta(hours=json_meta.get(level, {}).get("UpgradeTimeH"))
281+
for level in levels_available
282+
if json_meta.get(level, {}).get("UpgradeTimeH") is not None
283+
]
284+
cls.upgrade_time = try_enum(UnitStat, upgrade_times)
285+
284286
cls._is_home_village = False if json_meta.get("VillageType") else True
285287
cls.village = "home" if cls._is_home_village else "builderBase"
286288

287-
# spells and troops
288-
cls.training_cost = try_enum(UnitStat, json_meta.get("TrainingCost"))
289-
cls.training_time = try_enum(UnitStat, json_meta.get("TrainingTime"))
289+
cls.training_time = TimeDelta(seconds=json_meta.get("TrainingTime"))
290290

291291
# only heroes
292-
cls.ability_time = try_enum(UnitStat, json_meta.get("AbilityTime"))
293-
cls.ability_troop_count = try_enum(UnitStat, json_meta.get("AbilitySummonTroopCount"))
294-
cls.required_th_level = try_enum(UnitStat, json_meta.get("RequiredTownHallLevel") or laboratory_levels)
295-
cls.regeneration_time = try_enum(
296-
UnitStat, [TimeDelta(minutes=value) for value in json_meta.get("RegenerationTimeMinutes", [])]
297-
)
292+
cls.ability_time = try_enum(UnitStat, [json_meta.get(level).get("AbilityTime") for level in levels_available])
293+
cls.ability_troop_count = try_enum(UnitStat, [json_meta.get(level).get("AbilitySummonTroopCount") for level in levels_available])
294+
295+
required_townhall_levels = [json_meta.get(level).get("RequiredTownHallLevel") for level in levels_available]
296+
cls.required_th_level = try_enum(UnitStat, required_townhall_levels if any(required_townhall_levels) else laboratory_levels)
297+
298+
regeneration_times = [
299+
TimeDelta(minutes=json_meta.get(level, {}).get("RegenerationTimeMinutes"))
300+
for level in levels_available
301+
if json_meta.get(level, {}).get("RegenerationTimeMinutes") is not None
302+
]
303+
cls.regeneration_time = try_enum(UnitStat, regeneration_times)
298304

299305
cls.is_loaded = True
300306
return cls
@@ -355,11 +361,11 @@ def _load_json(self, english_aliases, lab_to_townhall):
355361
continue
356362

357363
# SC game files have "DisableProduction" true for all pet objects, which we want
358-
if True in meta.get("DisableProduction", [False]) and "pets" not in str(self.FILE_PATH):
364+
if meta.get("DisableProduction") and "pets" not in str(self.FILE_PATH):
359365
continue
360366

361367
# ignore deprecated content
362-
if True in meta.get("Deprecated", [False]):
368+
if meta.get("Deprecated"):
363369
continue
364370

365371
#hacky but the aliases convert so that isnt great
@@ -374,7 +380,7 @@ def _load_json(self, english_aliases, lab_to_townhall):
374380
new_item._load_json_meta(
375381
meta,
376382
id=id,
377-
name=english_aliases[meta["TID"][0]]["EN"][0],
383+
name=english_aliases[meta.get("TID")],
378384
lab_to_townhall=lab_to_townhall,
379385
)
380386
id += 1

0 commit comments

Comments
 (0)