class NOp(Order): """\ Wait around and do nothing... """ typeno = 0 attributes = {\ 'wait': Order.Attribute("wait", 0, 'protected', type=netlib.objects.constants.ARG_TIME, desc="How long to wait for.") } def do(self): self.wait -= 1 if self.wait <= 0: self.remove() else: self.save() def turns(self, turns=0): return self.wait + turns def resources(self): return [] def fn_wait(self, value=None): if value is None: return self.wait, -1 else: self.wait = value[0]
class Mine(Order): """\ Turn a mineable resource into a surface resource. """ typeno = 6 attributes = {\ 'resource': Order.Attribute("resource", 0, 'public', type=netlib.objects.constants.ARG_RANGE, desc="Which resource to dig up."), 'amount': Order.Attribute("amount", 0, 'public', type=netlib.objects.constants.ARG_RANGE, desc="How much to dig up.") } def do(self): pass def turns(self, turns=0): return turns def resources(self): return []
class Move(Order): """\ Move to a point in space. """ typeno = 1 attributes = {\ 'pos': Order.Attribute("pos", (0,0,0), 'public', type=netlib.objects.constants.ARG_ABS_COORD, desc="Where to go.") } 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 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 resources(self): return []
class BuildFleet(Order): """\ Build a new star ship from components at your head quaters.""" typeno = 2 attributes = {\ 'parts': Order.Attribute("parts", {}, 'protected', type=netlib.objects.constants.ARG_LIST, desc="Parts to build the ship from."), 'name': Order.Attribute("name", 'New Fleet', 'protected', type=netlib.objects.constants.ARG_STRING, desc="The new fleet's name.") } 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() def resources(self): return self.parts.items() def fn_parts(self, value=None): cid = Category.byname('Ship Parts') if value == None: returns = [] for rid in Resource.bycategory(cid) r = Resource(rid) returns.append((r.id, r.name, -1)) return returns, self.parts.items() else: parts = {} for rid, number in value[1]: try: r = Resource(rid) if r.categories in cid: raise NoSuch() except NoSuch: raise ValueError("Invalid ship part selected.") parts[rid] = number self.parts = parts def fn_name(self, value=None): if value == None: return (255, self.name) else: self.name = value[1]
class Colonise(Order): """\ Colonise the planet this fleet is orbiting. Will use one frigate class ship. """ typeno = 5 attributes = {\ 'target': Order.Attribute("target", -1, 'public', type=netlib.objects.constants.ARG_OBJECT, desc="ID of object to colonise."), } 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 turns(self, turns=0): return 1 + turns def resources(self): return []
class BuildFleet(Order): """\ Build a new star ship fleet.""" typeno = 2 attributes = {\ 'ships': Order.Attribute("ships", {}, 'protected', type=netlib.objects.constants.ARG_LIST, desc="Ships to build and launch."), 'name': Order.Attribute("name", 'New Fleet', 'protected', type=netlib.objects.constants.ARG_STRING, desc="The new fleet's name.") } 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 turns(self, turns=0): time = {0:1, 1:2, 2:4} for type, number in self.ships.items(): turns += time[type] * number return turns-self.worked def resources(self): return [] def fn_ships(self, value=None): if value == None: returns = [] for type, name in Fleet.ship_types.items(): returns.append((type, name, -1)) return returns, self.ships.items() else: ships = {} try: for type, number in value[1]: if not type in Fleet.ship_types.keys(): raise ValueError("Invalid type selected") ships[type] = number except: pass self.ships = ships def fn_name(self, value=None): if value == None: return (255, self.name) else: self.name = value[1]
class SplitFleet(Order): """\ Split some ships into a new fleet. """ typeno = 3 attributes = {\ 'call': Order.Attribute("call", "New Fleet", 'protected', type=netlib.objects.constants.ARG_STRING, desc="What to call the new fleet."), 'ships': Order.Attribute("ships", {}, 'protected', type=netlib.objects.constants.ARG_LIST, desc="Ships to move into new fleet.") } 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 simulate(self): pass def turns(self, turns=0): return turns + 1 def resources(self): return [] def fn_call(self, value=None): if value == None: return [0, self.call] else: self.call = value[1] def fn_ships(self, value=None): max = self.object.ships if value == None: returns = [] for type, number in max.items(): returns.append((type, Fleet.ship_types[type], number)) print returns, self.ships.items() return returns, self.ships.items() else: ships = {} try: for type, number in value[1]: if not type in Fleet.ship_types.keys(): raise ValueError("Invalid type selected") if number > max[type]: raise ValueError("Number to big") ships[type] = number except ValueError: pass self.ships = ships