diff --git a/mech_factory/__init__.py b/mech_factory/__init__.py index a5154fb..8f6a5de 100755 --- a/mech_factory/__init__.py +++ b/mech_factory/__init__.py @@ -1,7 +1,9 @@ from hangar.mech import Mech from mech_factory.component_storage import InnerStructure, Area, AreaNames, OuterAmor, ZoneNames -from mech_factory.component_storage.items import Activator, Cockpit, Gyroskope, Joint, Reaktor, Sensors, Sustainment +from mech_factory.component_storage.items import Activator, Cockpit, Gyroskope, Item, Joint, Reaktor, Sensors, \ + Sustainment from mech_factory.store import ItemStore, ComponentStore, InnerAmorStore +from mech_factory.watcher import Watcher class MechFabrik(object): @@ -9,6 +11,7 @@ class MechFabrik(object): def __init__(self, name: str, tonnage: float, movement_rate: int): self.__tonnage = tonnage self.__reactor_value = int(movement_rate * tonnage) + self._watcher = Watcher(tonnage) self.__areas = { AreaNames.HEAD: Area(), AreaNames.MIDDLE_TORSO: Area(), @@ -36,21 +39,26 @@ class MechFabrik(object): self._component_store = ComponentStore(tonnage, movement_rate) self._inner_amor_store = InnerAmorStore(tonnage) self._inner_structure = self._component_store.get_inner_structure() + for (index, area) in self.__areas.items(): + self._inner_structure.add_area(index, area) + self._watcher.add_item(self._inner_structure) self.__build_head_area() self.__build_middle_torso_area(self._inner_structure.gyroskope) self._mech = Mech(name, tonnage, movement_rate, self._inner_structure) + @property + def watcher(self): + return self._watcher + def __build_head_area(self) -> None: cockpit = self._item_store.get_cockpit() self.__areas[AreaNames.HEAD].cockpit = cockpit - self.__areas[AreaNames.HEAD].items = { - (1, 1): self._item_store.get_sustainment(), - (1, 2): self._item_store.get_sensors(), - (1, 3): cockpit, - (1, 4): None, - (1, 5): self._item_store.get_sensors(), - (1, 6): self._item_store.get_sustainment(), - } + self.__add_item_to_areas(AreaNames.HEAD, (1, 1), self._item_store.get_sustainment(), ) + self.__add_item_to_areas(AreaNames.HEAD, (1, 2), self._item_store.get_sensors(), ) + self.__add_item_to_areas(AreaNames.HEAD, (1, 3), cockpit, ) + self.__add_item_to_areas(AreaNames.HEAD, (1, 4), None, ) + self.__add_item_to_areas(AreaNames.HEAD, (1, 5), self._item_store.get_sensors(), ) + self.__add_item_to_areas(AreaNames.HEAD, (1, 6), self._item_store.get_sustainment(), ) self.__areas[AreaNames.HEAD].armor = 3 self.__areas[AreaNames.HEAD].parent = self.__areas[AreaNames.MIDDLE_TORSO] @@ -63,85 +71,77 @@ class MechFabrik(object): self.__areas[AreaNames.RIGHT_TORSO], self.__areas[AreaNames.LEFT_TORSO] ] - self.__areas[AreaNames.MIDDLE_TORSO].items = { - (1, 1): reactor, - (1, 2): reactor, - (1, 3): reactor, - (1, 4): gyroscope, - (1, 5): gyroscope, - (1, 6): gyroscope, - (2, 1): gyroscope, - (2, 2): reactor, - (2, 3): reactor, - (2, 4): reactor, - (2, 5): None, - (2, 6): None, - } + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (1, 1), reactor, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (1, 2), reactor, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (1, 3), reactor, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (1, 4), gyroscope, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (1, 5), gyroscope, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (1, 6), gyroscope, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (2, 1), gyroscope, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (2, 2), reactor, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (2, 3), reactor, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (2, 4), reactor, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (2, 5), None, ) + self.__add_item_to_areas(AreaNames.MIDDLE_TORSO, (2, 6), None) self.__areas[AreaNames.MIDDLE_TORSO].armor = self._inner_amor_store.get_middle_torso_amor() self.__areas[AreaNames.LEFT_TORSO].armor = self._inner_amor_store.get_side_torso_amor() self.__areas[AreaNames.RIGHT_TORSO].armor = self._inner_amor_store.get_side_torso_amor() - self.__build_arm(self.__areas[AreaNames.RIGHT_TORSO], AreaNames.RIGHT_ARM) - self.__build_leg(self.__areas[AreaNames.RIGHT_TORSO], AreaNames.RIGHT_LEG) - self.__build_arm(self.__areas[AreaNames.LEFT_TORSO], AreaNames.LEFT_ARM) - self.__build_leg(self.__areas[AreaNames.LEFT_TORSO], AreaNames.LEFT_LEG) + self.__build_arm_leg(self.__areas[AreaNames.RIGHT_TORSO], AreaNames.RIGHT_ARM, True) + self.__build_arm_leg(self.__areas[AreaNames.RIGHT_TORSO], AreaNames.RIGHT_LEG, False) + self.__build_arm_leg(self.__areas[AreaNames.LEFT_TORSO], AreaNames.LEFT_ARM, True) + self.__build_arm_leg(self.__areas[AreaNames.LEFT_TORSO], AreaNames.LEFT_LEG, False) - def __build_arm(self, parent: Area, index: AreaNames): + def __build_arm_leg(self, parent: Area, index: AreaNames, is_arm: bool) -> None: self.__areas[index].parent = parent - self.__areas[index].items = { - (1, 1): self._item_store.get_joint(), - (1, 2): self._item_store.get_activator(), - (1, 3): self._item_store.get_activator(), - (1, 4): self._item_store.get_activator(), - (1, 5): None, - (1, 6): None, - (2, 1): None, - (2, 2): None, - (2, 3): None, - (2, 4): None, - (2, 5): None, - (2, 6): None, - } - self.__areas[index].armor = self._inner_amor_store.get_arm_amore() - parent.children.append(self.__areas[index]) - - def __build_leg(self, parent: Area, index: AreaNames): - self.__areas[index].parent = parent - self.__areas[index].items = { - (1, 1): self._item_store.get_joint(), - (1, 2): self._item_store.get_activator(), - (1, 3): self._item_store.get_activator(), - (1, 4): self._item_store.get_activator(), - (1, 5): None, - (1, 6): None, - } - self.__areas[index].armor = self._inner_amor_store.get_leg_amore() + self.__add_item_to_areas(index, (1, 1), self._item_store.get_joint(), ) + self.__add_item_to_areas(index, (1, 2), self._item_store.get_activator(), ) + self.__add_item_to_areas(index, (1, 3), self._item_store.get_activator(), ) + self.__add_item_to_areas(index, (1, 4), self._item_store.get_activator(), ) + self.__add_item_to_areas(index, (1, 5), None, ) + self.__add_item_to_areas(index, (1, 6), None, ) + if is_arm: + self.__add_item_to_areas(index, (2, 1), None, ) + self.__add_item_to_areas(index, (2, 2), None, ) + self.__add_item_to_areas(index, (2, 3), None, ) + self.__add_item_to_areas(index, (2, 4), None, ) + self.__add_item_to_areas(index, (2, 5), None, ) + self.__add_item_to_areas(index, (2, 6), None, ) + self.__areas[index].armor = self._inner_amor_store.get_arm_amore() + else: + self.__areas[index].armor = self._inner_amor_store.get_leg_amore() parent.children.append(self.__areas[index]) def auslieferung(self) -> Mech: - for (index, area) in self.__areas.items(): - self._inner_structure.add_area(index, area) for (index, outer_amor) in self.__zones.items(): self._inner_structure.add_zone(index, outer_amor) return self._mech def set_head_armor(self, armor: int) -> None: + self._watcher.add_armor(AreaNames.HEAD, armor) self.__set_outer_armor(armor, ZoneNames.HEAD, AreaNames.HEAD) def set_middle_torso_armor(self, armor_front: int, amor_rear: int) -> None: + self._watcher.add_armor(AreaNames.MIDDLE_TORSO, armor_front + amor_rear) self.__set_outer_armor(armor_front, ZoneNames.MIDDLE_TORSO_FRONT, AreaNames.MIDDLE_TORSO) self.__set_outer_armor(amor_rear, ZoneNames.MIDDLE_TORSO_REAR, AreaNames.MIDDLE_TORSO) def set_side_torso_armor(self, armor_front: int, amor_rear: int) -> None: + self._watcher.add_armor(AreaNames.LEFT_TORSO, armor_front + amor_rear) self.__set_outer_armor(armor_front, ZoneNames.LEFT_TORSO_FRONT, AreaNames.LEFT_TORSO) self.__set_outer_armor(amor_rear, ZoneNames.LEFT_TORSO_REAR, AreaNames.LEFT_TORSO) + self._watcher.add_armor(AreaNames.RIGHT_TORSO, armor_front + amor_rear) self.__set_outer_armor(armor_front, ZoneNames.RIGHT_TORSO_FRONT, AreaNames.RIGHT_TORSO) self.__set_outer_armor(amor_rear, ZoneNames.RIGHT_TORSO_REAR, AreaNames.RIGHT_TORSO) def set_arm_armor(self, armor: int) -> None: + self._watcher.add_armor(AreaNames.LEFT_ARM, armor) + self._watcher.add_armor(AreaNames.RIGHT_ARM, armor) self.__set_outer_armor(armor, ZoneNames.LEFT_ARM, AreaNames.LEFT_ARM) self.__set_outer_armor(armor, ZoneNames.RIGHT_ARM, AreaNames.RIGHT_ARM) def set_leg_armor(self, armor: int) -> None: + self._watcher.add_armor(AreaNames.LEFT_LEG, armor) + self._watcher.add_armor(AreaNames.RIGHT_LEG, armor) self.__set_outer_armor(armor, ZoneNames.LEFT_LEG, AreaNames.LEFT_LEG) self.__set_outer_armor(armor, ZoneNames.RIGHT_LEG, AreaNames.RIGHT_LEG) @@ -149,3 +149,8 @@ class MechFabrik(object): self.__zones[zone_name].armor = armor self.__zones[zone_name].parent = self.__areas[parent_name] self.__areas[parent_name].outer_amor.append(self.__zones[zone_name]) + + def __add_item_to_areas(self, area_name: AreaNames, index: tuple, item: Item | None) -> None: + self.__areas[area_name].items[index] = item + # noinspection PyTypeChecker + self._watcher.add_item(item) diff --git a/mech_factory/watcher/__init__.py b/mech_factory/watcher/__init__.py new file mode 100644 index 0000000..5c3dd8a --- /dev/null +++ b/mech_factory/watcher/__init__.py @@ -0,0 +1,70 @@ +from typing import Any + +from mech_factory.component_storage import AreaNames, InnerStructure +from mech_factory.component_storage.items import BigItem + +class Watcher: + def __init__(self, tonnage: float): + self._tonnage = tonnage + self._weight_watcher = WeightWatcher(tonnage) + self._amor_watcher = ArmorWatcher() + + def add_item(self, item: Any) -> Any: + if isinstance(item, InnerStructure): + self._amor_watcher.set_inner_structure(item) + return self._weight_watcher.add_item(item) + + @property + def actual_weight(self): + return self._weight_watcher.actual_weight + self._amor_watcher.actual_armor_tonnage + + @property + def rest_weight(self): + return self._tonnage - self.actual_weight + + def add_armor(self, area: AreaNames, armor: int): + self._amor_watcher.add_armor(area, armor) + + +class ArmorWatcher: + def __init__(self): + self._inner_structure = None + self._areas = {} + + @property + def actual_armor_tonnage(self): + actual_armor = sum(self._areas.values()) + if actual_armor % 8 > 0: + raise ValueError('Armor is not valid') + return actual_armor / 16 + + def set_inner_structure(self, inner_structure: InnerStructure): + self._inner_structure = inner_structure + + def add_armor(self, area: AreaNames, armor: int): + max_armor = self._inner_structure.areas[area].armor * 2 + if area is AreaNames.HEAD and armor > 9: + raise ValueError(AreaNames.HEAD.name + 'Armor cannot be greater than 9') + elif armor > max_armor: + raise ValueError(AreaNames.HEAD.name + 'Armor cannot be greater than ' + str(max_armor)) + self._areas[area] = armor + +class WeightWatcher: + def __init__(self, max_weight: float): + self._max_weight = max_weight + self._items = {} + self._armor = 0 + + @property + def actual_weight(self): + return sum(self._items.values()) + + def add_item(self, item: Any) -> Any: + if isinstance(item, BigItem): + self._items[item] = item.tonnage + if isinstance(item, InnerStructure): + self._items[item] = item.tonnage + return item + + def set_armor(self, armor: int): + self._armor = armor \ No newline at end of file