Exemple #1
0
    def execute_research(self, asset_name, target_type):
        uc = UPGRADE_CLASSES[asset_name]
        if uc.alien_min_level > self.difficulty:
            return False
        if uc.resource_type in self.civ.upgrades_stocked:
            self.civ.upgrades_stocked.remove(uc.resource_type)
            #if uc.cursor is None: # TODO: add cursor to every tech??
            if uc.category == "tech":
                self.research_with_target(asset_name, self.civ)
            else:
                target = None
                available_planets = [
                    p for p in self.scene.get_civ_planets(self.civ)
                    if p.is_buildable()
                ]

                if not available_planets:
                    return False

                # Random planet
                if target_type == buildorder.BOResearch.TARGET_TYPE_RANDOM:
                    target = random.choice(available_planets)

                # Planet which lacks the building
                elif target_type == buildorder.BOResearch.TARGET_TYPE_LACKING_ASSET:

                    def key(p):
                        return asset_name in [
                            b['building'].upgrade.name for b in p.buildings
                        ]

                    available_planets.sort(key=key)
                    print([(p, key(p)) for p in available_planets])
                    target = available_planets[0]

                # Homeworld, or random if dead
                elif target_type == buildorder.BOResearch.TARGET_TYPE_HOMEWORLD:
                    if self.civ.homeworld in available_planets:
                        target = self.civ.homeworld
                    else:
                        target = random.choice(available_planets)

                # Undefended
                elif target_type == buildorder.BOResearch.TARGET_TYPE_UNDEFENDED:
                    available_planets.sort(key=lambda p: sum(p.ships.values()))
                    target = available_planets[0]

                if target is None:
                    return False

                self.research_with_target(asset_name, target)

            return True
        else:
            return False
Exemple #2
0
    def grant_achievement(self, name):
        if name not in ACHIEVEMENT_INFO:
            return

        was_new = self.save.set_achievement(name)
        self.save.save()

        if USE_STEAMWORKS:
            print("SET ACHIEVEMENT", name)
            steamworks_sdk.UserStats.SetAchievement(name.encode("ascii"))
            steamworks_sdk.UserStats.StoreStats()
            #steamworks_sdk.run_callbacks()

        else:
            if was_new:
                game.Game.inst.show_achievement(
                    ACHIEVEMENT_INFO[name]['name'],
                    ACHIEVEMENT_INFO[name]['description'])
Exemple #3
0
    def pause(self, key_pressed):
        #pause menu
        if (key_pressed != -1):
            debug.print(key_pressed)
        if key_pressed == 27:
            if self.paused:
                self.scrn.unrender_pause()
            else:
                self.scrn.render_pause()

            self.paused = not self.paused
            key_pressed = -1
        elif self.paused:
            self.scrn.scr.addstr(0, 0, "PAUSE")
            self.scrn.render_pause()
            if key_pressed == 27:
                self.paused = not self.paused
            elif key_pressed == ord('q'):
                self.should_keep_going = False
Exemple #4
0
    def update_post_build_order(self, dt):
        # Expand or attack if we are behind the expanding curve
        neutral_planets = self.scene.get_civ_planets(None)
        my_planets = self.scene.get_civ_planets(self.civ)
        num = len(my_planets)
        orders = self.get_ordered_ships(self.get_colonist())
        if orders:
            num += len(set([o[1] for o in orders]))

        target_num = self.get_target_num_planets(self.time *
                                                 self.build_order_acceleration)
        if num < target_num:
            if self.time_behind_expand_curve < 20:
                self.time_behind_expand_curve += dt
            else:
                if neutral_planets:
                    self.execute_expand(
                        buildorder.BOExpand.TARGET_TYPE_NEAR_HOME)
                    self.time_behind_expand_curve = 0
                else:
                    self.attack_behind_expansion_curve_countdown -= dt
                    if self.attack_behind_expansion_curve_countdown < 0:
                        self.time_behind_expand_curve = 0
                        print("attack because expand curve")
                        self.execute_attack(
                            buildorder.BOAttack.ATTACK_TYPE_OUTLYING)
                        self.attack_behind_expansion_curve_countdown = 120 / self.build_order_acceleration

        # Attack if we're close to winning
        if self.count_attacking_ships() < max(self.get_max_attackers() - 2, 3):
            winning_acceleration = 1
            if self.near_winning:
                winning_acceleration = 2

            # only count down when there's no attackers
            self.attack_countdown -= dt * winning_acceleration
            if self.attack_countdown < 0:
                print("attack because attack countdown")
                self.execute_attack(buildorder.BOAttack.ATTACK_TYPE_CENTRAL)
                self.attack_countdown = self.get_next_attack_countdown()

        # Research randomly
        self.research_randomly()
