def lock_on(self) -> Optional[LockOn]: if self.fire_groups and all_equal((fg.lock_on for fg in self.fire_groups)): return self.fire_groups[0].lock_on else: return None
def ammo(self) -> Optional[Ammo]: if self.fire_modes and all_equal((fm.ammo for fm in self.fire_modes)): return self.fire_modes[0].ammo else: return None
def heat(self) -> Optional[Heat]: if self.fire_modes and all_equal((fm.heat for fm in self.fire_modes)): return self.fire_modes[0].heat else: return None
def recoil(self) -> Optional[Recoil]: if self.fire_groups and all_equal((fg.recoil for fg in self.fire_groups)): return self.fire_groups[0].recoil else: return None
def projectile(self) -> Optional[Projectile]: if self.fire_groups and all_equal((fg.projectile for fg in self.fire_groups)): return self.fire_groups[0].projectile else: return None
def fire_timing(self) -> Optional[FireTiming]: if self.fire_groups and all_equal((fg.fire_timing for fg in self.fire_groups)): return self.fire_groups[0].fire_timing else: return None
def heat(self) -> Optional[Heat]: if self.fire_groups and all_equal((fg.heat for fg in self.fire_groups)): return self.fire_groups[0].heat else: return None
def ammo(self) -> Optional[Ammo]: if self.fire_groups and all_equal((fg.ammo for fg in self.fire_groups)): return self.fire_groups[0].ammo else: return None
def lock_on(self) -> Optional[LockOn]: if self.fire_modes and all_equal( (fm.lock_on for fm in self.fire_modes)): return self.fire_modes[0].lock_on else: return None
def projectile(self) -> Optional[Projectile]: if self.fire_modes and all_equal( (fm.projectile for fm in self.fire_modes)): return self.fire_modes[0].projectile else: return None
def player_state_can_ads(self) -> Optional[Dict[PlayerState, bool]]: if self.fire_modes and all_equal( (fm.player_state_can_ads for fm in self.fire_modes)): return self.fire_modes[0].player_state_can_ads else: return None
def recoil(self) -> Optional[Recoil]: if self.fire_modes and all_equal( (fm.recoil for fm in self.fire_modes)): return self.fire_modes[0].recoil else: return None
def direct_damage_profile(self) -> Optional[DamageProfile]: if self.fire_modes and all_equal( (fm.direct_damage_profile for fm in self.fire_modes)): return self.fire_modes[0].direct_damage_profile else: return None
def fire_timing(self) -> Optional[FireTiming]: if self.fire_modes and all_equal( (fm.fire_timing for fm in self.fire_modes)): return self.fire_modes[0].fire_timing else: return None
def direct_damage_profile(self) -> Optional[DamageProfile]: if self.fire_groups and all_equal( (fg.direct_damage_profile for fg in self.fire_groups)): return self.fire_groups[0].direct_damage_profile else: return None
def player_state_can_ads(self) -> Optional[Dict[PlayerState, bool]]: if self.fire_groups and all_equal( (fg.player_state_can_ads for fg in self.fire_groups)): return self.fire_groups[0].player_state_can_ads else: return None
def player_state_cone_of_fire( self) -> Optional[Dict[PlayerState, ConeOfFire]]: if self.fire_groups and all_equal( (fg.player_state_cone_of_fire for fg in self.fire_groups)): return self.fire_groups[0].player_state_cone_of_fire else: return None
def test_all_equal(): assert all_equal([1, 2, 3]) is False assert all_equal([1, 1]) is True assert all_equal([]) is True