Updated to use external tsv files for ids.

This commit is contained in:
Chris Davoren 2023-07-16 08:59:50 +10:00
parent 6e0ceaf239
commit 13073df432
2 changed files with 93 additions and 89 deletions

View File

@ -94,4 +94,6 @@
2728 Wound 2728 Wound
2729 Monster bite 2729 Monster bite
2798 Received an electric shock 2798 Received an electric shock
2843 I was held as a slave 2843 I was held as a slave
3311 Sleeping comfortably
3327 No entertainment
1 193 Panicked
94 2728 Wound
95 2729 Monster bite
96 2798 Received an electric shock
97 2843 I was held as a slave
98 3311 Sleeping comfortably
99 3327 No entertainment

View File

@ -2,6 +2,7 @@ import argparse
import copy import copy
import os import os
import datetime import datetime
import csv
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import rich import rich
@ -16,83 +17,32 @@ storage_ids = {
3062: {"name": "Body storage", "capacity": 20}, 3062: {"name": "Body storage", "capacity": 20},
} }
char_skills = {
1: "Piloting", # Likely deprecated - now using code 22
2: "Mining",
3: "Botany",
4: "Construction",
5: "Industry",
6: "Medical",
7: "Gunner",
8: "Shielding",
9: "Operations",
10: "Weapons",
11: "Unknown-11",
12: "Logistics", # All characters seem to have this but it doesn't show up in the UI
13: "Unknown-13", # All characters seem to have this skill but what is it for?
14: "Navigation",
15: "Unknown-15",
16: "Research",
22: "Piloting", # Appears to be the new piloting code?
}
char_attributes = {
210: "Bravery",
214: "Preception",
213: "Intelligence",
212: "Zest",
}
char_traits = {
"Iron Stomach": 1533,
"Spacefarer": 1045,
"Confident": 1046,
"Hard Working": 1041,
"Antisocial": 1037,
"Nyctophilia": 1534,
"Wimp": 655,
"Clumsy": 656,
"Charming": 1048,
"Bloodlust": 1036,
"Fast Learner": 1039,
"Minimalist": 1535,
"Lazy": 1040,
"Neurotic": 1047,
"Alien Lover": 2082,
"Needy": 1038,
"Peace-loving": 1043,
"Suicidal": 1034,
"Smart": 1035,
"Psychopath": 1042,
"Hero": 191,
"Talkative": 1560,
"Iron-Willed": 1044,
"Gourmand": 1562,
}
class ItemCodeDatabase:
def __init__(self, database_filename):
self.id_dict = {}
for line in open(database_filename):
result = line.split()
code = int(result[0])
name = ' '.join(result[1:])
# print(code, name)
self.id_dict[code] = name
def get_name_from_code(self, code):
return self.id_dict[code]
def validate_code(self, code):
return code in self.id_dict
# A single item with its code, name, and quantity # A single item with its code, name, and quantity
class Item: class Item:
item_ids = None
@classmethod
def load_ids(cls, item_filename):
if cls.item_ids is not None:
return
else:
cls.item_ids = {}
with open(item_filename, 'r') as item_file:
item_reader = csv.reader(item_file, delimiter='\t')
for row in item_reader:
cls.item_ids[int(row[0])] = row[1].strip()
@classmethod
def get_name_from_code(cls, code):
return cls.item_ids.get(code, None) if cls.item_ids is not None else None
@classmethod
def validate_code(cls, code):
return code in cls.id_dict if cls.item_ids is not None else False
def __init__(self, code, name, quantity): def __init__(self, code, name, quantity):
self.code = code self.code = code
self.name = name self.name = name
@ -106,7 +56,7 @@ class StorageArea:
self.tag = tag self.tag = tag
self.type_id = None self.type_id = None
self.items = [] self.items = []
self.is_abnormal_storage = False self.is_normal_storage = False
def add_item(self, item): def add_item(self, item):
self.items.append(item) self.items.append(item)
@ -121,6 +71,58 @@ class StorageArea:
class Character: class Character:
skill_ids = None
attribute_ids = None
trait_ids = None
condition_ids = None
@classmethod
def load_ids(cls, skill_filename, attribute_filename, trait_filename, condition_filename):
if cls.skill_ids is None:
cls.skill_ids = {}
with open(skill_filename, 'r') as skill_file:
skill_reader = csv.reader(skill_file, delimiter='\t')
for row in skill_reader:
cls.skill_ids[int(row[0])] = row[1].strip()
if cls.attribute_ids is None:
cls.attribute_ids = {}
with open(attribute_filename, 'r') as attribute_file:
attribute_reader = csv.reader(attribute_file, delimiter='\t')
for row in attribute_reader:
cls.attribute_ids[int(row[0])] = row[1].strip()
if cls.trait_ids is None:
cls.trait_ids = {}
with open(trait_filename, 'r') as trait_file:
trait_reader = csv.reader(trait_file, delimiter='\t')
for row in trait_reader:
print(row)
cls.trait_ids[int(row[0])] = row[1].strip()
if cls.condition_ids is None:
cls.condition_ids = {}
with open(condition_filename, 'r') as condition_file:
condition_reader = csv.reader(condition_file, delimiter='\t')
for row in condition_reader:
cls.condition_ids[int(row[0])] = row[1].strip()
@classmethod
def get_skill_from_code(cls, code):
return cls.skill_ids.get(code, None) if cls.skill_ids is not None else None
@classmethod
def get_attribute_from_code(cls, code):
return cls.attribute_ids.get(code, None) if cls.attribute_ids is not None else None
@classmethod
def get_trait_from_code(cls, code):
return cls.trait_ids.get(code, None) if cls.trait_ids is not None else None
@classmethod
def get_condition_from_code(cls, code):
return cls.condition_ids.get(code, None) if cls.condition_ids is not None else None
def __init__(self, name, tag): def __init__(self, name, tag):
self.name = name self.name = name
self.tag = tag self.tag = tag
@ -170,7 +172,7 @@ class Character:
console.print() console.print()
console.print("Skills:") console.print("Skills:")
for i, skill in enumerate(self.skills): for i, skill in enumerate(self.skills):
row_string = "{:12} [bright_cyan]{:2}[/]".format(char_skills[skill['id']], skill['level']) row_string = "{:12} [bright_cyan]{:2}[/]".format(Character.get_skill_from_code(skill['id']), skill['level'])
if i % 2 == 0: if i % 2 == 0:
console.print(" [on #222222]{}[/]".format(row_string)) console.print(" [on #222222]{}[/]".format(row_string))
else: else:
@ -178,7 +180,7 @@ class Character:
console.print() console.print()
console.print("Attributes:") console.print("Attributes:")
for i, attribute in enumerate(self.attributes): for i, attribute in enumerate(self.attributes):
row_string = "{:12} [bright_cyan]{:2}[/]".format(char_attributes[attribute['id']], attribute['points']) row_string = "{:12} [bright_cyan]{:2}[/]".format(Character.get_attribute_from_code(attribute['id']), attribute['points'])
if i % 2 == 0: if i % 2 == 0:
console.print(" [on #222222]{}[/]".format(row_string)) console.print(" [on #222222]{}[/]".format(row_string))
else: else:
@ -206,7 +208,7 @@ class Ship:
self.characters.append(character) self.characters.append(character)
def add_item(self, item): def add_item(self, item):
normal_storage_areas = [sa for sa in self.storage_areas if not sa.is_abnormal_storage] normal_storage_areas = [sa for sa in self.storage_areas if sa.is_normal_storage]
min_storage_area = normal_storage_areas[0] min_storage_area = normal_storage_areas[0]
min_occupancy = min_storage_area.get_total_occupancy() min_occupancy = min_storage_area.get_total_occupancy()
for storage_area in normal_storage_areas: for storage_area in normal_storage_areas:
@ -225,12 +227,11 @@ class Player:
class GameData: class GameData:
def __init__(self, soup, item_database): def __init__(self, soup):
self.player = None self.player = None
self.ships = [] self.ships = []
self.soup = soup self.soup = soup
self.item_database = item_database
def populate(self): def populate(self):
# Step 1 - Player data # Step 1 - Player data
@ -262,14 +263,12 @@ class GameData:
storage_area = StorageArea(inv_tag.find('inv')) storage_area = StorageArea(inv_tag.find('inv'))
# 632 is the "m" id code for LARGE storage # 632 is the "m" id code for LARGE storage
storage_area.type_id = int(inv_tag.parent.parent['m']) storage_area.type_id = int(inv_tag.parent.parent['m'])
if storage_area.type_id not in normal_storage_ids: # TODO: Un-hardcode this AND take into account SMALL storage storage_area.is_normal_storage = storage_area.type_id in normal_storage_ids
# rich.print("[on #222222]Found abnormal storage id [#666666]{}[/][/]".format(inv_tag.parent.parent['m']))
storage_area.is_abnormal_storage = True
ship.add_storage_area(storage_area) ship.add_storage_area(storage_area)
# Items within storage area # Items within storage area
for s_tag in inv_tag.find_all('s'): for s_tag in inv_tag.find_all('s'):
item_code = int(s_tag['elementaryId']) item_code = int(s_tag['elementaryId'])
item_name = self.item_database.get_name_from_code(item_code) item_name = Item.get_name_from_code(item_code)
item_quantity = int(s_tag['inStorage']) item_quantity = int(s_tag['inStorage'])
item = Item(item_code, item_name, item_quantity) item = Item(item_code, item_name, item_quantity)
storage_area.add_item(item) storage_area.add_item(item)
@ -420,7 +419,7 @@ class GameData:
continue continue
for index, storage_area in enumerate(ship.storage_areas): for index, storage_area in enumerate(ship.storage_areas):
console.print(" Storage area [bright_cyan]{}[/] (type: [bright_cyan]{}[/], abnormal storage: [bright_cyan]{}[/]):".format(index, storage_ids[storage_area.type_id]["name"], storage_area.is_abnormal_storage)) console.print(" Storage area [bright_cyan]{}[/] (type: [bright_cyan]{}[/], normal storage: [bright_cyan]{}[/]):".format(index, storage_ids[storage_area.type_id]["name"], storage_area.is_normal_storage))
if len(storage_area.items) == 0: if len(storage_area.items) == 0:
console.print(" This storage area is empty.") console.print(" This storage area is empty.")
console.print() console.print()
@ -632,11 +631,14 @@ def main():
soup = BeautifulSoup(full_text, "xml") soup = BeautifulSoup(full_text, "xml")
item_code_database = ItemCodeDatabase('item_ids.tsv') Item.load_ids('item_ids.tsv')
print("Item code database successfully loaded.") print("Item code database successfully loaded.")
print() print()
Character.load_ids('char_skills.tsv', 'char_attributes.tsv', 'char_traits.tsv', 'char_conditions.tsv')
print("Character code database successfully loaded.")
print()
game_data = GameData(soup, item_code_database) game_data = GameData(soup)
game_data.populate() game_data.populate()
edits_made = False edits_made = False
@ -665,7 +667,7 @@ def main():
# print(item_list) # print(item_list)
print("Items to be added:") print("Items to be added:")
for (item_code, item_quantity) in item_list: for (item_code, item_quantity) in item_list:
print("{} : {}".format(item_code_database.get_name_from_code(item_code), item_quantity)) print("{} : {}".format(Item.get_name_from_code(item_code), item_quantity))
game_data.add_item(item_code, item_quantity) game_data.add_item(item_code, item_quantity)
edits_made = True edits_made = True
@ -678,7 +680,7 @@ def main():
game_data.writeback() game_data.writeback()
if args.test_gamedata: if args.test_gamedata:
game_data = GameData(soup, item_code_database) game_data = GameData(soup)
game_data.populate() game_data.populate()
# game_data.add_item(1759, 100) # game_data.add_item(1759, 100)
# game_data.buff_characters() # game_data.buff_characters()