Пример #1
0
    def check_for_customer_by_polarity(self, is_hero):

        # Customer presence is determined in two phases. First
        # the average price for that customer type is computed.
        # The average price allure is then computed.

        # 1 customer appears every 20 seconds on average.
        # At 30 fps, this is 1 / 600, when all prices are $100.

        # The allure ratio is multiplied to the denominator and creates
        # a value X.

        # If random.random() is less than X, a customer is created.

        x = 1.0 / (NORMAL_CUSTOMER_FREQUENCY * 30)
        p = ('h', 'n') if is_hero else ('v', 'n')  # polarities relevant
        colors = ALL_COLORS[:self.spectrum_available]
        total_price = 0
        average_price = 0
        for color in colors:
            for polarity in p:
                average_price += 100
                total_price += self.prices[polarity + '_' + color]

        allure = 1.0 * average_price / total_price

        x *= allure

        if random.random() > x:
            return None

        character_key = random.choice(HEROES if is_hero else VILLAINS)

        # 2 colors or less: 1 demand
        # 5 colors or less: 1 or 2 demands
        # 8 colors or less: 1 to 3 demands
        # 9 or more colors: 2 to 4 demands
        lc = len(colors)
        if lc < 3:
            num_demands = [1]
        elif lc < 6:
            num_demands = [1, 2]
        elif lc < 9:
            num_demands = [1, 2, 3]
        else:
            num_demands = [2, 3, 4]
        num_demands = random.choice(num_demands)

        demands = self.get_demands(num_demands, is_hero)

        sprite = Sprite(character_key, is_hero, demands)

        return sprite
Пример #2
0
	def __init__(self):
		self.next = self
		
		self.session = Session()
		self.player = Sprite('player')
		self.player = Sprite('player')
		self.sprites = [self.player]
		self.last_color = None
		self.sprites_by_row = None
		self.lifetime = 0
		
		# Forgive me father for I am about to sin.
		m = [
			'xx xx xx xx xx xx xx xx c7 c8 c8 c8 c8 c8 c8 c8 c8 c8 c9 xx xx xx xx xx xx xx xx',
			'c7 c8 c8 c8 c8 c8 c9 xx c4 c5 c5 c5 c5 c5 c5 c5 c5 c5 c6 xx c7 c8 c8 c8 c8 c8 c9',
			'c4 c5 c5 c5 c5 c5 c6 xx c4 f7 f8 f8 f8 f8 f8 f8 f8 f9 c6 xx c4 c5 c5 c5 c5 c5 c6',
			'c4 f7 f8 f8 f8 f9 C1 c8 C3 f4 f5 f5 f5 f5 f5 f5 f5 f6 C1 c8 C3 f7 f8 f8 f8 f9 c6',
			'c4 f4 f5 f5 f5 f6 c5 c5 c5 f4 f5 f5 f5 f5 f5 f5 f5 f6 c5 c5 c5 f4 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 F1 f8 f8 f8 F3 f5 f5 f5 f5 f5 f5 f5 F1 f8 f8 f8 F3 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 F7 f2 f2 f2 F9 f5 f5 f5 f5 f5 f5 f5 F7 f2 f2 f2 F9 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 f6 C7 c2 C9 f4 f5 f5 f5 f5 f5 f5 f5 f6 C7 c2 C9 f4 f5 f5 f5 f6 c6',
			'c4 tl ct ct ct tr c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 tl ct ct ct tr c6',
			'c4 bl cb cb cb br c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 bl cb cb cb br c6',
			'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
			'c4 f1 f2 f5 f2 f3 c6 xx c4 f1 f2 f2 f2 f2 f2 f2 f2 f3 c6 xx c4 f1 f2 f5 f2 f3 c6',
			'c1 c2 c2 dd c2 c2 c3 xx c1 c2 c2 c2 c2 c2 c2 c2 c2 c2 c3 xx c1 c2 c2 dd c2 c2 c3'
			]
		
		# Transpose this
		cols = []
		row_count = len(m)
		col_count = len(m[0].split())
		for i in range(len(m)):
			m[i] = m[i].split()
		x = 0
		while x < col_count:
			col = []
			y = 0
			while y < row_count:
				col.append(Tile(m[y][x]))
				y += 1
			x += 1
			cols.append(col)
			
		self.grid = cols
		
		for i in range(5):
			v = self.grid[1 + i][8]
			h = self.grid[21 + i][8]
			v.is_counter = True
			h.is_counter = True
			v.counter_slot = i
			h.counter_slot = i
			v.counter_is_hero = False
			h.counter_is_hero = True
		
		self.player.x = 14.5
		self.player.y = 12.5
		
		#self.set_up_boxes(10)
		self.session.order_more('red', True)
