Пример #1
0
	def update(self, scene):
		self.t += 1
		if self.alienq and self.t >= self.alienq[0][0]:
			t, atype = self.alienq.pop(0)
			if self.hq.attackable and random.random() < 0.25:
				target = self.hq
			else:
				targets = [b for b in self.buildings if b.attackable and b.hp >= 0]
				target = random.choice(targets)
			self.deploy(scene, target, atype)

		self.set_hq_attackable()
		if not self.vulnerable and self.hq.attackable:
			self.vulnerable = True
			jukebox.play_voice("all_shields_disabled")
		
		for a in self.attackers: a.update(scene)
		for b in self.buildings: b.update(scene)
		
		self.attackers = [a for a in self.attackers if a.alive]
		# re-choose target if mine is already gone
		for a in self.attackers:
			if a.target and a.target.hp <= 0:
				targets = [b for b in self.buildings if b.attackable and b.hp > 0]
				if targets:
					target = min(targets, key=lambda t: (a.x-t.x)**2 + (a.y-t.y)**2)
					a.settarget(target)
		
		if self.is_computer_attacking():
			for b in self.buildings:
				if b.hp <= 0 and b is not self.hq:
					b.destroy()
 def init_radar(self, left, top, right, bottom):
     x, y = self.building.getModelXY()
     self.radar_signal = network.send_radar(self.user_id,
                                            self.playscene.password, int(x),
                                            int(y))
     self.rx = x
     self.ry = y
     jukebox.play_voice("scanning")
Пример #3
0
    def update(self, scene):
        self.t += 1
        if self.alienq and self.t >= self.alienq[0][0]:
            t, atype = self.alienq.pop(0)
            if self.hq.attackable and random.random() < 0.25:
                target = self.hq
            else:
                targets = [
                    b for b in self.buildings if b.attackable and b.hp >= 0
                ]
                target = random.choice(targets)
            self.deploy(scene, target, atype)

        self.set_hq_attackable()
        if not self.vulnerable and self.hq.attackable:
            self.vulnerable = True
            jukebox.play_voice("all_shields_disabled")

        for a in self.attackers:
            a.update(scene)
        for b in self.buildings:
            b.update(scene)

        self.attackers = [a for a in self.attackers if a.alive]
        # re-choose target if mine is already gone
        for a in self.attackers:
            if a.target and a.target.hp <= 0:
                targets = [
                    b for b in self.buildings if b.attackable and b.hp > 0
                ]
                if targets:
                    target = min(targets,
                                 key=lambda t: (a.x - t.x)**2 + (a.y - t.y)**2)
                    a.settarget(target)

        if self.is_computer_attacking():
            for b in self.buildings:
                if b.hp <= 0 and b is not self.hq:
                    b.destroy()
	def build_thing(self, type):
		sx,sy = self.get_current_sector()
		x,y = self.player.getModelXY()
		s = structure.btypedict[type].size
		client_token = self.get_new_client_token()
		
		cost = structure.get_structure_resources(type)
		
		if not self.potato.build_within_count_limit(self.user_id, type):
			self.show_error('count_limit')
			return
		
		if not self.potato.is_within_sector(self.user_id, sx, sy, x, y, type):
			self.show_error('outside_sector')
			return
		
		if self.potato.is_touching_other_building(self.user_id, sx, sy, x, y, type):
			self.show_error('adjacency_error')
			jukebox.play_voice("adjacent_structures")
			return
		
		if not self.potato.is_within_borders(self.user_id, sx, sy, x, y, s):
			self.show_error('outside_border')
			jukebox.play_voice("outside_border")
			return
		
		if not self.potato.try_spend_resources(
			cost['food'],
			cost['water'],
			cost['aluminum'],
			cost['copper'],
			cost['silicon'],
			cost['oil']):
			self.show_error('insufficient_resources')
