class CommandsTest(unittest.TestCase): def setUp(self): self.parser = CommandParser() def test_add_command(self): self.parser.add_command('plus', plus) self.assertEqual({'plus': plus}, self.parser._CommandParser__commands) def test_parse_arguments(self): result = self.parser.parse_arguments('(1, 2)') # ToDo def test_execute_key_error(self): self.parser.add_command('plus', plus) result = self.parser.execute('minus; 3') self.assertEqual('No such command', result) def test_execute(self): self.parser.add_command('plus', plus) result = self.parser.execute('plus; (1, 2)') self.assertEqual(3, result)
def start(self): cp = CommandParser() cp.add_command('show_movies', self.show_all_movies) cp.add_command('add_movie', self.add_movie) cp.add_command('add_projection', self.add_movie_projection) cp.add_command('show_projections', self.show_projections) cp.add_command('add_reservation', self.add_reservation) while True: user_input = input() if user_input == 'exit': break else: print(cp.execute(user_input))
class GameController(Controller): def __init__(self, window): super(GameController, self).__init__(window) self.sector = None self.time_of_day = 0.0 self.count = 0 self.clock = 6 self.light_y = 1.0 self.light_z = 1.0 self.bg_red = 0.0 self.bg_green = 0.0 self.bg_blue = 0.0 self.hour_deg = 15.0 self.highlighted_block = None self.block_damage = 0 self.crack = None self.mouse_pressed = False self.last_key = None self.sorted = False def update(self, dt): sector = sectorize(self.player.position) if sector != self.sector: self.model.change_sectors(self.sector, sector) # When the world is loaded, show every visible sector. if self.sector is None: self.model.process_entire_queue() self.sector = sector self.model.content_update(dt) m = 8 df = min(dt, 0.2) for _ in xrange(m): self.player.update(df / m, self) if self.mouse_pressed: vector = self.player.get_sight_vector() block, previous = self.model.hit_test(self.player.position, vector, self.player.attack_range) if block: if self.highlighted_block != block: self.set_highlighted_block(block) else: self.set_highlighted_block(None) if self.highlighted_block: hit_block = self.model[self.highlighted_block] if hit_block.hardness >= 0: multiplier = 1 current_item = self.item_list.get_current_block() if current_item is not None: if isinstance(current_item, Tool): # tool if current_item.tool_type == hit_block.digging_tool: multiplier = current_item.multiplier self.block_damage += self.player.attack_power * dt * multiplier if self.block_damage >= hit_block.hardness: self.model.remove_block(self.player, self.highlighted_block) self.set_highlighted_block(None) if hit_block.drop_id is not None and self.player.add_item(hit_block.drop_id): self.item_list.update_items() self.inventory_list.update_items() self.update_time() self.camera.update(dt) def setup(self): glClearColor(self.bg_red, self.bg_green, self.bg_blue, 1) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_LIGHT1) glEnable(GL_LIGHT2) glEnable(GL_ALPHA_TEST) glAlphaFunc(GL_GREATER, 0.1) glEnable(GL_BLEND) glEnable(GL_LINE_SMOOTH) if G.FOG_ENABLED: glEnable(GL_FOG) glFogfv(GL_FOG_COLOR, vec(self.bg_red, self.bg_green, self.bg_blue, 1)) glHint(GL_FOG_HINT, GL_DONT_CARE) glFogi(GL_FOG_MODE, GL_LINEAR) glFogf(GL_FOG_DENSITY, 0.35) glFogf(GL_FOG_START, 20.0) glFogf(GL_FOG_END, G.DRAW_DISTANCE) # 80) self.focus_block = Block(width=1.05, height=1.05) self.earth = vec(0.8, 0.8, 0.8, 1.0) self.white = vec(1.0, 1.0, 1.0, 1.0) self.ambient = vec(1.0, 1.0, 1.0, 1.0) self.polished = GLfloat(100.0) self.crack_batch = pyglet.graphics.Batch() if G.DISABLE_SAVE and world_exists(G.game_dir, G.SAVE_FILENAME): open_world(self, G.game_dir, G.SAVE_FILENAME) else: self.model = Model() self.player = Player((0, 0, 0), (-20, 0), game_mode=G.GAME_MODE) print("Game mode: " + self.player.game_mode) self.item_list = ItemSelector(self, self.player, self.model) self.inventory_list = InventorySelector(self, self.player, self.model) self.item_list.on_resize(self.window.width, self.window.height) self.inventory_list.on_resize(self.window.width, self.window.height) self.text_input = TextWidget(self.window, "", 0, 0, self.window.width, visible=False, font_name="Arial") self.text_input.push_handlers(on_toggled=self.on_text_input_toggled, key_released=self.text_input_callback) self.chat_box = TextWidget( self.window, "", 0, self.text_input.y + self.text_input.height + 50, self.window.width / 2, height=min(300, self.window.height / 3), visible=False, multi_line=True, readonly=True, font_size=14, font_name="Arial", background_color=(64, 64, 64, 200), ) self.command_parser = CommandParser() self.camera = Camera3D(target=self.player) if G.HUD_ENABLED: self.label = pyglet.text.Label( "", font_name="Arial", font_size=8, x=10, y=self.window.height - 10, anchor_x="left", anchor_y="top", color=(255, 255, 255, 255), ) pyglet.clock.schedule_interval_soft(self.model.process_queue, 1.0 / G.MAX_FPS) def update_time(self): """ The idle function advances the time of day. The day has 24 hours, from sunrise to sunset and from sunrise to second sunset. The time of day is converted to degrees and then to radians. """ if not self.window.exclusive: return time_of_day = self.time_of_day if self.time_of_day < 12.0 else 24.0 - self.time_of_day if time_of_day <= 2.5: self.time_of_day += 1.0 / G.TIME_RATE time_of_day += 1.0 / G.TIME_RATE self.count += 1 else: self.time_of_day += 20.0 / G.TIME_RATE time_of_day += 20.0 / G.TIME_RATE self.count += 1.0 / 20.0 if self.time_of_day > 24.0: self.time_of_day = 0.0 time_of_day = 0.0 side = len(self.model.sectors) * 2.0 self.light_y = 2.0 * side * sin(time_of_day * self.hour_deg * G.DEG_RAD) self.light_z = 2.0 * side * cos(time_of_day * self.hour_deg * G.DEG_RAD) if time_of_day <= 2.5: ambient_value = 1.0 else: ambient_value = 1 - (time_of_day - 2.25) / 9.5 self.ambient = vec(ambient_value, ambient_value, ambient_value, 1.0) # Calculate sky colour according to time of day. sin_t = sin(pi * time_of_day / 12.0) self.bg_red = 0.1 * (1.0 - sin_t) self.bg_green = 0.9 * sin_t self.bg_blue = min(sin_t + 0.4, 0.8) if fmod(self.count / 2, G.TIME_RATE) == 0: if self.clock == 18: self.clock = 6 else: self.clock += 1 def set_highlighted_block(self, block): self.highlighted_block = block self.block_damage = 0 if self.crack: self.crack.delete() self.crack = None def save_to_file(self): if G.DISABLE_SAVE: save_world(self, G.game_dir, G.SAVE_FILENAME) def on_mouse_press(self, x, y, button, modifiers): if self.window.exclusive: vector = self.player.get_sight_vector() block, previous = self.model.hit_test(self.player.position, vector, self.player.attack_range) if button == pyglet.window.mouse.LEFT: if block: self.mouse_pressed = True self.set_highlighted_block(None) else: if previous: hit_block = self.model[block] # show craft table gui if hit_block.id == craft_block.id: self.inventory_list.mode = 1 self.inventory_list.toggle(False) return if hit_block.id == furnace_block.id: self.inventory_list.mode = 2 self.inventory_list.toggle(False) return if hit_block.density >= 1: current_block = self.item_list.get_current_block() if current_block is not None: # if current block is an item, # call its on_right_click() method to handle this event if current_block.id >= G.ITEM_ID_MIN: current_block.on_right_click() else: localx, localy, localz = map(operator.sub, previous, normalize(self.player.position)) if localx != 0 or localz != 0 or (localy != 0 and localy != -1): self.model.add_block(previous, current_block) self.item_list.remove_current_block() elif ( self.item_list.get_current_block() and self.item_list.get_current_block().regenerated_health != 0 and self.player.health < self.player.max_health ): self.player.change_health(self.item_list.get_current_block().regenerated_health) self.item_list.get_current_block_item().change_amount(-1) self.item_list.update_health() self.item_list.update_items() else: self.window.set_exclusive_mouse(True) def on_mouse_release(self, x, y, button, modifiers): if self.window.exclusive: self.set_highlighted_block(None) self.mouse_pressed = False def on_mouse_motion(self, x, y, dx, dy): if self.window.exclusive: m = 0.15 x, y = self.player.rotation x, y = x + dx * m, y + dy * m y = max(-90, min(90, y)) self.player.rotation = (x, y) self.camera.rotate(x, y) def on_mouse_drag(self, x, y, dx, dy, button, modifiers): if button == pyglet.window.mouse.LEFT: self.on_mouse_motion(x, y, dx, dy) def on_key_press(self, symbol, modifiers): if symbol == G.TOGGLE_HUD_KEY: G.HUD_ENABLED = not G.HUD_ENABLED elif symbol == G.SAVE_KEY: self.save_to_file() elif symbol == G.INVENTORY_SORT_KEY: if self.last_key == symbol and not self.sorted: self.player.quick_slots.sort() self.player.inventory.sort() self.sorted = True else: self.player.quick_slots.change_sort_mode() self.player.inventory.change_sort_mode() self.item_list.update_items() self.inventory_list.update_items() elif symbol == G.INVENTORY_KEY: self.set_highlighted_block(None) self.mouse_pressed = False self.inventory_list.toggle() elif symbol == G.SOUND_UP_KEY: G.EFFECT_VOLUME = min(G.EFFECT_VOLUME + 0.1, 1) elif symbol == G.SOUND_DOWN_KEY: G.EFFECT_VOLUME = max(G.EFFECT_VOLUME - 0.1, 0) self.last_key = symbol def on_key_release(self, symbol, modifiers): if symbol == G.TALK_KEY: self.toggle_text_input() return pyglet.event.EVENT_HANDLED def on_resize(self, width, height): if G.HUD_ENABLED: self.label.y = height - 10 self.text_input.resize(x=0, y=0, width=self.window.width) self.chat_box.resize( x=0, y=self.text_input.y + self.text_input.height + 50, width=self.window.width / 2, height=min(300, self.window.height / 3), ) def set_3d(self): width, height = self.window.get_size() if G.FOG_ENABLED: glFogfv(GL_FOG_COLOR, vec(self.bg_red, self.bg_green, self.bg_blue, 1.0)) glEnable(GL_DEPTH_TEST) glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(G.FOV, width / float(height), G.NEAR_CLIP_DISTANCE, G.FAR_CLIP_DISTANCE) glMatrixMode(GL_MODELVIEW) glLoadIdentity() self.camera.transform() glEnable(GL_LIGHTING) glLightfv(GL_LIGHT0, GL_DIFFUSE, vec(0.9, 0.9, 0.9, 1.0)) glLightfv(GL_LIGHT0, GL_SPECULAR, vec(0.9, 0.9, 0.9, 1.0)) glLightfv(GL_LIGHT0, GL_POSITION, vec(1.0, self.light_y, self.light_z, 1.0)) glLightfv(GL_LIGHT1, GL_AMBIENT, self.ambient) glLightfv(GL_LIGHT2, GL_AMBIENT, self.ambient) glMaterialfv(GL_FRONT, GL_AMBIENT, self.earth) glMaterialfv(GL_FRONT, GL_DIFFUSE, self.white) glMaterialfv(GL_FRONT, GL_SHININESS, self.polished) def clear(self): glClearColor(self.bg_red, self.bg_green, self.bg_blue, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) def on_draw(self): self.clear() self.set_3d() glColor3d(1, 1, 1) self.model.batch.draw() self.model.transparency_batch.draw() self.crack_batch.draw() self.draw_focused_block() self.set_2d() if G.HUD_ENABLED: self.draw_label() self.item_list.draw() self.inventory_list.draw() self.text_input.draw() self.chat_box.draw() def show_cracks(self, hit_block, vertex_data): if self.block_damage: # also show the cracks crack_level = int(CRACK_LEVELS * self.block_damage / hit_block.hardness) # range: [0, CRACK_LEVELS[ if crack_level >= CRACK_LEVELS: return texture_data = crack_textures.texture_data[crack_level] count = len(texture_data) / 2 if self.crack: self.crack.delete() self.crack = self.crack_batch.add( count, GL_QUADS, self.model.group, ("v3f/static", vertex_data), ("t2f/static", texture_data) ) def draw_focused_block(self): glDisable(GL_LIGHTING) vector = self.player.get_sight_vector() position = self.model.hit_test(self.player.position, vector, self.player.attack_range)[0] if position: hit_block = self.model[position] if hit_block.density >= 1: self.focus_block.width = hit_block.width * 1.05 self.focus_block.height = hit_block.height * 1.05 vertex_data = self.focus_block.get_vertices(*position) if hit_block.hardness > 0.0: self.show_cracks(hit_block, vertex_data) glColor3d(0, 0, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) pyglet.graphics.draw(24, GL_QUADS, ("v3f/static", vertex_data)) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) def draw_label(self): x, y, z = self.player.position self.label.text = "%.1f %02d (%.2f, %.2f, %.2f) %d / %d" % ( self.time_of_day if (self.time_of_day < 12.0) else (24.0 - self.time_of_day), pyglet.clock.get_fps(), x, y, z, len(self.model._shown), len(self.model), ) self.label.draw() def write_line(self, text, **kwargs): self.chat_box.write_line(text, **kwargs) def text_input_callback(self, symbol, modifier): if symbol == G.VALIDATE_KEY: txt = self.text_input.text.replace("\n", "") try: ex = self.command_parser.execute(txt, controller=self, user=self.player, world=self.model) if ex != COMMAND_HANDLED: # Not a command self.write_line("> %s" % txt, color=(255, 255, 255, 255)) self.text_input.clear() except CommandException, e: error = str(e) self.write_line(error, color=COMMAND_ERROR_COLOR) return pyglet.event.EVENT_HANDLED