Extensive additions to class structure.
This commit is contained in:
parent
c2b438d918
commit
b00912b1e1
269
characters.py
269
characters.py
|
@ -1,16 +1,74 @@
|
|||
import sys, argparse
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
char_skills = {
|
||||
1 : "Piloting",
|
||||
2 : "Mining",
|
||||
3 : "Botany",
|
||||
4 : "Construction",
|
||||
5 : "Industry",
|
||||
6 : "Medical",
|
||||
7 : "Gunner",
|
||||
8 : "Shielding",
|
||||
9 : "Operations",
|
||||
10 : "Weapons",
|
||||
12 : "Logistics",
|
||||
13 : "Unknown",
|
||||
14 : "Navigation",
|
||||
16 : "Research",
|
||||
}
|
||||
|
||||
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):
|
||||
pass
|
||||
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):
|
||||
pass
|
||||
return self.id_dict[code]
|
||||
|
||||
def validate_code(self, code):
|
||||
pass
|
||||
return code in self.id_dict
|
||||
|
||||
|
||||
# A single item with its code, name, and quantity
|
||||
|
@ -25,28 +83,36 @@ class Item:
|
|||
# A single storage area, with a list of contents (Items)
|
||||
class StorageArea:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
def __init__(self, tag):
|
||||
self.tag = tag
|
||||
self.items = []
|
||||
|
||||
def add_item(self, item):
|
||||
pass
|
||||
self.items.append(item)
|
||||
|
||||
# Returns how full the storage area is based on its contents
|
||||
def total_occupancy(self):
|
||||
pass
|
||||
def get_total_occupancy(self):
|
||||
total_quantity = 0
|
||||
for item in self.items:
|
||||
total_quantity += item.quantity
|
||||
return total_quantity
|
||||
|
||||
|
||||
class Character:
|
||||
# Will need an internal sense of what the codes mean for string output purposes
|
||||
|
||||
def __init__(self, name):
|
||||
def __init__(self, name, tag):
|
||||
self.name = name
|
||||
self.tag = tag
|
||||
|
||||
def set_skills(self, skill_array):
|
||||
pass
|
||||
self.skills = {}
|
||||
self.attributes = {}
|
||||
|
||||
def set_attributes(self, attribute_array):
|
||||
pass
|
||||
def set_skills(self, skill_list):
|
||||
self.skills = skill_list
|
||||
|
||||
def set_attributes(self, attribute_list):
|
||||
self.attributes = attribute_list
|
||||
|
||||
def maximize_skills(self):
|
||||
pass
|
||||
|
@ -54,7 +120,146 @@ class Character:
|
|||
def maximize_attributes(self):
|
||||
pass
|
||||
|
||||
# How will we get all this back into the XML file though??
|
||||
def clone(self, new_name):
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return "{} - {} - {}".format(self.name, repr(self.skills), repr(self.attributes))
|
||||
|
||||
|
||||
class Ship:
|
||||
|
||||
def __init__(self, name, owner, state, tag):
|
||||
self.name = name
|
||||
self.owner = owner
|
||||
self.state = state
|
||||
self.tag = tag # Soup tag corresponding to this ship's node
|
||||
|
||||
self.storage_areas = []
|
||||
self.characters = []
|
||||
|
||||
def add_storage_area(self, storage_area):
|
||||
self.storage_areas.append(storage_area)
|
||||
|
||||
def add_character(self, character):
|
||||
self.characters.append(character)
|
||||
|
||||
|
||||
class Player:
|
||||
|
||||
def __init__(self, currency):
|
||||
self.currency = currency
|
||||
|
||||
|
||||
class GameData:
|
||||
|
||||
def __init__(self, soup, item_database):
|
||||
self.player = None
|
||||
self.ships = []
|
||||
|
||||
self.soup = soup
|
||||
self.item_database = item_database
|
||||
|
||||
def populate(self):
|
||||
# Step 1 - Player data
|
||||
char_tag = self.soup.find('playerBank')
|
||||
currency = char_tag['ca']
|
||||
self.player = Player(currency)
|
||||
|
||||
# Step 2 - Ship data
|
||||
ship_tags = self.soup.find_all('ship')
|
||||
|
||||
for ship_tag in ship_tags:
|
||||
ship_name = ship_tag['sname']
|
||||
|
||||
owner_node = ship_tag.find('settings', owner=True)
|
||||
ship_owner = owner_node['owner']
|
||||
ship_state = owner_node['state']
|
||||
|
||||
ship = Ship(ship_name, ship_owner, ship_state, ship_tag)
|
||||
self.ships.append(ship)
|
||||
|
||||
# Step 3 - Storage area data
|
||||
for inv_tag in ship_tag.find_all('feat', eatAllowed=True):
|
||||
storage_area = StorageArea(inv_tag)
|
||||
ship.add_storage_area(storage_area)
|
||||
# Items within storage area
|
||||
for s_tag in inv_tag.find_all('s'):
|
||||
item_code = int(s_tag['elementaryId'])
|
||||
item_name = self.item_database.get_name_from_code(item_code)
|
||||
item_quantity = int(s_tag['inStorage'])
|
||||
item = Item(item_code, item_name, item_quantity)
|
||||
storage_area.add_item(item)
|
||||
# print("{:4}: {} - {}".format(item_code, item_name, item_quantity))
|
||||
|
||||
# Step 4 - Character data
|
||||
for character_list in ship_tag.find_all('characters'):
|
||||
character_tags = character_list.find_all('c', attrs={'name':True})
|
||||
for character_tag in character_tags:
|
||||
char_name = character_tag['name']
|
||||
character = Character(char_name, character_tag)
|
||||
ship.add_character(character)
|
||||
|
||||
skills = []
|
||||
skill_tag = character_tag.find('skills')
|
||||
for sk_tag in skill_tag.find_all('s'):
|
||||
skill_id = sk_tag['sk']
|
||||
skill_level = sk_tag['level']
|
||||
skill_mxn = sk_tag['mxn']
|
||||
skill_exp = sk_tag['exp']
|
||||
skill_expd = sk_tag['expd']
|
||||
skill_dict = {
|
||||
'id' : int(skill_id),
|
||||
'level' : int(skill_level),
|
||||
'mxn' : int(skill_mxn),
|
||||
'exp' : int(skill_exp),
|
||||
'expd' : int(skill_expd),
|
||||
}
|
||||
skills.append(skill_dict)
|
||||
character.set_skills(skills)
|
||||
|
||||
attributes = []
|
||||
attribute_tag = character_tag.find('attr')
|
||||
for a_tag in attribute_tag.find_all('a'):
|
||||
attribute_id = a_tag['id']
|
||||
attribute_points = a_tag['points']
|
||||
attribute_dict = {
|
||||
'id' : int(attribute_id),
|
||||
'points' : int(attribute_points),
|
||||
}
|
||||
attributes.append(attribute_dict)
|
||||
character.set_attributes(attributes)
|
||||
|
||||
"""
|
||||
Need to find player
|
||||
Need to find ships
|
||||
Within ships, need to find:
|
||||
- Storage areas, then items within storage areas
|
||||
- Characters, then names, skills, attributes etc
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def writeback(self):
|
||||
# Purpose of this mission is to take all our data and replace the relevant parts of the soup
|
||||
# Suspect this may be harder than it sounds - original saved game editor more or less deleted and rewrote some sections (e.g. item lists)
|
||||
pass
|
||||
|
||||
def print_summary(self):
|
||||
print("Start game summary:")
|
||||
print(" Player currency: {}".format(self.player.currency))
|
||||
print(" Number of ships: {}".format(len(self.ships)))
|
||||
|
||||
for ship in self.ships:
|
||||
print(" {} (owner {}, state {})".format(ship.name, ship.owner, ship.state))
|
||||
print(" Contains {} storage area(s):".format(len(ship.storage_areas)))
|
||||
for index, storage_area in enumerate(ship.storage_areas):
|
||||
print(" Storage area {} - contains {} item(s) - occupancy {} unit(s)".format(index, len(storage_area.items), storage_area.get_total_occupancy()))
|
||||
print(" Has {} character(s):".format(len(ship.characters)))
|
||||
for char in ship.characters:
|
||||
print(" {}".format(char.name))
|
||||
print(" {}".format(repr(char)))
|
||||
|
||||
|
||||
def characters(soup):
|
||||
for character in soup.find_all('characters'):
|
||||
|
@ -160,6 +365,29 @@ def give_money(soup, amount):
|
|||
bank_tag['ca'] = amount
|
||||
|
||||
|
||||
def list_ships(soup):
|
||||
|
||||
ship_tags = soup.find_all('ship')
|
||||
|
||||
for ship_tag in ship_tags:
|
||||
ship_name = ship_tag['sname']
|
||||
|
||||
"""
|
||||
settings_nodes = ship_tag.find_all('settings')
|
||||
for settings_node in settings_nodes:
|
||||
if settings_node.has_attr('owner'):
|
||||
ship_owner = settings_node['owner']
|
||||
else:
|
||||
continue
|
||||
"""
|
||||
owner_node = ship_tag.find('settings', owner=True)
|
||||
ship_owner = owner_node['owner']
|
||||
ship_state = owner_node['state']
|
||||
print('Ship found: {} owned by {} (state: {})'.format(ship_name, ship_owner, ship_state))
|
||||
|
||||
# print(settings_node)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(prog="Space Haven Saved Game Inspector", description="As above.")
|
||||
|
||||
|
@ -167,6 +395,8 @@ def main():
|
|||
parser.add_argument('--add_item', required=False, metavar='N', type=int, nargs=2, help="Add more of an existing item to storage by CODE - refer to accompanying data file reference for codes. First number is the code, second is the desired quantity.")
|
||||
parser.add_argument('--buff_chars', required=False, action='store_true', help="For all characters, increases all skills and attributes to maximum. Use wisely.")
|
||||
parser.add_argument('--money', required=False, type=int, nargs=1, help="Give the player credits of the specified amount")
|
||||
parser.add_argument('--list_ships', required=False, action='store_true', help="List all ships with names and their respective owners")
|
||||
parser.add_argument('--test_gamedata', required=False, action='store_true', help="Test of new class-based system of storing game information")
|
||||
|
||||
args = parser.parse_args()
|
||||
# print(args)
|
||||
|
@ -202,6 +432,17 @@ def main():
|
|||
print('Increasing money to the given amount...')
|
||||
give_money(soup, args.money[0])
|
||||
|
||||
if args.list_ships:
|
||||
list_ships(soup)
|
||||
|
||||
if args.test_gamedata:
|
||||
item_code_database = ItemCodeDatabase('item_ids.txt')
|
||||
print("Item code database successfully loaded")
|
||||
|
||||
game_data = GameData(soup, item_code_database)
|
||||
game_data.populate()
|
||||
game_data.print_summary()
|
||||
|
||||
text = soup.prettify()
|
||||
# Delete XML header - game doesn't have it
|
||||
sansfirstline = '\n'.join(text.split('\n')[1:])
|
||||
|
|
Loading…
Reference in New Issue