Included actual research requirement information.

This commit is contained in:
Chris Davoren 2023-09-01 19:20:19 +10:00
parent aa5515701d
commit 7f13772336
3 changed files with 171 additions and 99 deletions

View File

@ -114,4 +114,32 @@ Composter - 85,15
Advanced Nutrition - 100,25,10 Advanced Nutrition - 100,25,10
Artificial Meat - 140,60,20 Artificial Meat - 140,60,20
Grains and Hops - 100,30,10 Grains and Hops - 100,30,10
Alcoholic Bar Machine - 120,25,10 Alcoholic Bar Machine - 120,25,10
-----
WORKBENCH
171 Raw Chemicals
158 Energium
174 Energy Rod
760 Five-Seven Pistol
725 Assault Rifle
2618 Fabrics
1922 Steel Plates
175 Plastics
173 Electronic Components
172 Hyperium
729 Shotgun
Disassembled Slave Collar
Disassembled Crawler Corpse
Disassembled Hauler Corpse
Disassembled Hive Core Remains
Disassembled Evolved Alien Core
15 Root Vegetables
706 Fruits
Disassembled Hamster Rubble
Disassembled Chimp Rubble
1925 Quantronics Components
1954 Dissected Human Corpse
Disassembled Android

View File

@ -1,76 +1,76 @@
# Tree id 2535 # Tree id 2535
2532 Scanner 2532 Scanner - - 150,40,10
2533 Shield Generator 2533 Shield Generator - - 180,40,12
2539 Botany 2539 Botany - - 40
2559 Medical Bed 2559 Medical Bed - - 120,60,15
2563 Arcade Machine 2563 Arcade Machine - - 125,60,20
2564 Jukebox 2564 Jukebox - - 120,50,10
2565 Solar Panel 2565 Solar Panel - - 180,50,10
2566 X2 Power Generator 2566 X2 Power Generator 3:158,1:174 80,20,10 300,60,30
2567 X3 Power Generator 2567 X3 Power Generator 3:158,2:174 100,40,30 320,120,50
2568 Power Capacity Node 2568 Power Capacity Node - - 120,60,5
2569 Item Fabricator 2569 Item Fabricator - - 150,40,6
2570 Microweaver 2570 Microweaver - - 60,25
2571 Assembler 2571 Assembler - - 90,10
2572 Energy Refinery 2572 Energy Refinery 2:171 50,10 110,50,10
2573 Chemical Refinery 2573 Chemical Refinery 2:171 40 140,45,8
2575 Advanced Assember 2575 Advanced Assember - - 200,80,50
2576 Composter 2576 Composter - - 85,15
2577 Hypersleep Chamber 2577 Hypersleep Chamber - - 150,50,20
2589 Weapons Console 2589 Weapons Console - - 125,15
2590 Shields Console 2590 Shields Console - - 125,15
2591 Rocket Turret 2591 Rocket Turret - - 180,75,12
2592 Energy Turret 2592 Energy Turret - - 160,55,10
2594 X1 Power Generator 2594 X1 Power Generator 2:158 30,10 130,70,10
2595 X1 Hyperdrive 2595 X1 Hyperdrive 3:172 40,20 140,40,12
2596 Unknown 2596 Unknown - - -
2597 Unknown 2597 Unknown - - -
2598 Unknown 2598 Unknown - - -
2599 Unknown 2599 Unknown - - -
2600 Unknown 2600 Unknown - - -
2601 Targeting Jammer 2601 Targeting Jammer - - 400,250,120
2602 Unknown 2602 Unknown - - -
2604 Unknown 2604 Unknown - - -
2605 Logistics Robot Station 2605 Logistics Robot Station - - 150,50,25
2606 Plasma Weapons 2606 Plasma Weapons 2:158,2:172,1:729,1:725 - 180,60,30
2607 Unknown 2607 Unknown - - -
2612 Metal Refinery 2612 Metal Refinery - - 80,20
2613 Unknown 2613 Unknown - - -
2614 Unknown 2614 Unknown - - -
2617 Unknown 2617 Unknown - - -
2619 Fibres 2619 Fibres - - 80,20
2622 Bulletproof Vest 2622 Bulletproof Vest 1:2618,1:1922,1:175 - 50,20,5
2623 Autopsy Table 2623 Autopsy Table - - 40
2626 Advanced Nutrition 2626 Advanced Nutrition 3:15,3:706 20 100,25,10
2628 Artificial Meat 2628 Artificial Meat - - 140,60,20
2629 Alcoholic Bar Machine 2629 Alcoholic Bar Machine - - 120,25,10
2630 Grains and Hops 2630 Grains and Hops - - 100,30,10
2694 Optotronics Fabricator 2694 Optotronics Fabricator - - 400,100,50
2847 Unknown 2847 Unknown - - -
3024 Laser Weapons 3024 Laser Weapons 2:174,1:760,1:725 - 150,50,25
3025 Salvage Robot Station 3025 Salvage Robot Station - - 200,75,50
3114 Unknown 3114 Unknown - - -
3115 Research Workbench 3115 Research Workbench - - 100,20,5
3116 Unknown 3116 Unknown - - -
3119 Navigation Console 3119 Navigation Console - - 60,20
3122 Operations Console 3122 Operations Console - - 60,10
3124 Unknown 3124 Unknown - - -
3125 Unknown 3125 Unknown - - -
3127 Robotics 01 3127 Robotics 01 - - 80,20,10
3128 Industry 01 3128 Industry 01 - - 50,5
3129 Industry 02 3129 Industry 02 - - 80,12
3130 Botany 02 3130 Botany 02 - - 50,20,5
3417 Armored Vest 3417 Armored Vest 1:2618,2:1922,2:175,1:3383 - 60,30,12
3420 Unknown 3420 Unknown - - -
3421 Unknown 3421 Unknown - - -
3422 Unknown 3422 Unknown - - -
3423 Unknown 3423 Unknown - - -
3464 Sentry Gun X1 3464 Sentry Gun X1 2:173,2:175 - 100,40,20
3704 Unknown 3704 Unknown - - -
3705 Unknown 3705 Unknown - - -
3706 Unknown 3706 Unknown - - -
3707 Unknown 3707 Unknown - - -
3708 Unknown 3708 Unknown - - -
3709 Unknown 3709 Unknown - - -
3710 Unknown 3710 Unknown - - -
Can't render this file because it has a wrong number of fields in line 3.

