More functions added.

This commit is contained in:
Chris Davoren 2023-08-30 13:50:24 +10:00
parent a99f66bbbe
commit 4c827cbec5
5 changed files with 192 additions and 5 deletions

View File

@ -4,3 +4,4 @@ python sheditor.py %1 --replace-original --add-item-set pack_medical.txt
python sheditor.py %1 --replace-original --add-item-set pack_trade.txt
python sheditor.py %1 --replace-original --add-item-set pack_weapons_basic.txt
python sheditor.py %1 --replace-original --add-item-set pack_weapons_advanced.txt
python sheditor.py %1 --replace-original --add-item-set pack_fuel.txt

View File

@ -5,3 +5,4 @@
712 30 # Space food
2657 20 # Nuts and seeds
71 20 # Biomatter
16 50 # Water

5
pack_fuel.txt Normal file
View File

@ -0,0 +1,5 @@
# Fuel Pack
172 200 # Hyperium
158 100 # Energium
178 100 # Hyperfuel
174 50 # Energy rods

76
research2.tsv Normal file
View File

@ -0,0 +1,76 @@
# Tree id 2535
2532 Unknown
2533 Unknown
2539 Unknown
2559 Unknown
2563 Unknown
2564 Unknown
2565 Unknown
2566 Unknown
2567 Unknown
2568 Unknown
2569 Unknown
2570 Unknown
2571 Unknown
2572 Unknown
2573 Unknown
2575 Unknown
2576 Unknown
2577 Unknown
2589 Unknown
2590 Unknown
2591 Unknown
2592 Unknown
2594 Unknown
2595 Unknown
2596 Unknown
2597 Unknown
2598 Unknown
2599 Unknown
2600 Unknown
2601 Unknown
2602 Unknown
2604 Unknown
2605 Unknown
2606 Unknown
2607 Unknown
2612 Unknown
2613 Unknown
2614 Unknown
2617 Unknown
2619 Unknown
2622 Unknown
2623 Unknown
2626 Unknown
2628 Unknown
2629 Unknown
2630 Unknown
2694 Unknown
2847 Unknown
3024 Unknown
3025 Unknown
3114 Unknown
3115 Unknown
3116 Unknown
3119 Unknown
3122 Unknown
3124 Unknown
3125 Unknown
3127 Unknown
3128 Unknown
3129 Unknown
3130 Unknown
3417 Unknown
3420 Unknown
3421 Unknown
3422 Unknown
3423 Unknown
3464 Unknown
3704 Unknown
3705 Unknown
3706 Unknown
3707 Unknown
3708 Unknown
3709 Unknown
3710 Unknown
Can't render this file because it has a wrong number of fields in line 3.

View File

