Updated Dino Class
This commit is contained in:
+192
-131
@@ -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'<Dino name={self.dino_data["TamedName"]}, level={self.dino_data["CharacterLevel"]}, guid={self.guid}>'
|
||||
@@ -177,3 +225,16 @@ class Dino:
|
||||
def __repr__(self):
|
||||
return (f'<Dino species={self.dino_data["DinoNameTag"]} name={self.dino_data["TamedName"]}, '
|
||||
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.')
|
||||
|
||||
Reference in New Issue
Block a user