Exemple #5
0
    def load_level(self, levelfile):
        print("load level")
        data = json.load(open(resource_path("levels/%s.json" % levelfile)))
        for obj in data:
            t = None
            owner = None
            if obj['type'].endswith("planet"):
                t = "planet"
                if obj['type'] == "my_planet": owner = self.player_civ
                elif obj['type'] == "enemy_planet": owner = self.enemy.civ
            if t == "planet":
                r = [v * 10 for v in obj['data']['resources']]
                pos = V2(*obj['pos'])
                o = Planet(self, pos + self.game.game_offset, obj['size'],
                           Resources(*r))
                if owner and not owner.homeworld:
                    owner.homeworld = o
                if owner:
                    o.change_owner(owner)
                    o.population = 1

            elif obj['type'] == "hazard":
                pos = V2(*obj['pos'])
                o = Hazard(self, pos + self.game.game_offset, obj['size'])
            elif obj['type'] == "crystal":
                pos = V2(*obj['pos'])
                r = [v * 10 for v in obj['data']['resources']]
                o = bosstimecrystal.TimeCrystal(self,
                                                pos + self.game.game_offset, 2,
                                                Resources(*r))
                o.change_owner(self.enemy.civ)
                o.generate_stranded_ships()
                o.add_ship("bosslaser")
                o.add_ship("bossfighter")
            else:
                print(obj)
            self.game_group.add(o)
        self.objgrid.generate_grid(self.get_objects_initial())
Exemple #6
0
    def send_attacking_party(self,
                             source,
                             target,
                             max_num=999,
                             possible_colonist=True):
        ships = self.get_planet_ship_instances(source)
        ships = [s for s in ships if s in self.get_attacking_ships()]
        num_to_send = random.randint(1, max(len(ships), 1))
        num_to_send = min(num_to_send, max_num)
        num_attackers = len(self.get_ordered_ships(target_filter=target))
        num_to_send = min(num_to_send,
                          self.get_max_attackers() - num_attackers)
        print("attacking with %d" % num_to_send)
        if num_to_send <= 0:
            return
        for s in ships[0:num_to_send]:
            source.emit_ship(s, {'to': target})

        num_planets = self.count_expansions_plus_pending()
        if ships and possible_colonist and num_planets < self.get_max_planets(
        ):
            if source.population > 1 and random.random() < 0.8:
                source.emit_ship(self.get_colonist(), {'to': target, 'num': 1})
Exemple #7
0
    def update(self, alien, dt):
        self.time += dt
        if self.is_over():
            return

        pending_step = self.steps[0]
        if self.time > pending_step.time:
            if not pending_step.triggered:
                print("trigger", str(pending_step))
                pending_step.trigger(alien)
            else:
                pending_step.update(alien, dt)
            if pending_step.done:
                print("done with", str(pending_step))
                self.steps.pop(0)
            elif pending_step.abandoned:
                print("abandoning", str(pending_step))
                self.steps.pop(0)
Exemple #8
0
 def open(self) -> "API":
     device_id = None
     try:
         if not os.path.isfile(SETTING_FILE):
             debug.print(f"API Unable to find Auth file: {SETTING_FILE}")
             self.api = Client(USERNAME,
                               PASSWORD,
                               on_login=self.__onlogin_callback)
         else:
             with open(SETTING_FILE) as file_data:
                 cached_settings = json.load(file_data,
                                             object_hook=self.__from_json)
             debug.print(f"API Reusing Auth Settings: {SETTING_FILE}")
             device_id = cached_settings.get("device_id")
             self.api = Client(USERNAME, PASSWORD, settings=cached_settings)
     except (ClientError) as err:
         debug.print(f"API Client Expired: {err}")
         self.api = Client(USERNAME,
                           PASSWORD,
                           device_id=device_id,
                           on_login=self.__onlogin_callback)
     return self
Exemple #9
0
def init_steam():
    if not STEAM_ENABLED:
        return

    global USE_STEAMWORKS
    global steamworks_sdk
    try:
        import steamworks
        steamworks_sdk = steamworks.STEAMWORKS()
        steamworks_sdk.initialize()
        print("USING STEAM")
        print("Steam ID", steamworks_sdk.Users.GetSteamID())
        print("Logged on:", steamworks_sdk.Users.LoggedOn())
        print("RequestCurrentStats:",
              steamworks_sdk.UserStats.RequestCurrentStats() == True)
        steamworks_sdk.run_callbacks()

        USE_STEAMWORKS = True
    except Exception as e:
        print(e)
        print("NOT USING STEAM")
