def parse_attributes(): logging.debug('Parsing attributes...') ies_path = os.path.join(constants.PATH_INPUT_DATA, 'ies_ability.ipf', 'ability.ies') with open(ies_path, 'rb') as ies_file: for row in csv.DictReader(ies_file, delimiter=',', quotechar='"'): obj = {} obj['$ID'] = int(row['ClassID']) obj['$ID_NAME'] = row['ClassName'] obj['Description'] = parser_translations.translate(row['Desc']).strip() + '{nl}' obj['Icon'] = parser_assets.parse_entity_icon(row['Icon']) obj['Name'] = parser_translations.translate(row['Name']) obj['IsToggleable'] = row['AlwaysActive'] == 'NO' obj['DescriptionRequired'] = None obj['LevelMax'] = -1 obj['Unlock'] = None obj['UnlockArgs'] = {} obj['UpgradePrice'] = [] obj['Link_Jobs'] = [] obj['Link_Skills'] = [skill for skill in row['SkillCategory'].split(';') if len(skill)] globals.attributes[obj['$ID']] = obj globals.attributes_by_name[obj['$ID_NAME']] = obj
def parse(): parse_items('item.ies') parse_items('item_colorspray.ies') parse_items('item_gem.ies') parse_items('item_equip.ies') parse_items('item_equip_ep12.ies') parse_items('item_premium.ies') parse_items('item_quest.ies') parse_items('recipe.ies') # Hotfix: Insert 'Silver' as an Item obj = {} obj['$ID'] = -1 obj['$ID_NAME'] = 'Moneybag1' obj['Icon'] = parser_assets.parse_entity_icon('icon_item_silver') obj['Name'] = parser_translations.translate(u'실버') obj['Tradability'] = 'FFFF' obj['Type'] = TOSItemGroup.UNUSED for key in globals.items.values()[0]: if key not in obj: obj[key] = None globals.items[obj['$ID']] = obj globals.items_by_name[obj['$ID_NAME']] = obj
def parse_cards(): logging.debug('Parsing cards...') ies_path = os.path.join(constants.PATH_INPUT_DATA, 'ies.ipf', 'item.ies') ies_file = open(ies_path, 'rb') ies_reader = csv.DictReader(ies_file, delimiter=',', quotechar='"') for row in ies_reader: if row['GroupName'] != 'Card': continue obj = globals.cards_by_name[row['ClassName']] obj['IconTooltip'] = parser_assets.parse_entity_icon( row['TooltipImage']) obj['TypeCard'] = TOSCardType.value_of(row['CardGroupName']) ies_file.close()
def parse_jobs(): logging.debug('Parsing Jobs...') ies_path = os.path.join(constants.PATH_INPUT_DATA, 'ies.ipf', 'job.ies') with open(ies_path, 'rb') as ies_file: for row in csv.DictReader(ies_file, delimiter=',', quotechar='"'): obj = {} obj['$ID'] = int(row['ClassID']) obj['$ID_NAME'] = row['ClassName'] obj['Description'] = parser_translations.translate(row['Caption1']) obj['Icon'] = parser_assets.parse_entity_icon(row['Icon']) obj['Name'] = parser_translations.translate(row['Name']) obj['CircleMax'] = int(row['MaxCircle']) obj['JobDifficulty'] = TOSJobDifficulty.value_of( row['ControlDifficulty']) obj['JobTree'] = TOSJobTree.value_of(row['CtrlType']) obj['JobType'] = [ TOSJobType.value_of(v.strip()) for v in row['ControlType'].split(',') ] if len(row['ControlType']) else None obj['IsHidden'] = row['HiddenJob'] == 'YES' obj['IsSecret'] = obj['IsHidden'] and len(row['PreFunction']) > 0 obj['IsStarter'] = int(row['Rank']) == 1 obj['Rank'] = int(row['Rank']) obj['Stat_CON'] = int(row['CON']) obj['Stat_DEX'] = int(row['DEX']) obj['Stat_INT'] = int(row['INT']) obj['Stat_SPR'] = int(row['MNA']) obj['Stat_STR'] = int(row['STR']) obj['StatBase_CON'] = 0 obj['StatBase_DEX'] = 0 obj['StatBase_INT'] = 0 obj['StatBase_SPR'] = 0 obj['StatBase_STR'] = 0 obj['Link_Attributes'] = [] obj['Link_Skills'] = [] globals.jobs[obj['$ID']] = obj globals.jobs_by_name[obj['$ID_NAME']] = obj
def parse_monsters(file_name): logging.debug('Parsing %s...', file_name) LUA = luautil.load_script('calc_property_monster.lua', [ 'GET_MON_STAT', 'SCR_Get_MON_STR', 'SCR_Get_MON_INT', 'SCR_Get_MON_CON', 'SCR_Get_MON_MNA', 'SCR_Get_MON_DEX', 'SCR_Get_MON_MHP', 'SCR_Get_MON_MSP', 'SCR_GET_MON_EXP', 'SCR_GET_MON_JOBEXP', 'SCR_Get_MON_DEF', 'SCR_Get_MON_MDEF', 'SCR_Get_MON_HR', 'SCR_Get_MON_DR', 'SCR_Get_MON_CRTHR', 'SCR_Get_MON_CRTDR', 'SCR_Get_MON_CRTATK', 'SCR_Get_MON_MINPATK', 'SCR_Get_MON_MAXPATK', 'SCR_Get_MON_MINMATK', 'SCR_Get_MON_MAXMATK', 'SCR_Get_MON_BLK', 'SCR_Get_MON_BLK_BREAK', 'SCR_MON_ITEM_ARMOR_CALC', 'SCR_MON_ITEM_ARMOR_DEF_CALC', 'SCR_MON_ITEM_ARMOR_MDEF_CALC', 'SCR_MON_ITEM_WEAPON_CALC', 'SCR_MON_ITEM_GRADE_RATE', 'SCR_MON_ITEM_REINFORCE_ARMOR_CALC', 'SCR_MON_ITEM_REINFORCE_WEAPON_CALC', 'SCR_MON_ITEM_TRANSCEND_CALC', 'SCR_RACE_TYPE_RATE', 'SCR_SIZE_TYPE_RATE', ]) ies_path = os.path.join(constants.PATH_INPUT_DATA, "ies.ipf", file_name.lower()) ies_file = open(ies_path, 'rb') ies_reader = csv.DictReader(ies_file, delimiter=',', quotechar='"') for row in ies_reader: if row['MonRank'].upper() not in MONSTER_RANK_WHITELIST: continue #logging.debug('Parsing monster: %s :: %s', row['ClassID'], row['ClassName']) # HotFix: these properties need to be calculated before the remaining ones row['Lv'] = int(row['Level']) if int(row['Level']) > 1 else 1 row['CON'] = LUA['SCR_Get_MON_CON'](row) row['DEX'] = LUA['SCR_Get_MON_DEX'](row) row['INT'] = LUA['SCR_Get_MON_INT'](row) row['MNA'] = LUA['SCR_Get_MON_MNA'](row) row['STR'] = LUA['SCR_Get_MON_STR'](row) obj = {} obj['$ID'] = int(row['ClassID']) obj['$ID_NAME'] = row['ClassName'] obj['Description'] = parser_translations.translate(row['Desc']) obj['Icon'] = parser_assets.parse_entity_icon(row['Icon']) obj['Name'] = parser_translations.translate(row['Name']) obj['Armor'] = TOSEquipmentMaterial.value_of(row['ArmorMaterial']) obj['Element'] = TOSElement.value_of(row['Attribute']) obj['Level'] = int(row['Lv']) obj['Race'] = TOSMonsterRace.value_of(row['RaceType']) obj['Rank'] = TOSMonsterRank.value_of(row['MonRank']) obj['Size'] = TOSMonsterSize.value_of(row['Size']) obj['EXP'] = int(LUA['SCR_GET_MON_EXP'](row)) if obj['Level'] < 999 else 0 obj['EXPClass'] = int(LUA['SCR_GET_MON_JOBEXP'](row)) if obj['Level'] < 999 else 0 obj['Stat_CON'] = int(row['CON']) obj['Stat_DEX'] = int(row['DEX']) obj['Stat_INT'] = int(row['INT']) obj['Stat_SPR'] = int(row['MNA']) obj['Stat_STR'] = int(row['STR']) obj['Stat_HP'] = int(LUA['SCR_Get_MON_MHP'](row)) obj['Stat_SP'] = int(LUA['SCR_Get_MON_MSP'](row)) obj['Stat_ATTACK_MAGICAL_MAX'] = int(LUA['SCR_Get_MON_MAXMATK'](row)) obj['Stat_ATTACK_MAGICAL_MIN'] = int(LUA['SCR_Get_MON_MINMATK'](row)) obj['Stat_ATTACK_PHYSICAL_MAX'] = int(LUA['SCR_Get_MON_MAXPATK'](row)) obj['Stat_ATTACK_PHYSICAL_MIN'] = int(LUA['SCR_Get_MON_MINPATK'](row)) obj['Stat_DEFENSE_MAGICAL'] = int(LUA['SCR_Get_MON_MDEF'](row)) obj['Stat_DEFENSE_PHYSICAL'] = int(LUA['SCR_Get_MON_DEF'](row)) obj['Stat_Accuracy'] = int(LUA['SCR_Get_MON_HR'](row)) obj['Stat_Evasion'] = int(LUA['SCR_Get_MON_DR'](row)) obj['Stat_CriticalDamage'] = int(LUA['SCR_Get_MON_CRTATK'](row)) obj['Stat_CriticalDefense'] = int(LUA['SCR_Get_MON_CRTDR'](row)) obj['Stat_CriticalRate'] = int(LUA['SCR_Get_MON_CRTHR'](row)) obj['Stat_BlockRate'] = int(LUA['SCR_Get_MON_BLK'](row)) obj['Stat_BlockPenetration'] = int(LUA['SCR_Get_MON_BLK_BREAK'](row)) obj['Link_Drops'] = [] obj['Link_Spawns'] = [] globals.monsters[obj['$ID']] = obj globals.monsters_by_name[obj['$ID_NAME']] = obj ies_file.close()
def parse_skills(is_rebuild): logging.debug('Parsing skills...') LUA = luautil.load_script('calc_property_skill.lua', '*', False) LUA_EMBEDDED = [ 'SCR_ABIL_ADD_SKILLFACTOR', 'SCR_ABIL_ADD_SKILLFACTOR_TOOLTIP', 'SCR_Get_SpendSP', 'SCR_REINFORCEABILITY_TOOLTIP', ] ies_path = os.path.join(constants.PATH_INPUT_DATA, 'ies.ipf', 'skill.ies') with open(ies_path, 'rb') as ies_file: for row in csv.DictReader(ies_file, delimiter=',', quotechar='"'): # Ignore 'Common_' skills (e.g. Bokor's Summon abilities) if row['ClassName'].find('Common_') == 0: continue obj = {} obj['$ID'] = int(row['ClassID']) obj['$ID_NAME'] = row['ClassName'] obj['Description'] = parser_translations.translate(row['Caption']) obj['Icon'] = parser_assets.parse_entity_icon(row['Icon']) obj['Name'] = parser_translations.translate(row['Name']) obj['Effect'] = parser_translations.translate(row['Caption2']) obj['Element'] = TOSElement.value_of(row['Attribute']) obj['IsShinobi'] = row[ 'CoolDown'] == 'SCR_GET_SKL_COOLDOWN_BUNSIN' or ( row['CoolDown'] and 'Bunshin_Debuff' in LUA[row['CoolDown']]) obj['OverHeat'] = { 'Value': int(row['SklUseOverHeat']), 'Group': row['OverHeatGroup'] } if not is_rebuild else int( row['SklUseOverHeat'] ) # Re:Build overheat is now simpler to calculate obj['Prop_BasicCoolDown'] = int(row['BasicCoolDown']) obj['Prop_BasicPoison'] = int(row['BasicPoison']) obj['Prop_BasicSP'] = int(math.floor(float(row['BasicSP']))) obj['Prop_LvUpSpendPoison'] = int(row['LvUpSpendPoison']) obj['Prop_LvUpSpendSp'] = float(row['LvUpSpendSp']) obj['Prop_SklAtkAdd'] = float(row['SklAtkAdd']) obj['Prop_SklAtkAddByLevel'] = float(row['SklAtkAddByLevel']) obj['Prop_SklFactor'] = float(row['SklFactor']) obj['Prop_SklFactorByLevel'] = float(row['SklFactorByLevel']) obj['Prop_SklSR'] = float(row['SklSR']) obj['Prop_SpendItemBaseCount'] = int(row['SpendItemBaseCount']) obj['RequiredStance'] = row['ReqStance'] obj['RequiredStanceCompanion'] = TOSRequiredStanceCompanion.value_of( row['EnableCompanion']) obj['RequiredSubWeapon'] = row['UseSubweaponDamage'] == 'YES' obj['CoolDown'] = None obj['IsEnchanter'] = False obj['IsPardoner'] = False obj['IsRunecaster'] = False obj['Prop_LevelPerGrade'] = -1 # Remove when Re:Build goes global obj['Prop_MaxLevel'] = -1 obj['Prop_UnlockGrade'] = -1 # Remove when Re:Build goes global obj['Prop_UnlockClassLevel'] = -1 obj['SP'] = None obj['TypeAttack'] = [] obj['Link_Attributes'] = [] obj['Link_Gem'] = None obj['Link_Job'] = None # Parse TypeAttack if row['ValueType'] == 'Buff': obj['TypeAttack'].append(TOSAttackType.BUFF) if row['ClassType'] is not None: obj['TypeAttack'].append( TOSAttackType.value_of(row['ClassType'])) if row['AttackType'] is not None: obj['TypeAttack'].append( TOSAttackType.value_of(row['AttackType'])) obj['TypeAttack'] = list(set(obj['TypeAttack'])) obj['TypeAttack'] = [ attack for attack in obj['TypeAttack'] if attack is not None and attack != TOSAttackType.UNKNOWN ] # Add missing Description header if not re.match(r'{#.+}{ol}(\[.+?\]){\/}{\/}{nl}', obj['Description']): header = [ '[' + TOSAttackType.to_string(attack) + ']' for attack in obj['TypeAttack'] ] header_color = '' header_color = '993399' if TOSAttackType.MAGIC in obj[ 'TypeAttack'] else header_color header_color = 'DD5500' if TOSAttackType.MELEE in obj[ 'TypeAttack'] else header_color header_color = 'DD5500' if TOSAttackType.MISSILE in obj[ 'TypeAttack'] else header_color if obj['Element'] != TOSElement.MELEE: header.append('[' + TOSElement.to_string(obj['Element']) + ']') obj['Description'] = '{#' + header_color + '}{ol}' + ' - '.join( header) + '{/}{/}{nl}' + obj['Description'] # Parse effects for effect in re.findall(r'{(.*?)}', obj['Effect']): if effect in EFFECT_DEPRECATE: # Hotfix: sometimes IMC changes which effects are used, however they forgot to properly communicate to the translation team. # This code is responsible for fixing that and warning so the in-game translations can be fixed logging.warning('[%32s] Deprecated effect [%s] in Effect', obj['$ID_NAME'], effect) effect_deprecate = effect effect = EFFECT_DEPRECATE[effect] obj['Effect'] = re.sub( r'\b' + re.escape(effect_deprecate) + r'\b', effect, obj['Effect']) if effect in row: key = 'Effect_' + effect # HotFix: make sure all skills have the same Effect columns (1/2) if key not in EFFECTS: EFFECTS.append('Effect_' + effect) if row[effect] != 'ZERO': obj[key] = parse_skills_lua_source( LUA, LUA_EMBEDDED, row[effect]) obj[key] = parse_skills_lua_source_to_javascript( row, obj[key]) else: # Hotfix: similar to the hotfix above logging.warning( '[%32s] Deprecated effect [%s] in Effect', obj['$ID_NAME'], effect) obj[key] = None else: continue # Parse formulas if row['CoolDown']: obj['CoolDown'] = parse_skills_lua_source( LUA, LUA_EMBEDDED, row['CoolDown']) obj['CoolDown'] = parse_skills_lua_source_to_javascript( row, obj['CoolDown']) if row['SpendSP']: obj['SP'] = parse_skills_lua_source(LUA, LUA_EMBEDDED, row['SpendSP']) obj['SP'] = parse_skills_lua_source_to_javascript( row, obj['SP']) globals.skills[obj['$ID']] = obj globals.skills_by_name[obj['$ID_NAME']] = obj # HotFix: make sure all skills have the same Effect columns (2/2) for skill in globals.skills.values(): for effect in EFFECTS: if effect not in skill: skill[effect] = None
def parse_skills_stances(): logging.debug('Parsing skills stances...') stance_list = [] ies_path = os.path.join(constants.PATH_INPUT_DATA, 'ies.ipf', 'stance.ies') # Parse stances with open(ies_path, 'rb') as ies_file: for row in csv.DictReader(ies_file, delimiter=',', quotechar='"'): stance_list.append(row) # Add stances to skills # from addon.ipf\skilltree\skilltree.lua :: MAKE_STANCE_ICON for skill in globals.skills.values(): stances_main_weapon = [] stances_sub_weapon = [] if skill['RequiredStance']: for stance in stance_list: index = skill['RequiredStance'].find(stance['ClassName']) if index == -1: continue if skill['RequiredStance'] == 'TwoHandBow' and stance[ 'ClassName'] == 'Bow': continue if 'Artefact' in stance['Name']: continue if stance['UseSubWeapon'] == 'NO': stances_main_weapon.append({ 'Icon': parser_assets.parse_entity_icon(stance['Icon']), 'Name': stance['ClassName'] }) else: found = False for stance_sub in stances_sub_weapon: if stance_sub[ 'Icon'] == parser_assets.parse_entity_icon( stance['Icon']): found = True break if not found: stances_sub_weapon.append({ 'Icon': parser_assets.parse_entity_icon(stance['Icon']), 'Name': stance['ClassName'] }) else: stances_main_weapon.append({ 'Icon': parser_assets.parse_entity_icon('weapon_All'), 'Name': 'All' }) if skill['RequiredStanceCompanion'] in [ TOSRequiredStanceCompanion.BOTH, TOSRequiredStanceCompanion.YES ]: stances_main_weapon.append({ 'Icon': parser_assets.parse_entity_icon('weapon_companion'), 'Name': 'Companion' }) skill['RequiredStance'] = [ stance for stance in (stances_main_weapon + stances_sub_weapon) if stance['Icon'] is not None ]
def parse_monsters(file_name): logging.debug('Parsing %s...', file_name) LUA_RUNTIME = luautil.LUA_RUNTIME LUA_SOURCE = luautil.LUA_SOURCE ies_path = os.path.join(constants.PATH_INPUT_DATA, "ies.ipf", file_name.lower()) ies_file = open(ies_path, 'rb') ies_reader = csv.DictReader(ies_file, delimiter=',', quotechar='"') for row in ies_reader: #logging.debug('Parsing monster: %s :: %s', row['ClassID'], row['ClassName']) # HotFix: these properties need to be calculated before the remaining ones row['Lv'] = int(row['Level']) if int(row['Level']) > 1 else 1 row['CON'] = LUA_RUNTIME['SCR_Get_MON_CON'](row) row['DEX'] = LUA_RUNTIME['SCR_Get_MON_DEX'](row) row['INT'] = LUA_RUNTIME['SCR_Get_MON_INT'](row) row['MNA'] = LUA_RUNTIME['SCR_Get_MON_MNA'](row) row['STR'] = LUA_RUNTIME['SCR_Get_MON_STR'](row) obj = {} obj['$ID'] = int(row['ClassID']) obj['$ID_NAME'] = row['ClassName'] obj['Description'] = parser_translations.translate(row['Desc']) obj['Icon'] = parser_assets.parse_entity_icon( row['Icon']) if row['Icon'] != 'ui_CreateMonster' else None obj['Name'] = parser_translations.translate(row['Name']) obj['Type'] = TOSMonsterType.value_of(row['GroupName']) if obj['Type'] == TOSMonsterType.MONSTER: obj['Armor'] = TOSEquipmentMaterial.value_of(row['ArmorMaterial']) obj['Element'] = TOSElement.value_of(row['Attribute']) obj['Level'] = int(row['Lv']) obj['Race'] = TOSMonsterRace.value_of(row['RaceType']) obj['Rank'] = TOSMonsterRank.value_of(row['MonRank']) obj['Size'] = TOSMonsterSize.value_of( row['Size']) if row['Size'] else None obj['EXP'] = int(LUA_RUNTIME['SCR_GET_MON_EXP']( row)) if obj['Level'] < 999 else 0 obj['EXPClass'] = int(LUA_RUNTIME['SCR_GET_MON_JOBEXP']( row)) if obj['Level'] < 999 else 0 obj['Stat_CON'] = int(row['CON']) obj['Stat_DEX'] = int(row['DEX']) obj['Stat_INT'] = int(row['INT']) obj['Stat_SPR'] = int(row['MNA']) obj['Stat_STR'] = int(row['STR']) obj['Stat_HP'] = int(LUA_RUNTIME['SCR_Get_MON_MHP'](row)) obj['Stat_SP'] = int(LUA_RUNTIME['SCR_Get_MON_MSP'](row)) obj['Stat_ATTACK_MAGICAL_MAX'] = int( LUA_RUNTIME['SCR_Get_MON_MAXMATK'](row)) obj['Stat_ATTACK_MAGICAL_MIN'] = int( LUA_RUNTIME['SCR_Get_MON_MINMATK'](row)) obj['Stat_ATTACK_PHYSICAL_MAX'] = int( LUA_RUNTIME['SCR_Get_MON_MAXPATK'](row)) obj['Stat_ATTACK_PHYSICAL_MIN'] = int( LUA_RUNTIME['SCR_Get_MON_MINPATK'](row)) obj['Stat_DEFENSE_MAGICAL'] = int( LUA_RUNTIME['SCR_Get_MON_MDEF'](row)) obj['Stat_DEFENSE_PHYSICAL'] = int( LUA_RUNTIME['SCR_Get_MON_DEF'](row)) obj['Stat_Accuracy'] = int(LUA_RUNTIME['SCR_Get_MON_HR'](row)) obj['Stat_Evasion'] = int(LUA_RUNTIME['SCR_Get_MON_DR'](row)) obj['Stat_CriticalDamage'] = int( LUA_RUNTIME['SCR_Get_MON_CRTATK'](row)) obj['Stat_CriticalDefense'] = int( LUA_RUNTIME['SCR_Get_MON_CRTDR'](row)) obj['Stat_CriticalRate'] = int( LUA_RUNTIME['SCR_Get_MON_CRTHR'](row)) obj['Stat_BlockRate'] = int(LUA_RUNTIME['SCR_Get_MON_BLK'](row)) obj['Stat_BlockPenetration'] = int( LUA_RUNTIME['SCR_Get_MON_BLK_BREAK'](row)) obj['Link_Items'] = [] obj['Link_Maps'] = [] globals.monsters[obj['$ID']] = obj globals.monsters_by_name[obj['$ID_NAME']] = obj elif obj['Type'] == TOSMonsterType.NPC: obj['Icon'] = parser_assets.parse_entity_icon( row['MinimapIcon']) if row['MinimapIcon'] else obj['Icon'] globals.npcs[obj['$ID']] = obj globals.npcs_by_name[obj['$ID_NAME']] = obj ies_file.close()
def parse_items(file_name): logging.debug('Parsing %s...', file_name) ies_path = os.path.join(constants.PATH_INPUT_DATA, "ies.ipf", file_name) ies_file = open(ies_path, 'rb') ies_reader = csv.DictReader(ies_file, delimiter=',', quotechar='"') for row in ies_reader: item_type = TOSItemGroup.RECIPE if file_name == 'recipe.ies' else TOSItemGroup.value_of( row['GroupName']) item_type_equipment = TOSEquipmentType.value_of( row['ClassType']) if 'ClassType' in row else None #logging.debug('Parsing item: %s :: %s', row['ClassID'], row['ClassName']) obj = {} obj['$ID'] = int(row['ClassID']) obj['$ID_NAME'] = row['ClassName'] obj['Description'] = parser_translations.translate( row['Desc']) if 'Desc' in row else None obj['Icon'] = parser_assets.parse_entity_icon(row['Icon']) obj['Name'] = parser_translations.translate( row['Name']) if 'Name' in row else None obj['Price'] = row['SellPrice'] obj['TimeCoolDown'] = float(int(row['ItemCoolDown']) / 1000) if 'ItemCoolDown' in row else None obj['TimeLifeTime'] = float(int( row['LifeTime'])) if 'LifeTime' in row else None obj['Tradability'] = '%s%s%s%s' % ( 'T' if row['MarketTrade'] == 'YES' else 'F', # Market 'T' if row['UserTrade'] == 'YES' else 'F', # Players 'T' if row['ShopTrade'] == 'YES' else 'F', # Shop 'T' if row['TeamTrade'] == 'YES' else 'F', # Team Storage ) obj['Type'] = item_type obj['Weight'] = float(row['Weight']) if 'Weight' in row else None obj['Link_Collections'] = [] obj['Link_Cubes'] = [] obj['Link_MonsterDrops'] = [] obj['Link_RecipeTarget'] = [] obj['Link_RecipeMaterial'] = [] if item_type == TOSItemGroup.BOOK: globals.books[obj['$ID']] = obj globals.books_by_name[obj['$ID_NAME']] = obj elif item_type == TOSItemGroup.CARD: globals.cards[obj['$ID']] = obj globals.cards_by_name[obj['$ID_NAME']] = obj elif item_type == TOSItemGroup.COLLECTION: globals.collections[obj['$ID']] = obj globals.collections_by_name[obj['$ID_NAME']] = obj elif item_type == TOSItemGroup.CUBE: globals.cubes[obj['$ID']] = obj globals.cubes_by_name[obj['$ID_NAME']] = obj globals.cubes_by_stringarg[row['StringArg']] = obj elif item_type == TOSItemGroup.GEM: globals.gems[obj['$ID']] = obj globals.gems_by_name[obj['$ID_NAME']] = obj elif item_type == TOSItemGroup.RECIPE: globals.recipes[obj['$ID']] = obj globals.recipes_by_name[obj['$ID_NAME']] = obj elif item_type in ITEM_GROUP_FASHION_WHITELIST\ or item_type_equipment in TYPE_EQUIPMENT_COSTUME_LIST\ or 'ClassType2' in row and row['ClassType2'] == 'Premium': globals.equipment[obj['$ID']] = obj globals.equipment_by_name[obj['$ID_NAME']] = obj elif item_type in ITEM_GROUP_ITEM_WHITELIST: globals.items[obj['$ID']] = obj globals.items_by_name[obj['$ID_NAME']] = obj elif item_type in ITEM_GROUP_EQUIPMENT_WHITELIST and item_type_equipment is not None: globals.equipment[obj['$ID']] = obj globals.equipment_by_name[obj['$ID_NAME']] = obj ies_file.close()