class ItemDAO(DAO, IItemDAO): DATABASE_TABLE = 'Item' TYPE = ObjectType.ITEM def __init__(self): self.database = ObjectDatabase(self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, item: Item, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new Item, depend on item type, insert correct data Items types: Item, Armor, Container, MeleeWeapon, ThrowableWeapon, RangedWeapon, Money :param item: Item object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created item """ if not contextType: contextType = self.TYPE strValues = { 'name' : item.name, 'description': item.description } intValues = { 'amount': item.amount, 'price' : item.price, 'type' : item.type.value if item.type else None, 'weight': item.weight } if isinstance(item, Armor): intValues.update({ 'quality': item.quality, 'weightA': item.weightA, 'weightB': item.weightB, 'weightC': item.weightC, 'size' : item.size.value if item.size else None, }) elif isinstance(item, Container): intValues.update({ 'capacity' : item.capacity, 'parent_id': item.parent_id }) elif isinstance(item, MeleeWeapon): intValues.update({ 'strength' : item.strength, 'rampancy' : item.rampancy, 'defence' : item.defence, 'length' : item.length, 'initiative' : item.initiative, 'handling' : item.handling.value if item.handling else None, 'weaponWeight': item.weaponWeight.value if item.weaponWeight else None, 'racial' : item.racial.value if item.racial else None }) elif isinstance(item, Money): intValues.update({ 'copper': item.copper, 'silver': item.silver, 'gold' : item.gold }) elif isinstance(item, RangeWeapon): intValues.update({ 'initiative' : item.initiative, 'strength' : item.strength, 'rampancy' : item.rampancy, 'rangeLow' : item.rangeLow, 'rangeMedium' : item.rangeMedium, 'rangeHigh' : item.rangeHigh, 'weaponWeight': item.weaponWeight.value if item.weaponWeight else None, 'racial' : item.racial.value if item.racial else None }) elif isinstance(item, ThrowableWeapon): intValues.update({ 'initiative' : item.initiative, 'strength' : item.strength, 'rampancy' : item.rampancy, 'rangeLow' : item.rangeLow, 'rangeMedium' : item.rangeMedium, 'rangeHigh' : item.rangeHigh, 'defence' : item.defence, 'weaponWeight': item.weaponWeight.value if item.weaponWeight else None, 'racial' : item.racial.value if item.racial else None }) id = self.database.insert(self.DATABASE_TABLE, intValues) item.id = id self.database.insert_translate(strValues, item.lang, id, self.TYPE) # Create node for tree structure node = NodeObject(None, item.name, nodeParentId, item) nodeId = self.treeDAO.insert_node(node, contextType) for effect in item.effects: EffectDAO().create(effect, nodeId, contextType) if isinstance(item, Container): for one in item.containers + item.armors + item.moneyList + item.meleeWeapons + item.rangedWeapons + item.throwableWeapons + item.items: self.create(one, nodeId, contextType) return id def update(self, item: Item): """ Update item in database :param item: Item object with new data """ strValues = { 'name' : item.name, 'description': item.description } intValues = { 'amount': item.amount, 'price' : item.price, 'type' : item.type.value if item.type else None, 'weight': item.weight } if isinstance(item, Armor): intValues.update({ 'quality': item.quality, 'weightA': item.weightA, 'weightB': item.weightB, 'weightC': item.weightC, 'size' : item.size.value if item.size else None, }) elif isinstance(item, Container): intValues.update({ 'capacity': item.capacity, }) elif isinstance(item, MeleeWeapon): intValues.update({ 'strength' : item.strength, 'rampancy' : item.rampancy, 'defence' : item.defence, 'length' : item.length, 'initiative' : item.initiative, 'handling' : item.handling.value if item.handling else None, 'weaponWeight': item.weaponWeight.value if item.weaponWeight else None, 'racial' : item.racial.value if item.racial else None }) elif isinstance(item, Money): intValues.update({ 'copper': item.copper, 'silver': item.silver, 'gold' : item.gold }) elif isinstance(item, RangeWeapon): intValues.update({ 'initiative' : item.initiative, 'strength' : item.strength, 'rampancy' : item.rampancy, 'rangeLow' : item.rangeLow, 'rangeMedium' : item.rangeMedium, 'rangeHigh' : item.rangeHigh, 'weaponWeight': item.weaponWeight.value if item.weaponWeight else None, 'racial' : item.racial.value if item.racial else None }) elif isinstance(item, ThrowableWeapon): intValues.update({ 'initiative' : item.initiative, 'strength' : item.strength, 'rampancy' : item.rampancy, 'rangeLow' : item.rangeLow, 'rangeMedium' : item.rangeMedium, 'rangeHigh' : item.rangeHigh, 'defence' : item.defence, 'weaponWeight': item.weaponWeight.value if item.weaponWeight else None, 'racial' : item.racial.value if item.racial else None }) self.database.update(self.DATABASE_TABLE, item.id, intValues) self.database.update_translate(strValues, item.lang, item.id, self.TYPE) def delete(self, item_id: int): """ Delete Item from database and from translate :param item_id: id of Item """ self.database.delete(self.DATABASE_TABLE, item_id) self.database.delete_where('translates', {'target_id': item_id, 'type': ObjectType.ITEM}) def get_all(self, lang=None) -> list: """ Get list of items for selected lang :param lang: lang of items :return: list of items """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all('Item') items = [] for line in lines: item = self.get(line['ID'], lang) items.append(item) return items def get(self, item_id: int, lang=None, nodeId: int = None, contextType: ObjectType = None) -> Item: """ Get Item , object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all sub objects) If not specified, only basic attributes are set. Returned correct type of item, depend on database, possible classes are: Item, Container, Armor, Money, MeleeWeapon, RangedWeapon, ThrowableWeapon :param item_id: id of Item :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Item object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.database.select(self.DATABASE_TABLE, {'ID': item_id}) if not data: return None else: data = dict(data[0]) tr_data = dict(self.database.select_translate(item_id, ObjectType.ITEM.value, lang)) if data['type'] == Items.CONTAINER.value: item = Container(item_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), data.get('parent_id', 0), data.get('weight', 0), data.get('price', 0), data.get('capacity', 0), data.get('amount', 1)) elif data['type'] == Items.MELEE_WEAPON.value: weaponWeightIndex = data.get('weaponWeight', None) weaponWeight = WeaponWeight(weaponWeightIndex) if weaponWeightIndex else None handlingIndex = data.get('handling', None) handling = Handling(handlingIndex) if handlingIndex else None racialIndex = data.get('racial', None) racial = Races(racialIndex) if racialIndex else None item = MeleeWeapon(item_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), data.get('parent_id', 0), data.get('weight', 0), data.get('price', 0), data.get('strength', 0), data.get('rampancy', 0), data.get('defence', 0), data.get('length', 0), weaponWeight, handling, data.get('amount', 1), data.get('initiative', 0), racial) elif data['type'] == Items.THROWABLE_WEAPON.value: weaponWeightIndex = data.get('weaponWeight', None) weaponWeight = WeaponWeight(weaponWeightIndex) if weaponWeightIndex else None racialIndex = data.get('racial', None) racial = Races(racialIndex) if racialIndex else None item = ThrowableWeapon(item_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), data.get('parent_id', 0), data.get('weight', 0), data.get('price', 0), data.get('initiative', 0), data.get('strength', 0), data.get('rampancy', 0), data.get('rangeLow', 0), data.get('rangeMedium', 0), data.get('rangeHigh', 0), data.get('defence', 0), weaponWeight, data.get('amount', 1), racial) elif data['type'] == Items.RANGED_WEAPON.value: weaponWeightIndex = data.get('weaponWeight', None) weaponWeight = WeaponWeight(weaponWeightIndex) if weaponWeightIndex else None racialIndex = data.get('racial', None) racial = Races(racialIndex) if racialIndex else None item = RangeWeapon(item_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), data.get('parent_id', 0), data.get('weight', 0), data.get('price', 0), data.get('initiative', 0), data.get('strength', 0), data.get('rampancy', 0), data.get('rangeLow', 0), data.get('rangeMedium', 0), data.get('rangeHigh', 0), data.get('amount', 1), weaponWeight, racial) elif data['type'] == Items.ARMOR.value: sizeIndex = data.get('size', None) size = ArmorSize(sizeIndex) if sizeIndex else None item = Armor(item_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), data.get('parent_id', 0), data.get('price', 0), data.get('quality', 0), data.get('weightA', 0), data.get('weightB', 0), data.get('weightC', 0), size, data.get('amount', 1)) elif data['type'] == Items.MONEY.value: item = Money(item_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), data.get('parent_id', 0), data.get('copper'), data.get('silver'), data.get('gold'), data.get('amount', 1)) else: item = Item(item_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), data.get('parent_id', 0), data.get('weight', 0), data.get('price', 0), data.get('amount', 1)) if nodeId and contextType: objects = PlayerTreeDAO().get_children_objects(nodeId, contextType) effects = [] armors = [] containers = [] items = [] moneys = [] meleeWeapons = [] rangedWeapons = [] throwableWeapons = [] for one in objects: if one.object.object_type is ObjectType.ITEM and data['type'] == Items.CONTAINER.value: childItem = self.get(one.object.id, None, one.id, contextType) if isinstance(childItem, Armor): armors.append(childItem) elif isinstance(childItem, Container): containers.append(childItem) elif isinstance(childItem, Money): moneys.append(childItem) elif isinstance(childItem, MeleeWeapon): meleeWeapons.append(childItem) elif isinstance(childItem, RangeWeapon): rangedWeapons.append(childItem) elif isinstance(childItem, ThrowableWeapon): throwableWeapons.append(childItem) else: items.append(childItem) elif one.object.object_type is ObjectType.EFFECT: effect = EffectDAO().get(one.object.id, None, one.id, contextType) effects.append(effect) if data['type'] is Items.CONTAINER.value: item.items = items item.armors = armors item.moneyList = moneys item.meleeWeapons = meleeWeapons item.rangedWeapons = rangedWeapons item.throwableWeapons = throwableWeapons item.containers = containers item.effects = effects return item
class MonsterDAO(DAO, IMonsterDAO): DATABASE_TABLE = 'Monster' TYPE = ObjectType.MONSTER def __init__(self): self.database = ObjectDatabase(self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, monster: Monster, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new Monster :param monster: Modifier object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created monster """ if not contextType: contextType = self.TYPE intValues = { 'defense' : monster.defense, 'endurance' : monster.endurance, 'rampancy' : monster.rampancy, 'mobility' : monster.mobility, 'perseverance': monster.perseverance, 'intelligence': monster.intelligence, 'charisma' : monster.charisma, 'experience' : monster.experience, 'hp' : monster.hp, 'alignment' : monster.alignment.value if monster.alignment else None, 'monsterRace' : monster.monsterRace.value if monster.monsterRace else None, 'size' : monster.size.value if monster.size else None, } strValues = { 'name' : monster.name, 'description': monster.description, 'offense' : monster.offense, 'viability' : monster.viability, } id = self.database.insert(self.DATABASE_TABLE, intValues) monster.id = id self.database.insert_translate(strValues, monster.lang, id, self.TYPE) # Create node for tree structure node = NodeObject(None, monster.name, nodeParentId, monster) nodeId = self.treeDAO.insert_node(node, contextType) for one in monster.containers + monster.armors + monster.moneyList + monster.meleeWeapons + monster.rangedWeapons + monster.throwableWeapons + monster.items: ItemDAO().create(one, nodeId, contextType) for spell in monster.spells: SpellDAO().create(spell, nodeId, contextType) for ability in monster.abilities: AbilityDAO().create(ability, nodeId, contextType) return id def update(self, monster: Monster): """ Update monster in database :param monster: Monster object with new data """ intValues = { 'defense' : monster.defense, 'endurance' : monster.endurance, 'rampancy' : monster.rampancy, 'mobility' : monster.mobility, 'perseverance': monster.perseverance, 'intelligence': monster.intelligence, 'charisma' : monster.charisma, 'experience' : monster.experience, 'hp' : monster.hp, 'alignment' : monster.alignment.value if monster.alignment else None, 'monsterRace' : monster.monsterRace.value if monster.monsterRace else None, 'size' : monster.size.value if monster.size else None, } strValues = { 'name' : monster.name, 'description': monster.description, 'offense' : monster.offense, 'viability' : monster.viability, } self.database.update(self.DATABASE_TABLE, monster.id, intValues) self.database.update_translate(strValues, monster.lang, monster.id, self.TYPE) def delete(self, monster_id: int): """ Delete Monster from database and all his translates :param monster_id: id of Monster """ self.database.delete(self.DATABASE_TABLE, monster_id) self.database.delete_where('translates', {'target_id': monster_id, 'type': ObjectType.SPELL}) def get(self, monster_id: int, lang: str = None, nodeId: int = None, contextType: ObjectType = None) -> Monster: """ Get Monster , object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all sub objects) If not specified, only basic attributes are set. :param monster_id: id of Monster :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Monster object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.database.select(self.DATABASE_TABLE, {'ID': monster_id}) if not data: return None else: data = dict(data[0]) tr_data = self.database.select_translate(monster_id, ObjectType.MONSTER.value, lang) monsterRace = MonsterRace(data['monsterRace']) if data['monsterRace'] else None monsterSize = MonsterSize(data['size']) if data['size'] else None alignment = Alignment(data['alignment']) if data['alignment'] else None monster = Monster(data['ID'], lang, tr_data.get('name', ''), tr_data.get('description', ''), tr_data.get('viability', 0), tr_data.get('offense', ''), data.get('defense', 0), data.get('endurance', 0), data.get('rampancy', 0), data.get('mobility', 0), data.get('perseverance', 0), data.get('intelligence', 0), data.get('charisma', 0), alignment, data.get('experience', 0), data.get('hp', 0), monsterRace, monsterSize) if nodeId and contextType: children = self.treeDAO.get_children_objects(nodeId, contextType) abilities = [] spells = [] items = [] armors = [] moneys = [] containers = [] meleeWeapons = [] rangedWeapons = [] throwableWeapons = [] for child in children: if child.object.object_type is ObjectType.SPELL: spell = SpellDAO().get(child.object.id, None, child.id, contextType) spells.append(spell) elif child.object.object_type is ObjectType.ABILITY: ability = AbilityDAO().get(child.object.id, None, child.id, contextType) abilities.append(ability) elif child.object.object_type is ObjectType.ITEM: childItem = ItemDAO().get(child.object.id, None, child.id, contextType) if isinstance(childItem, Armor): armors.append(childItem) elif isinstance(childItem, Container): containers.append(childItem) elif isinstance(childItem, Money): moneys.append(childItem) elif isinstance(childItem, MeleeWeapon): meleeWeapons.append(childItem) elif isinstance(childItem, RangeWeapon): rangedWeapons.append(childItem) elif isinstance(childItem, ThrowableWeapon): throwableWeapons.append(childItem) else: items.append(childItem) monster.abilities = abilities monster.spells = spells monster.items = items monster.armors = armors monster.moneyList = moneys monster.containers = containers monster.meleeWeapons = meleeWeapons monster.rangedWeapons = rangedWeapons monster.throwableWeapons = throwableWeapons return monster def get_all(self, lang=None) -> list: """ Get list of Monsters for selected lang :param lang: lang of Monsters :return: list of Monsters """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all(self.DATABASE_TABLE) items = [] for line in lines: item = self.get(line['ID'], lang) items.append(item) return items
def create_tables(self, databaseName: str = "file::memory:?cache=shared"): """ Try to create all tables in database :return: """ database = ObjectDatabase(databaseName) # /////////////////////////////////// Languages \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ languages_columns = [ Column('ID', 'INTEGER', True, False, True), Column('name', 'TEXT', False, False, False, True), Column('code', 'TEXT', False, True, False, True), ] try: database.create_table('languages', languages_columns) except OperationalError: pass # /////////////////////////////// Translate \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ translate_columns = [ Column('ID', 'INTEGER', True, False, True), Column('target_id', 'INTEGER', not_null=True), Column('lang', 'TEXT'), Column('type', 'INTEGER', not_null=True), Column('name', 'TEXT', not_null=True), Column('value', 'TEXT') ] translate_foreign = [Foreign('lang', 'languages', 'code')] try: database.create_table('translates', translate_columns, translate_foreign) except OperationalError: pass # //////////////////////////// Items \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ item_columns = [ Column('ID', 'INTEGER', True, False, True), Column('parent_id', 'INTEGER'), Column('type', 'INTEGER', not_null=True), Column('price', 'INTEGER'), Column('weight', 'INTEGER'), Column('capacity', 'INTEGER'), Column('quality', 'INTEGER'), Column('size', 'INTEGER'), Column('copper', 'INTEGER'), Column('silver', 'INTEGER'), Column('gold', 'INTEGER'), Column('weightA', 'INTEGER'), Column('weightB', 'INTEGER'), Column('weightC', 'INTEGER'), Column('strength', 'INTEGER'), Column('rampancy', 'INTEGER'), Column('length', 'INTEGER'), Column('defence', 'INTEGER'), Column('initiative', 'INTEGER'), Column('rangeLow', 'INTEGER'), Column('rangeMedium', 'INTEGER'), Column('rangeHigh', 'INTEGER'), Column('weaponWeight', 'INTEGER'), Column('handling', 'INTEGER'), Column('amount', 'INTEGER'), Column('racial', 'INTEGER'), ] try: database.create_table('Item', item_columns) except OperationalError: pass # //////////////////////////// Ability \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ability_columns = [ Column('ID', 'INTEGER', True, False, True), Column('drd_race', 'INTEGER'), Column('drd_class', 'INTEGER'), Column('level', 'INTEGER'), ] try: database.create_table('Ability', ability_columns) except OperationalError: pass # //////////////////////////// Ability context \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ability_context_columns = [ Column('ID', 'INTEGER', True, False, True), Column('value', 'INTEGER'), Column('valueType', 'INTEGER'), Column('targetAttribute', 'INTEGER'), ] try: database.create_table('AbilityContext', ability_context_columns) except OperationalError: pass # //////////////////////////// Spell \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ spell_columns = [ Column('ID', 'INTEGER', True, False, True), Column('cast_time', 'INTEGER'), Column('drd_class', 'INTEGER') ] try: database.create_table('Spell', spell_columns) except OperationalError: pass # //////////////////////////// Modifier \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ modifier_columns = [ Column('ID', 'INTEGER', True, False, True), Column('value', 'INTEGER'), Column('valueType', 'INTEGER'), Column('targetType', 'INTEGER'), Column('characterTargetAttribute', 'INTEGER'), Column('itemTargetAttribute', 'INTEGER') ] try: database.create_table('Modifier', modifier_columns) except OperationalError: pass # //////////////////////////// Effect \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ modifier_columns = [ Column('ID', 'INTEGER', True, False, True), Column('targetType', 'INTEGER'), Column('active', 'INTEGER'), ] try: database.create_table('Effect', modifier_columns) except OperationalError: pass # //////////////////////////// Character \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ character_columns = [ Column('ID', 'INTEGER', True, False, True), Column('age', 'INTEGER'), Column('agility', 'INTEGER'), Column('charisma', 'INTEGER'), Column('height', 'INTEGER'), Column('intelligence', 'INTEGER'), Column('level', 'INTEGER'), Column('mobility', 'INTEGER'), Column('strength', 'INTEGER'), Column('toughness', 'INTEGER'), Column('weight', 'INTEGER'), Column('xp', 'INTEGER'), Column('maxHealth', 'INTEGER'), Column('maxMana', 'INTEGER'), Column('drdRace', 'INTEGER'), Column('drdClass', 'INTEGER'), Column('alignment', 'INTEGER'), Column('currentMana', 'INTEGER'), Column('currentHealth', 'INTEGER'), Column('inventoryId', 'INTEGER'), Column('groundId', 'INTEGER'), ] try: database.create_table('Character', character_columns) except OperationalError: pass # //////////////////////////// Party character \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ party_character_columns = [ Column('ID', 'INTEGER', True, False, True), Column('deviceName', 'TEXT'), Column('MACAddress', 'TEXT'), Column('character_id', 'INTEGER'), Column('scenario_id', 'INTEGER'), Column('name', 'TEXT'), ] try: database.create_table('PartyCharacter', party_character_columns) except OperationalError: pass # //////////////////////////// Messages \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ message_columns = [ Column('ID', 'INTEGER', True, False, True), Column('text', 'TEXT'), Column('date', 'INTEGER'), Column('isMine', 'INTEGER'), Column('partyCharacterId', 'INTEGER'), Column('characterId', 'INTEGER'), ] try: database.create_table('Message', message_columns) except OperationalError: pass # //////////////////////////// Monster \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ monster_columns = [ Column('ID', 'INTEGER', True, False, True), Column('defense', 'INTEGER'), Column('endurance', 'INTEGER'), Column('rampancy', 'INTEGER'), Column('mobility', 'INTEGER'), Column('viability', 'INTEGER'), Column('perseverance', 'INTEGER'), Column('intelligence', 'INTEGER'), Column('charisma', 'INTEGER'), Column('alignment', 'INTEGER'), Column('experience', 'INTEGER'), Column('hp', 'INTEGER'), Column('monsterRace', 'INTEGER'), Column('size', 'INTEGER'), ] try: database.create_table('Monster', monster_columns) except OperationalError: pass # //////////////////////////// Scenario \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ scenario_columns = [ Column('ID', 'INTEGER', True, False, True), Column('date', 'INTEGER'), ] try: database.create_table('Scenario', scenario_columns) except OperationalError: pass # //////////////////////////// Location \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ location_columns = [ Column('ID', 'INTEGER', True, False, True), ] try: database.create_table('Location', location_columns) except OperationalError: pass # //////////////////////////// Player tree structure \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ structure_columns = [ Column('ID', 'INTEGER', True, False, True), Column('target_id', 'INTEGER'), Column('target_type', 'INTEGER'), Column('parent_id', 'INTEGER'), Column('parent_type', 'INTEGER', not_null=True), Column('type', 'INTEGER', not_null=True), Column('name', 'TEXT') ] structure_foreigns = [ Foreign('parent_id', 'player_tree_structure', 'ID', 'CASCADE') ] try: database.create_table('player_tree_structure', structure_columns, structure_foreigns) except OperationalError: pass # //////////////////////////// Map \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ mapColumns = [ Column('ID', 'INTEGER', True, False, True), Column('name', 'TEXT'), Column('description', 'TEXT'), Column('map_file', 'TEXT'), ] try: database.create_table('Map', mapColumns) except OperationalError: pass # //////////////////////////// MapItem \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ mapItemColumns = [ Column('ID', 'INTEGER', True, False, True), Column('name', 'TEXT'), Column('description', 'TEXT'), Column('positionX', 'REAL'), Column('positionY', 'REAL'), Column('scale', 'INTEGER'), Column('object_type', 'INTEGER'), Column('object_id', 'INTEGER'), Column('number', 'INTEGER'), Column('map_id', 'INTEGER'), Column('itemType', 'INTEGER') ] mapItemForeigns = [Foreign('map_id', 'Map', 'ID', 'CASCADE')] try: database.create_table('Map_item', mapItemColumns, mapItemForeigns) except OperationalError: pass # //////////////////////////// Settings \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ settingsColumns = [ Column('ID', 'INTEGER', True, False, True), Column('name', 'TEXT', not_null=True), Column('int_value', 'INTEGER'), Column('str_value', 'TEXT'), ] try: database.create_table('Settings', settingsColumns) except OperationalError: pass # //////////////////////////// Initialize Languages \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ data = database.select('languages', {'code': 'cs'}) if len(data) == 0: database.insert('languages', {'name': 'Čeština', 'code': 'cs'}) database.insert('languages', {'name': 'Angličtina', 'code': 'en'}) database.insert('Settings', {'name': 'language', 'str_value': 'cs'})
class LocationDAO(DAO, ILocationDAO): DATABASE_TABLE = 'Location' TYPE = ObjectType.LOCATION def __init__(self): self.database = ObjectDatabase(self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, location: Location, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new location :param location: Location object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created location """ if not contextType: contextType = self.TYPE strValues = { 'name': location.name, 'description': location.description } id = self.database.insert_null(self.DATABASE_TABLE) location.id = id self.database.insert_translate(strValues, location.lang, id, self.TYPE) # Create node for tree structure node = NodeObject(None, location.name, nodeParentId, location) nodeId = self.treeDAO.insert_node(node, contextType) for one in location.containers + location.armors + location.moneyList + location.meleeWeapons + location.rangedWeapons + location.throwableWeapons + location.items: ItemDAO().create(one, nodeId, contextType) for monster in location.monsters: MonsterDAO().create(monster, nodeId, contextType) for one in location.locations: self.create(one, nodeId, contextType) for character in location.characters: CharacterDAO().create(character, nodeId, contextType) return id def update(self, location: Location): """ Update location in database :param location: Location object with new data """ strValues = { 'name': location.name, 'description': location.description } self.database.update_translate(strValues, location.lang, location.id, self.TYPE) def delete(self, location_id: int): """ Delete Location from database and from translate :param location_id: id of Location """ self.database.delete(self.DATABASE_TABLE, location_id) self.database.delete_where('translates', { 'target_id': location_id, 'type': self.TYPE }) def get(self, location_id: int, lang: str = None, nodeId: int = None, contextType: ObjectType = None) -> Location: """ Get Location , object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all sub objects) If not specified, only basic attributes are set. :param location_id: id of Location :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Location object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.database.select(self.DATABASE_TABLE, {'ID': location_id}) if not data: return None else: data = dict(data[0]) tr_data = dict( self.database.select_translate(location_id, self.TYPE.value, lang)) location = Location(data.get('ID'), lang, tr_data.get('name', ''), tr_data.get('description', '')) if nodeId and contextType: children = self.treeDAO.get_children_objects(nodeId, contextType) locations = [] monsters = [] characters = [] items = [] armors = [] moneys = [] containers = [] meleeWeapons = [] rangedWeapons = [] throwableWeapons = [] maps = [] for child in children: if child.object.object_type is ObjectType.LOCATION: childLocation = self.get(child.object.id, None, child.id, contextType) locations.append(childLocation) elif child.object.object_type is ObjectType.MONSTER: monster = MonsterDAO().get(child.object.id, None, child.id, contextType) monsters.append(monster) elif child.object.object_type is ObjectType.CHARACTER: character = CharacterDAO().get(child.object.id, None, child.id, contextType) characters.append(character) elif child.object.object_type is ObjectType.MAP: map = MapDAO().get(child.object.id) maps.append(map) elif child.object.object_type is ObjectType.ITEM: childItem = ItemDAO().get(child.object.id, None, child.id, contextType) if isinstance(childItem, Armor): armors.append(childItem) elif isinstance(childItem, Container): containers.append(childItem) elif isinstance(childItem, Money): moneys.append(childItem) elif isinstance(childItem, MeleeWeapon): meleeWeapons.append(childItem) elif isinstance(childItem, RangeWeapon): rangedWeapons.append(childItem) elif isinstance(childItem, ThrowableWeapon): throwableWeapons.append(childItem) else: items.append(childItem) location.items = items location.armors = armors location.moneyList = moneys location.containers = containers location.meleeWeapons = meleeWeapons location.rangedWeapons = rangedWeapons location.throwableWeapons = throwableWeapons location.locations = locations location.monsters = monsters location.characters = characters location.maps = maps return location def get_all(self, lang=None) -> list: """ Get list of locations for selected lang :param lang: lang of locations :return: list of locations """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all(self.DATABASE_TABLE) items = [] for line in lines: item = self.get(line['ID'], lang) items.append(item) return items
class EffectDAO(DAO, IEffectDAO): DATABASE_TABLE = 'Effect' TYPE = ObjectType.EFFECT def __init__(self): self.database = ObjectDatabase(self.DATABASE_DRIVER) # self.obj_database = ObjectDatabase(self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, effect: Effect, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new effect :param effect: Effect object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created effect """ if not contextType: contextType = self.TYPE if type(effect.active) is str: active = True if effect.active == 'true' else False else: active = effect.active intValues = { 'targetType': effect.targetType.value if effect.targetType else None, 'active': int(active) if active else 0 } strValues = {'name': effect.name, 'description': effect.description} id = self.database.insert(self.DATABASE_TABLE, intValues) effect.id = id self.database.insert_translate(strValues, effect.lang, id, self.TYPE) # Create node for tree structure node = NodeObject(None, effect.name, nodeParentId, effect) nodeId = self.treeDAO.insert_node(node, contextType) for modifier in effect.modifiers: ModifierDAO().create(modifier, nodeId, contextType) return id def update(self, effect: Effect) -> None: """ Update effect in database :param effect: Effect object with new data """ if type(effect.active) is str: active = True if effect.active == 'true' else False else: active = effect.active intValues = { 'targetType': effect.targetType.value if effect.targetType else None, 'active': int(active) if active else 0, } strValues = {'name': effect.name, 'description': effect.description} self.database.update(self.DATABASE_TABLE, effect.id, intValues) self.database.update_translate(strValues, effect.lang, effect.id, self.TYPE) def delete(self, effect_id: int) -> None: """ Delete Effect from database and from translate :param effect_id: id of effect """ self.database.delete(self.DATABASE_TABLE, effect_id) self.database.delete_where('translates', { 'target_id': effect_id, 'type': ObjectType.EFFECT }) def get(self, effect_id: int, lang: str = None, nodeId: int = None, contextType: ObjectType = None) -> Effect: """ Get Effect , object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all sub objects) If not specified, only basic attributes are set. :param effect_id: id of Effect :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Effect object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.database.select(self.DATABASE_TABLE, {'ID': effect_id}) if not data: return None else: data = dict(data[0]) tr_data = self.database.select_translate(effect_id, self.TYPE.value, lang) index = data.get('targetType', 1) if data.get('targetType', 1) is not None else 1 targetType = ModifierTargetTypes(index) effect = Effect(effect_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), targetType, bool(data.get('active', 0))) if nodeId and contextType: children = self.treeDAO.get_children_objects(nodeId, contextType) modifiers = [] for child in children: if child.object.object_type is ObjectType.MODIFIER: modifiers.append(ModifierDAO().get(child.object.id, None, child.id, contextType)) effect.modifiers = modifiers return effect def get_all(self, lang=None) -> list: """ Get list of effects for selected lang :param lang: lang of effects :return: list of effects """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all(self.DATABASE_TABLE) effects = [] for line in lines: character = self.get(line['ID'], lang) effects.append(character) return effects
class ScenarioDAO(DAO, IScenarioDAO): DATABASE_TABLE = 'Scenario' TYPE = ObjectType.SCENARIO def __init__(self): self.database = ObjectDatabase(self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, scenario: Scenario, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new scenario :param scenario: Scenario object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created Scenario """ if not contextType: contextType = self.TYPE if isinstance(scenario.date, dd.date): curDate = scenario.date else: curDate = datetime.strptime(scenario.date, '%d/%m/%Y') if scenario.date else None intValues = {'date': curDate.toordinal() if curDate else None} strValues = { 'name': scenario.name, 'description': scenario.description } id = self.database.insert(self.DATABASE_TABLE, intValues) scenario.id = id self.database.insert_translate(strValues, scenario.lang, id, self.TYPE) # Create node for tree structure node = NodeObject(None, scenario.name, nodeParentId, scenario) nodeId = self.treeDAO.insert_node(node, contextType) for location in scenario.locations: LocationDAO().create(location, nodeId, contextType) for spell in scenario.spells: SpellDAO().create(spell, nodeId, contextType) for ability in scenario.abilities: AbilityDAO().create(ability, nodeId, contextType) for effect in scenario.effects: EffectDAO().create(effect, nodeId, contextType) for character in scenario.party: PartyCharacterDAO().create(character, nodeId, contextType) return id def update(self, scenario: Scenario): """ Update scenario in database :param scenario: Scenario object with new data """ intValues = { 'date': scenario.date.toordinal() if scenario.date else None } strValues = { 'name': scenario.name, 'description': scenario.description } self.database.update(self.DATABASE_TABLE, scenario.id, intValues) self.database.update_translate(strValues, scenario.lang, scenario.id, self.TYPE) def delete(self, scenario_id: int): """ Delete Scenario from database and all his translates :param scenario_id: id of Scenario """ self.database.delete(self.DATABASE_TABLE, scenario_id) self.database.delete_where('translates', { 'target_id': scenario_id, 'type': ObjectType.SCENARIO }) def get(self, scenario_id: int, lang: str = None, nodeId: int = None, contextType: ObjectType = None) -> Scenario: """ Get Scenario , object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all sub objects) If not specified, only basic attributes are set. :param scenario_id: id of Scenario :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Scenario object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.database.select(self.DATABASE_TABLE, {'ID': scenario_id}) if not data: return None else: data = dict(data[0]) tr_data = dict( self.database.select_translate(scenario_id, self.TYPE.value, lang)) scenarioDate = date.fromordinal( data.get('date')) if data.get('date') else None scenario = Scenario(data.get('ID'), lang, tr_data.get('name', ''), tr_data.get('description', ''), scenarioDate) if nodeId and contextType: children = self.treeDAO.get_children_objects(nodeId, contextType) abilities = [] spells = [] effects = [] locations = [] partyCharacters = [] for child in children: if child.object.object_type is ObjectType.ABILITY: ability = AbilityDAO().get(child.object.id, None, child.id, contextType) abilities.append(ability) elif child.object.object_type is ObjectType.SPELL: spell = SpellDAO().get(child.object.id, None, child.id, contextType) spells.append(spell) elif child.object.object_type is ObjectType.EFFECT: effect = EffectDAO().get(child.object.id, None, child.id, contextType) effects.append(effect) elif child.object.object_type is ObjectType.LOCATION: location = LocationDAO().get(child.object.id, None, child.id, contextType) locations.append(location) elif child.object.object_type is ObjectType.CHARACTER: character = CharacterDAO().get(child.object.id, None, child.id, contextType) partyCharacter = PartyCharacterDAO().get(character.id) if not partyCharacter: partyCharacter = PartyCharacter() partyCharacter.character = character partyCharacters.append(partyCharacter) # Search non connected party character chars = self.database.select('PartyCharacter', {'scenario_id': scenario_id}) for char in chars: if char['character_id'] is None: partyCharacters.append(PartyCharacterDAO().get_by_id( char['ID'])) scenario.spells = spells scenario.abilities = abilities scenario.effects = effects scenario.locations = locations scenario.party = partyCharacters return scenario def get_all(self, lang=None) -> list: """ Get list of Scenario for selected lang :param lang: lang of Scenario :return: list of Scenario """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all(self.DATABASE_TABLE) items = [] for line in lines: item = self.get(line['ID'], lang) items.append(item) return items
class AbilityDAO(DAO, IAbilityDAO): DATABASE_TABLE = 'Ability' TYPE = ObjectType.ABILITY def __init__(self, databaseDriver: str = None): self.database = ObjectDatabase( databaseDriver if databaseDriver else self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, ability: Ability, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new ability :param ability: Ability object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created ability """ if not contextType: contextType = self.TYPE intValues = { 'drd_race': ability.drd_race.value if ability.drd_race else None, 'drd_class': ability.drd_class.value if ability.drd_class else None, 'level': ability.level } strValues = { 'name': ability.name, 'description': ability.description, 'chance': ability.chance } id = self.database.insert(self.DATABASE_TABLE, intValues) ability.id = id self.database.insert_translate(strValues, ability.lang, id, self.TYPE) # Create node for tree structure node = NodeObject(None, ability.name, nodeParentId, ability) nodeId = self.treeDAO.insert_node(node, contextType) for context in ability.contexts: AbilityContextDAO().create(context, nodeId, contextType) return id def update(self, ability: Ability): """ Update ability in database :param ability: Ability object with new data """ intValues = { 'drd_race': ability.drd_race.value if ability.drd_race else None, 'drd_class': ability.drd_class.value if ability.drd_class else None, 'level': ability.level } strValues = { 'name': ability.name, 'description': ability.description, 'chance': ability.chance } self.database.update(self.DATABASE_TABLE, ability.id, intValues) self.database.update_translate(strValues, ability.lang, ability.id, self.TYPE) def delete(self, ability_id: int): """ Delete ability from database and from translate :param ability_id: id of ability """ self.database.delete(self.DATABASE_TABLE, ability_id) self.database.delete_where('translates', { 'target_id': ability_id, 'type': ObjectType.ABILITY }) def get(self, ability_id: int, lang=None, nodeId: int = None, contextType: ObjectType = None) -> Ability: """ Get ability , object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all sub objects) If not specified, only basic attributes are set. :param ability_id: id of ability :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Ability object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.database.select(self.DATABASE_TABLE, {'ID': ability_id}) if not data: return None else: data = dict(data[0]) tr_data = self.database.select_translate(ability_id, ObjectType.ABILITY.value, lang) drd_class = Classes(data.get('drd_class')) if data.get( 'drd_class') is not None else None drd_race = Races( data.get('drd_race')) if data.get('drd_race') is not None else None ability = Ability(ability_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), tr_data.get('chance', ''), drd_race, drd_class, data.get('level', 1)) if nodeId and contextType: children = self.treeDAO.get_children_objects(nodeId, contextType) contexts = [] for child in children: if child.object.object_type is ObjectType.ABILITY_CONTEXT: contexts.append(AbilityContextDAO().get( child.object.id, None, child.id, contextType)) ability.contexts = contexts return ability def get_all(self, lang=None) -> list: """ Get list of abilities for selected lang :param lang: lang of abilities :return: list of abilities """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all(self.DATABASE_TABLE) items = [] for line in lines: item = self.get(line['ID'], lang) items.append(item) return items
class ModifierDAO(DAO, IModifierDAO): DATABASE_TABLE = 'Modifier' TYPE = ObjectType.MODIFIER def __init__(self): self.database = Database(self.DATABASE_DRIVER) self.obj_database = ObjectDatabase(self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, modifier: Modifier, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new Modifier :param modifier: Modifier object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created Modifier """ if not contextType: contextType = self.TYPE if modifier.valueType is ModifierValueTypes.TYPE_ARMOR_SIZE: value = ArmorSize.by_name(ArmorSize, modifier.value).value elif modifier.valueType is ModifierValueTypes.TYPE_WEAPON_HANDLING: value = Handling.by_name(Handling, modifier.value).value elif modifier.valueType is ModifierValueTypes.TYPE_WEAPON_WEIGHT: value = WeaponWeight.by_name(WeaponWeight, modifier.value).value else: value = modifier.value intValues = { 'value': value, 'valueType': modifier.valueType.value if modifier.valueType else None, 'targetType': modifier.targetType.value if modifier.targetType else None, 'characterTargetAttribute': modifier.characterTargetAttribute.value if modifier.characterTargetAttribute else None, 'itemTargetAttribute': modifier.itemTargetAttribute.value if modifier.itemTargetAttribute else None } strValues = { 'name': modifier.name, 'desccription': modifier.description } id = self.database.insert(self.DATABASE_TABLE, intValues) modifier.id = id self.obj_database.insert_translate(strValues, modifier.lang, id, self.TYPE) # Create node for tree structure node = NodeObject(None, modifier.name, nodeParentId, modifier) self.treeDAO.insert_node(node, contextType) return id def update(self, modifier: Modifier) -> None: """ Update modifier in database :param modifier: Modifier object with new data """ intValues = { 'value': modifier.value if type(modifier.value) is int else modifier.value.value, 'valueType': modifier.valueType.value if modifier.valueType else None, 'targetType': modifier.targetType.value if modifier.targetType.value else None, 'characterTargetAttribute': modifier.characterTargetAttribute.value if modifier.characterTargetAttribute else None, 'itemTargetAttribute': modifier.itemTargetAttribute.value if modifier.itemTargetAttribute else None } strValues = { 'name': modifier.name, 'desccription': modifier.description } self.database.update(self.DATABASE_TABLE, modifier.id, intValues) self.obj_database.update_translate(strValues, modifier.lang, modifier.id, self.TYPE) def delete(self, modifier_id: int) -> None: """ Delete Modifier from database and all his translates :param modifier_id: id of Modifier """ self.obj_database.delete(self.DATABASE_TABLE, modifier_id) self.database.delete_where('translates', { 'target_id': modifier_id, 'type': ObjectType.MODIFIER }) def get(self, modifier_id: int, lang: str = None, nodeId: int = None, contextType: ObjectType = None) -> Modifier: """ Get Modifier , object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all sub objects) If not specified, only basic attributes are set. :param modifier_id: id of Modifier :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Modifier object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.obj_database.select(self.DATABASE_TABLE, {'ID': modifier_id}) if not data: return None else: data = dict(data[0]) tr_data = dict( self.database.select_translate(modifier_id, ObjectType.MODIFIER.value, lang)) targetTypeIndex = data.get('targetType', None) targetType = ModifierTargetTypes( int(targetTypeIndex)) if targetTypeIndex is not None else None characterAttributeIndex = data.get('characterTargetAttribute', None) itemAttributeIndex = data.get('itemTargetAttribute', None) characterTargetAttribute = CharacterAttributes( characterAttributeIndex ) if characterAttributeIndex is not None else None itemTargetAttribute = ItemsAttributes( itemAttributeIndex) if itemAttributeIndex is not None else None valueTypeIndex = data.get('valueType', None) valueType = ModifierValueTypes( valueTypeIndex) if valueTypeIndex else None value = data.get('value', 0) if valueType is ItemsAttributes.WEAPON_MELEE_HANDLING: value = Handling(value) elif valueType is ItemsAttributes.WEAPON_WEIGHT: value = WeaponWeight(value) elif valueType is ItemsAttributes.ARMOR_SIZE: valueType = ArmorSize(value) else: value = value modifier = Modifier(modifier_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), valueType, value, characterTargetAttribute, itemTargetAttribute, targetType) return modifier def get_all(self, lang: str = None) -> list: """ Get list of modifiers for selected lang :param lang: lang of modifiers :return: list of modifiers """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all('Item') modifiers = [] for line in lines: item = self.get(line['ID'], lang) modifiers.append(item) return modifiers
class AbilityContextDAO(DAO, IAbilityContextDAO): DATABASE_TABLE = 'AbilityContext' TYPE = ObjectType.ABILITY_CONTEXT def __init__(self): self.database = Database(self.DATABASE_DRIVER) self.obj_database = ObjectDatabase(self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, context: AbilityContext, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new ability context :param context: Ability context object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created ability context """ if contextType is None: contextType = self.TYPE intValues = { 'value': context.value, 'valueType': context.valueType.value if context.valueType else None, 'targetAttribute': context.targetAttribute.value if context.targetAttribute else None } strValues = {'name': context.name, 'description': context.description} id = self.database.insert(self.DATABASE_TABLE, intValues) context.id = id self.obj_database.insert_translate(strValues, context.lang, id, self.TYPE) # Create node for tree structure node = NodeObject(None, context.name, nodeParentId, context) self.treeDAO.insert_node(node, contextType) return id def update(self, context: AbilityContext) -> None: """ Update Ability context with new values :param context: Ability context object with new values """ intValues = { 'value': context.value, 'valueType': context.valueType.value if context.valueType else None, 'targetAttribute': context.targetAttribute.value if context.targetAttribute else None } strValues = {'name': context.name, 'description': context.description} self.database.update(self.DATABASE_TABLE, context.id, intValues) self.obj_database.update_translate(strValues, context.lang, context.id, self.TYPE) def delete(self, context_id: int) -> None: """ Delete ability context from database :param context_id: id of context :return: """ self.obj_database.delete(self.DATABASE_TABLE, context_id) self.database.delete_where('translates', { 'target_id': context_id, 'type': ObjectType.ABILITY_CONTEXT }) def get(self, context_id: int, lang: str = None, nodeId: int = None, contextType: ObjectType = None) -> AbilityContext: """ Get ability context, object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all subobjects) If not specified, only basic attributes are set. :param context_id: id of ability context :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Ability context object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.obj_database.select(self.DATABASE_TABLE, {'ID': context_id}) if not data: return None else: data = dict(data[0]) tr_data = dict( self.database.select_translate(context_id, self.TYPE.value, lang)) valueType = ModifierValueTypes( data['valueType']) if data['valueType'] else None targetAttribute = CharacterAttributes( data['targetAttribute']) if data['targetAttribute'] else None context = AbilityContext(data['ID'], lang, tr_data.get('name', ''), tr_data.get('description', ''), valueType, data.get('value', 0), targetAttribute) return context def get_all(self, lang: str = None) -> list: """ Gel list of all Ability context :param lang: lang of objects :return: list of Ability context """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all(self.DATABASE_TABLE) items = [] for line in lines: item = self.get(line['ID'], lang) items.append(item) return items
class CharacterDAO(DAO, ISpellDAO): DATABASE_TABLE = 'Character' TYPE = ObjectType.CHARACTER def __init__(self): self.database = ObjectDatabase(self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, character: Character, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new character :param character: Character object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created character """ if contextType is None: contextType = self.TYPE intValues = { 'agility' : character.agility, 'charisma' : character.charisma, 'intelligence' : character.intelligence, 'mobility' : character.mobility, 'strength' : character.strength, 'toughness' : character.toughness, 'age' : character.age, 'height' : character.height, 'weight' : character.weight, 'level' : character.level, 'xp' : character.xp, 'maxHealth' : character.maxHealth, 'maxMana' : character.maxMana, 'currentHealth': character.currentHealth, 'currentMana' : character.currentMana, 'drdClass' : character.drdClass.value if character.drdClass else None, 'drdRace' : character.drdRace.value if character.drdRace else None, 'alignment' : character.alignment.value if character.alignment else None, } strValues = { 'name' : character.name, 'description': character.description } id = self.database.insert(self.DATABASE_TABLE, intValues) character.id = id self.database.insert_translate(strValues, character.lang, id, self.TYPE) # Create node for tree structure node = NodeObject(None, character.name, nodeParentId, character) nodeId = self.treeDAO.insert_node(node, contextType) for spell in character.spells: SpellDAO().create(spell, nodeId, contextType) for ability in character.abilities: AbilityDAO().create(ability, nodeId, contextType) for effect in character.effects: EffectDAO().create(effect, nodeId, contextType) if character.inventory is None: c = Container(None, None, TR().tr('Inventory'), None, -1) inventoryId = ItemDAO().create(c, nodeId, contextType) else: character.inventory.parent_id = -1 inventoryId = ItemDAO().create(character.inventory, nodeId, contextType) if character.ground is None: c = Container(None, None, TR().tr('Ground'), None, -2) groundId = ItemDAO().create(c, nodeId, contextType) else: character.ground.parent_id = -2 groundId = ItemDAO().create(character.ground, nodeId, contextType) self.database.update(self.DATABASE_TABLE, id, {'inventoryId': inventoryId, 'groundId': groundId}) return id def update(self, character: Character): """ Update spell in database :param character: Character object with new data """ intValues = { 'agility' : character.agility, 'charisma' : character.charisma, 'intelligence' : character.intelligence, 'mobility' : character.mobility, 'strength' : character.strength, 'toughness' : character.toughness, 'age' : character.age, 'height' : character.height, 'weight' : character.weight, 'level' : character.level, 'xp' : character.xp, 'maxHealth' : character.maxHealth, 'maxMana' : character.maxMana, 'currentHealth': character.currentHealth, 'currentMana' : character.currentMana, 'drdClass' : character.drdClass.value if character.drdClass else None, 'drdRace' : character.drdRace.value if character.drdRace else None, 'alignment' : character.alignment.value if character.alignment else None, } strValues = { 'name' : character.name, 'description': character.description } self.database.update(self.DATABASE_TABLE, character.id, intValues) self.database.update_translate(strValues, character.lang, character.id, self.TYPE) def delete(self, character_id: int): """ Delete character from database and from translate :param character_id: id of character """ self.database.delete(self.DATABASE_TABLE, character_id) self.database.delete_where('translates', {'target_id': character_id, 'type': ObjectType.CHARACTER}) def get(self, character_id: int, lang: str = None, nodeId: int = None, contextType: ObjectType = None) -> Character: """ Get Character , object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all sub objects) If not specified, only basic attributes are set. :param character_id: id of Character :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Character object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.database.select(self.DATABASE_TABLE, {'ID': character_id}) if not data: return None else: data = dict(data[0]) tr_data = self.database.select_translate(character_id, ObjectType.CHARACTER.value, lang) drdClass = Classes(data.get('drdClass')) if data.get('drdClass') is not None else None drdRace = Races(data.get('drdRace')) if data.get('drdRace') is not None else None alignment = Alignment(data.get('alignment')) if data.get('alignment') is not None else None character = Character(data.get('ID'), lang, tr_data.get('name', ''), tr_data.get('description', ''), data.get('agility', 0), data.get('charisma', 0), data.get('intelligence', 0), data.get('mobility', 0), data.get('strength', 0), data.get('toughness', 0), data.get('age', 0), data.get('height', 0), data.get('weight', 0), data.get('level', 0), data.get('xp', 0), data.get('maxHealth', 0), data.get('maxMana', 0), drdClass, drdRace, alignment, data.get('currentHealth', 0), data.get('currentMana', 0)) if nodeId and contextType: children = self.treeDAO.get_children_objects(nodeId, contextType) abilities = [] spells = [] effects = [] for child in children: if child.object.object_type is ObjectType.SPELL: spell = SpellDAO().get(child.object.id, None, child.id, contextType) spells.append(spell) elif child.object.object_type is ObjectType.ABILITY: ability = AbilityDAO().get(child.object.id, None, child.id, contextType) abilities.append(ability) elif child.object.object_type is ObjectType.EFFECT: effect = EffectDAO().get(child.object.id, None, child.id, contextType) effects.append(effect) elif child.object.object_type is ObjectType.ITEM and child.object.type is Items.CONTAINER and child.object.parent_id == -1: inventory = ItemDAO().get(child.object.id, None, child.id, contextType) character.inventory = inventory elif child.object.object_type is ObjectType.ITEM and child.object.type is Items.CONTAINER and child.object.parent_id == -2: ground = ItemDAO().get(child.object.id, None, child.id, contextType) character.ground = ground character.spells = spells character.abilities = abilities character.effects = effects return character def get_all(self, lang=None) -> list: """ Get list of characters for selected lang :param lang: lang of characters :return: list of characters """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all(self.DATABASE_TABLE) characters = [] for line in lines: character = self.get(line['ID'], lang) characters.append(character) return characters
class SpellDAO(DAO, ISpellDAO): DATABASE_TABLE = 'Spell' TYPE = ObjectType.SPELL def __init__(self): self.database = ObjectDatabase(self.DATABASE_DRIVER) self.treeDAO = PlayerTreeDAO() def create(self, spell: Spell, nodeParentId: int = None, contextType: ObjectType = None) -> int: """ Create new Spell :param spell: Spell object :param nodeParentId: id of parent node in tree :param contextType: Object type of tree, where item is located :return: id of created Spell """ if not contextType: contextType = self.TYPE intValues = { 'cast_time': spell.cast_time if spell.cast_time else 0, 'drd_class': spell.drd_class.value if spell.drd_class else None } strValues = { 'name': spell.name, 'description': spell.description, 'mana_cost_initial': spell.mana_cost_initial, 'mana_cost_continual': spell.mana_cost_continual, 'range': spell.range, 'scope': spell.scope, 'duration': spell.duration } # Insert NON transable values id = self.database.insert(self.DATABASE_TABLE, intValues) # Insert transable values self.database.insert_translate(strValues, spell.lang, id, self.TYPE) spell.id = id # Create node for tree structure node = NodeObject(None, spell.name, nodeParentId, spell) self.treeDAO.insert_node(node, contextType) return id def update(self, spell: Spell): """ Update spell in database :param spell: Spell object with new data """ if spell.id is None: raise ValueError('Cant update object without ID') data = self.database.select(self.DATABASE_TABLE, {'ID': spell.id}) if not data: raise ValueError('Cant update none existing object') intValues = { 'cast_time': spell.cast_time, 'drd_class': spell.drd_class.value if spell.drd_class else None } self.database.update(self.DATABASE_TABLE, spell.id, intValues) strValues = { 'name': spell.name, 'description': spell.description, 'mana_cost_initial': spell.mana_cost_initial, 'mana_cost_continual': spell.mana_cost_continual, 'range': spell.range, 'scope': spell.scope, 'duration': spell.duration } self.database.update_translate(strValues, spell.lang, spell.id, self.TYPE) def delete(self, spell_id: int): """ Delete spell from database and all his translates :param spell_id: id of spell """ self.database.delete(self.DATABASE_TABLE, spell_id) self.database.delete_where('translates', { 'target_id': spell_id, 'type': ObjectType.SPELL }) def get(self, spell_id: int, lang: str = None, nodeId: int = None, contextType: ObjectType = None) -> Spell: """ Get Spell , object transable attributes depends on lang If nodeId and contextType is specified, whole object is returned (with all sub objects) If not specified, only basic attributes are set. :param spell_id: id of Spell :param lang: lang of object :param nodeId: id of node in tree, where object is located :param contextType: object type of tree, where is node :return: Spell object """ if lang is None: lang = SettingsDAO().get_value('language', str) data = self.database.select(self.DATABASE_TABLE, {'ID': spell_id}) if not data: return None else: data = dict(data[0]) tr_data = self.database.select_translate(spell_id, ObjectType.SPELL.value, lang) drdClassIndex = data.get('drd_class', None) drdClass = Classes( drdClassIndex) if drdClassIndex is not None else None spell = Spell(spell_id, lang, tr_data.get('name', ''), tr_data.get('description', ''), tr_data.get('mana_cost_initial', ''), tr_data.get('mana_cost_continual', ''), tr_data.get('range', ''), tr_data.get('scope', ''), data.get('cast_time', 0), tr_data.get('duration', ''), drdClass) return spell def get_all(self, lang=None) -> list: """ Get list of Spell for selected lang :param lang: lang of Spell :return: list of Spell """ if lang is None: lang = SettingsDAO().get_value('language', str) lines = self.database.select_all(self.DATABASE_TABLE) items = [] for line in lines: item = self.get(line['ID'], lang) items.append(item) return items