From 0ce8cd0c7e0c764622d6df5cc4dc60e5c71e9c56 Mon Sep 17 00:00:00 2001 From: "Dusty.P" Date: Thu, 17 May 2018 01:14:53 -0800 Subject: [PATCH] Updated Dino Class --- exts/imports/misc_classes.py | 323 +++++++++++------- .../DinoExport_6768953196397063.ini | 66 ++++ submissions_temp/Dusty.P_failed.json | 152 +++++++++ 3 files changed, 410 insertions(+), 131 deletions(-) create mode 100644 submissions_temp/DinoExport_6768953196397063.ini create mode 100644 submissions_temp/Dusty.P_failed.json diff --git a/exts/imports/misc_classes.py b/exts/imports/misc_classes.py index 13d855f..b747908 100644 --- a/exts/imports/misc_classes.py +++ b/exts/imports/misc_classes.py @@ -1,175 +1,223 @@ -import configparser +from configparser import ConfigParser from . import guid +from distutils.util import strtobool +from collections import OrderedDict + +config_setup = {'Dino Data': ['DinoID1', + 'DinoID2', + 'DinoClass', + 'DinoNameTag', + 'bIsFemale', + 'bNeutered', + 'TamerString', + 'TamedName', + 'ImprinterName', + 'RandomMutationsMale', + 'RandomMutationsFemale', + 'BabyAge', + 'CharacterLevel', + 'DinoImprintingQuality'], + 'Colorization': ['ColorSet'], + 'Max Character Status Values': ['Health', + 'Stamina', + 'Torpidity', + 'Oxygen', + 'food', + 'Water', + 'Temperature', + 'Weight', + 'Melee Damage', + 'Movement Speed', + 'Fortitude', + 'Crafting Skill'], + 'Dino Ancestry': ['DinoAncestorsCount', 'DinoAncestorsMale'] + } + +ancestry_setup = {'DinoAncestors': ['DinoAncestors'], + 'DinoAncestorsMale': ['DinoAncestorsMale'] + } + + +class InvalidConfig(AttributeError): + pass class Color: def __init__(self, r=0, g=0, b=0, a=0): - self.r = self.float_to_hex(r) if isinstance(r, float) else r - self.g = self.float_to_hex(g) if isinstance(g, float) else g - self.b = self.float_to_hex(b) if isinstance(b, float) else b - self.a = self.float_to_hex(a) if isinstance(a, float) else a + self.r = self._hex_to_float(r) if isinstance(r, int) else r + self.g = self._hex_to_float(g) if isinstance(g, int) else g + self.b = self._hex_to_float(b) if isinstance(b, int) else b + self.a = self._hex_to_float(a) if isinstance(a, int) else a + + def to_rgba_string(self, hex_values: bool=False): + if not hex_values: + return f'(R={self.r:.6f},G={self.g:.6f},B={self.b:.6f},A={self.a:.6f})' + else: + return (f'(R={self._float_to_hex(self.r)},' + f'G={self._float_to_hex(self.g)},' + f'B={self._float_to_hex(self.b)},' + f'A={self._float_to_hex(self.a)})') @staticmethod - def float_to_hex(a: float): - return ((a - 0.0)/(1.0 - 0.0)) * (255 - 0) + 0.0 + def _float_to_hex(a: float) -> int: + return int(((a - 0.0)/(1.0 - 0.0)) * (255 - 0) + 0.0) + + @staticmethod + def _hex_to_float(a: int) -> float: + return float(((a - 0.0)/(255.0 - 0.0)) * (1.0 - 0.0) + 0.0) class Dino: - def __init__(self, dino_data=None, parent=False): - self.parent = parent - if dino_data is None and parent is False: - self.dino_data = None - self.dino_data_orig = None - self.colors = None - self.stats = None - self.ancestry = None - self.guid = guid.Guid() - elif parent is False and isinstance(dino_data, configparser.ConfigParser): - self.dino_data_orig = dino_data - self.dino_data = self._get_dino_data(dino_data['Dino Data']) - self.colors = self._get_colors(dino_data['Colorization']) - self.stats = self._get_colors(dino_data['Max Character Status Values']) - self.ancestry = self._get_ancestry(dino_data['Dino Ancestry'], dino_data) + def __init__(self, dino_data: ConfigParser): + self.dino_data_orig = dino_data + if dino_data == ConfigParser(): + self.dino_data = self._get_dino_data() + self.colors = self._get_colors() + self.stats = self._get_colors() + self.ancestry = self._get_ancestry() self.guid = self.get_guid() - elif parent is True and isinstance(dino_data, list): - self.dino_data = { - 'TamedName': dino_data[0], - 'DinoID1': dino_data[1], - 'DinoID2': dino_data[2] - } - self.stats = self._zero_stats() - self.colors = list() - self.ancestry = dict() + elif isinstance(dino_data, ConfigParser): + self.dino_data = self._get_dino_data(list(dino_data['Dino Data'].values())) + self.colors = self._get_colors(list(dino_data['Colorization'].values())) + self.stats = self._get_stats(list(dino_data['Max Character Status Values'].values())) + self.ancestry = self._get_ancestry(list(dino_data['Dino Ancestry'].values()), dino_data) self.guid = self.get_guid() else: - raise TypeError('Arguments don\'t match any valid configuration.') + raise InvalidConfig('Arguments don\'t match any valid configuration.') def get_guid(self) -> guid.Guid: return guid.Guid(self.dino_data['DinoID1'], self.dino_data['DinoID2']) @staticmethod - def _get_colors(colorization) -> [Color]: + def _get_colors(colorization: list=list()) -> [Color]: colors = list() - for color, values in colorization.items(): - value = values.strip('()').split(',') - c = dict() - for v in value: - v = v.split('=') - c[v[0]] = float(v[1]) - colors.append(Color(**c)) + if colorization != list(): + for values in colorization: + value = values.strip('()').split(',') + c = dict() + for v in value: + v = v.split('=') + c[v[0].lower()] = float(v[1]) + colors.append(Color(**c)) return colors - def _zero_stats(self): - return self._get_stats({i: '0' for i in range(12)}) + @staticmethod + def _get_stats(stats: list=list()) -> OrderedDict: + if len(stats) < 12: + stats.extend([0] * (12 - len(stats))) + elif len(stats) > 12: + raise InvalidConfig("Stats list is too long") + stats = [float(stat) for stat in stats] + return OrderedDict(zip(config_setup['Max Character Status Values'], stats)) @staticmethod - def _get_stats(stat_values) -> dict: - stats = [stat for stat in stat_values.values()] - stats_dict = dict() - stats_dict['Health'] = float(stats[0]) - stats_dict['Stamina'] = float(stats[1]) - stats_dict['Torpidity'] = float(stats[2]) - stats_dict['Oxygen'] = float(stats[3]) - stats_dict['food'] = float(stats[4]) - stats_dict['Water'] = float(stats[5]) - stats_dict['Temperature'] = float(stats[6]) - stats_dict['Weight'] = float(stats[7]) - stats_dict['Melee Damage'] = float(stats[8]) - stats_dict['Movement Speed'] = float(stats[9]) - stats_dict['Fortitude'] = float(stats[10]) - stats_dict['Crafting Skill'] = float(stats[11]) - return stats_dict + def _get_dino_data(data: list=list()) -> OrderedDict: + for i, value in enumerate(data): + try: + data[i] = int(value) + except ValueError: + try: + data[i] = float(value) + except ValueError: + try: + data[i] = bool(strtobool(value)) + except ValueError: + pass + + if len(data) < 14: + data.extend([0] * (14 - len(data))) + elif len(data) > 14: + raise InvalidConfig + dino_dict = OrderedDict(zip(config_setup['Dino Data'], data)) + return dino_dict @staticmethod - def _get_dino_data(dino_data) -> dict: - data = [d for d in dino_data.values()] - data_dict = dict() - data_dict['DinoID1'] = int(data[0]) - data_dict['DinoID2'] = int(data[1]) - data_dict['DinoClass'] = data[2] - data_dict['DinoNameTag'] = data[3] - if data[4] == 'True': - data_dict['bIsFemale'] = True - else: - data_dict['bIsFemale'] = False - if data[5] == 'True': - data_dict['bNeutered'] = True - else: - data_dict['bNeutered'] = False - data_dict['TamerString'] = data[6] - data_dict['TamedName'] = data[7] - data_dict['ImprinterName'] = data[8] - data_dict['RandomMutationsMale'] = int(data[9]) - data_dict['RandomMutationsFemale'] = int(data[10]) - data_dict['BabyAge'] = float(data[11]) - data_dict['CharacterLevel'] = int(data[12]) - data_dict['DinoImprintingQuality'] = float(data[13]) - return data_dict + def _get_ancestry(ancestry: list=list(), data: ConfigParser=None) -> OrderedDict: + ancestry_dict = OrderedDict() + if ancestry != list(): + ancestry_dict['DinoAncestorsCount'] = int(ancestry[0]) + ancestry_dict['DinoAncestorsMale'] = int(ancestry[1]) - @staticmethod - def _get_ancestry(ancestry_data, data) -> dict: - ancestry = [a for a in ancestry_data.values()] - ancestry_dict = dict() - ancestry_dict['DinoAncestorsCount'] = int(ancestry[0]) - ancestry_dict['DinoAncestorsMale'] = int(ancestry[1]) + if ancestry_dict['DinoAncestorsCount'] != 0: + if 'DinoAncestors' in data.sections(): + dino_anc = [a for a in data['DinoAncestors'].values()] + ancestors = list() + for dino in dino_anc: + ancestors.append(OrderedDict([field.split('=') for field in dino.split(';')])) + ancestry_dict['DinoAncestors_'] = ancestors - if ancestry_dict['DinoAncestorsCount'] != 0: - if 'DinoAncestors' in data.sections(): - dino_anc = [a for a in data['DinoAncestors'].values()] - ancestors = list() - for dino in dino_anc: - ancestors.append(dict([field.split('=') for field in dino.split(';')])) - ancestry_dict['DinoAncestors'] = ancestors - - if ancestry_dict['DinoAncestorsMale'] != 0: - if 'DinoAncestorsMale' in data.sections(): - dino_anc = [a for a in data['DinoAncestorsMale'].values()] - ancestors_male = list() - for dino in dino_anc: - ancestors_male.append(dict([field.split('=') for field in dino.split(';')])) - ancestry_dict['DinoAncestorsMale'] = ancestors_male + if ancestry_dict['DinoAncestorsMale'] != 0: + if 'DinoAncestorsMale' in data.sections(): + dino_anc = [a for a in data['DinoAncestorsMale'].values()] + ancestors_male = list() + for dino in dino_anc: + ancestors_male.append(OrderedDict([field.split('=') for field in dino.split(';')])) + ancestry_dict['DinoAncestorsMale_'] = ancestors_male return ancestry_dict - def parents(self) -> (Dino, Dino): + def to_config(self): + config = ConfigParser() + config.optionxform = str + for section in config_setup: + config.add_section(section) + for key, data in self.dino_data.items(): + config.set('Dino Data', str(key), (f'{data:.6f}' if type(data) == float else str(data))) + config.set('Dino Data', 'ASMBot_GUID', str(self.guid)) + for key, data in self.stats.items(): + config.set('Max Character Status Values', str(key), f'{data:.6f}') + for i, data in enumerate(self.colors): + config.set('Colorization', f'{config_setup["Colorization"][0]}[{i}]', data.to_rgba_string(hex_values=False)) + if 'DinoAncestors_' in self.ancestry: + config.add_section('DinoAncestors') + if 'DinoAncestorsMale_' in self.ancestry: + config.add_section('DinoAncestorsMale') + for key, data in self.ancestry.items(): + if key == 'DinoAncestors_': + for i, item in enumerate(data): + config.set('DinoAncestors', f'{ancestry_setup["DinoAncestors"][0]}{i}', + ';'.join([f'{k}={v}' for k, v in item.items()])) + elif key == 'DinoAncestorsMale_': + for i, item in enumerate(data): + config.set('DinoAncestorsMale', f'{ancestry_setup["DinoAncestorsMale"][0]}{i}', + ';'.join([f'{k}={v}' for k, v in item.items()])) + else: + config.set('Dino Ancestry', str(key), str(data)) + return config + + def to_file(self, path: str): + if not path.endswith('/'): + path += '/' + path += f'DinoExport_{self.dino_data["DinoID1"]}{self.dino_data["DinoID2"]}.ini' + config = self.to_config() + with open(path, 'w') as f: + config.write(f, space_around_delimiters=False) + print(f'Dino has been written to {path}') + + def parents(self): if 'DinoAncestors' in self.ancestry: parents = self.ancestry['DinoAncestors'][-1] - father = Dino.from_min_req(parents['MaleName'], - parents['MaleDinoID1'], - parents['MaleDinoID2'], - True) - mother = Dino.from_min_req(parents['FemaleName'], - parents['FemaleDinoID1'], - parents['FemaleDinoID2'], - True) + father = Parent(name=parents['MaleName'], + id1=parents['MaleDinoID1'], + id2=parents['MaleDinoID2'], + female=False) + mother = Parent(name=parents['FemaleName'], + id1=parents['FemaleDinoID1'], + id2=parents['FemaleDinoID2'], + female=True) return father, mother else: - return Dino.empty(), Dino.empty() - - @classmethod - def from_min_req(cls, name, id1, id2, parent=False): - return Dino([name, id1, id2], parent=parent) + return Parent('', True, 0, 0), Parent('', False, 0, 0) @classmethod def empty(cls): - return Dino() + return Dino(ConfigParser()) def __eq__(self, other): - if isinstance(other, Dino): + if self.__class__ == other.__class__: if self.guid == other.guid: return self.dino_data == other.dino_data and self.stats == other.stats - return False - elif isinstance(other, str): - try: - o = guid.Guid(other) - except TypeError: - return False - else: - return self.guid == o - elif isinstance(other, guid.Guid): - return self.guid == other - else: - return False + return False def __str__(self): return f'' @@ -177,3 +225,16 @@ class Dino: def __repr__(self): return (f'') + + +class Parent(Dino): + # noinspection PyMissingConstructor + def __init__(self, name: str, female: bool, id1: int=0, id2: int=0): + try: + self.dino_data = self._get_dino_data([id1, id2, '', '', female, '', '', name]) + self.colors = self._get_colors([]) + self.stats = self._get_stats([]) + self.ancestry = self._get_ancestry([]) + self.guid = self.get_guid() + except InvalidConfig: + raise InvalidConfig('Arguments don\'t match any valid configuration.') diff --git a/submissions_temp/DinoExport_6768953196397063.ini b/submissions_temp/DinoExport_6768953196397063.ini new file mode 100644 index 0000000..505a39e --- /dev/null +++ b/submissions_temp/DinoExport_6768953196397063.ini @@ -0,0 +1,66 @@ +[Dino Data] +DinoID1=67689531 +DinoID2=96397063 +DinoClass=/Game/ScorchedEarth/Dinos/SpineyLizard/SpineyLizard_Character_BP.SpineyLizard_Character_BP_C +DinoNameTag=spineyLizard +bIsFemale=True +bNeutered=False +TamerString=TheGeeks +TamedName=[Dusty.P] S2 F 2 +ImprinterName=Dusty.P +RandomMutationsMale=0 +RandomMutationsFemale=0 +BabyAge=1.000000 +CharacterLevel=346 +DinoImprintingQuality=0.000000 +ASMBot_GUID=05bee707-dc3b-0408-0000-000000000000 + +[Colorization] +ColorSet[0]=(R=1.000000,G=0.475000,B=0.300000,A=0.000000) +ColorSet[1]=(R=0.825000,G=0.704920,B=0.668250,A=1.000000) +ColorSet[2]=(R=0.250000,G=0.084211,B=0.025000,A=0.000000) +ColorSet[3]=(R=0.000000,G=0.000000,B=0.000000,A=1.000000) +ColorSet[4]=(R=1.000000,G=0.750000,B=0.500000,A=0.000000) +ColorSet[5]=(R=0.300000,G=0.240000,B=0.180000,A=0.000000) + +[Max Character Status Values] +Health=2704.092285 +Stamina=1960.000000 +Torpidity=9765.500000 +Oxygen=915.000000 +food=9246.000000 +Water=100.000000 +Temperature=0.000000 +Weight=576.000000 +Melee Damage=3.276724 +Movement Speed=0.300000 +Fortitude=0.000000 +Crafting Skill=0.000000 + +[Dino Ancestry] +DinoAncestorsCount=9 +DinoAncestorsMale=10 + +[DinoAncestors] +DinoAncestors0=MaleName=[Dusty.P] Thor 000 M 3 - Lvl 269;MaleDinoID1=245648145;MaleDinoID2=341930255;FemaleName=[Dusty.P] Thor 000 F 1 - Lvl 269;FemaleDinoID1=333516684;FemaleDinoID2=434095466 +DinoAncestors1=MaleName=[Dusty.P] Thor 000 M 4 - Lvl 260;MaleDinoID1=310229987;MaleDinoID2=476933752;FemaleName=[Dusty.P] Thor 001 F 4 - Lvl 294;FemaleDinoID1=388212621;FemaleDinoID2=110151978 +DinoAncestors2=MaleName=[Dusty.P] Thor 000 M 6 [ - Lvl 242;MaleDinoID1=9732552;MaleDinoID2=39291524;FemaleName=[Dusty.P] Thor 002 F 3 - Lvl 308;FemaleDinoID1=279067496;FemaleDinoID2=91283771 +DinoAncestors3=MaleName=[Dusty.P] Thor 002 M 3 - Lvl 303;MaleDinoID1=497905531;MaleDinoID2=251914433;FemaleName=[Dusty.P] Thor 003 F 1 - Lvl 296;FemaleDinoID1=445811457;FemaleDinoID2=316338707 +DinoAncestors4=MaleName=[Dusty.P] Thor 005 M 1 - Lvl 333;MaleDinoID1=142203840;MaleDinoID2=392650130;FemaleName=[Dusty.P] Thor 004 F 1 - Lvl 328;FemaleDinoID1=205932658;FemaleDinoID2=294294111 +DinoAncestors5=MaleName=[Dusty.P] Thor 003 M 2 - Lvl 309;MaleDinoID1=474920327;MaleDinoID2=124706671;FemaleName=[Dusty.P] Thor 006 F 1 - Lvl 333;FemaleDinoID1=247273560;FemaleDinoID2=412274835 +DinoAncestors6=MaleName=[Dusty.P] Thor 005 M 1 - Lvl 333;MaleDinoID1=142203840;MaleDinoID2=392650130;FemaleName=[Dusty.P] Thor 007 F 1 - Lvl 334;FemaleDinoID1=469853905;FemaleDinoID2=463294607 +DinoAncestors7=MaleName=[Dusty.P] Thor 010 M 1 - Lvl 342;MaleDinoID1=477515441;MaleDinoID2=100817536;FemaleName=[Dusty.P] Thor S1 F 1 - Lvl 334;FemaleDinoID1=234035802;FemaleDinoID2=405087418 +DinoAncestors8=MaleName=[Dusty.P] - Lvl 346;MaleDinoID1=97415132;MaleDinoID2=30837736;FemaleName=[Dusty.P] Thor 011 F 1 - Lvl 343;FemaleDinoID1=253375298;FemaleDinoID2=446732150 + +[DinoAncestorsMale] +DinoAncestorsMale0=MaleName=[Wiz] W M6 - Lvl 251;MaleDinoID1=430625202;MaleDinoID2=17665070;FemaleName=[Wiz] G6 F4 - Lvl 294;FemaleDinoID1=160662331;FemaleDinoID2=128849927 +DinoAncestorsMale1=MaleName=[Wiz] G7 M2 - Lvl 278;MaleDinoID1=45309048;MaleDinoID2=343783812;FemaleName=[Wiz] G7 F3 - Lvl 318;FemaleDinoID1=491743784;FemaleDinoID2=117323774 +DinoAncestorsMale2=MaleName=[Wiz] G8 M3 - Lvl 303;MaleDinoID1=245512077;MaleDinoID2=178264385;FemaleName=[Wiz] G7 F5 - Lvl 299;FemaleDinoID1=178788519;FemaleDinoID2=24940599 +DinoAncestorsMale3=MaleName=[Wiz] G8 M4 - Lvl 330;MaleDinoID1=475281007;MaleDinoID2=304693211;FemaleName=[Wiz] G8 F3 - Lvl 298;FemaleDinoID1=444580765;FemaleDinoID2=132226718 +DinoAncestorsMale4=MaleName=[Wiz] S1 M - Lvl 332;MaleDinoID1=284929545;MaleDinoID2=257007771;FemaleName=[Wiz] S1 F - Lvl 332;FemaleDinoID1=337635280;FemaleDinoID2=333945166 +DinoAncestorsMale5=MaleName=[Dusty.P] Wiz S1 M 1 - Lvl 332;MaleDinoID1=430695116;MaleDinoID2=51865108;FemaleName=[Dusty.P] Thor S1 F 1 - Lvl 334;FemaleDinoID1=234035802;FemaleDinoID2=405087418 +DinoAncestorsMale6=MaleName=[Dusty.P] Thor 008 M 1 - Lvl 342;MaleDinoID1=396664712;MaleDinoID2=293096519;FemaleName=[Dusty.P] Thor 009 F 1 - Lvl 342;FemaleDinoID1=345548955;FemaleDinoID2=251224157 +DinoAncestorsMale7=MaleName=[Dusty.P] Thor 010 M 2 - Lvl 342;MaleDinoID1=416372693;MaleDinoID2=309226474;FemaleName=[Dusty.P] Wiz S1 F 1 - Lvl 332;FemaleDinoID1=351226687;FemaleDinoID2=101240636 +DinoAncestorsMale8=MaleName=[Dusty.P] Thor 011 M 9 - Lvl 345;MaleDinoID1=35770562;MaleDinoID2=96528642;FemaleName=[Dusty.P] Thor 011 F 1 - Lvl 343;FemaleDinoID1=253375298;FemaleDinoID2=446732150 +DinoAncestorsMale9=MaleName=[Dusty.P] - Lvl 346;MaleDinoID1=97415132;MaleDinoID2=30837736;FemaleName=[Dusty.P] Thor 011 F 1 - Lvl 343;FemaleDinoID1=253375298;FemaleDinoID2=446732150 + diff --git a/submissions_temp/Dusty.P_failed.json b/submissions_temp/Dusty.P_failed.json new file mode 100644 index 0000000..732e82c --- /dev/null +++ b/submissions_temp/Dusty.P_failed.json @@ -0,0 +1,152 @@ +{ + "[GS] Converter": { + "wildLevels": { + "health": 4, + "stamina": 4, + "torpor": 0, + "oxygen": 5, + "food": 7, + "water": 0, + "temperature": 0, + "weight": 6, + "melee": 4, + "speed": 4, + "fortitude": 0, + "crafting": 0 + }, + "tamedLevels": { + "health": 0, + "stamina": 0, + "torpor": 0, + "oxygen": 0, + "food": 0, + "water": 0, + "temperature": 0, + "weight": 50, + "melee": 0, + "speed": 0, + "fortitude": 0, + "crafting": 0 + } + }, + "[GS] Scarab": { + "wildLevels": { + "health": 16, + "stamina": 12, + "torpor": 0, + "oxygen": 16, + "food": 21, + "water": 0, + "temperature": 0, + "weight": 27, + "melee": 16, + "speed": 16, + "fortitude": 0, + "crafting": 0 + }, + "tamedLevels": { + "health": 0, + "stamina": 0, + "torpor": 0, + "oxygen": 0, + "food": 0, + "water": 0, + "temperature": 0, + "weight": 50, + "melee": 0, + "speed": 0, + "fortitude": 0, + "crafting": 0 + } + }, + "[GS] Snow": { + "wildLevels": { + "health": 26, + "stamina": 14, + "torpor": 0, + "oxygen": 20, + "food": 25, + "water": 0, + "temperature": 0, + "weight": 42, + "melee": 27, + "speed": 15, + "fortitude": 0, + "crafting": 0 + }, + "tamedLevels": { + "health": 0, + "stamina": 0, + "torpor": 0, + "oxygen": 0, + "food": 43, + "water": 0, + "temperature": 0, + "weight": 0, + "melee": 0, + "speed": 0, + "fortitude": 0, + "crafting": 0 + } + }, + "[GS] Stud": { + "wildLevels": { + "health": 24, + "stamina": 22, + "torpor": 0, + "oxygen": 15, + "food": 23, + "water": 0, + "temperature": 0, + "weight": 20, + "melee": 23, + "speed": 24, + "fortitude": 0, + "crafting": 0 + }, + "tamedLevels": { + "health": 0, + "stamina": 0, + "torpor": 0, + "oxygen": 0, + "food": 0, + "water": 0, + "temperature": 0, + "weight": 0, + "melee": 0, + "speed": 0, + "fortitude": 0, + "crafting": 0 + } + }, + "[GS] Sheep Trick": { + "wildLevels": { + "health": 8, + "stamina": 4, + "torpor": 0, + "oxygen": 3, + "food": 5, + "water": 0, + "temperature": 0, + "weight": 4, + "melee": 4, + "speed": 6, + "fortitude": 0, + "crafting": 0 + }, + "tamedLevels": { + "health": 0, + "stamina": 0, + "torpor": 0, + "oxygen": 0, + "food": 26, + "water": 0, + "temperature": 0, + "weight": 16, + "melee": 0, + "speed": 0, + "fortitude": 0, + "crafting": 0 + } + } +} \ No newline at end of file