Пример #3
0
class PlayScene:
	def __init__(self):
		self.next = self
		
		self.session = Session()
		self.player = Sprite('player')
		self.player = Sprite('player')
		self.sprites = [self.player]
		self.last_color = None
		self.sprites_by_row = None
		self.lifetime = 0
		
		# Forgive me father for I am about to sin.
		m = [
			'xx xx xx xx xx xx xx xx c7 c8 c8 c8 c8 c8 c8 c8 c8 c8 c9 xx xx xx xx xx xx xx xx',
			'c7 c8 c8 c8 c8 c8 c9 xx c4 c5 c5 c5 c5 c5 c5 c5 c5 c5 c6 xx c7 c8 c8 c8 c8 c8 c9',
			'c4 c5 c5 c5 c5 c5 c6 xx c4 f7 f8 f8 f8 f8 f8 f8 f8 f9 c6 xx c4 c5 c5 c5 c5 c5 c6',
			'c4 f7 f8 f8 f8 f9 C1 c8 C3 f4 f5 f5 f5 f5 f5 f5 f5 f6 C1 c8 C3 f7 f8 f8 f8 f9 c6',
			'c4 f4 f5 f5 f5 f6 c5 c5 c5 f4 f5 f5 f5 f5 f5 f5 f5 f6 c5 c5 c5 f4 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 F1 f8 f8 f8 F3 f5 f5 f5 f5 f5 f5 f5 F1 f8 f8 f8 F3 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 F7 f2 f2 f2 F9 f5 f5 f5 f5 f5 f5 f5 F7 f2 f2 f2 F9 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 f6 C7 c2 C9 f4 f5 f5 f5 f5 f5 f5 f5 f6 C7 c2 C9 f4 f5 f5 f5 f6 c6',
			'c4 tl ct ct ct tr c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 tl ct ct ct tr c6',
			'c4 bl cb cb cb br c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 bl cb cb cb br c6',
			'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
			'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
			'c4 f1 f2 f5 f2 f3 c6 xx c4 f1 f2 f2 f2 f2 f2 f2 f2 f3 c6 xx c4 f1 f2 f5 f2 f3 c6',
			'c1 c2 c2 dd c2 c2 c3 xx c1 c2 c2 c2 c2 c2 c2 c2 c2 c2 c3 xx c1 c2 c2 dd c2 c2 c3'
			]
		
		# Transpose this
		cols = []
		row_count = len(m)
		col_count = len(m[0].split())
		for i in range(len(m)):
			m[i] = m[i].split()
		x = 0
		while x < col_count:
			col = []
			y = 0
			while y < row_count:
				col.append(Tile(m[y][x]))
				y += 1
			x += 1
			cols.append(col)
			
		self.grid = cols
		
		for i in range(5):
			v = self.grid[1 + i][8]
			h = self.grid[21 + i][8]
			v.is_counter = True
			h.is_counter = True
			v.counter_slot = i
			h.counter_slot = i
			v.counter_is_hero = False
			h.counter_is_hero = True
		
		self.player.x = 14.5
		self.player.y = 12.5
		
		#self.set_up_boxes(10)
		self.session.order_more('red', True)

	def place_box(self, key):
		storage_left = 11
		storage_width = 5
		storage_top = 2
		storage_height = 5
		
		box = Box(key)
		while True:
			x = storage_left + int(random.random() * storage_width)
			y = storage_top + int(random.random() * storage_height)
			dx = abs(x - self.player.x)
			dy = abs(y - self.player.y)
			if dx > 2 or dy > 2:
				break
		
		tile = self.grid[x][y]
		if tile.stack == None:
			tile.stack = []
		tile.stack.append(box)
	
	def create_random_boxes(self, count):
		storage_left = 11
		storage_width = 5
		storage_top = 2
		storage_height = 5
		
		output = []
		
		for i in range(count):
			box = self.session.get_random_box(True)
			x = int(random.random() * storage_width) + storage_left
			y = int(random.random() * storage_height) + storage_top
			
			output.append([box, x, y])
			
		return output
		
	def set_up_boxes(self, count):
		boxes = self.create_random_boxes(count)
		for box in boxes:
			b = box[0]
			x = box[1]
			y = box[2]
			tile = self.grid[x][y]
			if tile.stack == None:
				tile.stack = []
			tile.stack.append(b)
	
	def incorrect_order(self):
		play_sound("incorrect_order")
		pass
	
	def lift(self, is_full):
		dxdy = _direction_to_vector[self.player.direction]
		x = int(self.player.x) + dxdy[0]
		y = int(self.player.y) + dxdy[1]
		tile = self.grid[x][y]
		
		if self.player.holding == None:
			if tile.stack != None and not tile.is_counter:
				if is_full:
					self.player.holding = tile.stack
					tile.stack = None
				else:
					self.player.holding = [tile.stack[-1]]
					if len(tile.stack) == 1:
						tile.stack = None
					else:
						tile.stack = tile.stack[:-1]
				play_sound('lift')
		else:
			fix_loc = False
			if not tile.passable and not tile.is_counter:
				play_sound('cant_drop_box')
				return
			
			to_drop = []
			
			if is_full:
				to_drop = self.player.holding[:]
			else:
				to_drop = self.player.holding[:1]
			
			item_sold = False
			
			if tile.is_counter:
				for sprite in self.sprites:
					if sprite.phase == 4:
						if sprite.counter_slot == tile.counter_slot:
							if sprite.is_hero == tile.counter_is_hero:
								sprite_demands = sprite.demands[:]
								for item_to_drop in to_drop:
									found = False
									i = 0
									while i < len(sprite_demands):
										d = sprite_demands[i]
										if d == item_to_drop.key:
											found = True
											sprite_demands = sprite_demands[:i] + sprite_demands[i + 1:]
											break
										i += 1
									if not found:
										self.incorrect_order()
										return
								self.session.item_sold(sprite, item_to_drop.key)
								item_sold = True
								break
			
			if item_sold:
				play_sound('money_sound')
			elif tile.is_counter:
				# can't drop a box on a counter without selling it
				return
			else:
				play_sound('drop')
			if tile.stack == None:
				fix_loc = True
				tile.stack = []
			
			if is_full:
				for item in self.player.holding:
					tile.stack.append(item)
				self.player.holding = None
			else:
				tile.stack.append(self.player.holding[0])
				if len(self.player.holding) == 1:
					self.player.holding = None
				else:
					self.player.holding = self.player.holding[1:]
			
			# player could possibly set a box down and then be standing in an invalid position
			# nudge the player closer to the center of his tile to prevent this invalid state
			if fix_loc:
				if self.player.direction == 'left' or self.player.direction == 'right':
					left = self.player.direction == 'left'
					attempts = 10
					while self.player.is_overlapping(left) and attempts > 0:
						cx = int(self.player.x) + 0.5
						#cy = int(self.player.y) + 0.5 if (not horizontal) else self.player.y
						self.player.x = cx * .3 + self.player.x * .7
						#self.player.y = cy * .3 + self.player.y * .7
						attempts -= 1
					
					if attempts == 0: # my paranoia of some bug causing an infinite loop here
						self.player.x = int(self.player.x) + 0.5
						self.player.y = int(self.player.y) + 0.5

	def process_input(self, events, pressed_keys):
		for event in events:
			if event.down:
				if event.action == 'full' or event.action == 'single':
					self.lift(event.action == 'full')
				elif event.action == 'menu':
					self.next = PriceMenu(self)
				elif event.action == 'order':
					self.next = OrderStuffMenu(self)
				elif event.action == 'pause':
					self.next = PauseMenu(self)
		
		v = 1.3
		dx = 0
		dy = 0
		if pressed_keys.get('left'):
			dx = -1
		elif pressed_keys.get('right'):
			dx = 1
		if pressed_keys.get('up'):
			dy = -1
		elif pressed_keys.get('down'):
			dy = 1
		self.player.try_move(dx, dy)
			
			
	def lose_scene(self, type):
		self.next = DefeatScene(type, int(self.lifetime / 30.0), self.session.budget, self.session.things_sold)
		
	def update(self, counter):
		self.lifetime += 1
		ensure_playing('shopmusic')
		self.session.update()
		
		# TODO: pause movement, make a noise while brining attention to the balance meter, and then move to the defeat screen a second later
		# probably done with a simple transition scene
		balance = self.session.is_defeat()
		if balance != 0:
			if balance == -1:
				type = 'hero_win'
			else:
				type = 'villain_win'
			self.lose_scene(type)
			return
		
		if len(self.session.get_disgruntled_count(True)) > 6:
			self.lose_scene('hero_angry')
			return
		elif len(self.session.get_disgruntled_count(False)) > 6:
			self.lose_scene('villain_angry')
			return
		
		if counter % 10 == 0:
			r = self.session.pop_restocking()
			if r != None:
				self.place_box(r)
				
		c = self.session.get_last_available_color()
		if c != self.last_color:
			self.last_color = c
			self.next = NewProductsMenu(self, c)
		customers = self.session.check_for_customers()
		
		if customers != None:
			for customer in customers:
				is_hero = customer.is_hero
				taken = {}
				for i in range(5):
					taken[i] = False
				for sprite in self.sprites:
					if sprite != self.player and sprite.is_hero == is_hero:
						taken[sprite.counter_slot] = True
				open = []
				for k in taken.keys():
					if not taken[k]:
						open.append(k)
				random.shuffle(open)
				
				if (len(open) > 0):
					customer.set_counter_slot(open[0])
					self.sprites.append(customer)
				else:
					# counter full. reject customer
					self.session.reject_last_customer()
		
		for sprite in self.sprites:
			if sprite != self.player:
				sprite.automate(self.grid, self.session)
		
		new_sprites = []
		for sprite in self.sprites:
			if not sprite.destroy_me:
				sprite.update(self.grid, self.sprites)
				new_sprites.append(sprite)
		self.sprites = new_sprites
	
	def render2(self, screen, counter):
		_LEFT2 = _LEFT * 2
		_TOP2 = _TOP * 2
		spacing = 28
		for sprite in self.sprites:
			if sprite != self.player:
				if sprite.phase == 4:
					slot = sprite.counter_slot
					demand_x = int(16 * sprite.x - 8) * 2 - 2 + _LEFT2
					demand_y = int(16 * sprite.y) * 2 + _TOP2
					
					img = get_image('misc/demand_bubble')
					screen.blit(img, (demand_x, demand_y))
					demands = sprite.demands
					height = len(demands) * spacing
					icon_y = demand_y + img.get_height() // 2 - height // 2 - 30 + 2 + spacing * 3 // 2
					icon_x = demand_x + 8 + 2
					for d in demands:
						screen.blit(get_image('boxes/' + d), (icon_x, icon_y))
						icon_y += spacing
					
					gbarx = demand_x + 4
					gbary = demand_y + img.get_height() + 8
					gbarw = img.get_width() - 8
					percent= 1.0 * sprite.gruntles / STARTING_GRUNTLES_COUNT
					gbarw0 = max(1, int(gbarw * percent))
					gbarh = 3
					
					if percent < 0.3: color = (255, 0, 0)
					elif percent > 0.7: color = (0, 220, 0)
					else: color = (255, 255, 0)
					
					pygame.draw.rect(screen, (0, 0, 0), pygame.Rect(gbarx - 1, gbary - 1, gbarw + 2, gbarh + 2))
					pygame.draw.rect(screen, color, pygame.Rect(gbarx, gbary, gbarw0, gbarh))
		
		self.draw_budget_bar(screen)
		self.draw_power_balance(screen)
		self.draw_options(screen)
		
		screen.blit(get_image('misc/radio'), (529, 615))
		
		for is_hero in (False, True):
			x = 717 if is_hero else 86
			y = 640
			i = 0
			x += 6
			sprite_types = self.session.get_disgruntled_count(is_hero)
			while i < 6:
				sprite_type = None if (i >= len(sprite_types)) else sprite_types[i]
				
				if sprite_type != None:
					img = get_image('fwownyface/' + sprite_type)
					screen.blit(img, (x, y))
				
				pygame.draw.rect(screen, (0, 0, 0), pygame.Rect(x - 3, y - 3, 22, 22), 1)
				
				i += 1
				x += 28
	
	def draw_options(self, screen):
		
		prices = get_small_text("Adjust prices (R)")
		order_more = get_small_text("Restock (T)")
		cloud = get_image('misc/thought_cloud')
		x = screen.get_width() - cloud.get_width() - 20
		y = 0
		screen.blit(cloud, (x, y))
		screen.blit(prices, (x + 73, y + 40))
		screen.blit(order_more, (x + 73, y + 70))
		
	
	def draw_power_balance(self, screen):
		left = 416
		top = 564
		text = get_small_text("Power Balance")
		screen.blit(text, (left, top))
		
		width = 220
		y = top + text.get_height() + 10
		x = left + text.get_width() // 2 - width // 2
		
		evil = int(self.session.balance * width)
		good = width - evil
		height = 20
		border = 3
		pygame.draw.rect(screen, (123, 123, 123), pygame.Rect(x - border, y - border, width + border * 2, height + border * 2))
		pygame.draw.rect(screen, (0, 0, 0), pygame.Rect(x, y, evil, height))
		x += evil
		pygame.draw.rect(screen, (255, 255, 255), pygame.Rect(x, y, good, height))
		
	
	def draw_budget_bar(self, screen):
		screen.blit(get_image('misc/budget_bar'), (10, 10))
		screen.blit(get_text("Budget: " + format_money(self.session.budget)), (30, 38))
		
				
					
	def render1(self, screen, rcounter):
		screen.fill((100, 180, 255))
		self.render_room(screen, (_LEFT, _TOP), rcounter)

	def render_room(self, screen, roomtopleft, rcounter):
		rows = len(self.grid[0])
		cols = len(self.grid)
		grid = self.grid
		
		left = roomtopleft[0]
		top = roomtopleft[1]
		
		if self.sprites_by_row == None:
			i = 0
			self.sprites_by_row = []
			while i < rows:
				self.sprites_by_row.append([])
				i += 1
		
		i = 0
		while i < rows:
			self.sprites_by_row[i] = []
			i += 1
		
		for sprite in self.sprites:
			row = int(sprite.y)
			if row >= 0 and row < rows:
				self.sprites_by_row[row].append(sprite)
		
		row = 0
		while row < rows:
			col = 0
			while col < cols:
				tile = self.grid[col][row]
				img = tile.image
				if img != None:
					screen.blit(img, (col * 16 + left, row * 16 + top))
					if tile.stack != None:
						i = 0
						x = col + 0.5
						y = row + 0.5
						for box in tile.stack:
							box.render(screen, left, top, x, y, i)
							i += 1
				col += 1
			
			for sprite in self.sprites_by_row[row]:
				sprite.render(screen, left, top, rcounter)
				if sprite.holding != None:
					i = 4.7
					for box in sprite.holding:
						box.render(screen, left, top, sprite.x, sprite.y, i)
						i += 1
			row += 1