Exemple #10
0
    def render(self):
        t = time.time()
        #self.game.screen.fill(PICO_BLACK)
        self.update_layers()
        if game.DEV:
            for spr in self.background_group.sprites(
            ) + self.game_group.sprites() + self.ui_group.sprites():
                if spr.image is None and spr.visible:
                    print(spr, "bad image")
        self.background_group.draw(self.game.screen)
        self.particle_group.draw(self.game.screen)
        self.game_group.draw(self.game.screen)

        if self.shake_sprite:
            self.shake_sprite.render(self.game.screen)

        if self.debug:
            for k, v in self.fleet_managers.items():
                for fleet in v.current_fleets:
                    fleet.debug_render(self.game.screen)

            gi = pygame.Surface(self.game.screen.get_size(), pygame.SRCALPHA)
            gi.fill((0, 0, 0, 0))
            ff = list(self.flowfield.fields.values())[self.flowfielddebug]
            if self.flowfielddebugstage > 0:
                for col in range(1, len(ff.base_grid[0])):
                    x = col * flowfield.GRIDSIZE + ff.offset.x
                    pygame.draw.line(gi, (255, 255, 255, 50), (x, ff.offset.y),
                                     (x, ff.offset.y + game.RES[1]), 1)
                for row in range(1, len(ff.base_grid)):
                    y = row * flowfield.GRIDSIZE + ff.offset.y
                    pygame.draw.line(gi, (255, 255, 255, 50), (ff.offset.x, y),
                                     (ff.offset.x + game.RES[0], y), 1)
            if self.flowfielddebugstage == 1:
                for y, gr in enumerate(ff.base_grid):
                    for x, gc in enumerate(gr):
                        pt = V2(x * flowfield.GRIDSIZE,
                                y * flowfield.GRIDSIZE) + ff.offset
                        s = "-"
                        if gc:
                            s = "O"
                        FONTS['tiny'].render_to(gi, (pt.x + 2, pt.y + 2), s,
                                                (128, 255, 128, 180))

            if self.flowfielddebugstage == 2:
                for y, gr in enumerate(ff.dgrid):
                    for x, gc in enumerate(gr):
                        pt = V2(x * flowfield.GRIDSIZE,
                                y * flowfield.GRIDSIZE) + ff.offset
                        if isinstance(gc, tuple):
                            s = "-"
                        elif gc is None:
                            s = "??"
                        else:
                            s = str(gc % 10)
                        FONTS['tiny'].render_to(gi, (pt.x + 2, pt.y + 2), s,
                                                (128, 255, 128, 180))

            elif self.flowfielddebugstage == 3:
                for y, gr in enumerate(ff.grid):
                    for x, gc in enumerate(gr):
                        p1 = V2((x + 0.5) * flowfield.GRIDSIZE,
                                (y + 0.5) * flowfield.GRIDSIZE) + ff.offset
                        if gc is not None:
                            p2 = p1 + gc * flowfield.GRIDSIZE * 0.75
                            pygame.draw.line(gi, (0, 0, 255), p1, p2)
                            pygame.draw.circle(gi, (0, 0, 255), p1, 1)
                        else:
                            pygame.draw.circle(gi, (255, 0, 255), p1, 3, 1)

            if False:
                for y in range(len(self.objgrid.grid)):
                    for x in range(len(self.objgrid.grid[0])):
                        x1 = x * self.objgrid.grid_size
                        y1 = y * self.objgrid.grid_size
                        pygame.draw.rect(gi, (0, 255, 0, 150),
                                         (x1, y1, self.objgrid.grid_size + 1,
                                          self.objgrid.grid_size + 1), 1)
                        FONTS['tiny'].render_to(
                            gi, (x1 + 2, y1 + 2),
                            "%d" % len(self.objgrid.grid[y][x]),
                            (128, 255, 128, 180))

            self.game.screen.blit(gi, (0, 0))

        self.pause_sprite.visible = self.paused
        if self.stage_name.time < 2 and self.stage_name.alive():
            self.pause_sprite.visible = False

        if not self.cinematic:
            self.ui_group.draw(self.game.screen)
            self.tutorial_group.draw(self.game.screen)
        if self.debug:
            self.enemy.render(self.game.screen)
            debug_render(self.game.screen, self)

        self.update_times['render'] = time.time() - t

        #FONTS['small'].render_to(self.game.screen, (5,game.RES[1] - 25), "%d" % self.time, (255,255,255,255))
        if self.debug:
            for i, s in enumerate([
                    "%s:%.1f" % (a, b * 1000)
                    for a, b in self.update_times.items()
            ]):
                FONTS['tiny'].render_to(self.game.screen, (30, 100 + i * 8), s,
                                        (128, 255, 128, 180))

            FONTS['tiny'].render_to(
                self.game.screen, (30, 50), "diagram: %.1f MAX, %.1f MEAN" %
                (self.fleet_diagram.max_debug_time * 1000,
                 self.fleet_diagram.mean_debug_time * 1000),
                (128, 255, 255, 180))

        if game.DEV:
            FONTS['tiny'].render_to(self.game.screen, (game.RES[0] - 120, 4),
                                    "%d" % self.time, (128, 255, 128, 180))

        res = self.game.game_resolution
        if self.cinematic:
            surf = pygame.Surface(res, pygame.SRCALPHA)
            pygame.draw.rect(surf, PICO_DARKBLUE, (0, 0, res.x, 40), 0)
            pygame.draw.rect(surf, PICO_DARKBLUE, (0, res.y - 40, res.x, 40),
                             0)
            #surf.set_alpha(160)
            self.game.screen.blit(surf, (0, 0))

        tri = [V2(0, 0), V2(4, 4), V2(0, 8)]
        if self.game_speed > 1:
            color = PICO_BLUE if ((self.time % 2) > 1) else PICO_WHITE

            pygame.draw.rect(self.game.screen, PICO_BLUE, (0, 0, res.x, res.y),
                             1)

            pygame.draw.polygon(self.game.screen, color,
                                [(z + V2(res.x - 12, res.y - 12))
                                 for z in tri], 0)
            pygame.draw.polygon(self.game.screen, color,
                                [(z + V2(res.x - 7, res.y - 12)) for z in tri],
                                0)

        elif not self.cinematic:
            ctl = "Space"
            if self.game.input_mode == "joystick":
                ctl = "L1"
            t = text.render_multiline(ctl,
                                      "small",
                                      PICO_LIGHTGRAY,
                                      wrap_width=130)
            self.game.screen.blit(t, (res.x - t.get_width() - 16, res.y - 12))
            pygame.draw.polygon(self.game.screen, PICO_LIGHTGRAY,
                                [(z + V2(res.x - 12, res.y - 12))
                                 for z in tri], 0)
            pygame.draw.polygon(self.game.screen, PICO_LIGHTGRAY,
                                [(z + V2(res.x - 7, res.y - 12)) for z in tri],
                                0)
            #FONTS['small'].render_to(self.game.screen, PICO_BLUE, "")

        return None
