Esempio n. 1
0
class UpgradeState(UIEnabledState):
    NEARBY_RANGE = 70
    is_basic_joystick_panel = True
    def __init__(self, scene):
        UIEnabledState.__init__(self, scene)
        self.pending_upgrade = None
        self.cursor_icon = None
        self.selection_info_text = None
        #self.back_button = None
        self.current_cursor = None

    def enter(self):
        sound.play("panel")
        self.scene.paused = True
        resource = self.scene.player_civ.upgrades_stocked[0]
        is_new_roll = len(self.scene.player_civ.offered_upgrades) == 0
        offered_upgrades = self.scene.player_civ.offer_upgrades(resource)
        self.panel = UpgradePanel(V2(0,0), offered_upgrades, resource, self.on_select, self.on_reroll, is_new_roll)
        self.panel.add_all_to_group(self.scene.ui_group)
        self.panel.position_nicely(self.scene)
        
        self.hover_filter = self.filter_only_panel_ui
        self.selected_targets = []
        self.extras = []
        super().enter()
        self.panel.fade_in(speed=3)

    def filter_my_planets(self, x):
        return (
            x.get_selection_info() and
            x.get_selection_info()['type'] == 'planet' and
            x.owning_civ == self.scene.player_civ and 
            x.upgradeable and
            x.is_buildable()
        )

    def filter_any_planets(self, x):
        return (
            x.get_selection_info() and
            x.get_selection_info()['type'] == 'planet'
        )        

    def filter_my_fleets(self, x):
        return (
            x.get_selection_info() and x.get_selection_info()['type'] == 'fleet' and x.owning_civ == self.scene.player_civ
        )

    def get_joystick_cursor_controls(self):
        l = []
        if self.panel:
            return self.panel.joystick_controls

    def exit(self):
        self.hover_filter = lambda x:True
        self.scene.paused = False
        if self.selection_info_text:
            self.selection_info_text.kill()
        if self.cursor_icon:
            self.cursor_icon.kill()
        #if self.back_button:
        #    self.back_button.kill()
        super().exit()

    def finish(self, target=None, cancel = False):
        for extra in self.extras:
            extra.kill()
        self.extras = []        
        if not cancel:
            self.scene.player_civ.upgrades_stocked.pop(0)
            self.scene.player_civ.register_research(self.pending_upgrade.name)
            self.scene.player_civ.clear_offers()
            sound.play("upgrade2")
            self.scene.pop_asset_button()
        if self.panel:
            self.panel.kill()
        if self.joystick_overlay:
            self.joystick_overlay.kill()
        self.scene.sm.transition(levelstates.PlayState(self.scene))

    def on_reroll(self):
        self.scene.player_civ.clear_offers()
        self.panel.kill()
        self.scene.game.run_info.rerolls -= 1
        resource = self.scene.player_civ.upgrades_stocked[0]
        self.panel = UpgradePanel(V2(0,0), self.scene.player_civ.offer_upgrades(resource), resource, self.on_select, self.on_reroll, True)
        self.panel.add_all_to_group(self.scene.ui_group)
        self.panel.position_nicely(self.scene)
        self.panel.fade_in(speed=10)

        if self.joystick_overlay:
            self.joystick_overlay.kill()
            self.joystick_overlay = joystickcursor.JoystickPanelCursor(self.scene, self.get_joystick_cursor_controls())
            self.scene.ui_group.add(self.joystick_overlay)

    def setup_cursor_type(self, cursor):
        if self.joystick_overlay:
            self.joystick_overlay.kill()
            self.joystick_overlay = joystickcursor.JoystickCursor(self.scene, self.scene.game.last_joystick_pos[0])
            self.scene.ui_group.add(self.joystick_overlay)
            self.joystick_overlay.set_button_options(["[*x*] Select"])

        res = self.scene.game.game_resolution

        if self.panel:
            self.panel.kill()
        if cursor == "allied_planet":
            self.cursor_icon = SimpleSprite(V2(0,0), "assets/i-planet-cursor.png")
            self.hover_filter = self.filter_my_planets
            self.selection_info_text = text.Text("Select one of your Planets to apply upgrade", "big", V2(res.x / 2, res.y / 2), PICO_WHITE, multiline_width=180,shadow=PICO_BLACK, flash_color=PICO_YELLOW)
        elif cursor == "any_planet":
            self.cursor_icon = SimpleSprite(V2(0,0), "assets/i-planet-cursor.png")
            self.hover_filter = self.filter_any_planets
            self.selection_info_text = text.Text("Select any Planet to apply upgrade", "big", V2(res.x / 2, res.y / 2), PICO_WHITE, multiline_width=180,shadow=PICO_BLACK, flash_color=PICO_YELLOW)            
        elif cursor == "allied_fleet":
            self.scene.fleet_managers['my'].generate_selectable_objects()
            self.cursor_icon = SimpleSprite(V2(0,0), "assets/i-fleet-cursor.png")
            self.hover_filter = self.filter_my_fleets
            self.selection_info_text = text.Text("Select one of your Fleets to apply upgrade", "big", V2(res.x / 2, res.y / 2), PICO_WHITE, multiline_width=180,shadow=PICO_BLACK, flash_color=PICO_YELLOW)
        elif cursor == "point":
            self.cursor_icon = SimpleSprite(V2(0,0), "assets/i-point-cursor.png")
            self.hover_filter = self.filter_only_ui
            self.selection_info_text = text.Text("Select a point", "big", V2(res.x / 2, res.y / 2), PICO_WHITE, multiline_width=180,shadow=PICO_BLACK, flash_color=PICO_YELLOW)
        elif cursor == "nearby":
            self.cursor_icon = SimpleSprite(V2(0,0), "assets/i-point-cursor.png")
            self.range = RangeIndicator(self.selected_targets[0].pos, self.NEARBY_RANGE, PICO_LIGHTGRAY)
            self.scene.ui_group.add(self.range)
            self.extras.append(self.range)
            self.hover_filter = self.filter_only_ui
            self.selection_info_text = text.Text("Select a point nearby", "big", V2(res.x / 2, res.y / 2), PICO_WHITE, multiline_width=180,shadow=PICO_BLACK, flash_color=PICO_YELLOW)

        self.cursor_icon.offset = (0.5, 0.5)
        self.cursor_icon._recalc_rect()
        self.scene.ui_group.add(self.cursor_icon)
        self.selection_info_text.offset = (0.5,0.5)
        self.selection_info_text.layer = 15    
        self.scene.ui_group.add(self.selection_info_text)                             
        self.scene.pause_sprite.set_exceptions([s for s in self.scene.game_group.sprites() if self.hover_filter(s)])

    def on_select(self, upgrade):
        if isinstance(upgrade.cursor, list):
            self.cursors = upgrade.cursor[::]
        else:
            self.cursors = [upgrade.cursor]

        self.current_cursor = self.cursors.pop(0)

        if self.current_cursor == None:
            self.pending_upgrade = upgrade
            self.scene.player_civ.upgrades.append(upgrade)
            upgrade().apply(self.scene.player_civ)
            self.scene.ui_group.add(FunNotification(self.pending_upgrade.title, None))
            self.finish()
        else:
            self.pending_upgrade = upgrade
            self.setup_cursor_type(self.current_cursor)
            #self.back_button = Button(V2(game.RES[0] / 2, game.RES[1] - 5), "Back", "small", self.on_back)
            #self.back_button.offset = (0.5, 1)
            #self.scene.ui_group.add(self.back_button)            

    def next_selection_step(self):
        sound.play("click1")
        for extra in self.extras:
            extra.kill()
        self.extras = []

        if self.selection_info_text:
            self.selection_info_text.kill()
        if self.cursor_icon:
            self.cursor_icon.kill()

        if self.cursors:
            self.current_cursor = self.cursors.pop(0)
            self.setup_cursor_type(self.current_cursor)
        else:
            u = self.pending_upgrade().apply(*self.selected_targets)
            self.finish(target=self.selected_targets[0])

    def mouse_input(self, input, event):
        handled = super().mouse_input(input, event)
        if handled and input != "menu":
            return
        if self.cursor_icon:
            if input in ["mouse_move", "mouse_drag"]:
                self.cursor_icon.pos = event.gpos + V2(10,10)

        if self.current_cursor:
            if input == "menu":
                self.on_back()

            if input == "click" and self.hover_sprite:
                sel = self.hover_sprite.get_selection_info()
                if sel:
                    if self.current_cursor == "allied_planet" and sel['type'] == "planet" and self.hover_sprite.owning_civ == self.scene.player_civ:
                        self.selected_targets.append(self.hover_sprite)
                        self.next_selection_step()
                        return

                    if self.current_cursor == "any_planet" and sel['type'] == "planet":
                        self.selected_targets.append(self.hover_sprite)
                        self.next_selection_step()
                        return                        

                    if self.current_cursor == "allied_fleet" and sel['type'] == "fleet":
                        self.selected_targets.append(self.hover_sprite)
                        self.scene.fleet_managers['my'].destroy_selectable_objects()
                        self.next_selection_step()
                        return

            if input == "click" and self.current_cursor == "point":
                self.selected_targets.append(event.gpos)
                self.next_selection_step()
                return

            if input == "click" and self.current_cursor == "nearby":
                if (event.gpos - self.selected_targets[0].pos).length_squared() < self.NEARBY_RANGE ** 2:
                    self.selected_targets.append(event.gpos)
                    self.next_selection_step()
                    return                

        else:
            if input == "menu":
                self.finish(cancel = True)

            if input == "click":
                pr = pygame.Rect(self.panel.x, self.panel.y, self.panel.width, self.panel.height)
                if not pr.collidepoint(event.gpos):
                    self.finish(cancel = True)    

    def joystick_input(self, input, event):
        if input == "back":
            if self.pending_upgrade:
                sound.play("cancel")
                self.on_back()
            else:
                sound.play("cancel")
                self.finish(cancel = True)

        if self.pending_upgrade is None:
            self.joystick_overlay.controls = self.get_joystick_cursor_controls()
            return super().joystick_input(input, event)

        if input == "joymotion":
            self.joystick_overlay.joystick_delta(event['delta'])

        if input == "confirm":
            spr = self.joystick_overlay.nearest_obj
            if spr:
                sel = spr.get_selection_info()
                if sel:
                    if self.current_cursor == "allied_planet" and sel['type'] == "planet" and spr.owning_civ == self.scene.player_civ:
                        self.selected_targets.append(spr)
                        self.next_selection_step()
                        return

                    if self.current_cursor == "any_planet" and sel['type'] == "planet":
                        self.selected_targets.append(spr)
                        self.next_selection_step()
                        return                           

                    if self.current_cursor == "allied_fleet" and sel['type'] == "fleet":
                        self.selected_targets.append(spr)
                        self.scene.fleet_managers['my'].destroy_selectable_objects()
                        self.next_selection_step()
                        return

            if self.current_cursor == "point":
                self.selected_targets.append(self.joystick_overlay.cursor_pos)
                self.next_selection_step()
                return

            if self.current_cursor == "nearby":
                if (self.joystick_overlay.cursor_pos - self.selected_targets[0].pos).length_squared() < self.NEARBY_RANGE ** 2:
                    self.selected_targets.append(self.joystick_overlay.cursor_pos)
                    self.next_selection_step()
                    return      

    def joystick_update(self, dt):
        if self.pending_upgrade is None:
            return

        all_sprites = []
        all_sprites.extend(
            sorted(self.scene.ui_group.sprites()[::], key=lambda x:x.layer, reverse=True)
        )        
        all_sprites.extend(
            sorted(self.scene.game_group.sprites()[::], key=lambda x:x.layer, reverse=True)
        )
        selectable_sprites = [s for s in all_sprites if s.selectable and s.visible and isinstance(s, SpaceObject) and self.hover_filter(s)]

        nearest, d = get_nearest(self.joystick_overlay.cursor_pos, selectable_sprites)
        if d < 40 ** 2:
            self.joystick_overlay.set_nearest(nearest)
        else:
            self.joystick_overlay.set_nearest(None)                              
        
    def on_back(self):
        print("on_back")
        if self.cursor_icon:
            self.cursor_icon.kill()
            self.cursor_icon = None

        self.current_cursor = None

        self.cursor_type = None
        self.pending_upgrade = None
        resource = self.scene.player_civ.upgrades_stocked[0]
        self.panel = UpgradePanel(V2(0,0), self.scene.player_civ.offer_upgrades(resource), resource, self.on_select, self.on_reroll, False)
        self.panel.add_all_to_group(self.scene.ui_group)
        self.panel.position_nicely(self.scene)
        self.panel.fade_in(speed=10)
        self.hover_filter = self.filter_only_panel_ui
        #self.back_button.kill()
        #self.back_button = None
        self.selection_info_text.kill()
        self.selection_info_text = None
        self.selected_targets = []
        for extra in self.extras:
            extra.kill()
        self.extras = []   

        if self.joystick_overlay:
            self.joystick_overlay.kill()
            self.joystick_overlay = joystickcursor.JoystickPanelCursor(self.scene, self.get_joystick_cursor_controls())
            self.scene.ui_group.add(self.joystick_overlay)             

    def update(self, dt):
        if self.scene.game.input_mode == "joystick":
            self.joystick_update(dt)
        return super().update(dt)
