Updated Dino Class

This commit is contained in:
Dusty.P 2018-05-17 01:14:53 -08:00
parent 978be57ec4
commit 0ce8cd0c7e
3 changed files with 410 additions and 131 deletions

View File

@ -1,115 +1,140 @@
import configparser from configparser import ConfigParser
from . import guid 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: class Color:
def __init__(self, r=0, g=0, b=0, a=0): 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.r = self._hex_to_float(r) if isinstance(r, int) else r
self.g = self.float_to_hex(g) if isinstance(g, float) else g self.g = self._hex_to_float(g) if isinstance(g, int) else g
self.b = self.float_to_hex(b) if isinstance(b, float) else b self.b = self._hex_to_float(b) if isinstance(b, int) else b
self.a = self.float_to_hex(a) if isinstance(a, float) else a 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 @staticmethod
def float_to_hex(a: float): def _float_to_hex(a: float) -> int:
return ((a - 0.0)/(1.0 - 0.0)) * (255 - 0) + 0.0 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: class Dino:
def __init__(self, dino_data=None, parent=False): def __init__(self, dino_data: ConfigParser):
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_orig = dino_data
self.dino_data = self._get_dino_data(dino_data['Dino Data']) if dino_data == ConfigParser():
self.colors = self._get_colors(dino_data['Colorization']) self.dino_data = self._get_dino_data()
self.stats = self._get_colors(dino_data['Max Character Status Values']) self.colors = self._get_colors()
self.ancestry = self._get_ancestry(dino_data['Dino Ancestry'], dino_data) self.stats = self._get_colors()
self.ancestry = self._get_ancestry()
self.guid = self.get_guid() self.guid = self.get_guid()
elif parent is True and isinstance(dino_data, list): elif isinstance(dino_data, ConfigParser):
self.dino_data = { self.dino_data = self._get_dino_data(list(dino_data['Dino Data'].values()))
'TamedName': dino_data[0], self.colors = self._get_colors(list(dino_data['Colorization'].values()))
'DinoID1': dino_data[1], self.stats = self._get_stats(list(dino_data['Max Character Status Values'].values()))
'DinoID2': dino_data[2] self.ancestry = self._get_ancestry(list(dino_data['Dino Ancestry'].values()), dino_data)
}
self.stats = self._zero_stats()
self.colors = list()
self.ancestry = dict()
self.guid = self.get_guid() self.guid = self.get_guid()
else: 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: def get_guid(self) -> guid.Guid:
return guid.Guid(self.dino_data['DinoID1'], self.dino_data['DinoID2']) return guid.Guid(self.dino_data['DinoID1'], self.dino_data['DinoID2'])
@staticmethod @staticmethod
def _get_colors(colorization) -> [Color]: def _get_colors(colorization: list=list()) -> [Color]:
colors = list() colors = list()
for color, values in colorization.items(): if colorization != list():
for values in colorization:
value = values.strip('()').split(',') value = values.strip('()').split(',')
c = dict() c = dict()
for v in value: for v in value:
v = v.split('=') v = v.split('=')
c[v[0]] = float(v[1]) c[v[0].lower()] = float(v[1])
colors.append(Color(**c)) colors.append(Color(**c))
return colors return colors
def _zero_stats(self): @staticmethod
return self._get_stats({i: '0' for i in range(12)}) 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 @staticmethod
def _get_stats(stat_values) -> dict: def _get_dino_data(data: list=list()) -> OrderedDict:
stats = [stat for stat in stat_values.values()] for i, value in enumerate(data):
stats_dict = dict() try:
stats_dict['Health'] = float(stats[0]) data[i] = int(value)
stats_dict['Stamina'] = float(stats[1]) except ValueError:
stats_dict['Torpidity'] = float(stats[2]) try:
stats_dict['Oxygen'] = float(stats[3]) data[i] = float(value)
stats_dict['food'] = float(stats[4]) except ValueError:
stats_dict['Water'] = float(stats[5]) try:
stats_dict['Temperature'] = float(stats[6]) data[i] = bool(strtobool(value))
stats_dict['Weight'] = float(stats[7]) except ValueError:
stats_dict['Melee Damage'] = float(stats[8]) pass
stats_dict['Movement Speed'] = float(stats[9])
stats_dict['Fortitude'] = float(stats[10]) if len(data) < 14:
stats_dict['Crafting Skill'] = float(stats[11]) data.extend([0] * (14 - len(data)))
return stats_dict elif len(data) > 14:
raise InvalidConfig
dino_dict = OrderedDict(zip(config_setup['Dino Data'], data))
return dino_dict
@staticmethod @staticmethod
def _get_dino_data(dino_data) -> dict: def _get_ancestry(ancestry: list=list(), data: ConfigParser=None) -> OrderedDict:
data = [d for d in dino_data.values()] ancestry_dict = OrderedDict()
data_dict = dict() if ancestry != list():
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
@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['DinoAncestorsCount'] = int(ancestry[0])
ancestry_dict['DinoAncestorsMale'] = int(ancestry[1]) ancestry_dict['DinoAncestorsMale'] = int(ancestry[1])
@ -118,58 +143,81 @@ class Dino:
dino_anc = [a for a in data['DinoAncestors'].values()] dino_anc = [a for a in data['DinoAncestors'].values()]
ancestors = list() ancestors = list()
for dino in dino_anc: for dino in dino_anc:
ancestors.append(dict([field.split('=') for field in dino.split(';')])) ancestors.append(OrderedDict([field.split('=') for field in dino.split(';')]))
ancestry_dict['DinoAncestors'] = ancestors ancestry_dict['DinoAncestors_'] = ancestors
if ancestry_dict['DinoAncestorsMale'] != 0: if ancestry_dict['DinoAncestorsMale'] != 0:
if 'DinoAncestorsMale' in data.sections(): if 'DinoAncestorsMale' in data.sections():
dino_anc = [a for a in data['DinoAncestorsMale'].values()] dino_anc = [a for a in data['DinoAncestorsMale'].values()]
ancestors_male = list() ancestors_male = list()
for dino in dino_anc: for dino in dino_anc:
ancestors_male.append(dict([field.split('=') for field in dino.split(';')])) ancestors_male.append(OrderedDict([field.split('=') for field in dino.split(';')]))
ancestry_dict['DinoAncestorsMale'] = ancestors_male ancestry_dict['DinoAncestorsMale_'] = ancestors_male
return ancestry_dict 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: if 'DinoAncestors' in self.ancestry:
parents = self.ancestry['DinoAncestors'][-1] parents = self.ancestry['DinoAncestors'][-1]
father = Dino.from_min_req(parents['MaleName'], father = Parent(name=parents['MaleName'],
parents['MaleDinoID1'], id1=parents['MaleDinoID1'],
parents['MaleDinoID2'], id2=parents['MaleDinoID2'],
True) female=False)
mother = Dino.from_min_req(parents['FemaleName'], mother = Parent(name=parents['FemaleName'],
parents['FemaleDinoID1'], id1=parents['FemaleDinoID1'],
parents['FemaleDinoID2'], id2=parents['FemaleDinoID2'],
True) female=True)
return father, mother return father, mother
else: else:
return Dino.empty(), Dino.empty() return Parent('', True, 0, 0), Parent('', False, 0, 0)
@classmethod
def from_min_req(cls, name, id1, id2, parent=False):
return Dino([name, id1, id2], parent=parent)
@classmethod @classmethod
def empty(cls): def empty(cls):
return Dino() return Dino(ConfigParser())
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, Dino): if self.__class__ == other.__class__:
if self.guid == other.guid: if self.guid == other.guid:
return self.dino_data == other.dino_data and self.stats == other.stats return self.dino_data == other.dino_data and self.stats == other.stats
return False 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
def __str__(self): def __str__(self):
return f'<Dino name={self.dino_data["TamedName"]}, level={self.dino_data["CharacterLevel"]}, guid={self.guid}>' return f'<Dino name={self.dino_data["TamedName"]}, level={self.dino_data["CharacterLevel"]}, guid={self.guid}>'
@ -177,3 +225,16 @@ class Dino:
def __repr__(self): def __repr__(self):
return (f'<Dino species={self.dino_data["DinoNameTag"]} name={self.dino_data["TamedName"]}, ' return (f'<Dino species={self.dino_data["DinoNameTag"]} name={self.dino_data["TamedName"]}, '
f'level={self.dino_data["CharacterLevel"]}, guid={self.guid}>') f'level={self.dino_data["CharacterLevel"]}, guid={self.guid}>')
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.')

View File

@ -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

View File

@ -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
}
}
}