#			jukebox.play_voice("insufficient_resources")
			return

		self.poll.append(
			network.send_build(
				self.user_id, self.password,
				type,
				util.floor(sx), util.floor(sy), util.floor(x % 60), util.floor(y % 60), (util.floor(sx), util.floor(sy)), self.potato.last_id_by_sector, client_token)
			)
		jukebox.play_voice("constructing")
    def render_bot_factory(self, screen):
        self.bot_data = None

        if self.build_bot_command != None and self.build_bot_command.has_response(
        ):
            r = self.build_bot_command.get_response()
            if r != None:
                self.build_bot_command = None
                if r.get('success', False):
                    self.counts[0] = r.get('a', 0)
                    self.counts[1] = r.get('b', 0)
                    self.counts[2] = r.get('c', 0)
                    self.render_bot_factory_invalidate()
                else:
                    err = r.get('error', None)
                    if err == 'capacity':
                        jukebox.play_voice("arsenal_exceeded")
                    elif err == 'resources':
                        jukebox.play_voice("insufficient_resources")
                    else:
                        pass

        if not self.has_data:
            if self.bot_query.has_response():
                self.has_data = True
                results = self.bot_query.get_response()
                if results != None:
                    self.counts = [
                        results.get('a', 0),
                        results.get('b', 0),
                        results.get('c', 0)
                    ]
                    self.playscene.potato.apply_bot_snapshot(
                        self.counts[0], self.counts[1], self.counts[2])
                    left = 105
                    top = 90
                    self.totals = []
                    y = top

                    img = get_tiny_text("Builds " +
                                        settings.botnames[self.bot_type - 1] +
                                        's')
                    self.add_element(Image(left, y, img))
                    y += img.get_height()

                    img = get_tiny_text("(Limit 3 per " +
                                        ('Foundry', 'Machinery Lab',
                                         'Science Lab')[self.bot_type - 1] +
                                        ")")
                    self.add_element(Image(left, y, img))
                    y += img.get_height()

                    y += 5

                    for i in range(3):
                        y += 5 + self.add_label(
                            left, y, settings.botnames[i] + ": " +
                            str(self.counts[i]), 18)
                        self.totals.append(self.elements[-1])

                    handler = [self.add_bot1, self.add_bot2,
                               self.add_bot3][self.bot_type - 1]

                    costs = [
                        settings.BOT_COST_1, settings.BOT_COST_2,
                        settings.BOT_COST_3
                    ][self.bot_type - 1]

                    y += 13
                    rimages = []
                    for key in 'food water aluminum copper silicon oil'.split(
                            ' '):
                        if costs.get(key, 0) > 0:
                            rimages.append(get_resource_icon(key))
                            rimages.append(get_tiny_text(costs[key]))

                    x = left
                    for img in rimages:
                        self.add_element(Image(x, y, img))
                        x += img.get_width() + 2
                    y += 5
                    self.add_element(
                        Button(left, y + 10,
                               "Build " + settings.botnames[self.bot_type - 1],
                               handler, True))

            img = get_text("Cataloging the arsenal...", (255, 255, 255), 18)
            screen.blit(img,
                        (screen.get_width() // 2 - img.get_width() // 2,
                         screen.get_height() // 2 - img.get_height() // 2))

        if self.initialized:
            pass
	def init_radar(self, left, top, right, bottom):
		x, y = self.building.getModelXY()
		self.radar_signal = network.send_radar(self.user_id, self.playscene.password, int(x), int(y))
		self.rx = x
		self.ry = y
		jukebox.play_voice("scanning")
	def render_bot_factory(self, screen):
		self.bot_data = None
		
		if self.build_bot_command != None and self.build_bot_command.has_response():
			r = self.build_bot_command.get_response()
			if r != None:
				self.build_bot_command = None
				if r.get('success', False):
					self.counts[0] = r.get('a', 0)
					self.counts[1] = r.get('b', 0)
					self.counts[2] = r.get('c', 0)
					self.render_bot_factory_invalidate()
				else:
					err = r.get('error', None)
					if err == 'capacity':
						jukebox.play_voice("arsenal_exceeded")
					elif err == 'resources':
						jukebox.play_voice("insufficient_resources")
					else:
						pass
						
		
		if not self.has_data:
			if self.bot_query.has_response():
				self.has_data = True
				results = self.bot_query.get_response()
				if results != None:
					self.counts = [results.get('a', 0), results.get('b', 0), results.get('c', 0)]
					self.playscene.potato.apply_bot_snapshot(self.counts[0], self.counts[1], self.counts[2])
					left = 105
					top = 90
					self.totals = []
					y = top
					
					img = get_tiny_text("Builds " + settings.botnames[self.bot_type - 1] + 's')
					self.add_element(Image(left, y, img))
					y += img.get_height()
					
					img = get_tiny_text("(Limit 3 per " + ('Foundry', 'Machinery Lab', 'Science Lab')[self.bot_type - 1] + ")")
					self.add_element(Image(left, y, img))
					y += img.get_height()
					
					y += 5
					
					for i in range(3):
						y += 5 + self.add_label(left, y, settings.botnames[i] + ": " + str(self.counts[i]), 18)
						self.totals.append(self.elements[-1])
					
					handler = [self.add_bot1, self.add_bot2, self.add_bot3][self.bot_type - 1]

					costs = [
						settings.BOT_COST_1,
						settings.BOT_COST_2,
						settings.BOT_COST_3
					][self.bot_type - 1]
					
					y += 13
					rimages = []
					for key in 'food water aluminum copper silicon oil'.split(' '):
						if costs.get(key, 0) > 0:
							rimages.append(get_resource_icon(key))
							rimages.append(get_tiny_text(costs[key]))
					
					x = left
					for img in rimages:
						self.add_element(Image(x, y, img))
						x += img.get_width() + 2
					y += 5
					self.add_element(Button(left, y + 10, "Build " + settings.botnames[self.bot_type - 1], handler, True))
					
			img = get_text("Cataloging the arsenal...", (255, 255, 255), 18)
			screen.blit(img, (screen.get_width() // 2 - img.get_width() // 2, screen.get_height() // 2 - img.get_height() // 2))
			
		if self.initialized:
			pass
	def update(self, bdsoverride=True):
		
		bot_deploy_success = self.potato.deploy_success(bdsoverride)
		if bot_deploy_success != None:
			b = bot_deploy_success
			self.next = DeployBotsScene(self, b[0], b[1], b[2])
		
		if self.curiosity != None:
			self.curiosity.update()
			if self.curiosity.is_done():
				self.curiosity = None
		
		self.potato.update()
		self.poll_countdown -= 1
		if self.poll_countdown < 0 and len(self.poll) == 0:
			self.poll.append(network.send_poll(
				self.user_id, self.password,
				self.get_current_sector(),
				self.potato.last_id_by_sector))
		
		i = 0
		while i < len(self.poll):
			if self.poll[i].has_response():
				if not self.poll[i].is_error():
					self.potato.apply_poll_data(self.poll[i].get_response(), self.user_id)
				self.poll = self.poll[:i] + self.poll[i + 1:]
			else:
				i += 1

		if self.potato.queue_epic_battle and not self.potato.epic_battle_won and self.pendingbattle == None and self.battle == None:
		
			buildings = self.potato.get_all_buildings_of_player_SLOW(self.user_id)
			if not any(b.btype == "launchsite" for b in buildings):
				self.potato.queue_epic_battle = False
			else:
				bord = self.potato.borders_by_user[self.user_id]
				self.pendingbattle = battle.Battle(self.user_id, buildings, bord, None, nbytes=10000)
			
		
		if len(self.poll) == 0 and self.poll_countdown < 0:
			self.poll_countdown = 10 * settings.fps
		if self.battle is None:
			worldmap.killtime(0.01)  # Helps remove jitter when exploring

		# TODO: this could just as easily be called once every 100 frames or so.
		# Populate nearby sectors with aliens
		self.exploret += 1
		if not self.battle and self.exploret >= 10:
			self.explore()
		
		if self.battle != None:
			self.battle.update(self)
			if self.battle.is_complete(self):
				self.pendingbattle = 17  # dummy number
		
		px, py = self.player.getModelXY()
		bords = self.potato.get_borders_near_sector(int(px // 60), int(py // 60))
		t0 = time.time()
		for s in self.sprites:
			# HACK
			if (s.x - self.player.x) ** 2 + (s.y - self.player.y) ** 2 > 80 ** 2:
				continue
			s.update(self)
			if s.freerange:
				if any(border.iswithin(s.x, s.y) for border in bords):
					s.die()
#		print len(self.sprites), time.time() - t0
		self.player.update(self)
		for s in self.shots:
			s.update(self)
			s.handlealiens(self.sprites)
			if self.battle:
				s.handlealiens(self.battle.attackers)
		for s in self.sprites:
			if not s.alive and s.awardnumber is not None:
				network.send_alien_award(self.user_id, self.password, s.awardnumber)
		self.sprites = [s for s in self.sprites if s.alive]
		self.shots = [s for s in self.shots if s.alive]
		
		if not self.player.alive:
			self.player.x, self.player.y = terrain.toCenterRender(self.cx, self.cy + 1)
			self.player.healall()
			self.sprites.append(self.player)
			self.player.alive = True
		effects.update()
		
		if self.pendingbattle:
			self.blinkt += 1
			if self.blinkt >= 10:
				if self.pendingbattle == 17:   # ending a battle
					if self.battle:
						for building in self.battle.buildings:
							if building.destroyed:
								self.blow_stuff_up(*building.getModelXY())
							if building.btype == "fireturret":
								building.cleartargets()
						if self.battle.nbytes >= 10000:
							if self.battle.hq.hp == 0:
								self.blow_stuff_up(*self.battle.hq.getModelXY())
								jukebox.play_voice("research_failed")
							for building in self.battle.buildings:
								if building.hp > 0:
									building.healfull()
						elif self.battle.is_computer_attacking():
							for building in self.battle.buildings:
								if building.hp > 0:
									building.healfull()
							if self.battle.hq.hp > 0:
								jukebox.play_voice("research_successful")
							else:
								jukebox.play_voice("research_failed")
						else:
							if self.battle.hq.hp > 0:
								jukebox.play_voice("infiltration_failed")
							else:
								jukebox.play_voice("infiltration_successful")
							for building in self.battle.buildings:
								building.healfull()
						self.battle.hq.healfull()   # Repair the HQ after the battle
						self.battle = None
						self.pendingbattle = None
					self.explored = set()
				else:   # starting a battle
					jukebox.play_sound("klaxon")
					self.battle = self.pendingbattle
					if self.battle.is_computer_attacking():
						jukebox.play_voice("incoming_attack")
					self.sprites = [self.player]  # get rid of all the free range aliens
					self.pendingbattle = None
		elif self.blinkt:
			self.blinkt -= 1
	def process_input(self, events, pressed):
		
		if self.tutorial:
			if self.tutorial_instance.current_step == 5:
				x, y = self.player.getModelXY()
				if x > 85 and x < 94 and y > 27 and y < 39:
					self.tutorial_instance.current_step += 1
			pages = self.tutorial_instance.get_active_dialog()
			if pages != None:
				title = self.tutorial_instance.active_step()[0]
				self.toolbar.mode == 'main'
				self.next = TutorialDialogScene(self, pages, title, self.tutorial_instance.current_step == 6)
		
		building_menu = False
		demolish_building = False
		attack_building = False  # set to 0, 1, or 2 to be an attack type
		if self.curiosity != None:
			pass
		else:
			direction = ''
			dx, dy = 0, 0
			if pressed['up']: dy = 1.0
			if pressed['down']: dy = -1.0
			if pressed['left']: dx = -1.0
			if pressed['right']: dx = 1.0
			
			if dx != 0 and dy != 0:
				dx *= .7071
				dy *= .7071
			
			self.player.setrun(False)  # TODO: would be nice if we ran when you were holding down shift
			self.player.move(dx, dy)
			
			if self.battle:
				for event in events:
					if event.type == 'mouseleft':
						pass
					elif event.type == 'mousemove':
						pass
					elif event.type == 'key':
						if event.down and event.action in ('shoot', 'build'):
							self.shoot()
						elif event.down and event.action == 'b1':
							if not self.battle.is_computer_attacking():
								attack_building = 0
						elif event.down and event.action == 'b2':
							if not self.battle.is_computer_attacking():
								attack_building = 1
						elif event.down and event.action == 'b3':
							if not self.battle.is_computer_attacking():
								attack_building = 2
						elif event.down and event.action == 'f9':
							self.battle.forfeit()
			else:
				for event in events:
					if event.type == 'mouseleft':
						if event.down:
							self.toolbar.click(event.x, event.y, self.last_width, self)
					elif event.type == 'mousemove':
						self.mousex, self.mousey = event.x, event.y
						self.toolbar.hover(event.x, event.y, self.last_width)
					elif event.type == 'key':
						if event.down and event.action == 'debug':
							buildings = self.potato.get_all_buildings_of_player_SLOW(self.user_id)
							bord = self.potato.borders_by_user[self.user_id]
							self.pendingbattle = battle.Battle(self.user_id, buildings, bord, None)
						elif event.down and event.action == 'build':
							if self.build_mode != None:
								self.build_thing(self.build_mode)
							elif self.toolbar.mode == 'fight':
								self.shoot()
							elif self.toolbar.mode == 'demolish':
								demolish_building = True
						elif event.down and event.action == 'action':
							building_menu = True
						elif event.down and event.action == 'back':
							self.toolbar.press_back()
						elif event.down and event.action == 'shoot':
							self.shoot()
					elif event.type == 'type':
						self.toolbar.accept_key(event.action, self)
						
		you_x, you_y = terrain.toModel(self.player.x, self.player.y)
		selected_building = self.potato.get_building_selection(you_x, you_y)
		
		if building_menu and selected_building != None:
			if selected_building.user_id == self.user_id or selected_building.btype == 'radar':
				self.next = buildingmenu.BuildingMenu(self, selected_building)
		if demolish_building and selected_building != None:
			jukebox.play_voice("demolishing_please_stand_back")
			x, y = selected_building.getModelXY()
			self.blow_stuff_up(x, y)
		if attack_building is not False and selected_building is not None:
			self.battle.attack_building(self, selected_building, attack_building)