def initialise(self): """\ Minisec """ dbconn.use(self.game) trans = dbconn.begin() try: RulesetBase.initialise(self) # Need to create the top level universe object... universe = Object(type='tp.server.rules.base.objects.Universe') universe.id = 0 universe.name = "The Universe" universe.size = SIZE universe.parent = 0 universe.posx = 0 universe.posy = 0 universe.turn = 0 universe.insert() trans.commit() except: trans.rollback() raise
def turns(self, turns=0): obj = Object(self.oid) xd, yd, zd = self.pos[0] - obj.posx, self.pos[1] - obj.posy, self.pos[ 2] - obj.posz distance = math.sqrt(xd**2 + yd**2 + zd**2) return away(distance / obj.speed()) + turns
def populate(self, seed, system_min, system_max, planet_min, planet_max): """\ --populate <game> <random seed> <min systems> <max systems> <min planets> <max planets> Populate a universe with a number of systems and planets. The number of systems in the universe is dictated by min/max systems. The number of planets per system is dictated by min/max planets. """ dbconn.use(self.game) trans = dbconn.begin() try: MinisecRuleset.populate(self, seed, system_min, system_max, planet_min, planet_max) # Add a random smattering of resources to planets... r = random.Random() r.seed(int(seed)) for planetid, time in Object.bytype('tp.server.rules.base.objects.Planet'): planet = Object(id=planetid) ids = r.sample(range(1, 4), r.randint(0, 3)) for id in ids: planet.resources_add(id, r.randint(0, 10), Planet.ACCESSABLE) planet.resources_add(id, r.randint(0, 100), Planet.MINABLE) planet.resources_add(id, r.randint(0, 1000), Planet.INACCESSABLE) planet.save() trans.commit() except: trans.rollback() raise
def do(self, action): # We are going to have to modify the object so lets load it obj = Object(self.oid) # Work out what the maximum speed of this object is speed = obj.speed() xd, yd, zd = self.pos[0] - obj.posx, self.pos[1] - obj.posy, self.pos[2] - obj.posz if action == 'finalise': # Make sure that we haven't missed the object if (obj.velx, obj.vely, obj.velz) != (0,0,0): if xd*obj.velx < 0 or yd*obj.vely < 0 or zd*obj.velz < 0: print "Object %i (%s) has overshot destination %s to (%i, %i, %i)" % \ (obj.id, obj.name, self.pos, obj.velx, obj.vely, obj.velz) obj.posx, obj.posy, obj.posz = self.pos ReparentOne(obj) obj.save() # Have we reached our destination? if self.pos == (obj.posx, obj.posy, obj.posz): print "Object %i (%s) has arrived at destination (%i, %i, %i)" % \ (obj.id, obj.name, obj.posx, obj.posy, obj.posz) obj.velx = obj.vely = obj.velz = 0 obj.save() self.remove() # Send a message to the owner that the object has arrived... message = Message() message.bid = obj.owner message.slot = -1 message.subject = "%s arrived" % obj.name message.body = """%s has arrive at it's destination (%i, %i, %i).""" % \ (obj.name, obj.posx, obj.posy, obj.posz) message.insert() return elif action == 'prepare': distance = math.sqrt(xd**2 + yd**2 + zd**2) if distance == 0: return # Set the velocity so we are moving towards self.pos at speed velx = away(closest(speed * xd/distance, xd)) vely = away(closest(speed * yd/distance, yd)) velz = away(closest(speed * zd/distance, zd)) if (velx, vely, velz) != (obj.velx, obj.vely, obj.velz): print "Setting velocity of object %i to %r currently at %r destination %r" % (obj.id, (velx, vely, velz), (obj.posx, obj.posy, obj.posz), self.pos) obj.velx, obj.vely, obj.velz = velx, vely, velz obj.save() return else: raise Exception("Unknown action!")
def ReparentOne(obj): # Reparent the object parents = Object.bypos([obj.posx, obj.posy, obj.posz], size=0, orderby=Object.bypos_size) print "Possible parents", parents obj.parent = 0 parents = [id for (id, time) in parents if Object(id).type != obj.type] if parents: obj.parent = parents[0] else: print "No parents left! Using Universe."
class Planet(Object, Combattant): attributes = { \ 'owner': Object.Attribute('owner', -1, 'public'), 'resources': Object.Attribute('resources', {}, 'protected'), } orderclasses = ('tp.server.rules.base.orders.NOp', 'tp.server.rules.minisec.orders.BuildFleet') def ghost(self): """\ Planets never die - even when owned by the universe. """ return False ############################################# # Combat functions ############################################# damage = 0 def dead(self): """\ Planets are dead went delt 12 damage. """ return self.damage > 12 def damage_do(self, damage): if type(amount) in (TupleType, ListType): for a in amount: self.damage_do(a) return self.damage = self.damage + damage def damage_get(self, fail=False): return (6, 2)[fail] def fn_resources(self, value=None): res = [] for id, values in self.resources.items(): res.append((id, values[0], values[1], values[2])) return res def resources_add(self, resource, amount, type=ACCESSABLE): if not self.resources.has_key(resource): self.resources[resource] = [0, 0, 0] self.resources[resource][type] += amount if self.resources[resource][type] < 0: raise TypeError("Resources some how became negative!")
def h(obj): if obj.type == "sobjects.Fleet": parent = Object(obj.parent) if parent.type == "sobjects.Planet": if obj.owner == parent.owner: print "Healing %s (%s) because orbiting %s (%s)" % (obj.name, obj.id, parent.name, parent.id) obj.damage = {} obj.save()
def do(self): # We need the original fleet fleet1 = Object(self.oid) # We need the other fleet if self.fleet != -1: fleet2 = Object(self.fleet) message = Message() message.slot = -1 message.bid = fleet1.owner message.subject = "Merge Fleet failed." # Check the other object is actually a fleet... if self.fleet == -1 or fleet2.type.endswith('Fleet'): # Send message about the owner not matching... message.body = """\ The merge failed (of %s) because the merge target wasn't a fleet! The merge order has been removed. """ % (fleet1.name) message.insert() self.remove() return # Check they have the same owner :) if fleet1.owner != fleet2.owner: # Send message about the owner not matching... message.body = """\ The merge between %s and %s failed because you didn't own both fleets. The merge order has been removed. """ % (fleet1.name, fleet2.name) message.insert() self.remove() return # Check they are at the same position if (fleet1.posx, fleet1.posy, fleet1.posz) != (fleet2.posx, fleet2.posy, fleet2.posz): return # Merge the fleets for type, number in fleet1.ships.items(): if fleet2.ships.has_key(type): fleet2.ships[type] += number else: fleet2.ships[type] = number del fleet1.ships[type] fleet1.save() # Remove the other fleet fleet2.remove() self.remove()
def do(self): # We need the original fleet fleet1 = Object(self.oid) # Create the new fleet fleet2 = copy.deepcopy(fleet1) fleet2.name = self.call fleet2.ships = {} # Add the ships to the new fleet for type, number in self.ships: if fleet1.ships[type] - number > 0: fleet1.ships[type] -= number fleet2.ships[type] = number else: fleet2.ships[type] = fleet1.ships[type] fleet1.ships[type] = 0 fleet1.save() fleet2.insert() self.remove()
def WalkUniverse(top, order, callback, *args, **kw): """\ Walks around the universe and calls a command for each object. If the first argument is "before" parents will be called before there children. If the first argument is "after" parents will be called after there children. """ if order == "before": callback(top, *args, **kw) for id in top.contains(): WalkUniverse(Object(id), order, callback, *args, **kw) if order == "after": callback(top, *args, **kw)
class Universe(Object): attributes = {'turn': Object.Attribute('turn', 0, 'public')}
def do(self): # We are going to have to modify the object so lets load it fleet = Object(self.oid) planet = Object(self.target) # Do checks :) message = Message() message.slot = -1 message.bid = fleet.owner message.subject = "Colonise failed." if planet.posx != fleet.posx or planet.posy != fleet.posy or planet.posz != planet.posz: print "Colonise of Planet %s (%s) (by %s-%s) failed. The fleet was not orbiting the planet!" % (planet.id, planet.name, fleet.id, fleet.name) message.body = """\ Colonise of %s <b>failed</b> because %s was not orbiting the planet.<br> The order has been removed.""" % (planet.name, fleet.name) message.insert() self.remove() return if not planet.type.endswith('Planet'): print "Colonise of Planet %s (%s) (by %s-%s) failed. %s not a planet!" % (planet.id, planet.name, fleet.id, fleet.name, planet.name) message.body = """\ Colonise of %s <b>failed</b> because %s is not a Planet!<br> The order has been removed.""" % (planet.name, planet.name) message.insert() self.remove() return if not planet.owner in (-1, 0): print "Colonise of Planet %s (%s) (by %s-%s) failed. %s is owned by %s." % (planet.id, planet.name, fleet.id, fleet.name, planet.name, planet.owner) message.body = """\ Colonise of %s <b>failed</b> because %s is already colonised by %s!<br> You can decolonised the planet by bombing the bejesus out of it. The order has been removed.""" % (planet.name, planet.name, planet.owner) message.insert() self.remove() return if not fleet.ships.has_key(Frigate) or fleet.ships[Frigate] < 1: print "Colonise of Planet %s (%s) (by %s-%s) failed. %s has no frigates." % (planet.id, planet.name, fleet.id, fleet.name, fleet.name) message.body = """\ Colonise of %s <b>failed</b> because %s does not have any Frigates!<br> The order has been removed.""" % (planet.name, fleet.name) message.insert() self.remove() return print "Colonise of Planet %s (%s) (by %s-%s) succeeded." % (planet.id, planet.name, fleet.id, fleet.name) message.subject = "Colonise success." message.body = """\ Colonisation of %s <b>succeded</b>.""" % (planet.name,) message.insert() planet.owner = fleet.owner fleet.ships[Frigate] -= 1 planet.save() fleet.save() self.remove()
def initialise(self, seed=None): """\ TIM Trader """ trans = dbconn.begin() try: RulesetBase.initialise(self) # Need to create the top level universe object... universe = Object(type='tp.server.rules.base.objects.Universe') universe.id = 0 universe.name = "The Universe" universe.size = SIZE universe.parent = 0 universe.posx = 0 universe.posy = 0 universe.turn = 0 universe.insert() # Create all the resources, they consist of, # - One resource for each resource specified in resources.csv # - One resource for each factory specified in prodcon.csv reader = csv.DictReader( open(os.path.join(self.files, "resources.csv"), "r")) for row in reader: if row['namesingular'] is '': continue r = Resource() for name, cell in row.iteritems(): if cell is '': continue try: setattr(r, name, convert(getattr(Resource.table.c, name), cell)) except AttributeError, e: # FIXME: These shouldn't really occur... pass r.transportable = bool(row['transportable']) r.insert() import ProducersConsumers for factory in ProducersConsumers.loadfile( os.path.join(self.files, "prodcon.csv")): # FIXME: Make these auto generated resources much nicer... # Ignore the special case factories which are also goods. try: r = Resource(Resource.byname(factory.name)) r.desc += "\n" except NoSuch: r = Resource() r.namesingular = factory.name r.nameplural = factory.name r.desc = "" r.weight = 1000 r.size = 1000 r.desc += "Converts" for product in factory.products: # FIXME: Should also display if usage of this resource is required to grow.... r.desc += "\n\t%s -> %s" % product r.products = factory.products r.save() trans.commit()
def populate(self, seed, system_min, system_max, planet_min, planet_max): """\ --populate <game> <random seed> <min systems> <max systems> <min planets> <max planets> Populate a universe with a number of systems and planets. The number of systems in the universe is dictated by min/max systems. The number of planets per system is dictated by min/max planets. """ seed, system_min, system_max, planet_min, planet_max = ( int(seed), int(system_min), int(system_max), int(planet_min), int(planet_max)) dbconn.use(self.game) trans = dbconn.begin() try: # FIXME: Assuming that the Universe and the Galaxy exist. r = random.Random() r.seed(int(seed)) # Create this many systems for i in range(0, r.randint(system_min, system_max)): pos = r.randint(SIZE * -1, SIZE) * 1000, r.randint( SIZE * -1, SIZE) * 1000, r.randint(SIZE * -1, SIZE) * 1000 # Add system system = Object(type='tp.server.rules.base.objects.System') system.name = "System %s" % i system.size = r.randint(800000, 2000000) system.posx = pos[0] system.posy = pos[1] system.insert() ReparentOne(system) system.save() print "Created system (%s) with the id: %i" % (system.name, system.id) # In each system create a number of planets for j in range(0, r.randint(planet_min, planet_max)): planet = Object(type='tp.server.rules.base.objects.Planet') planet.name = "Planet %i in %s" % (j, system.name) planet.size = r.randint(1000, 10000) planet.parent = system.id planet.posx = pos[0] + r.randint(1, 100) * 1000 planet.posy = pos[1] + r.randint(1, 100) * 1000 planet.insert() print "Created planet (%s) with the id: %i" % (planet.name, planet.id) trans.commit() except: trans.rollback() raise
def populate(self, seed, system_min, system_max, planet_min, planet_max): """\ --populate <game> <random seed> <min systems> <max systems> <min planets> <max planets> Populate a universe with a number of systems and planets. The number of systems in the universe is dictated by min/max systems. The number of planets per system is dictated by min/max planets. """ # Convert arguments to integers seed, system_min, system_max, planet_min, planet_max = ( int(seed), int(system_min), int(system_max), int(planet_min), int(planet_max)) dbconn.use(self.game) trans = dbconn.begin() try: RulesetBase.populate(self, seed) r = Resource(Resource.byname('Ship Parts Factory')) # FIXME: Assuming that the Universe and the Galaxy exist. r = random.Random() r.seed(seed) # Create the actual systems and planets. for i in range(0, r.randint(system_min, system_max)): pos = r.randint(SIZE * -1, SIZE) * 1000, r.randint( SIZE * -1, SIZE) * 1000, r.randint(SIZE * -1, SIZE) * 1000 # Add system system = Object(type='tp.server.rules.base.objects.System') system.name = "System %s" % i system.size = r.randint(800000, 2000000) system.posx = pos[0] system.posy = pos[1] system.insert() ReparentOne(system) system.save() print "Created system (%s) with the id: %i" % (system.name, system.id) # In each system create a number of planets for j in range(0, r.randint(planet_min, planet_max)): planet = Object( type='tp.server.rules.timtrader.objects.Planet') planet.name = "Planet %i in %s" % (j, system.name) planet.size = r.randint(1000, 10000) planet.parent = system.id planet.posx = pos[0] + r.randint(1, 100) * 1000 planet.posy = pos[1] + r.randint(1, 100) * 1000 planet.insert() print "Created planet (%s) with the id: %i" % (planet.name, planet.id) # FIXME: Add minerals Iron, Uranium mine = False for mineral in minerals: # Does this planet have this mineral if r.random() * 100 > mineral.probability: # Add a smattering of minerals planet.resources_add(id, r.randint(0, mineral.density), Planet.MINEABLE) mine = True # Add a mine to each planet which has minerals if mine: planet.resources_add(Resource.byname('Mine'), 1, Planet.ACCESSABLE) # FIXME: Add growing resources for grow in growing: if r.random() * 100 > grow.probability: # Add a smattering of breeding grounds planet.resources_add(Resource.byname(''), 1, Planet.ACCESSABLE) # Add a smattering of the same stocks planet.resources_add(Resource.byname(''), r.randint(0, grow.density), Planet.MINEABLE) # Add 1 fishery/slaughter house to each location # FIXME: Add a other industries in random locations for factory in factories: pass # FIXME: Add a bunch of cities planet.save() trans.commit() except: trans.rollback() raise
def player(self, username, password, email='Unknown', comment='A Minisec Player'): """\ Create a Solar System, Planet, and initial Fleet for the player, positioned randomly within the Universe. """ dbconn.use(self.game) trans = dbconn.begin() try: user = RulesetBase.player(self, username, password, email, comment) # FIXME: Hack! This however means that player x will always end up in the same place.. r = random.Random() r.seed(user.id) pos = r.randint(SIZE * -1, SIZE) * 1000, r.randint( SIZE * -1, SIZE) * 1000, r.randint(SIZE * -1, SIZE) * 1000 system = Object(type='tp.server.rules.base.objects.System') system.name = "%s Solar System" % username system.parent = 0 system.size = r.randint(800000, 2000000) (system.posx, system.posy, junk) = pos ReparentOne(system) system.owner = user.id system.save() planet = Object(type='tp.server.rules.timtrader.objects.Planet') planet.name = "%s Planet" % username planet.parent = system.id planet.size = 100 planet.posx = system.posx + r.randint(1, 100) * 1000 planet.posy = system.posy + r.randint(1, 100) * 1000 planet.owner = user.id # Get the player's planet object and add the empire capital planet.resources_add(Resource.byname('Header Quarter'), 1) planet.resources_add(Resource.byname('Credit'), 10000) planet.save() fleet = Object(type='tp.server.rules.minisec.objects.Fleet') fleet.parent = planet.id fleet.size = 3 fleet.name = "%s First Fleet" % username fleet.ships = {1: 3} (fleet.posx, fleet.posy, fleet.posz) = (planet.posx, planet.posy, planet.posz) fleet.owner = user.id fleet.save() trans.commit() except: trans.rollback() raise
def populate(self, seed, system_min, system_max, planet_min, planet_max): """\ --populate <game> <random seed> <min systems> <max systems> <min planets> <max planets> Populate a universe with a number of systems and planets. The number of systems in the universe is dictated by min/max systems. The number of planets per system is dictated by min/max planets. """ dbconn.use(self.game) trans = dbconn.begin() try: MinisecRuleset.populate(self, seed, system_min, system_max, planet_min, planet_max) # Add a random smattering of resources to planets... r = random.Random() r.seed(int(seed)) for planetid, time in Object.bytype( 'tp.server.rules.base.objects.Planet'): planet = Object(id=planetid) ids = r.sample(range(1, 4), r.randint(0, 3)) for id in ids: planet.resources_add(id, r.randint(0, 10), Planet.ACCESSABLE) planet.resources_add(id, r.randint(0, 100), Planet.MINABLE) planet.resources_add(id, r.randint(0, 1000), Planet.INACCESSABLE) planet.save() trans.commit() except: trans.rollback() raise
def do(top): universe = Object(id=0) universe.turn += 1 print "Turn number is now", universe.turn universe.save()
def turns(self, turns=0): obj = Object(self.oid) xd, yd, zd = self.pos[0] - obj.posx, self.pos[1] - obj.posy, self.pos[2] - obj.posz distance = math.sqrt(xd**2 + yd**2 + zd**2) return away(distance/obj.speed()) + turns
def initialise(self, seed=None): """\ TIM Trader """ trans = dbconn.begin() try: RulesetBase.initialise(self) # Need to create the top level universe object... universe = Object(type='tp.server.rules.base.objects.Universe') universe.id = 0 universe.name = "The Universe" universe.size = SIZE universe.parent = 0 universe.posx = 0 universe.posy = 0 universe.turn = 0 universe.insert() # Create all the resources, they consist of, # - One resource for each resource specified in resources.csv # - One resource for each factory specified in prodcon.csv reader = csv.DictReader(open(os.path.join(self.files, "resources.csv"), "r")) for row in reader: if row['namesingular'] is '': continue r = Resource() for name, cell in row.iteritems(): if cell is '': continue try: setattr(r, name, convert(getattr(Resource.table.c, name), cell)) except AttributeError, e: # FIXME: These shouldn't really occur... pass r.transportable = bool(row['transportable']) r.insert() import ProducersConsumers for factory in ProducersConsumers.loadfile(os.path.join(self.files, "prodcon.csv")): # FIXME: Make these auto generated resources much nicer... # Ignore the special case factories which are also goods. try: r = Resource(Resource.byname(factory.name)) r.desc += "\n" except NoSuch: r = Resource() r.namesingular = factory.name r.nameplural = factory.name r.desc = "" r.weight = 1000 r.size = 1000 r.desc += "Converts" for product in factory.products: # FIXME: Should also display if usage of this resource is required to grow.... r.desc += "\n\t%s -> %s" % product r.products = factory.products r.save() trans.commit()
def do(self, action): # We are going to have to modify the object so lets load it obj = Object(self.oid) # Work out what the maximum speed of this object is speed = obj.speed() xd, yd, zd = self.pos[0] - obj.posx, self.pos[1] - obj.posy, self.pos[ 2] - obj.posz if action == 'finalise': # Make sure that we haven't missed the object if (obj.velx, obj.vely, obj.velz) != (0, 0, 0): if xd * obj.velx < 0 or yd * obj.vely < 0 or zd * obj.velz < 0: print "Object %i (%s) has overshot destination %s to (%i, %i, %i)" % \ (obj.id, obj.name, self.pos, obj.velx, obj.vely, obj.velz) obj.posx, obj.posy, obj.posz = self.pos ReparentOne(obj) obj.save() # Have we reached our destination? if self.pos == (obj.posx, obj.posy, obj.posz): print "Object %i (%s) has arrived at destination (%i, %i, %i)" % \ (obj.id, obj.name, obj.posx, obj.posy, obj.posz) obj.velx = obj.vely = obj.velz = 0 obj.save() self.remove() # Send a message to the owner that the object has arrived... message = Message() message.bid = obj.owner message.slot = -1 message.subject = "%s arrived" % obj.name message.body = """%s has arrive at it's destination (%i, %i, %i).""" % \ (obj.name, obj.posx, obj.posy, obj.posz) message.insert() return elif action == 'prepare': distance = math.sqrt(xd**2 + yd**2 + zd**2) if distance == 0: return # Set the velocity so we are moving towards self.pos at speed velx = away(closest(speed * xd / distance, xd)) vely = away(closest(speed * yd / distance, yd)) velz = away(closest(speed * zd / distance, zd)) if (velx, vely, velz) != (obj.velx, obj.vely, obj.velz): print "Setting velocity of object %i to %r currently at %r destination %r" % ( obj.id, (velx, vely, velz), (obj.posx, obj.posy, obj.posz), self.pos) obj.velx, obj.vely, obj.velz = velx, vely, velz obj.save() return else: raise Exception("Unknown action!")
def player(self, username, password, email='Unknown', comment='A Minisec Player'): """\ Create a Solar System, Planet, and initial Fleet for the player, positioned randomly within the Universe. """ dbconn.use(self.game) trans = dbconn.begin() try: user = RulesetBase.player(self, username, password, email, comment) # FIXME: Hack! This however means that player x will always end up in the same place.. r = random.Random() r.seed(user.id) pos = r.randint(SIZE*-1, SIZE)*1000, r.randint(SIZE*-1, SIZE)*1000, r.randint(SIZE*-1, SIZE)*1000 system = Object(type='tp.server.rules.base.objects.System') system.name = "%s Solar System" % username system.parent = 0 system.size = r.randint(800000, 2000000) (system.posx, system.posy, junk) = pos ReparentOne(system) system.owner = user.id system.save() planet = Object(type='tp.server.rules.base.objects.Planet') planet.name = "%s Planet" % username planet.parent = system.id planet.size = 100 planet.posx = system.posx+r.randint(1,100)*1000 planet.posy = system.posy+r.randint(1,100)*1000 planet.owner = user.id planet.save() fleet = Object(type='tp.server.rules.minisec.objects.Fleet') fleet.parent = planet.id fleet.size = 3 fleet.name = "%s First Fleet" % username fleet.ships = {1:3} (fleet.posx, fleet.posy, fleet.posz) = (planet.posx, planet.posy, planet.posz) fleet.owner = user.id fleet.save() trans.commit() return (user, system, planet, fleet) except: trans.rollback() raise
def populate(self, seed, system_min, system_max, planet_min, planet_max): """\ --populate <game> <random seed> <min systems> <max systems> <min planets> <max planets> Populate a universe with a number of systems and planets. The number of systems in the universe is dictated by min/max systems. The number of planets per system is dictated by min/max planets. """ seed, system_min, system_max, planet_min, planet_max = (int(seed), int(system_min), int(system_max), int(planet_min), int(planet_max)) dbconn.use(self.game) trans = dbconn.begin() try: # FIXME: Assuming that the Universe and the Galaxy exist. r = random.Random() r.seed(int(seed)) # Create this many systems for i in range(0, r.randint(system_min, system_max)): pos = r.randint(SIZE*-1, SIZE)*1000, r.randint(SIZE*-1, SIZE)*1000, r.randint(SIZE*-1, SIZE)*1000 # Add system system = Object(type='tp.server.rules.base.objects.System') system.name = "System %s" % i system.size = r.randint(800000, 2000000) system.posx = pos[0] system.posy = pos[1] system.insert() ReparentOne(system) system.save() print "Created system (%s) with the id: %i" % (system.name, system.id) # In each system create a number of planets for j in range(0, r.randint(planet_min, planet_max)): planet = Object(type='tp.server.rules.base.objects.Planet') planet.name = "Planet %i in %s" % (j, system.name) planet.size = r.randint(1000, 10000) planet.parent = system.id planet.posx = pos[0]+r.randint(1,100)*1000 planet.posy = pos[1]+r.randint(1,100)*1000 planet.insert() print "Created planet (%s) with the id: %i" % (planet.name, planet.id) trans.commit() except: trans.rollback() raise
def turn(self): """ generate a turn for this ruleset For simple rulesets (and some reasonably complicated ones), this default method works. This method performs orders and actions in the order dictated via the orderOfOrders attribute. The program treats actions and orders almost identically. For example, If orderOfOrders contained, [MoveAction, Nop, (Clean, 'fleetsonly')] The move action would be applied first. Then all NOp orders would be performed. Then the Clean action would be applied with the argument ('fleetsonly') """ # Create a turn processing lock dbconn.use(self.game) lock = Lock.new('processing') # Connect to the database trans = dbconn.begin() try: # FIXME: This won't work as if a move then colonise order occurs, # and the move order completed the colonise order won't be # performed. It also removes the ability for dummy orders to be # removed. # # Get all the orders d = OrderGet() print d for action in self.orderOfOrders: if type(action) == TupleType: action, args = action[0], action[1:] else: args = tuple() name = str(action.__name__) if "orders" in name: green("%s - Starting with" % name, args) if d.has_key(name): for order in d[name]: order.do(*args) else: print "No orders of that type avaliable.." green("%s - Finished" % name) elif "actions" in name: blue("%s - Starting with" % name, args) __import__(name, globals(), locals(), ["do"]).do(Object(0), *args) blue("%s - Finished" % name) sys.stdout.write("\n") # Reparent the universe # Create a EOT event Event.new('endofturn', self.game) trans.commit() except: dbconn.rollback() raise
def do(self): builder = Object(self.oid) # FIXME: Check that this is a planet # FIXME: Check that this planet has the headquarter resource if False: print "Could not do a build order because it was on a planet headquaters. (This should not happen.)" self.remove() # Check that there are enough components to build this ship... # Build new fleet object fleet = Object(type='tp.server.rules.minisec.objects.Fleet') # Check if there is a design which matches this amount of components. If not create it... # Type Fleet fleet.parent = builder.id fleet.posx = builder.posx fleet.posy = builder.posy fleet.posz = builder.posz fleet.size = 1 fleet.owner = builder.owner fleet.ships = self.ships fleet.insert() fleet.name = self.name fleet.save() message = Message() message.slot = -1 message.bid = builder.owner message.subject = "Fleet built" message.body = """\ A new ship (%s) has been built and is orbiting %s. """ % (fleet.name, builder.name) message.insert() self.remove()
class Fleet(Object, Combattant): __metaclass__ = ShipTypes attributes = { \ 'owner': Object.Attribute('owner', -1, 'public'), 'ships': Object.Attribute('ships', {}, 'protected'), 'damage': Object.Attribute('damage', {}, 'protected'), } orderclasses = ( 'tp.server.rules.base.orders.NOp', 'tp.server.rules.minisec.orders.Move', 'tp.server.rules.minisec.orders.SplitFleet', 'tp.server.rules.base.orders.MergeFleet', 'tp.server.rules.base.orders.Colonise', ) def fn_ships(self, value=None): if value == None: return self.ships.items() def fn_damage(self, value=None): if value == None: return sum(map(sum, self.damage.values())) totaldamage = 0 for type, damage in self.damage: if type in self.ships.keys(): for d in damage: totaldamage += damage return totaldamage def tidy(self): """\ Fix up the ships and damage stuff. """ # Run a consistancy check # Check the ships actually exist for t, number in self.ships.items(): if number < 1: del self.ships[t] # Check the damage goes to the right place for t, damage in self.damage.items(): if not t in self.ships.keys(): del self.damage[t] def ghost(self): """\ Returns if the fleet has no ships. """ self.tidy() return len(self.ships.keys()) < 1 ############################################# # Movement functions ############################################# def speed(self): """\ Returns the maximum speed of the fleet. """ return self.ship_speed[max(self.ships.keys())] ############################################# # Combat functions ############################################# def dead(self): """\ Checks if this object is a can still participate in combat. """ return self.ghost() or self.ships.keys() == [ 0, ] def damage_do(self, amount): """\ Damages a fleet. Can be called with either a single integer or a tuple of integers. """ if type(amount) in (TupleType, ListType): for a in amount: self.damage_do(a) return self.tidy() # Find the largest ship type. s = self.ships.keys() s.sort() s.reverse() t = s[0] if not self.damage.has_key(t): self.damage[t] = [] damage = self.damage[t] # Condense the damage if len(damage) + 1 > self.ships[t]: damage.sort() if damage[0] + amount >= self.ship_hp[t]: damage[-1] += amount else: damage[0] += amount else: damage.append(amount) if damage[-1] >= self.ship_hp[t]: self.ships[t] -= 1 if self.ships[t] < 1: del self.ships[t] del damage[-1] def damage_get(self, fail=False): """\ Returns the amount of damage this fleet can do. """ r = [] for type, no in self.ships.items(): r.extend([self.ship_damage[type][fail]] * no) return r
def do(self): builder = Object(self.oid) if not hasattr(builder, "owner"): print "Could not do a build order because it was on an unownable object." self.remove() if self.turns() > 1: # Add another year to worked... self.worked += 1 print "Worked %s, %s left until built." % (self.worked, self.turns()) self.save() return # Build new fleet object fleet = Object(type='tp.server.rules.minisec.objects.Fleet') # Type Fleet fleet.parent = builder.id fleet.posx = builder.posx fleet.posy = builder.posy fleet.posz = builder.posz fleet.size = 1 fleet.owner = builder.owner fleet.ships = self.ships fleet.insert() fleet.name = self.name fleet.save() message = Message() message.slot = -1 message.bid = builder.owner message.subject = "Fleet built" message.body = """\ A new fleet (%s) has been built and is orbiting %s. It consists of: """ % (fleet.name, builder.name) for type, number in fleet.ships.items(): if number > 1: message.body += "%s %ss" % (number, Fleet.ship_types[type]) else: message.body += "%s %s" % (number, Fleet.ship_types[type]) message.insert() self.remove()
def populate(self, seed, system_min, system_max, planet_min, planet_max): """\ --populate <game> <random seed> <min systems> <max systems> <min planets> <max planets> Populate a universe with a number of systems and planets. The number of systems in the universe is dictated by min/max systems. The number of planets per system is dictated by min/max planets. """ # Convert arguments to integers seed, system_min, system_max, planet_min, planet_max = (int(seed), int(system_min), int(system_max), int(planet_min), int(planet_max)) dbconn.use(self.game) trans = dbconn.begin() try: RulesetBase.populate(self, seed) r = Resource(Resource.byname('Ship Parts Factory')) # FIXME: Assuming that the Universe and the Galaxy exist. r = random.Random() r.seed(seed) # Create the actual systems and planets. for i in range(0, r.randint(system_min, system_max)): pos = r.randint(SIZE*-1, SIZE)*1000, r.randint(SIZE*-1, SIZE)*1000, r.randint(SIZE*-1, SIZE)*1000 # Add system system = Object(type='tp.server.rules.base.objects.System') system.name = "System %s" % i system.size = r.randint(800000, 2000000) system.posx = pos[0] system.posy = pos[1] system.insert() ReparentOne(system) system.save() print "Created system (%s) with the id: %i" % (system.name, system.id) # In each system create a number of planets for j in range(0, r.randint(planet_min, planet_max)): planet = Object(type='tp.server.rules.timtrader.objects.Planet') planet.name = "Planet %i in %s" % (j, system.name) planet.size = r.randint(1000, 10000) planet.parent = system.id planet.posx = pos[0]+r.randint(1,100)*1000 planet.posy = pos[1]+r.randint(1,100)*1000 planet.insert() print "Created planet (%s) with the id: %i" % (planet.name, planet.id) # FIXME: Add minerals Iron, Uranium mine = False for mineral in minerals: # Does this planet have this mineral if r.random()*100 > mineral.probability: # Add a smattering of minerals planet.resources_add(id, r.randint(0, mineral.density), Planet.MINEABLE) mine = True # Add a mine to each planet which has minerals if mine: planet.resources_add(Resource.byname('Mine'), 1, Planet.ACCESSABLE) # FIXME: Add growing resources for grow in growing: if r.random()*100 > grow.probability: # Add a smattering of breeding grounds planet.resources_add(Resource.byname(''), 1, Planet.ACCESSABLE) # Add a smattering of the same stocks planet.resources_add(Resource.byname(''), r.randint(0, grow.density), Planet.MINEABLE) # Add 1 fishery/slaughter house to each location # FIXME: Add a other industries in random locations for factory in factories: pass # FIXME: Add a bunch of cities planet.save() trans.commit() except: trans.rollback() raise