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
예제 #2
0
    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
예제 #4
0
	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!")
예제 #5
0
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."
예제 #6
0
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!")
예제 #7
0
	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 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()
예제 #11
0
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 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 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()
예제 #15
0
    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
예제 #17
0
    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
예제 #18
0
    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
예제 #19
0
    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
예제 #20
0
def do(top):
    universe = Object(id=0)
    universe.turn += 1
    print "Turn number is now", universe.turn
    universe.save()
예제 #21
0
def do(top):
	universe = Object(id=0)
	universe.turn += 1
	print "Turn number is now", universe.turn
	universe.save()
예제 #22
0
	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()
예제 #24
0
    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
예제 #27
0
    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
예제 #28
0
	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()
예제 #29
0
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
예제 #30
0
	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