@@ -171,6 +171,12 @@ def __init__(self, data, townhall):
171171
172172 self ._townhall = townhall
173173
174+ # copies for a static hash
175+ self .__name = data ['name' ]
176+ self .__level = data ['level' ]
177+ self .__village = data ['village' ]
178+ self .__is_active = data .get ("superTroopIsActive" )
179+
174180 def __repr__ (self ):
175181 attrs = [
176182 ("name" , self .name ),
@@ -180,20 +186,27 @@ def __repr__(self):
180186 return "<%s %s>" % (
181187 self .__class__ .__name__ , " " .join ("%s=%r" % t for t in attrs ),)
182188
189+ def __eq__ (self , other ):
190+ return self .name == other .name and self .level == other .level \
191+ and self .village == other .village and self .is_active == other .is_active
192+
193+ def __hash__ (self ):
194+ return hash ((self .__name , self .__level , self .__village , self .__is_active ))
195+
183196 @classmethod
184- def _load_json_meta (cls , troop_meta , id , name , lab_to_townhall ):
197+ def _load_json_meta (cls , json_meta , id , name , lab_to_townhall ):
185198 cls .id = int (id )
186199 cls .name = name
187200 cls .lab_to_townhall = lab_to_townhall
188201
189- cls .range = try_enum (UnitStat , troop_meta .get ("AttackRange" ))
190- cls .dps = try_enum (UnitStat , troop_meta .get ("DPS" ))
191- cls .ground_target = _get_maybe_first (troop_meta , "GroundTargets" ,
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" ,
192205 default = True )
193- cls .hitpoints = try_enum (UnitStat , troop_meta .get ("Hitpoints" ))
206+ cls .hitpoints = try_enum (UnitStat , json_meta .get ("Hitpoints" ))
194207
195208 # get production building
196- production_building = troop_meta .get ("ProductionBuilding" , [None ])[0 ] if troop_meta .get ("ProductionBuilding" ) else None
209+ production_building = json_meta .get ("ProductionBuilding" , [None ])[0 ] if json_meta .get ("ProductionBuilding" ) else None
197210 if production_building == "Barrack" :
198211 cls .is_elixir_troop = True
199212 elif production_building == "Dark Elixir Barrack" :
@@ -213,16 +226,16 @@ def _load_json_meta(cls, troop_meta, id, name, lab_to_townhall):
213226
214227 # without production_building, it is a hero
215228 if not production_building :
216- laboratory_levels = troop_meta .get ("LaboratoryLevel" )
229+ laboratory_levels = json_meta .get ("LaboratoryLevel" )
217230 else :
218231 # it is a troop or spell or siege
219232 prod_unit = buildings .get (production_building )
220233 if production_building in ("SiegeWorkshop" , "Spell Forge" , "Mini Spell Factory" ,
221234 "Dark Elixir Barrack" , "Barrack" , "Barrack2" ):
222- min_prod_unit_level = troop_meta .get ("BarrackLevel" , [None , ])[0 ]
235+ min_prod_unit_level = json_meta .get ("BarrackLevel" , [None , ])[0 ]
223236 # there are some special troops, which have no BarrackLevel attribute
224237 if not min_prod_unit_level :
225- laboratory_levels = troop_meta .get ("LaboratoryLevel" )
238+ laboratory_levels = json_meta .get ("LaboratoryLevel" )
226239 else :
227240 # get the min th level were we can unlock by the required level of the production building
228241 min_th_level = [th for i , th in
@@ -235,10 +248,10 @@ def _load_json_meta(cls, troop_meta, id, name, lab_to_townhall):
235248 # the first_lab_level is the lowest possible (there are some inconsistencies with siege machines)
236249 # To handle them properly, replacing all lab_level lower than first_lab_level with first_lab_level
237250 laboratory_levels = []
238- for lab_level in troop_meta .get ("LaboratoryLevel" ):
251+ for lab_level in json_meta .get ("LaboratoryLevel" ):
239252 laboratory_levels .append (max (lab_level , first_lab_level ))
240253 elif production_building == "Pet Shop" :
241- min_prod_unit_level = troop_meta .get ("LaboratoryLevel" , [None , ])[0 ]
254+ min_prod_unit_level = json_meta .get ("LaboratoryLevel" , [None , ])[0 ]
242255 # there are some special troops, which have no BarrackLevel attribute
243256
244257 # get the min th level were we can unlock by the required level of the production building
@@ -252,35 +265,35 @@ def _load_json_meta(cls, troop_meta, id, name, lab_to_townhall):
252265 # the first_lab_level is the lowest possible (there are some inconsistencies with siege machines)
253266 # To handle them properly, replacing all lab_level lower than first_lab_level with first_lab_level
254267 laboratory_levels = []
255- for lab_level in troop_meta .get ("LaboratoryLevel" ):
268+ for lab_level in json_meta .get ("LaboratoryLevel" ):
256269 laboratory_levels .append (max (lab_level , first_lab_level ))
257270 else :
258271 return
259272
260273 cls .lab_level = try_enum (UnitStat , laboratory_levels )
261- cls .housing_space = _get_maybe_first (troop_meta , "HousingSpace" , default = 0 )
262- cls .speed = try_enum (UnitStat , troop_meta .get ("Speed" ))
274+ cls .housing_space = _get_maybe_first (json_meta , "HousingSpace" , default = 0 )
275+ cls .speed = try_enum (UnitStat , json_meta .get ("Speed" ))
263276 cls .level = cls .dps and UnitStat (range (1 , len (cls .dps ) + 1 ))
264277
265278 # all 3
266- cls .upgrade_cost = try_enum (UnitStat , troop_meta .get ("UpgradeCost" ))
267- cls .upgrade_resource = Resource (value = troop_meta ["UpgradeResource" ][0 ])
279+ cls .upgrade_cost = try_enum (UnitStat , json_meta .get ("UpgradeCost" ))
280+ cls .upgrade_resource = Resource (value = json_meta ["UpgradeResource" ][0 ])
268281 cls .upgrade_time = try_enum (UnitStat ,
269282 [TimeDelta (hours = hours ) for hours in
270- troop_meta .get ("UpgradeTimeH" , [])])
271- cls ._is_home_village = False if troop_meta .get ("VillageType" ) else True
283+ json_meta .get ("UpgradeTimeH" , [])])
284+ cls ._is_home_village = False if json_meta .get ("VillageType" ) else True
272285 cls .village = "home" if cls ._is_home_village else "builderBase"
273286
274287 # spells and troops
275- cls .training_cost = try_enum (UnitStat , troop_meta .get ("TrainingCost" ))
276- cls .training_time = try_enum (UnitStat , troop_meta .get ("TrainingTime" ))
288+ cls .training_cost = try_enum (UnitStat , json_meta .get ("TrainingCost" ))
289+ cls .training_time = try_enum (UnitStat , json_meta .get ("TrainingTime" ))
277290
278291 # only heroes
279- cls .ability_time = try_enum (UnitStat , troop_meta .get ("AbilityTime" ))
280- cls .ability_troop_count = try_enum (UnitStat , troop_meta .get ("AbilitySummonTroopCount" ))
281- cls .required_th_level = try_enum (UnitStat , troop_meta .get ("RequiredTownHallLevel" ) or laboratory_levels )
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 )
282295 cls .regeneration_time = try_enum (
283- UnitStat , [TimeDelta (minutes = value ) for value in troop_meta .get ("RegenerationTimeMinutes" , [])]
296+ UnitStat , [TimeDelta (minutes = value ) for value in json_meta .get ("RegenerationTimeMinutes" , [])]
284297 )
285298
286299 cls .is_loaded = True
@@ -345,6 +358,10 @@ def _load_json(self, english_aliases, lab_to_townhall):
345358 if True in meta .get ("DisableProduction" , [False ]) and "pets" not in str (self .FILE_PATH ):
346359 continue
347360
361+ # ignore deprecated content
362+ if True in meta .get ("Deprecated" , [False ]):
363+ continue
364+
348365 #hacky but the aliases convert so that isnt great
349366 IGNORED_PETS = ["Unused" , "PhoenixEgg" ]
350367 if "pets" in str (self .FILE_PATH ) and supercell_name in IGNORED_PETS :
0 commit comments