Exemple #11
0
    def load(self):
        print("load")
        self.create_layers()
        civ_name = self.game.run_info.get_current_level_galaxy()['alien']
        if self.alienrace:
            civ_name = self.alienrace
        AlienClass = aliens.alien.ALIENS[civ_name]
        self.enemies = [AlienClass(self, Civ(self))]
        self.enemy = self.enemies[0]
        self.enemy.bonus_supply = 999

        if self.levelfile:
            self.load_level(self.levelfile)
        else:
            self.load_level("choke")

        if self.difficulty == 9:
            self.level_controller = bosslevelcontroller.BossLevelController(
                self)
        else:
            self.level_controller = levelcontroller.LevelController(self)

        self.setup_players()
        self.add_extra_spaceobjects()
        self.objgrid.generate_grid(
            [s for s in self.game_group.sprites() if s.collidable])
        print("generate image")
        self.background.generate_image(self.objgrid)
        print("done generate image")
        self.add_ui_elements()

        self.fleet_managers = {
            'my': fleet.FleetManager(self, self.player_civ),
            'enemy': fleet.FleetManager(self, self.enemy.civ)
        }

        print("generate flowfield")
        self.flowfield = flowfield.FlowFieldMap()
        self.flowfield.generate(self)
        self.flowfielddebug = 0
        self.flowfielddebugstage = 0

        self.fleet_diagram.generate_image(self)

        self.enemy.set_difficulty(self.difficulty)
        self.setup_mods()

        # Add the time loops
        if self.difficulty >= 6 and self.difficulty < 9:
            planets = [
                s for s in self.get_objects_initial() if isinstance(s, Planet)
                and s.owning_civ == None and s.time_loop == False
            ]
            if planets:
                planets.sort(key=lambda x: x.pos.x)
                for i in range(1):
                    p = planets.pop(int(len(planets) / 2))
                    #p.set_time_loop()

        if self.options == "surround":
            for planet in self.get_civ_planets(None):
                planet.change_owner(self.enemy.civ)
            self.enemy.civ.resources.set_resource("gas", 220)

        if self.options == "performance":
            from aliens.alien1fighter import Alien1Fighter
            for i in range(60):
                #civ = self.player_civ if i % 2 == 0 else self.enemy.civ
                civ = self.enemy.civ
                p = V2(random.randint(50, self.game.game_resolution.x - 50),
                       random.randint(50, self.game.game_resolution.y - 50))
                s = Alien1Fighter(self, p, civ)
                self.game_group.add(s)
                random_planet = random.choice(self.get_planets())
                s.set_target(random_planet)

        if self.options == "rich":
            self.player_civ.resources.set_resource("iron", 1150)
            self.player_civ.resources.set_resource("ice", 1150)
            self.player_civ.resources.set_resource("gas", 1150)

        if self.options == "gas":
            self.player_civ.resources.set_resource("gas", 1150)

        if self.options == "fighters":
            for i in range(20):
                self.homeworld.add_ship("fighter")