Пример #4
0
    def __init__(self):
        self.next = self

        self.session = Session()
        self.player = Sprite('player')
        self.player = Sprite('player')
        self.sprites = [self.player]
        self.last_color = None
        self.sprites_by_row = None
        self.lifetime = 0

        # Forgive me father for I am about to sin.
        m = [
            'xx xx xx xx xx xx xx xx c7 c8 c8 c8 c8 c8 c8 c8 c8 c8 c9 xx xx xx xx xx xx xx xx',
            'c7 c8 c8 c8 c8 c8 c9 xx c4 c5 c5 c5 c5 c5 c5 c5 c5 c5 c6 xx c7 c8 c8 c8 c8 c8 c9',
            'c4 c5 c5 c5 c5 c5 c6 xx c4 f7 f8 f8 f8 f8 f8 f8 f8 f9 c6 xx c4 c5 c5 c5 c5 c5 c6',
            'c4 f7 f8 f8 f8 f9 C1 c8 C3 f4 f5 f5 f5 f5 f5 f5 f5 f6 C1 c8 C3 f7 f8 f8 f8 f9 c6',
            'c4 f4 f5 f5 f5 f6 c5 c5 c5 f4 f5 f5 f5 f5 f5 f5 f5 f6 c5 c5 c5 f4 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 F1 f8 f8 f8 F3 f5 f5 f5 f5 f5 f5 f5 F1 f8 f8 f8 F3 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 F7 f2 f2 f2 F9 f5 f5 f5 f5 f5 f5 f5 F7 f2 f2 f2 F9 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 f6 C7 c2 C9 f4 f5 f5 f5 f5 f5 f5 f5 f6 C7 c2 C9 f4 f5 f5 f5 f6 c6',
            'c4 tl ct ct ct tr c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 tl ct ct ct tr c6',
            'c4 bl cb cb cb br c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 bl cb cb cb br c6',
            'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
            'c4 f1 f2 f5 f2 f3 c6 xx c4 f1 f2 f2 f2 f2 f2 f2 f2 f3 c6 xx c4 f1 f2 f5 f2 f3 c6',
            'c1 c2 c2 dd c2 c2 c3 xx c1 c2 c2 c2 c2 c2 c2 c2 c2 c2 c3 xx c1 c2 c2 dd c2 c2 c3'
        ]

        # Transpose this
        cols = []
        row_count = len(m)
        col_count = len(m[0].split())
        for i in range(len(m)):
            m[i] = m[i].split()
        x = 0
        while x < col_count:
            col = []
            y = 0
            while y < row_count:
                col.append(Tile(m[y][x]))
                y += 1
            x += 1
            cols.append(col)

        self.grid = cols

        for i in range(5):
            v = self.grid[1 + i][8]
            h = self.grid[21 + i][8]
            v.is_counter = True
            h.is_counter = True
            v.counter_slot = i
            h.counter_slot = i
            v.counter_is_hero = False
            h.counter_is_hero = True

        self.player.x = 14.5
        self.player.y = 12.5

        #self.set_up_boxes(10)
        self.session.order_more('red', True)