Esempio n. 2
0
class Scout(fighter.Fighter):
    SHIP_NAME = "scout"
    SHIP_BONUS_NAME = "scout"
    BASE_HEALTH = 15
    BASE_DAMAGE = 3
    FIRE_RATE = 0.5
    FIRE_RANGE = 36
    DOGFIGHTS = True
    BOMBS = True
    FUEL = 9999

    def __init__(self, scene, pos, owning_civ):
        super().__init__(scene, pos, owning_civ)
        self._set_player_ship_sprite_sheet()
        self.busters = 2
        self.max_busters = 2
        self.buster_time = 1.0
        self.states['siege']['enter'] = self.enter_state_siege
        self.comm_radius = 100
        self.owning_civ.comm_objects.append(self)

        self.buster_display = SimpleSprite(V2(0, 0), None)
        self.buster_display.offset = (0.5, 0)
        self.buster_display.layer = 5
        self._generate_buster_display()
        self.scene.game_group.add(self.buster_display)

        self.enter_stealth_time = 1

    def set_starting_busters(self, num):
        self.max_busters = num
        self.busters = num
        self._generate_buster_display()

    def _generate_buster_display(self):
        self.buster_display.image = pygame.Surface((3 * self.max_busters, 3),
                                                   pygame.SRCALPHA)
        self.buster_display._width, self.buster_display._height = self.buster_display.image.get_size(
        )
        for i in range(self.max_busters):
            pygame.draw.ellipse(self.buster_display.image, PICO_PURPLE,
                                (i * 3, 0, 3, 3))
            if i < self.busters:
                self.buster_display.image.set_at((i * 3 + 1, 1), PICO_PINK)
            else:
                self.buster_display.image.set_at((i * 3 + 1, 1), PICO_BLACK)
        self.buster_display._recalc_rect()

    def update(self, dt):
        if self.get_stat("scout_stealth") and not self.stealth:
            self.enter_stealth_time -= dt
            if self.enter_stealth_time < 0:
                self.stealth = True
                self.enter_stealth_time = 10

        self.buster_display.pos = self.pos + V2(0, 4)

        return super().update(dt)

    def fire(self, at):
        super().fire(at)
        self.enter_stealth_time = 10

    def wants_to_dogfight(self):
        if self.stealth:
            return False
        if not isinstance(self.effective_target, planet.Planet):
            return True
        if not self.effective_target.owning_civ or self.effective_target.owning_civ == self.owning_civ:
            return True
        if (self.effective_target.pos - self.pos).length_squared() > 100**2:
            return True
        if self.busters <= 0:
            return True
        return False

    def enter_state_siege(self):
        self.buster_time = 1.3

    def prepare_bullet_mods(self):
        mods = super().prepare_bullet_mods()
        mods['shape'] = 'circle'
        mods['size'] = 1
        mods['grey_goo'] = self.get_stat("grey_goo")
        return mods

    def state_siege(self, dt):
        super().state_siege(dt)
        if self.busters > 0 and isinstance(self.effective_target,
                                           planet.Planet):
            self.buster_time -= dt
            if self.buster_time <= 0:
                self.busters -= 1
                self.buster_time = 0.5
                ang = (self.effective_target.pos - self.pos).as_polar()[1]
                ang *= 3.14159 / 180
                rvel = helper.from_angle(ang + 3.14159 + random.random() - 0.5)
                b = bullet.Bullet(self.pos,
                                  self.effective_target,
                                  self,
                                  vel=rvel,
                                  mods={
                                      'homing': 0.5,
                                      'color': PICO_PINK,
                                      'missile_speed': -0.65,
                                      'life': 15,
                                      'kill_pop': 1,
                                      'shape': 'circle',
                                      'size': 2,
                                      'trail': PICO_PINK
                                  })
                self.scene.game_group.add(b)
                self._generate_buster_display()

    def emit_thrust_particles(self):
        pvel = V2(random.random() - 0.5, random.random() - 0.5) * 5
        pvel += -self.velocity / 2
        p = particle.Particle(
            [PICO_WHITE, PICO_BLUE], 1,
            self.pos + -helper.try_normalize(self.velocity) * self.radius, 2,
            pvel)
        self.scene.add_particle(p)

    def kill(self):
        self.buster_display.kill()
        return super().kill()