View File

@ -55,39 +55,77 @@ class Item:
self.quantity = quantity self.quantity = quantity
class ResearchItem: class ResearchRequirement:
"""
Requires that item database be loaded first.
"""
research_ids = None requirements = None
@classmethod @classmethod
def load_ids(cls, item_filename): def load_requirements(cls, requirement_filename):
if cls.research_ids is not None: if cls.requirements is not None:
return return
else: cls.requirements = {}
cls.research_ids = {}
with open(item_filename, 'r') as item_file: with open(requirement_filename, 'r') as requirement_file:
item_reader = csv.reader(item_file, delimiter='\t') item_reader = csv.reader(requirement_file, delimiter='\t')
for row in item_reader: for row in item_reader:
# console.print(row) if len(row) == 0 or row[0][0] == "#":
if len(row) == 0 or row[0][0] == '#':
continue continue
cls.research_ids[int(row[0])] = row[1].strip() id = int(row[0])
name = row[1]
workbench_items = None
if row[2] != '-':
workbench_items = {}
wb_items = row[2].split(',')
for wbi in wb_items:
quantity = wbi[0]
code = int(wbi[2:])
workbench_items[quantity] = Item.get_name_from_code(code)
first_level_research = row[3] if row[3] != '-' else None
second_level_research = row[4] if row[4] != '-' else None
req = ResearchRequirement(id, name, workbench_items, first_level_research, second_level_research)
cls.requirements[id] = req
@classmethod @classmethod
def get_name_from_code(cls, code): def get_name_from_code(cls, code):
return cls.research_ids.get(code, None) if cls.research_ids is not None else None return cls.requirements[code].name
def __init__(self, id, active_stage, paused, states, tag): @classmethod
def test_listing(cls):
for k, v in cls.requirements.items():
console.print("{} : {} : {} : {}".format(k, v.name, v.first_level_research, v.second_level_research))
if v.workbench_items is not None:
for x, y in v.workbench_items.items():
console.print("{} : {}".format(x, y))
def __init__(self, id, name, workbench_items, first_level_research, second_level_research):
self.id = id self.id = id
self.name = ResearchItem.get_name_from_code(id) self.name = name
self.workbench_items = workbench_items
self.first_level_research = first_level_research
self.second_level_research = second_level_research
class ResearchItem:
def __init__(self, id, num_stages, active_stage, paused, states, tag):
self.id = id
self.name = ResearchRequirement.get_name_from_code(id)
# Paused is self-explanatory I assume but appears rarely used
self.paused = paused self.paused = paused
self.num_stages = num_stages
# activeStageIndex results (i.e. 1, 2) should correspond to the number of states for the research item (always 1 or 2) - a value of 0 means no active stage
self.active_stage = active_stage self.active_stage = active_stage
# Measures of the status of each sub-state for the research item
self.stage_states = states self.stage_states = states
# A reference to the actual tag for convenience
self.tag = tag self.tag = tag
# Do not forgot the <benchTaskStates> which appears to be related to the state of research workbench pre-research requirements
def __str__(self): def __str__(self):
return "{} : {} : {}".format(self.id, self.name, self.active_stage) return "{} : {} : {} : {}".format(self.id, self.name, self.num_stages, self.active_stage)
class ResearchItemState: class ResearchItemState:
@ -304,9 +342,8 @@ class Ship:
console.print("Total number of new items: {}".format(len(new_items))) console.print("Total number of new items: {}".format(len(new_items)))
console.print("Total number of unique codes: {}".format(len(unique_codes))) console.print("Total number of unique codes: {}".format(len(unique_codes)))
new_amount = 0 new_amount = 0
for item in new_items: for item in new_items:
new_amount += item.quantity new_amount += item.quantity
console.print(new_amount) console.print(new_amount)
@ -321,7 +358,7 @@ class Ship:
if area.get_total_occupancy() < min_occupancy: if area.get_total_occupancy() < min_occupancy:
min_area = area min_area = area
min_area.items.append(item) min_area.items.append(item)
item_number = 0 item_number = 0
for area in normal_storage_areas: for area in normal_storage_areas:
for item in area.items: for item in area.items:
@ -329,7 +366,6 @@ class Ship:
console.print("{} : {} : {}".format(item.code, item.name, item.quantity)) console.print("{} : {} : {}".format(item.code, item.name, item.quantity))
console.print("Item number: {}".format(item_number)) console.print("Item number: {}".format(item_number))
def consolidate_weapons(self): def consolidate_weapons(self):
normal_storage_areas = [sa for sa in self.storage_areas if sa.is_normal_storage] normal_storage_areas = [sa for sa in self.storage_areas if sa.is_normal_storage]
for area in normal_storage_areas: for area in normal_storage_areas:
@ -354,6 +390,7 @@ class GameData:
self.soup = soup self.soup = soup
self.item_database = item_database self.item_database = item_database
self.base_res_tag = None
def populate(self): def populate(self):
# Step 1 - Player data # Step 1 - Player data
@ -437,6 +474,7 @@ class GameData:
# Step 5 - Research Data # Step 5 - Research Data
# console.print('Finding research...') # console.print('Finding research...')
res_tag = self.soup.find("research", treeId=True) res_tag = self.soup.find("research", treeId=True)
self.base_res_tag = res_tag.find('states')
item_ids = [] item_ids = []
for item in res_tag.find_all('l', techId=True): for item in res_tag.find_all('l', techId=True):
active_stage = int(item['activeStageIndex']) active_stage = int(item['activeStageIndex'])
@ -454,7 +492,7 @@ class GameData:
blocksdone = [int(blocksdone_tag['level1']), int(blocksdone_tag['level2']), int(blocksdone_tag['level3'])] blocksdone = [int(blocksdone_tag['level1']), int(blocksdone_tag['level2']), int(blocksdone_tag['level3'])]
ris = ResearchItemState(done, stage_no, blocksdone) ris = ResearchItemState(done, stage_no, blocksdone)
stages.append(ris) stages.append(ris)
ri = ResearchItem(techId, active_stage, paused, stages, item) ri = ResearchItem(techId, len(stages), active_stage, paused, stages, item)
self.research.append(ri) self.research.append(ri)
""" """
@ -481,6 +519,7 @@ class GameData:
""" """
Step 1 - Update characters Step 1 - Update characters
Step 2 - Update storage areas Step 2 - Update storage areas
Step 3 - Update research
""" """
# Step 1 - Update characters # Step 1 - Update characters
@ -523,6 +562,7 @@ class GameData:
new_mood_tag.append(new_submood_tag) new_mood_tag.append(new_submood_tag)
condition_tag.append(new_tag) condition_tag.append(new_tag)
# Step 2 - Update storage areas
for storage_area in ship.storage_areas: for storage_area in ship.storage_areas:
area_tag = storage_area.tag area_tag = storage_area.tag
area_tag.clear() area_tag.clear()
@ -531,6 +571,7 @@ class GameData:
new_tag = self.soup.new_tag('s', attrs=tag_dict) new_tag = self.soup.new_tag('s', attrs=tag_dict)
area_tag.append(new_tag) area_tag.append(new_tag)
# Step 3 - Update research
for research_item in self.research: for research_item in self.research:
pass pass
@ -636,7 +677,8 @@ class GameData:
ship.redistribute_storage() ship.redistribute_storage()
def list_research(self): def list_research(self):
for research in sorted(self.research, key=lambda item:item.id): return
for research in sorted(self.research, key=lambda item: item.id):
console.print(research) console.print(research)
for ris in research.stage_states: for ris in research.stage_states:
console.print(ris) console.print(ris)
@ -705,8 +747,9 @@ def main():
Character.load_ids('char_skills.tsv', 'char_attributes.tsv', 'char_traits.tsv', 'char_conditions.tsv') Character.load_ids('char_skills.tsv', 'char_attributes.tsv', 'char_traits.tsv', 'char_conditions.tsv')
console.print("Character code database successfully loaded.") console.print("Character code database successfully loaded.")
console.print() console.print()
ResearchItem.load_ids('research2.tsv') ResearchRequirement.load_requirements('research2.tsv')
console.print("Research name database successfully loaded.") ResearchRequirement.test_listing()
console.print("Research requirements successfully loaded.")
console.print() console.print()
game_data = GameData(soup, Item) game_data = GameData(soup, Item)
@ -763,7 +806,8 @@ def main():
if args.list_research: if args.list_research:
console.print("Listing research status...") console.print("Listing research status...")
game_data.list_research() # game_data.list_research()
console.print(len(ResearchRequirement.requirements))
if args.consolidate_weapons: if args.consolidate_weapons:
console.print("Consolidating weapons...") console.print("Consolidating weapons...")