@@ -234,6 +234,11 @@ class Type50(GenieClass):
234234 displayed_range : float
235235 displayed_reload_time : float
236236 blast_damage : float
237+ damage_reflection : float
238+ friendly_fire_damage : float
239+ interrupt_frame : int
240+ garrison_firepower : float
241+ attack_graphic_2 : int
237242
238243 @classmethod
239244 def from_bytes (cls , content : ByteHandler ) -> 'Type50' :
@@ -261,6 +266,17 @@ def from_bytes(cls, content: ByteHandler) -> 'Type50':
261266 displayed_range = content .read_float ()
262267 displayed_reload_time = content .read_float ()
263268 blast_damage = content .read_float ()
269+ damage_reflection = 0.0
270+ friendly_fire_damage = 1.0
271+ interrupt_frame = - 1
272+ garrison_firepower = 0.0
273+ attack_graphic_2 = - 1
274+ if content .version >= Version .VER_84 :
275+ damage_reflection = content .read_float ()
276+ friendly_fire_damage = content .read_float ()
277+ interrupt_frame = content .read_int_16 ()
278+ garrison_firepower = content .read_float ()
279+ attack_graphic_2 = content .read_int_16 ()
264280 return cls (
265281 base_armor = base_armor ,
266282 attacks = attacks ,
@@ -284,10 +300,15 @@ def from_bytes(cls, content: ByteHandler) -> 'Type50':
284300 displayed_range = displayed_range ,
285301 displayed_reload_time = displayed_reload_time ,
286302 blast_damage = blast_damage ,
303+ damage_reflection = damage_reflection ,
304+ friendly_fire_damage = friendly_fire_damage ,
305+ interrupt_frame = interrupt_frame ,
306+ garrison_firepower = garrison_firepower ,
307+ attack_graphic_2 = attack_graphic_2 ,
287308 )
288309
289310 def to_bytes (self , version : Version ) -> bytes :
290- return b'' .join ([
311+ value = b'' .join ([
291312 self .write_int_16 (self .base_armor ),
292313 self .write_int_16 (len (self .attacks )),
293314 self .write_class_array (self .attacks , version ),
@@ -313,6 +334,15 @@ def to_bytes(self, version: Version) -> bytes:
313334 self .write_float (self .displayed_reload_time ),
314335 self .write_float (self .blast_damage ),
315336 ])
337+ if version >= Version .VER_84 :
338+ value += b'' .join ([
339+ self .write_float (self .damage_reflection ),
340+ self .write_float (self .friendly_fire_damage ),
341+ self .write_int_16 (self .interrupt_frame ),
342+ self .write_float (self .garrison_firepower ),
343+ self .write_int_16 (self .attack_graphic_2 ),
344+ ])
345+ return value
316346
317347
318348PROJECTILE_FORMAT = '<bbbbbf'
@@ -379,6 +409,8 @@ def to_bytes(self, version: Version) -> bytes:
379409
380410CREATABLE_FORMAT = '<hhbffbblhhhffhhffffbfffllbh'
381411CREATABLE_FORMAT_LENGTH = 77
412+ CREATABLE_FORMAT_84 = '<hhbffbblhhhhffhhhlbfhllhffffbfffllbh'
413+ CREATABLE_FORMAT_LENGTH_84 = struct .calcsize (CREATABLE_FORMAT_84 )
382414
383415@dataclass (slots = True )
384416class Creatable (GenieClass ):
@@ -394,10 +426,19 @@ class Creatable(GenieClass):
394426 spawning_graphic : int
395427 upgrade_graphic : int
396428 hero_glow_graphic : int
429+ idle_attack_graphic : int
397430 max_charge : float
398431 recharge_rate : float
399432 charge_event : int
400433 charge_type : int
434+ charge_target : int
435+ charge_projectile_unit : int
436+ attack_priority : int
437+ invulnerability_level : float
438+ button_icon_id : int
439+ button_short_tooltip_id : int
440+ button_extended_tooltip_id : int
441+ button_hotkey_action : int
401442 min_conversion_time_mod : float
402443 max_conversion_time_mod : float
403444 conversion_chance_mod : float
@@ -411,6 +452,12 @@ class Creatable(GenieClass):
411452
412453 @classmethod
413454 def from_bytes (cls , content : ByteHandler ) -> 'Creatable' :
455+ if content .version >= Version .VER_84 :
456+ return cls .from_bytes_84 (content )
457+ return cls .from_bytes_78 (content )
458+
459+ @classmethod
460+ def from_bytes_78 (cls , content : ByteHandler ) -> 'Creatable' :
414461 resource_costs = content .read_class_array_3 (ResourceCost )
415462 train_time , \
416463 train_location_id , \
@@ -439,6 +486,96 @@ def from_bytes(cls, content: ByteHandler) -> 'Creatable':
439486 special_graphic , \
440487 special_ability , \
441488 displayed_pierce_armor = struct .unpack (CREATABLE_FORMAT , content .consume_range (CREATABLE_FORMAT_LENGTH ))
489+ idle_attack_graphic = - 1
490+ charge_target = 0
491+ charge_projectile_unit = - 1
492+ attack_priority = 0
493+ invulnerability_level = 0
494+ button_icon_id = - 1
495+ button_short_tooltip_id = - 1
496+ button_extended_tooltip_id = - 1
497+ button_hotkey_action = - 1
498+ return cls (
499+ resource_costs = resource_costs ,
500+ train_time = train_time ,
501+ train_location_id = train_location_id ,
502+ button_id = button_id ,
503+ rear_attack_modifier = rear_attack_modifier ,
504+ flank_attack_modifier = flank_attack_modifier ,
505+ creatable_type = creatable_type ,
506+ hero_mode = hero_mode ,
507+ garrison_graphic = garrison_graphic ,
508+ spawning_graphic = spawning_graphic ,
509+ upgrade_graphic = upgrade_graphic ,
510+ hero_glow_graphic = hero_glow_graphic ,
511+ idle_attack_graphic = idle_attack_graphic ,
512+ max_charge = max_charge ,
513+ recharge_rate = recharge_rate ,
514+ charge_event = charge_event ,
515+ charge_type = charge_type ,
516+ charge_target = charge_target ,
517+ charge_projectile_unit = charge_projectile_unit ,
518+ attack_priority = attack_priority ,
519+ invulnerability_level = invulnerability_level ,
520+ button_icon_id = button_icon_id ,
521+ button_short_tooltip_id = button_short_tooltip_id ,
522+ button_extended_tooltip_id = button_extended_tooltip_id ,
523+ button_hotkey_action = button_hotkey_action ,
524+ min_conversion_time_mod = min_conversion_time_mod ,
525+ max_conversion_time_mod = max_conversion_time_mod ,
526+ conversion_chance_mod = conversion_chance_mod ,
527+ total_projectiles = total_projectiles ,
528+ max_total_projectiles = max_total_projectiles ,
529+ projectile_spawning_area = (
530+ projectile_spawning_area_1 ,
531+ projectile_spawning_area_2 ,
532+ projectile_spawning_area_3 ),
533+ secondary_projectile_unit = secondary_projectile_unit ,
534+ special_graphic = special_graphic ,
535+ special_ability = special_ability ,
536+ displayed_pierce_armor = displayed_pierce_armor ,
537+ )
538+
539+ @classmethod
540+ def from_bytes_84 (cls , content : ByteHandler ) -> 'Creatable' :
541+ resource_costs = content .read_class_array_3 (ResourceCost )
542+ train_time , \
543+ train_location_id , \
544+ button_id , \
545+ rear_attack_modifier , \
546+ flank_attack_modifier , \
547+ creatable_type , \
548+ hero_mode , \
549+ garrison_graphic , \
550+ spawning_graphic , \
551+ upgrade_graphic , \
552+ hero_glow_graphic , \
553+ idle_attack_graphic , \
554+ max_charge , \
555+ recharge_rate , \
556+ charge_event , \
557+ charge_type , \
558+ charge_target , \
559+ charge_projectile_unit , \
560+ attack_priority , \
561+ invulnerability_level , \
562+ button_icon_id , \
563+ button_short_tooltip_id , \
564+ button_extended_tooltip_id , \
565+ button_hotkey_action , \
566+ min_conversion_time_mod , \
567+ max_conversion_time_mod , \
568+ conversion_chance_mod , \
569+ total_projectiles , \
570+ max_total_projectiles , \
571+ projectile_spawning_area_1 , \
572+ projectile_spawning_area_2 , \
573+ projectile_spawning_area_3 , \
574+ secondary_projectile_unit , \
575+ special_graphic , \
576+ special_ability , \
577+ displayed_pierce_armor = struct .unpack (CREATABLE_FORMAT_84 ,
578+ content .consume_range (CREATABLE_FORMAT_LENGTH_84 ))
442579 return cls (
443580 resource_costs = resource_costs ,
444581 train_time = train_time ,
@@ -452,10 +589,19 @@ def from_bytes(cls, content: ByteHandler) -> 'Creatable':
452589 spawning_graphic = spawning_graphic ,
453590 upgrade_graphic = upgrade_graphic ,
454591 hero_glow_graphic = hero_glow_graphic ,
592+ idle_attack_graphic = idle_attack_graphic ,
455593 max_charge = max_charge ,
456594 recharge_rate = recharge_rate ,
457595 charge_event = charge_event ,
458596 charge_type = charge_type ,
597+ charge_target = charge_target ,
598+ charge_projectile_unit = charge_projectile_unit ,
599+ attack_priority = attack_priority ,
600+ invulnerability_level = invulnerability_level ,
601+ button_icon_id = button_icon_id ,
602+ button_short_tooltip_id = button_short_tooltip_id ,
603+ button_extended_tooltip_id = button_extended_tooltip_id ,
604+ button_hotkey_action = button_hotkey_action ,
459605 min_conversion_time_mod = min_conversion_time_mod ,
460606 max_conversion_time_mod = max_conversion_time_mod ,
461607 conversion_chance_mod = conversion_chance_mod ,
@@ -472,6 +618,11 @@ def from_bytes(cls, content: ByteHandler) -> 'Creatable':
472618 )
473619
474620 def to_bytes (self , version : Version ) -> bytes :
621+ if version >= Version .VER_84 :
622+ return self .to_bytes_84 (version )
623+ return self .to_bytes_78 (version )
624+
625+ def to_bytes_78 (self , version : Version ) -> bytes :
475626 return self .write_class_array (self .resource_costs , version ) + \
476627 struct .pack (CREATABLE_FORMAT ,
477628 self .train_time ,
@@ -501,6 +652,45 @@ def to_bytes(self, version: Version) -> bytes:
501652 self .displayed_pierce_armor ,
502653 )
503654
655+ def to_bytes_84 (self , version : Version ) -> bytes :
656+ return self .write_class_array (self .resource_costs , version ) + \
657+ struct .pack (CREATABLE_FORMAT_84 ,
658+ self .train_time ,
659+ self .train_location_id ,
660+ self .button_id ,
661+ self .rear_attack_modifier ,
662+ self .flank_attack_modifier ,
663+ self .creatable_type ,
664+ self .hero_mode ,
665+ self .garrison_graphic ,
666+ self .spawning_graphic ,
667+ self .upgrade_graphic ,
668+ self .hero_glow_graphic ,
669+ self .idle_attack_graphic ,
670+ self .max_charge ,
671+ self .recharge_rate ,
672+ self .charge_event ,
673+ self .charge_type ,
674+ self .charge_target ,
675+ self .charge_projectile_unit ,
676+ self .attack_priority ,
677+ self .invulnerability_level ,
678+ self .button_icon_id ,
679+ self .button_short_tooltip_id ,
680+ self .button_extended_tooltip_id ,
681+ self .button_hotkey_action ,
682+ self .min_conversion_time_mod ,
683+ self .max_conversion_time_mod ,
684+ self .conversion_chance_mod ,
685+ self .total_projectiles ,
686+ self .max_total_projectiles ,
687+ * self .projectile_spawning_area ,
688+ self .secondary_projectile_unit ,
689+ self .special_graphic ,
690+ self .special_ability ,
691+ self .displayed_pierce_armor ,
692+ )
693+
504694
505695BUILDING_ANNEX_FORMAT = '<hff'
506696BUILDING_ANNEX_FORMAT_LENGTH = 10
0 commit comments