Exemple #12
0
    def execute_attack(self, attack_type, attack_strength=1):
        all_potential_targets = self.scene.get_civ_planets(
            self.scene.player_civ)
        all_potential_targets = [
            t for t in all_potential_targets
            if len(self.get_ordered_ships(
                target_filter=t)) <= self.get_max_attackers() * attack_strength
        ]
        if not all_potential_targets:
            return False

        sorted_targets = all_potential_targets[::]

        all_potential_sources = self.scene.get_civ_planets(self.civ)
        all_potential_sources = [
            s for s in all_potential_sources if sum({
                k: v
                for k, v in s.ships.items() if k in self.get_attacking_ships()
            }.values()) > 0
        ]
        all_potential_ships = sum([
            sum({
                k: v
                for k, v in s.ships.items() if k in self.get_attacking_ships()
            }.values()) for s in all_potential_sources
        ])
        num_to_send = math.ceil(all_potential_ships * attack_strength)
        possible_colonist = True
        if attack_strength < 0.25:
            possible_colonist = False
        print("num to send", num_to_send)

        if not all_potential_sources:
            return False

        sorted_sources = all_potential_sources[::]

        if attack_type == buildorder.BOAttack.ATTACK_TYPE_CENTRAL:
            sorted_targets.sort(key=lambda p: p.population, reverse=True)
            target = sorted_targets[0]

            sorted_sources.sort(
                key=lambda p: (p.pos - target.pos).length_squared())
            num_sources = random.randint(2, 4)
            sources = sorted_sources[0:num_sources]
            for source in sources:
                self.send_attacking_party(source, target, num_to_send,
                                          possible_colonist)

        elif attack_type == buildorder.BOAttack.ATTACK_TYPE_OUTLYING:

            def key(p):
                # Middle = smallest delta between near me and near enemy distances.
                d1 = (p.pos -
                      self.scene.player_civ.homeworld.pos).length_squared()
                d2 = (p.pos - self.civ.homeworld.pos).length_squared()
                return abs(d1 - d2)

            sorted_targets.sort(key=key)
            target = sorted_targets[0]
            sorted_sources.sort(
                key=lambda p: (p.pos - target.pos).length_squared())
            self.send_attacking_party(sorted_sources[0], target, num_to_send,
                                      possible_colonist)

        elif attack_type == buildorder.BOAttack.ATTACK_TYPE_RANDOM:
            target = random.choice(sorted_targets)
            sorted_sources.sort(
                key=lambda p: (p.pos - target.pos).length_squared())
            self.send_attacking_party(sorted_sources[0], target, num_to_send,
                                      possible_colonist)

        return True
Exemple #13
0
 def research_with_target(self, asset_name, target):
     print("Researching %s" % asset_name)
     up = UPGRADE_CLASSES[asset_name]
     up().apply(target)
     self.civ.register_research(up.name)
     self.civ.upgrades.append(up)
Exemple #14
0
 def __onlogin_callback(self, api):
     cache_settings = api.settings
     with open(SETTING_FILE, 'w') as outfile:
         json.dump(cache_settings, outfile, default=self.__to_json)
         debug.print(f"API Saving Auth Settings: {SETTING_FILE}")