@@ 7,13 7,39 @@ import struct
class PlanetsData(object):
"""Base class for all Planets data objects"""
COUNT = None # Default number of objects in a data file
- PACK_LENGTH = None # Length of binary data fo single object
- id = None # Every object needs an id (if not set, generated automatically)
+ PACK_LENGTH = None # Length of binary data for single object
+ PACK_FORMAT = None # Format of binary data for single object
+ FIELDS = ()
+
+ def __init__(self):
+ for field in self.FIELDS:
+ # Dictionary field: see EngSpec class in fixed.py for an example
+ if isinstance(field, tuple):
+ setattr(self, str(field[0])+'['+str(field[1])+']', None)
+ else:
+ setattr(self, field, None)
+ self.id = None
+ def __setattr__(self, name, value):
+ """__setattr__() is modified to rstrip() space padded BASIC strings"""
+ if isinstance(value, str):
+ value = value.rstrip()
+ object.__setattr__(self, name, value)
+
def unpack(self, data):
"""Unpacks binary data into class instance variables"""
- raise NotImplementedError
-
+ if len(data) is not self.PACK_LENGTH:
+ raise ValueError('Binary data passed has incorrect length')
+ values = struct.unpack(self.PACK_FORMAT, data)
+ if len(self.FIELDS) is not len(values):
+ raise ValueError('Incorrect number of variables in pack format')
+ for name, value in zip(self.FIELDS, values):
+ # Dictionary field: see EngSpec class in fixed.py for an example
+ if isinstance(name, tuple):
+ setattr(self, str(name[0])+'['+str(name[1])+']', value)
+ else:
+ setattr(self, name, value)
+
@classmethod
def load(cls, data, count=None):
"""Unpacks binary data into a list of object instances"""
@@ 3,103 3,72 @@ Classes for reading files that are const
such as the "spec" and name lists, which are used by both client and host.
"""
-import struct
from common import PlanetsData
class BeamSpec(PlanetsData):
"""List of starship beam weapons"""
COUNT = 10
PACK_LENGTH = 36
- name = ''
- cost = 0
- tritanium = 0
- duranium = 0
- molybdenum = 0
- mass = 0
- tech = 0
- kill = 0
- damage = 0
-
- def unpack(self, data):
- (self.name, self.cost, self.tritanium, self.duranium, self.molybdenum,
- self.mass, self.tech, self.kill, self.damage) = struct.unpack(
- '< 20s h h h h h h h h', data)
- self.name = self.name.rstrip()
+ PACK_FORMAT = '< 20s h h h h h h h h'
+ FIELDS = ('name',
+ 'cost',
+ 'tritanium',
+ 'duranium',
+ 'molybdenum',
+ 'mass',
+ 'tech',
+ 'kill',
+ 'damage')
class EngSpec(PlanetsData):
"""List of starship engines"""
COUNT = 9
PACK_LENGTH = 66
- name = ''
- cost = 0
- tritanium = 0
- duranium = 0
- molybdenum = 0
- tech = 0
- mileage = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0}
-
- def unpack(self, data):
- if len(data) is not self.PACK_LENGTH:
- raise ValueError('Binary data passed has incorrect length')
- # Reinitialize mileage dict or it will not be seen as instance variable
- self.mileage = {}
- (self.name, self.cost, self.tritanium, self.duranium, self.molybdenum,
- self.tech, self.mileage[1], self.mileage[2], self.mileage[3],
- self.mileage[4], self.mileage[5], self.mileage[6],
- self.mileage[7], self.mileage[8], self.mileage[9]) = struct.unpack(
- '< 20s h h h h h i i i i i i i i i', data)
- self.name = self.name.rstrip()
+ PACK_FORMAT = '< 20s h h h h h i i i i i i i i i'
+ FIELDS = ('name',
+ 'cost',
+ 'tritanium',
+ 'duranium',
+ 'molybdenum',
+ 'tech',
+ ('mileage', 1,), ('mileage', 2,), ('mileage', 3,),
+ ('mileage', 4,), ('mileage', 5,), ('mileage', 6,),
+ ('mileage', 7,), ('mileage', 8,), ('mileage', 9,))
class HullSpec(PlanetsData):
"""List of starship hulls"""
# No COUNT, but typically 105 objects in default HULLSPEC.DAT
PACK_LENGTH = 60
- name = ''
- picture = 0
- damaged = 0 # Unused field for picture of damaged ship
- tritanium = 0
- duranium = 0
- molybdenum = 0
- fueltank = 0
- crew = 0
- engines = 0
- mass = 0
- tech = 0
- cargo = 0
- fighterbays = 0
- torpedolaunchers = 0
- beams = 0
- cost = 0
-
- def unpack(self, data):
- if len(data) is not self.PACK_LENGTH:
- raise ValueError('Binary data passed has incorrect length')
- (self.name, self.picture, self.damaged, self.tritanium, self.duranium,
- self.molybdenum, self.fueltank, self.crew, self.engines, self.mass,
- self.tech, self.cargo, self.fighterbays, self.torpedolaunchers,
- self.beams, self.cost) = struct.unpack(
- '< 30s h h h h h h h h h h h h h h h', data)
- self.name = self.name.rstrip()
-
+ PACK_FORMAT = '< 30s h h h h h h h h h h h h h h h'
+ FIELDS = ('name',
+ 'picture',
+ 'damaged', # Unused field for picture of damaged ship
+ 'tritanium',
+ 'duranium',
+ 'molybdenum',
+ 'fueltank',
+ 'crew',
+ 'engines',
+ 'mass',
+ 'tech',
+ 'cargo',
+ 'fighterbays',
+ 'torpedolaunchers',
+ 'beams',
+ 'cost')
+
class TorpSpec(PlanetsData):
"""List of starship torpedo weapons"""
COUNT = 10
PACK_LENGTH = 38
- name = ''
- torpedo_cost = 0
- launcher_cost = 0
- tritanium = 0
- duranium = 0
- molybdenum = 0
- mass = 0
- tech = 0
- kill = 0
- damage = 0
-
- def unpack(self, data):
- if len(data) is not self.PACK_LENGTH:
- raise ValueError('Binary data passed has incorrect length')
- (self.name, self.torpedo_cost, self.launcher_cost, self.tritanium,
- self.duranium, self.molybdenum, self.mass, self.tech, self.kill,
- self.damage) = struct.unpack('< 20s h h h h h h h h h', data)
- self.name = self.name.rstrip()
No newline at end of file
+ PACK_FORMAT = '< 20s h h h h h h h h h'
+ FIELDS = ('name',
+ 'torpedo_cost',
+ 'launcher_cost',
+ 'tritanium',
+ 'duranium',
+ 'molybdenum',
+ 'mass',
+ 'tech',
+ 'kill',
+ 'damage')
No newline at end of file