Пример #5
0
class PlayScene:
    def __init__(self):
        self.next = self

        self.session = Session()
        self.player = Sprite('player')
        self.player = Sprite('player')
        self.sprites = [self.player]
        self.last_color = None
        self.sprites_by_row = None
        self.lifetime = 0

        # Forgive me father for I am about to sin.
        m = [
            'xx xx xx xx xx xx xx xx c7 c8 c8 c8 c8 c8 c8 c8 c8 c8 c9 xx xx xx xx xx xx xx xx',
            'c7 c8 c8 c8 c8 c8 c9 xx c4 c5 c5 c5 c5 c5 c5 c5 c5 c5 c6 xx c7 c8 c8 c8 c8 c8 c9',
            'c4 c5 c5 c5 c5 c5 c6 xx c4 f7 f8 f8 f8 f8 f8 f8 f8 f9 c6 xx c4 c5 c5 c5 c5 c5 c6',
            'c4 f7 f8 f8 f8 f9 C1 c8 C3 f4 f5 f5 f5 f5 f5 f5 f5 f6 C1 c8 C3 f7 f8 f8 f8 f9 c6',
            'c4 f4 f5 f5 f5 f6 c5 c5 c5 f4 f5 f5 f5 f5 f5 f5 f5 f6 c5 c5 c5 f4 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 F1 f8 f8 f8 F3 f5 f5 f5 f5 f5 f5 f5 F1 f8 f8 f8 F3 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 F7 f2 f2 f2 F9 f5 f5 f5 f5 f5 f5 f5 F7 f2 f2 f2 F9 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 f6 C7 c2 C9 f4 f5 f5 f5 f5 f5 f5 f5 f6 C7 c2 C9 f4 f5 f5 f5 f6 c6',
            'c4 tl ct ct ct tr c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 tl ct ct ct tr c6',
            'c4 bl cb cb cb br c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 bl cb cb cb br c6',
            'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
            'c4 f4 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f5 f5 f5 f5 f6 c6 xx c4 f4 f5 f5 f5 f6 c6',
            'c4 f1 f2 f5 f2 f3 c6 xx c4 f1 f2 f2 f2 f2 f2 f2 f2 f3 c6 xx c4 f1 f2 f5 f2 f3 c6',
            'c1 c2 c2 dd c2 c2 c3 xx c1 c2 c2 c2 c2 c2 c2 c2 c2 c2 c3 xx c1 c2 c2 dd c2 c2 c3'
        ]

        # Transpose this
        cols = []
        row_count = len(m)
        col_count = len(m[0].split())
        for i in range(len(m)):
            m[i] = m[i].split()
        x = 0
        while x < col_count:
            col = []
            y = 0
            while y < row_count:
                col.append(Tile(m[y][x]))
                y += 1
            x += 1
            cols.append(col)

        self.grid = cols

        for i in range(5):
            v = self.grid[1 + i][8]
            h = self.grid[21 + i][8]
            v.is_counter = True
            h.is_counter = True
            v.counter_slot = i
            h.counter_slot = i
            v.counter_is_hero = False
            h.counter_is_hero = True

        self.player.x = 14.5
        self.player.y = 12.5

        #self.set_up_boxes(10)
        self.session.order_more('red', True)

    def place_box(self, key):
        storage_left = 11
        storage_width = 5
        storage_top = 2
        storage_height = 5

        box = Box(key)
        while True:
            x = storage_left + int(random.random() * storage_width)
            y = storage_top + int(random.random() * storage_height)
            dx = abs(x - self.player.x)
            dy = abs(y - self.player.y)
            if dx > 2 or dy > 2:
                break

        tile = self.grid[x][y]
        if tile.stack == None:
            tile.stack = []
        tile.stack.append(box)

    def create_random_boxes(self, count):
        storage_left = 11
        storage_width = 5
        storage_top = 2
        storage_height = 5

        output = []

        for i in range(count):
            box = self.session.get_random_box(True)
            x = int(random.random() * storage_width) + storage_left
            y = int(random.random() * storage_height) + storage_top

            output.append([box, x, y])

        return output

    def set_up_boxes(self, count):
        boxes = self.create_random_boxes(count)
        for box in boxes:
            b = box[0]
            x = box[1]
            y = box[2]
            tile = self.grid[x][y]
            if tile.stack == None:
                tile.stack = []
            tile.stack.append(b)

    def incorrect_order(self):
        play_sound("incorrect_order")
        pass

    def lift(self, is_full):
        dxdy = _direction_to_vector[self.player.direction]
        x = int(self.player.x) + dxdy[0]
        y = int(self.player.y) + dxdy[1]
        tile = self.grid[x][y]

        if self.player.holding == None:
            if tile.stack != None and not tile.is_counter:
                if is_full:
                    self.player.holding = tile.stack
                    tile.stack = None
                else:
                    self.player.holding = [tile.stack[-1]]
                    if len(tile.stack) == 1:
                        tile.stack = None
                    else:
                        tile.stack = tile.stack[:-1]
                play_sound('lift')
        else:
            fix_loc = False
            if not tile.passable and not tile.is_counter:
                play_sound('cant_drop_box')
                return

            to_drop = []

            if is_full:
                to_drop = self.player.holding[:]
            else:
                to_drop = self.player.holding[:1]

            item_sold = False

            if tile.is_counter:
                for sprite in self.sprites:
                    if sprite.phase == 4:
                        if sprite.counter_slot == tile.counter_slot:
                            if sprite.is_hero == tile.counter_is_hero:
                                sprite_demands = sprite.demands[:]
                                for item_to_drop in to_drop:
                                    found = False
                                    i = 0
                                    while i < len(sprite_demands):
                                        d = sprite_demands[i]
                                        if d == item_to_drop.key:
                                            found = True
                                            sprite_demands = sprite_demands[:i] + sprite_demands[
                                                i + 1:]
                                            break
                                        i += 1
                                    if not found:
                                        self.incorrect_order()
                                        return
                                self.session.item_sold(sprite,
                                                       item_to_drop.key)
                                item_sold = True
                                break

            if item_sold:
                play_sound('money_sound')
            elif tile.is_counter:
                # can't drop a box on a counter without selling it
                return
            else:
                play_sound('drop')
            if tile.stack == None:
                fix_loc = True
                tile.stack = []

            if is_full:
                for item in self.player.holding:
                    tile.stack.append(item)
                self.player.holding = None
            else:
                tile.stack.append(self.player.holding[0])
                if len(self.player.holding) == 1:
                    self.player.holding = None
                else:
                    self.player.holding = self.player.holding[1:]

            # player could possibly set a box down and then be standing in an invalid position
            # nudge the player closer to the center of his tile to prevent this invalid state
            if fix_loc:
                if self.player.direction == 'left' or self.player.direction == 'right':
                    left = self.player.direction == 'left'
                    attempts = 10
                    while self.player.is_overlapping(left) and attempts > 0:
                        cx = int(self.player.x) + 0.5
                        #cy = int(self.player.y) + 0.5 if (not horizontal) else self.player.y
                        self.player.x = cx * .3 + self.player.x * .7
                        #self.player.y = cy * .3 + self.player.y * .7
                        attempts -= 1

                    if attempts == 0:  # my paranoia of some bug causing an infinite loop here
                        self.player.x = int(self.player.x) + 0.5
                        self.player.y = int(self.player.y) + 0.5

    def process_input(self, events, pressed_keys):
        for event in events:
            if event.down:
                if event.action == 'full' or event.action == 'single':
                    self.lift(event.action == 'full')
                elif event.action == 'menu':
                    self.next = PriceMenu(self)
                elif event.action == 'order':
                    self.next = OrderStuffMenu(self)
                elif event.action == 'pause':
                    self.next = PauseMenu(self)

        v = 1.3
        dx = 0
        dy = 0
        if pressed_keys.get('left'):
            dx = -1
        elif pressed_keys.get('right'):
            dx = 1
        if pressed_keys.get('up'):
            dy = -1
        elif pressed_keys.get('down'):
            dy = 1
        self.player.try_move(dx, dy)

    def lose_scene(self, type):
        self.next = DefeatScene(type, int(self.lifetime / 30.0),
                                self.session.budget, self.session.things_sold)

    def update(self, counter):
        self.lifetime += 1
        ensure_playing('shopmusic')
        self.session.update()

        # TODO: pause movement, make a noise while brining attention to the balance meter, and then move to the defeat screen a second later
        # probably done with a simple transition scene
        balance = self.session.is_defeat()
        if balance != 0:
            if balance == -1:
                type = 'hero_win'
            else:
                type = 'villain_win'
            self.lose_scene(type)
            return

        if len(self.session.get_disgruntled_count(True)) > 6:
            self.lose_scene('hero_angry')
            return
        elif len(self.session.get_disgruntled_count(False)) > 6:
            self.lose_scene('villain_angry')
            return

        if counter % 10 == 0:
            r = self.session.pop_restocking()
            if r != None:
                self.place_box(r)

        c = self.session.get_last_available_color()
        if c != self.last_color:
            self.last_color = c
            self.next = NewProductsMenu(self, c)
        customers = self.session.check_for_customers()

        if customers != None:
            for customer in customers:
                is_hero = customer.is_hero
                taken = {}
                for i in range(5):
                    taken[i] = False
                for sprite in self.sprites:
                    if sprite != self.player and sprite.is_hero == is_hero:
                        taken[sprite.counter_slot] = True
                open = []
                for k in taken.keys():
                    if not taken[k]:
                        open.append(k)
                random.shuffle(open)

                if (len(open) > 0):
                    customer.set_counter_slot(open[0])
                    self.sprites.append(customer)
                else:
                    # counter full. reject customer
                    self.session.reject_last_customer()

        for sprite in self.sprites:
            if sprite != self.player:
                sprite.automate(self.grid, self.session)

        new_sprites = []
        for sprite in self.sprites:
            if not sprite.destroy_me:
                sprite.update(self.grid, self.sprites)
                new_sprites.append(sprite)
        self.sprites = new_sprites

    def render2(self, screen, counter):
        _LEFT2 = _LEFT * 2
        _TOP2 = _TOP * 2
        spacing = 28
        for sprite in self.sprites:
            if sprite != self.player:
                if sprite.phase == 4:
                    slot = sprite.counter_slot
                    demand_x = int(16 * sprite.x - 8) * 2 - 2 + _LEFT2
                    demand_y = int(16 * sprite.y) * 2 + _TOP2

                    img = get_image('misc/demand_bubble')
                    screen.blit(img, (demand_x, demand_y))
                    demands = sprite.demands
                    height = len(demands) * spacing
                    icon_y = demand_y + img.get_height(
                    ) // 2 - height // 2 - 30 + 2 + spacing * 3 // 2
                    icon_x = demand_x + 8 + 2
                    for d in demands:
                        screen.blit(get_image('boxes/' + d), (icon_x, icon_y))
                        icon_y += spacing

                    gbarx = demand_x + 4
                    gbary = demand_y + img.get_height() + 8
                    gbarw = img.get_width() - 8
                    percent = 1.0 * sprite.gruntles / STARTING_GRUNTLES_COUNT
                    gbarw0 = max(1, int(gbarw * percent))
                    gbarh = 3

                    if percent < 0.3: color = (255, 0, 0)
                    elif percent > 0.7: color = (0, 220, 0)
                    else: color = (255, 255, 0)

                    pygame.draw.rect(
                        screen, (0, 0, 0),
                        pygame.Rect(gbarx - 1, gbary - 1, gbarw + 2,
                                    gbarh + 2))
                    pygame.draw.rect(screen, color,
                                     pygame.Rect(gbarx, gbary, gbarw0, gbarh))

        self.draw_budget_bar(screen)
        self.draw_power_balance(screen)
        self.draw_options(screen)

        screen.blit(get_image('misc/radio'), (529, 615))

        for is_hero in (False, True):
            x = 717 if is_hero else 86
            y = 640
            i = 0
            x += 6
            sprite_types = self.session.get_disgruntled_count(is_hero)
            while i < 6:
                sprite_type = None if (
                    i >= len(sprite_types)) else sprite_types[i]

                if sprite_type != None:
                    img = get_image('fwownyface/' + sprite_type)
                    screen.blit(img, (x, y))

                pygame.draw.rect(screen, (0, 0, 0),
                                 pygame.Rect(x - 3, y - 3, 22, 22), 1)

                i += 1
                x += 28

    def draw_options(self, screen):

        prices = get_small_text("Adjust prices (R)")
        order_more = get_small_text("Restock (T)")
        cloud = get_image('misc/thought_cloud')
        x = screen.get_width() - cloud.get_width() - 20
        y = 0
        screen.blit(cloud, (x, y))
        screen.blit(prices, (x + 73, y + 40))
        screen.blit(order_more, (x + 73, y + 70))

    def draw_power_balance(self, screen):
        left = 416
        top = 564
        text = get_small_text("Power Balance")
        screen.blit(text, (left, top))

        width = 220
        y = top + text.get_height() + 10
        x = left + text.get_width() // 2 - width // 2

        evil = int(self.session.balance * width)
        good = width - evil
        height = 20
        border = 3
        pygame.draw.rect(
            screen, (123, 123, 123),
            pygame.Rect(x - border, y - border, width + border * 2,
                        height + border * 2))
        pygame.draw.rect(screen, (0, 0, 0), pygame.Rect(x, y, evil, height))
        x += evil
        pygame.draw.rect(screen, (255, 255, 255),
                         pygame.Rect(x, y, good, height))

    def draw_budget_bar(self, screen):
        screen.blit(get_image('misc/budget_bar'), (10, 10))
        screen.blit(get_text("Budget: " + format_money(self.session.budget)),
                    (30, 38))

    def render1(self, screen, rcounter):
        screen.fill((100, 180, 255))
        self.render_room(screen, (_LEFT, _TOP), rcounter)

    def render_room(self, screen, roomtopleft, rcounter):
        rows = len(self.grid[0])
        cols = len(self.grid)
        grid = self.grid

        left = roomtopleft[0]
        top = roomtopleft[1]

        if self.sprites_by_row == None:
            i = 0
            self.sprites_by_row = []
            while i < rows:
                self.sprites_by_row.append([])
                i += 1

        i = 0
        while i < rows:
            self.sprites_by_row[i] = []
            i += 1

        for sprite in self.sprites:
            row = int(sprite.y)
            if row >= 0 and row < rows:
                self.sprites_by_row[row].append(sprite)

        row = 0
        while row < rows:
            col = 0
            while col < cols:
                tile = self.grid[col][row]
                img = tile.image
                if img != None:
                    screen.blit(img, (col * 16 + left, row * 16 + top))
                    if tile.stack != None:
                        i = 0
                        x = col + 0.5
                        y = row + 0.5
                        for box in tile.stack:
                            box.render(screen, left, top, x, y, i)
                            i += 1
                col += 1

            for sprite in self.sprites_by_row[row]:
                sprite.render(screen, left, top, rcounter)
                if sprite.holding != None:
                    i = 4.7
                    for box in sprite.holding:
                        box.render(screen, left, top, sprite.x, sprite.y, i)
                        i += 1
            row += 1