@ -12,6 +12,8 @@ DEFAULT_SAVEGAMEPATH = "c:\\Program Files (x86)\\GOG Galaxy\\Games\\SpaceHaven\\
# Only "normal storage" is used to insert requested items
normal_storage_ids = [82, 632]
weapon_ids = [726, 725, 3383, 760, 3069, 3070, 3071, 3072, 3384]
storage_ids = {
82: {"name": "Small storage", "capacity": 50},
632: {"name": "Large storage", "capacity": 250},
@ -51,6 +53,38 @@ class Item:
self.name = name
self.quantity = quantity
class ResearchItem:
research_ids = None
@classmethod
def load_ids(cls, item_filename):
if cls.research_ids is not None:
return
else:
cls.research_ids = {}
with open(item_filename, 'r') as item_file:
item_reader = csv.reader(item_file, delimiter='\t')
for row in item_reader:
# console.print(row)
if len(row) == 0 or row[0][0] == '#':
continue
cls.research_ids[int(row[0])] = row[1].strip()
@classmethod
def get_name_from_code(cls, code):
return cls.research_ids.get(code, None) if cls.research_ids is not None else None
def __init__(self, id, active_stage):
self.id = id
self.name = ResearchItem.get_name_from_code(id)
self.active_stage = active_stage
self.stage_states = []
def __str__(self):
return "{} : {} : {}".format(self.id, self.name, self.active_stage)
# A single storage area, with a list of contents (Items)
class StorageArea:
@ -132,6 +166,7 @@ class Character:
self.skills = []
self.attributes = []
self.conditions = []
def set_skills(self, skill_list):
# Expected format is a list of dictionaries
@ -156,6 +191,9 @@ class Character:
for attribute in self.attributes:
attribute['points'] = 6
def clear_conditions(self):
self.conditions = [1550, 2246, 3311]
def clone(self, new_name):
# How to deep copy the skills/attributes appropriately?
print("Cloning character {}".format(self.name))
@ -224,6 +262,13 @@ class Ship:
total += area.get_total_occupancy()
print(total)
def consolidate_weapons(self):
normal_storage_areas = [sa for sa in self.storage_areas if sa.is_normal_storage]
for area in normal_storage_areas:
for item in area.items:
if item.code in weapon_ids:
console.print("{} : {}".format(item.code, item.quantity))
class Player:
@ -237,6 +282,7 @@ class GameData:
def __init__(self, soup, item_database):
self.player = None
self.ships = []
self.research = []
self.soup = soup
self.item_database = item_database
@ -320,6 +366,20 @@ class GameData:
attributes.append(attribute_dict)
character.set_attributes(attributes)
# Step 5 - Research Data
# console.print('Finding research...')
res_tag = self.soup.find("research", treeId=True)
# console.print(res_tag)
item_ids = []
for item in res_tag.find_all('l', techId=True):
# console.print(item['techId'])
active_stage = int(item['activeStageIndex'])
techId = int(item['techId'])
item_ids.append(int(item['techId']))
self.research.append(ResearchItem(techId, active_stage))
# console.print(sorted(item_ids))
# [console.print(id) for id in sorted(item_ids)]
def writeback(self):
def replace_id(dict, old_key, new_key):
dict_copy = dict.copy()
@ -344,9 +404,9 @@ class GameData:
self.player.tag['ca'] = self.player.currency
for ship in self.ships:
# console.print('Doing chars...')
for character in ship.characters:
# Cloned character tags have to be added to the list
print('Doing chars...')
if character.is_clone:
print("ADDING CLONED CHARACTER")
charlist_tag = ship.tag.find('characters')
@ -365,6 +425,19 @@ class GameData:
new_tag = self.soup.new_tag('a', attrs=attribute)
attribute_tag.append(new_tag)
condition_tag = character.tag.find('conditions')
condition_tag.clear()
for condition in character.conditions:
attrs = { "id": str(condition), "level" : "1", "rs" : "1"}
new_tag = self.soup.new_tag('c', attrs=attrs)
# What do the <rec> tags mean with ht and wt attrs?
# What does the ac attr mean on the m mood sub tag mean?
new_mood_tag = self.soup.new_tag('mood')
new_submood_tag = self.soup.new_tag('m', ac="5")
new_tag.append(new_mood_tag)
new_mood_tag.append(new_submood_tag)
condition_tag.append(new_tag)
for storage_area in ship.storage_areas:
area_tag = storage_area.tag
area_tag.clear()
@ -387,13 +460,14 @@ class GameData:
for character in ship.characters:
character.maximize_skills()
character.maximize_attributes()
character.clear_conditions()
def add_currency(self, amount):
self.player.currency += amount
def clone_character(self, character_name, new_name):
print("Clone char method called")
print("Warning names are case sensitive!")
console.print("Clone char method called")
console.print("Warning names are case sensitive!")
for ship in self.ships:
for character in ship.characters:
if character.name == character_name:
@ -470,6 +544,15 @@ class GameData:
for ship in self.ships:
ship.redistribute_storage()
def list_research(self):
for research in self.research:
console.print(research)
def consolidate_weapons(self):
for ship in self.ships:
if ship.owner == "Player":
ship.consolidate_weapons()
def parse_item_file(filename):
@ -501,6 +584,8 @@ def main():
parser.add_argument('--detailed-items', required=False, action='store_true', help='Print a detailed item listing from player inventory')
parser.add_argument('--detailed-chars', required=False, action='store_true', help='Print a comprehensive listing of player character details')
parser.add_argument('--redistribute', required=False, action='store_true', help='Redistribute internal storage')
parser.add_argument('--list-research', required=False, action='store_true', help='List all research/research states')
parser.add_argument('--consolidate-weapons', required=False, action='store_true', help='Put all weapons in one storage area')
parser.add_argument('--replace-original', required=False, action='store_true', help='Replace original file instead of creating edited alternative. Renames original for backup, but USE WITH CAUTION')
args = parser.parse_args()
@ -527,6 +612,9 @@ def main():
Character.load_ids('char_skills.tsv', 'char_attributes.tsv', 'char_traits.tsv', 'char_conditions.tsv')
console.print("Character code database successfully loaded.")
console.print()
ResearchItem.load_ids('research2.tsv')
console.print("Research name database successfully loaded.")
console.print()
game_data = GameData(soup, Item)
game_data.populate()
@ -534,27 +622,32 @@ def main():
edits_made = False
if args.buff_chars:
console.print("Buffing chars...")
game_data.buff_characters()
edits_made = True
print("Buffed chars")
if args.add_item:
console.print("Adding item...")
game_data.add_item(args.add_item[0], args.add_item[1])
edits_made = True
if args.money:
console.print("Adding currency...")
game_data.add_currency(args.money[0])
edits_made = True
if args.list_ships:
console.print("Listing ships...")
game_data.print_summary()
if args.clone_character:
print("Clone char requested.")
console.print("Char clone requested...")
game_data.clone_character(args.clone_character[0], args.clone_character[1])
edits_made = True
if args.add_item_set:
console.print("Adding item set...")
item_list = parse_item_file(args.add_item_set[0])
# console.print(item_list)
console.print("Items to be added:")
@ -564,14 +657,25 @@ def main():
edits_made = True
if args.detailed_items:
console.print("Printing detailed item list...")
game_data.print_detailed_item_summary()
if args.detailed_chars:
console.print("Printing detailed character list...")
game_data.print_detailed_character_summary()
if args.redistribute:
console.print("Item redistribution requested...")
game_data.redistribute()
if args.list_research:
console.print("Listing research status...")
game_data.list_research()
if args.consolidate_weapons:
console.print("Consolidating weapons...")
game_data.consolidate_weapons()
game_data.writeback()
if args.test_gamedata: