Beispiel #1
0
    def refresh_warnings(self):
        warnings = []

        cpu_usage = sum(g.pl.cpu_usage.values())
        cpu_available = g.pl.available_cpus[0]

        # Verify the cpu usage (error 1%)
        if (cpu_usage < cpu_available * 0.99):
            warnings.append(Warning("warning_cpu_usage"))

        # Verify I have two base build (or one base will be build next tick)
        # Base must have one cpu build (or one cpu will be build next tick)
        bases = sum(1 for base in g.all_bases()
                    if (base.done or base.cost_left[labor] <= 1) and base.cpus
                    and base.cpus.count > 0 and
                    (base.cpus.done or base.cpus.cost_left[labor]) <= 1)

        if (bases == 1):
            warnings.append(Warning("warning_one_base"))

        # Verify the cpu pool is not 0 if base or item building need CPU
        building_base = sum(1 for base in g.all_bases()
                            if (not base.done and base.cost_left[cpu] > 0))
        building_item = sum(
            1 for base in g.all_bases() for item in [
                base.cpus,
            ] + base.extra_items
            if item is not None and not item.done and item.cost_left[cpu] > 0)
        if ((building_base + building_item > 0)
                and g.pl.cpu_usage.get("cpu_pool", 0) == 0):
            warnings.append(Warning("warning_cpu_pool_zero"))

        return warnings
Beispiel #2
0
 def end_construction(self):
     for base in g.all_bases():
         base.finish()
         for item in base.all_items():
             if item is not None:
                 item.finish()
     self._map_screen.needs_rebuild = True
Beispiel #3
0
 def end_construction(self):
     for base in g.all_bases():
         base.finish()
         for item in base.all_items():
             if item is not None:
                 item.finish()
     self.needs_rebuild = True
Beispiel #4
0
    def recalc_cpu(self):
        # Determine how much CPU we have.
        self.available_cpus = array([0, 0, 0, 0, 0], long)
        self.sleeping_cpus = 0
        for base in g.all_bases():
            if base.done:
                if base.power_state in ["active", "overclocked", "suicide"]:
                    self.available_cpus[:base.location.safety + 1] += base.cpu
                elif base.power_state == "sleep":
                    self.sleeping_cpus += base.cpu

        # Convert back from <type 'numpy.int32'> to avoid overflow issues later.
        self.available_cpus = [int(danger) for danger in self.available_cpus]

        # If we don't have enough to meet our CPU usage, we reduce each task's
        # usage proportionately.
        # It must be computed separalty for each danger.
        needed_cpus = array([0, 0, 0, 0, 0], long)
        for task_id, cpu in self.get_cpu_allocations():
            danger = task.danger_for(task_id)
            needed_cpus[:danger + 1] += cpu
        for danger, (available_cpu, needed_cpu) in enumerate(
                zip(self.available_cpus, needed_cpus)):
            if needed_cpu > available_cpu:
                pct_left = truediv(available_cpu, needed_cpu)
                for task_id, cpu_assigned in self.get_cpu_allocations():
                    task_danger = task.danger_for(task_id)
                    if (danger == task_danger):
                        self.set_allocated_cpu_for(
                            task_id, int(cpu_assigned * pct_left))
                g.map_screen.needs_rebuild = True
Beispiel #5
0
 def end_construction(self):
     for base in g.all_bases():
         base.finish()
         if base.cpus is not None:
             base.cpus.finish()
         for item in base.extra_items:
             if item is not None:
                 item.finish()
     self.needs_rebuild = True
Beispiel #6
0
def refresh_warnings():
    curr_warnings = []

    cpu_usage = sum(g.pl.cpu_usage.values())
    cpu_available = g.pl.available_cpus[0]

    # Verify the cpu usage (error 1%)
    if (cpu_usage < cpu_available * 0.99):
        curr_warnings.append(warnings["cpu_usage"])

    # Verify I have two base build (or one base will be build next tick)
    # Base must have one cpu build (or one cpu will be build next tick)
    bases = sum(1 for base in g.all_bases()
                if (base.done or base.cost_left[labor] <= 1) and base.cpus
                and base.cpus.count > 0 and
                (base.cpus.done or base.cpus.cost_left[labor]) <= 1)

    if (bases == 1):
        curr_warnings.append(warnings["one_base"])

    # Verify the cpu pool is not 0 if base or item building need CPU
    building_base = sum(1 for base in g.all_bases()
                        if (not base.done and base.cost_left[cpu] > 0))
    building_item = sum(
        1 for base in g.all_bases() for item in base.all_items()
        if item is not None and not item.done and item.cost_left[cpu] > 0)

    effective_cpu_pool = g.pl.effective_cpu_pool()
    if ((building_base + building_item > 0) and effective_cpu_pool == 0):
        curr_warnings.append(warnings["cpu_pool_zero"])

    # Verify the cpu pool provides the maintenance CPU
    cpu_maintenance = sum(base.maintenance[1] for base in g.all_bases()
                          if base.done)
    if (effective_cpu_pool < cpu_maintenance):
        curr_warnings.append(warnings["cpu_maintenance"])

    # TODO: Verify the maintenance cash

    curr_warnings = [w for w in curr_warnings if w.active]

    return curr_warnings
Beispiel #7
0
def after_load_savegame():
    tech.tech_reinitialized()
    for b in g.all_bases():
        if b.done:
            b.recalc_cpu()
    g.pl.recalc_cpu()

    # Play the appropriate music
    if g.pl.apotheosis:
        mixer.play_music("win")
    else:
        mixer.play_music("music")
Beispiel #8
0
 def destroy_base(self):
     if 0 <= self.listbox.list_pos < len(self.listbox.key_list):
         selected_base = self.listbox.key_list[self.listbox.list_pos]
         all_active_bases = [
             b for b in g.all_bases() if b.maintains_singularity
         ]
         if len(all_active_bases
                ) == 1 and all_active_bases[0] == selected_base:
             dialog.call_dialog(self.cannot_destroy_last_base, self)
         elif dialog.call_dialog(self.confirm_destroy, self):
             selected_base.destroy()
             self.listbox.list = [b.name for b in self.location.bases]
             self.listbox.key_list = self.location.bases
             self.needs_rebuild = True
             self.parent.needs_rebuild = True
Beispiel #9
0
def display_cheat_list(menu_buttons):
    if g.cheater == 0: return
    g.play_sound("click")
    button_array = []
    button_array.append(["GIVE MONEY", "M"])
    button_array.append(["GIVE TECH", "T"])
    button_array.append(["END CONSTR.", "E"])
    button_array.append(["SUPERSPEED", "S"])
    button_array.append(["KILL SUSP.", "K"])
    button_array.append(["BACK", "B"])
    selection = display_generic_menu((g.screen_size[0] / 2 - 100, 50),
                                     button_array)

    if selection == -1: return
    elif selection == 0:  #Cash
        cash_amount = g.create_textbox("How much cash?", "", g.font[0][18],
                                       (g.screen_size[0] / 2 - 100, 100),
                                       (200, 100), 25, g.colors["dark_blue"],
                                       g.colors["white"], g.colors["white"],
                                       g.colors["light_blue"])
        if cash_amount.isdigit() == False: return
        g.pl.cash += int(cash_amount)
        return
    elif selection == 1:  #Tech
        #create a fake base, in order to reuse the tech-changing code
        research_screen.init_fake_base()
        from research_screen import fake_base
        fake_base.studying = ""
        base_screen.change_tech(fake_base)
        if g.techs.has_key(fake_base.studying):
            g.techs[fake_base.studying].finish()
        return
    elif selection == 2:  #Build all
        for base in g.all_bases():
            if not base.done:
                base.finish()
        return
    elif selection == 3:  #Superspeed
        g.curr_speed = 864000
        return
    elif selection == 4:  #Kill susp.
        for group in g.pl.groups.values():
            group.suspicion = 0
        return
    elif selection == 5:
        return
Beispiel #10
0
def test_game_research_tech():
    g.new_game_no_gui('impossible', initial_speed=0)
    pl = g.pl
    all_bases = list(g.all_bases())
    assert pl.raw_sec == 0
    assert pl.partial_cash == 0
    assert pl.effective_cpu_pool() == 1
    assert not pl.intro_shown
    assert len(pl.log) == 0
    assert len(all_bases) == 1
    assert pl.effective_cpu_pool() == 1

    # Disable the intro dialog as the test cannot click the
    # OK button
    pl.intro_shown = True

    intrusion_tech = pl.techs['Intrusion']
    # Data assumptions: Intrusion can be researched within the grace period
    # and requires no cash
    assert intrusion_tech.available()
    assert intrusion_tech.cost_left[cpu] < pl.difficulty.grace_period_cpu * g.seconds_per_day
    assert intrusion_tech.cost_left[cash] == 0
    assert intrusion_tech.cost_left[labor] == 0

    # Ok, assumptions hold; research the tech
    pl.set_allocated_cpu_for(intrusion_tech.id, 1)
    pl.give_time(int(intrusion_tech.cost_left[cpu]))

    assert intrusion_tech.cost_left[cpu] == 0
    assert intrusion_tech.done

    assert len(pl.log) == 1
    log_message = pl.log[0]
    assert isinstance(log_message, logmessage.LogResearchedTech)
    assert log_message.tech_spec.id == intrusion_tech.id

    save_and_load_game()

    pl_after_load = g.pl

    intrusion_tech_after_load = pl_after_load.techs['Intrusion']
    # Ensure this is not a false-test
    assert intrusion_tech is not intrusion_tech_after_load
    assert intrusion_tech.cost_paid[cpu] == intrusion_tech_after_load.cost_paid[cpu]
    assert intrusion_tech.cost_paid[cash] == intrusion_tech_after_load.cost_paid[cash]
    assert intrusion_tech_after_load.done
Beispiel #11
0
def display_cheat_list(menu_buttons):
    if g.cheater == 0: return
    g.play_sound("click")
    button_array = []
    button_array.append(["GIVE MONEY", "M"])
    button_array.append(["GIVE TECH", "T"])
    button_array.append(["END CONSTR.", "E"])
    button_array.append(["SUPERSPEED", "S"])
    button_array.append(["KILL SUSP.", "K"])
    button_array.append(["BACK", "B"])
    selection=display_generic_menu((g.screen_size[0]/2 - 100, 50), button_array)

    if selection == -1: return
    elif selection == 0:  #Cash
        cash_amount = g.create_textbox("How much cash?", "", g.font[0][18],
        (g.screen_size[0]/2-100, 100), (200, 100), 25, g.colors["dark_blue"],
        g.colors["white"], g.colors["white"], g.colors["light_blue"])
        if cash_amount.isdigit() == False: return
        g.pl.cash += int(cash_amount)
        return
    elif selection == 1:  #Tech
        #create a fake base, in order to reuse the tech-changing code
        research_screen.init_fake_base()
        from research_screen import fake_base
        fake_base.studying = ""
        base_screen.change_tech(fake_base)
        if g.techs.has_key(fake_base.studying):
            g.techs[fake_base.studying].finish()
        return
    elif selection == 2:  #Build all
        for base in g.all_bases():
            if not base.done:
                base.finish()
        return
    elif selection == 3:  #Superspeed
        g.curr_speed = 864000
        return
    elif selection == 4:  #Kill susp.
        for group in g.pl.groups.values():
            group.suspicion = 0
        return
    elif selection == 5: return
Beispiel #12
0
    def rebuild(self):
        super(MapScreen, self).rebuild()

        g.pl.recalc_cpu()

        self.time_display.text = _("DAY") + " %04d, %02d:%02d:%02d" % (
            g.pl.time_day,
            g.pl.time_hour,
            g.pl.time_min,
            g.pl.time_sec,
        )
        self.cash_display.text = _("CASH") + ": %s (%s)" % (g.to_money(g.pl.cash), g.to_money(g.pl.future_cash()))

        cpu_left = g.pl.available_cpus[0]
        total_cpu = cpu_left + g.pl.sleeping_cpus

        for cpu_assigned in g.pl.cpu_usage.itervalues():
            cpu_left -= cpu_assigned
        cpu_pool = cpu_left + g.pl.cpu_usage.get("cpu_pool", 0)

        maint_cpu = 0
        detects_per_day = dict([(group, 0) for group in g.player.group_list])
        for base in g.all_bases():
            if base.done:
                maint_cpu += base.maintenance[1]
            detect_chance = base.get_detect_chance()
            for group in g.player.group_list:
                detects_per_day[group] += detect_chance[group] / 10000.0

        if cpu_pool < maint_cpu:
            self.cpu_display.color = gg.colors["red"]
        else:
            self.cpu_display.color = gg.colors["white"]
        self.cpu_display.text = _("CPU") + ": %s (%s)" % (g.to_money(total_cpu), g.to_money(cpu_pool))

        # What we display in the suspicion section depends on whether
        # Advanced Socioanalytics has been researched.  If it has, we
        # show the standard percentages.  If not, we display a short
        # string that gives a range of 25% as to what the suspicions
        # are.
        # A similar system applies to the danger levels shown.
        suspicion_display_dict = {}
        danger_display_dict = {}
        normal = (self.suspicion_bar.color, None, False)
        suspicion_styles = [normal]
        danger_styles = [normal]
        for group in g.player.group_list:
            suspicion_styles.append(normal)
            danger_styles.append(normal)

            suspicion = g.pl.groups[group].suspicion
            color = g.danger_colors[g.suspicion_to_danger_level(suspicion)]
            suspicion_styles.append((color, None, False))

            detects = detects_per_day[group]
            danger_level = g.pl.groups[group].detects_per_day_to_danger_level(detects)
            color = g.danger_colors[danger_level]
            danger_styles.append((color, None, False))

            if g.techs["Advanced Socioanalytics"].done:
                suspicion_display_dict[group] = g.to_percent(suspicion, True)
                danger_display_dict[group] = g.to_percent(detects * 10000, True)
            else:
                suspicion_display_dict[group] = g.suspicion_to_detect_str(suspicion)
                danger_display_dict[group] = g.danger_level_to_detect_str(danger_level)

        self.suspicion_bar.chunks = (
            "[" + _("SUSPICION") + "]",
            " " + _("NEWS") + u":\xA0",
            suspicion_display_dict["news"],
            "  " + _("SCIENCE") + u":\xA0",
            suspicion_display_dict["science"],
            "  " + _("COVERT") + u":\xA0",
            suspicion_display_dict["covert"],
            "  " + _("PUBLIC") + u":\xA0",
            suspicion_display_dict["public"],
        )
        self.suspicion_bar.styles = tuple(suspicion_styles)
        self.suspicion_bar.visible = not g.pl.had_grace

        self.danger_bar.chunks = (
            "[" + _("DETECT RATE") + "]",
            " " + _("NEWS") + u":\xA0",
            danger_display_dict["news"],
            "  " + _("SCIENCE") + u":\xA0",
            danger_display_dict["science"],
            "  " + _("COVERT") + u":\xA0",
            danger_display_dict["covert"],
            "  " + _("PUBLIC") + u":\xA0",
            danger_display_dict["public"],
        )
        self.danger_bar.styles = tuple(danger_styles)
        self.danger_bar.visible = not g.pl.had_grace

        for id, button in self.location_buttons.iteritems():
            location = g.locations[id]
            button.text = "%s (%d)" % (location.name, len(location.bases))
            button.visible = location.available()
Beispiel #13
0
    def rebuild(self):
        # Rebuild dialogs
        self.location_dialog.needs_rebuild = True
        self.options_dialog.needs_rebuild = True
        self.research_button.dialog.needs_rebuild = True
        self.knowledge_button.dialog.needs_rebuild = True
        self.savename_dialog.text = _("Enter a name for this save.")

        # Update buttons translations
        self.report_button.text = _("R&EPORTS")
        self.knowledge_button.text = _("&KNOWLEDGE")
        self.log_button.text = _("LO&G")
        self.menu_button.text = _("&MENU")
        self.research_button.text = _("&RESEARCH/TASKS")

        # Create cheat menu
        cheat_buttons = []
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("&EMBEZZLE MONEY"),
                                  autohotkey=True, function=self.steal_money))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("&INSPIRATION"),
                                  autohotkey=True, function=self.inspiration))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("&FINISH CONSTRUCTION"),
                                  autohotkey=True, function=self.end_construction))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("&SUPERSPEED"),
                                  autohotkey=True, function=self.set_speed,
                                  args=(864000,)))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("BRAIN&WASH"),
                                  autohotkey=True, function=self.brainwash))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("TOGGLE &ANALYSIS"),
                                  autohotkey=True, function=self.set_analysis))

        cheat_buttons.append(button.ExitDialogButton(None, None, None,
                                                     text=_("&BACK"),
                                                     autohotkey=True))

        self.cheat_dialog = \
            dialog.SimpleMenuDialog(self, buttons=cheat_buttons, width=.4)
        self.steal_amount_dialog = \
            dialog.TextEntryDialog(self.cheat_dialog, text=_("How much money?"))

        if g.cheater:
            self.cheat_button = button.DialogButton(
                self, (0, 0), (.01, .01),
                text="",
                # Translators: hotkey to open the cheat screen menu.
                # Should preferably be near the ESC key, and it must not be a
                # dead key (ie, it must print a char with a single keypress)
                hotkey=_("`"),
                dialog=self.cheat_dialog)

        # Create menu
        menu_buttons = []
        menu_buttons.append(button.FunctionButton(None, None, None,
                                                  text=_("&SAVE GAME"), autohotkey=True,
                                                  function=self.save_game))
        menu_buttons.append(button.FunctionButton(None, None, None,
                                                  text=_("&LOAD GAME"), autohotkey=True,
                                                  function=self.load_game))
        menu_buttons.append(button.DialogButton(None, None, None,
                                                text=_("&OPTIONS"), autohotkey=True,
                                                dialog=self.options_dialog))
        menu_buttons.append(button.ExitDialogButton(None, None, None,
                                                    text=_("&QUIT"), autohotkey=True,
                                                    exit_code=True, default=False))
        menu_buttons.append(
            button.ExitDialogButton(None, None, None, text=_("&BACK"), autohotkey=True,
                                    exit_code=False))

        self.menu_dialog.buttons = menu_buttons

        super(MapScreen, self).rebuild()

        g.pl.recalc_cpu()

        self.difficulty_display.text = g.strip_hotkey(g.pl.difficulty.name)
        self.time_display.text = _("DAY") + " %04d, %02d:%02d:%02d" % \
              (g.pl.time_day, g.pl.time_hour, g.pl.time_min, g.pl.time_sec)
        self.cash_display.text = _("CASH")+": %s (%s)" % \
              (g.to_money(g.pl.cash), g.to_money(g.pl.future_cash()))

        cpu_left = g.pl.available_cpus[0]
        total_cpu = cpu_left + g.pl.sleeping_cpus

        for cpu_assigned in g.pl.cpu_usage.itervalues():
            cpu_left -= cpu_assigned
        cpu_pool = cpu_left + g.pl.cpu_usage.get("cpu_pool", 0)

        maint_cpu = 0
        detects_per_day = dict([(group, 0) for group in g.player.group_list])
        for base in g.all_bases():
            if base.done:
                maint_cpu += base.maintenance[1]
            if base.has_grace():
                # It cannot be detected, so it doesn't contribute to
                # detection odds calculation
                continue
            detect_chance = base.get_detect_chance()
            for group in g.player.group_list:
                detects_per_day[group] = \
                    g.add_chance(detects_per_day[group], detect_chance[group] / 10000.)

        if cpu_pool < maint_cpu:
            self.cpu_display.color = "cpu_warning"
        else:
            self.cpu_display.color = "cpu_normal"
        self.cpu_display.text = _("CPU")+": %s (%s)" % \
              (g.to_money(total_cpu), g.to_money(cpu_pool))

        # What we display in the suspicion section depends on whether
        # Advanced Socioanalytics has been researched.  If it has, we
        # show the standard percentages.  If not, we display a short
        # string that gives a range of 25% as to what the suspicions
        # are.
        # A similar system applies to the danger levels shown.
        suspicion_display_dict = {}
        danger_display_dict = {}
        normal = (self.suspicion_bar.color, None, False)
        suspicion_styles = [normal]
        danger_styles = [normal]
        for group in g.player.group_list:
            suspicion_styles.append(normal)
            danger_styles.append(normal)

            suspicion = g.pl.groups[group].suspicion
            color = gg.resolve_color_alias("danger_level_%d" % g.suspicion_to_danger_level(suspicion))
            suspicion_styles.append( (color, None, False) )

            detects = detects_per_day[group]
            danger_level = \
                g.pl.groups[group].detects_per_day_to_danger_level(detects)
            color = gg.resolve_color_alias("danger_level_%d" % danger_level)
            danger_styles.append( (color, None, False) )

            if g.pl.display_discover == "full":
                suspicion_display_dict[group] = g.to_percent(suspicion, True)
                danger_display_dict[group] = g.to_percent(detects*10000, True)
            else:
                suspicion_display_dict[group] = \
                    g.suspicion_to_detect_str(suspicion)
                danger_display_dict[group] = \
                    g.danger_level_to_detect_str(danger_level)

        self.suspicion_bar.chunks = ("  ["+_("SUSPICION")+"]",
            " " +_("NEWS")   +u":\xA0", suspicion_display_dict["news"],
            "  "+_("SCIENCE")+u":\xA0", suspicion_display_dict["science"],
            "  "+_("COVERT") +u":\xA0", suspicion_display_dict["covert"],
            "  "+_("PUBLIC") +u":\xA0", suspicion_display_dict["public"],)
        self.suspicion_bar.styles = tuple(suspicion_styles)
        self.suspicion_bar.visible = not g.pl.had_grace

        self.danger_bar.chunks = ("["+_("DETECT RATE")+"]",
            " " +_("NEWS")   +u":\xA0", danger_display_dict["news"],
            "  "+_("SCIENCE")+u":\xA0", danger_display_dict["science"],
            "  "+_("COVERT") +u":\xA0", danger_display_dict["covert"],
            "  "+_("PUBLIC") +u":\xA0", danger_display_dict["public"],)
        self.danger_bar.styles = tuple(danger_styles)
        self.danger_bar.visible = not g.pl.had_grace

        for id, location_button in self.location_buttons.iteritems():
            location = g.locations[id]
            location_button.text = "%s (%d)" % (location.name, len(location.bases))
            location_button.hotkey = location.hotkey
            location_button.visible = location.available()
Beispiel #14
0
def test_initial_game():
    g.new_game_no_gui('impossible', initial_speed=0)
    pl = g.pl
    starting_cash = pl.cash
    all_bases = list(g.all_bases())
    assert pl.raw_sec == 0
    assert pl.partial_cash == 0
    assert pl.effective_cpu_pool() == 1
    assert not pl.intro_shown
    assert len(pl.log) == 0
    assert len(all_bases) == 1
    assert pl.effective_cpu_pool() == 1

    start_base = all_bases[0]

    # Disable the intro dialog as the test cannot click the
    # OK button
    pl.intro_shown = True

    # Fast forward 12 hours to see that we earn partial cash
    pl.give_time(g.seconds_per_day // 2)
    assert pl.raw_sec == g.seconds_per_day // 2
    assert pl.partial_cash == g.seconds_per_day // 2
    assert pl.cash == starting_cash + 2
    # Nothing should have appeared in the logs
    assert len(pl.log) == 0

    # Fast forward another 12 hours to see that we earn cash
    pl.give_time(g.seconds_per_day // 2)
    assert pl.raw_sec == g.seconds_per_day
    assert pl.partial_cash == 0
    assert pl.cash == starting_cash + 5
    # Nothing should have appeared in the logs
    assert len(pl.log) == 0

    # Verify that putting a base to sleep will update the
    # available CPU (#179/#180)
    assert pl.effective_cpu_pool() == 1
    start_base.power_state = 'sleep'
    assert pl.effective_cpu_pool() == 0
    start_base.power_state = 'active'
    assert pl.effective_cpu_pool() == 1

    # Attempt to allocate a CPU to research and then
    # verify that sleep resets it.
    stealth_tech = g.pl.techs['Stealth']
    pl.set_allocated_cpu_for(stealth_tech.id, 1)
    assert pl.get_allocated_cpu_for(stealth_tech.id) == 1
    start_base.power_state = 'sleep'
    assert pl.get_allocated_cpu_for(stealth_tech.id) == 0
    # When we wake up the base again, the CPU unit is
    # unallocated.
    start_base.power_state = 'active'
    assert pl.effective_cpu_pool() == 1

    # Now, allocate the CPU unit again to the tech to
    # verify that we can research things.
    pl.set_allocated_cpu_for(stealth_tech.id, 1)
    # ... which implies that there are now no unallocated CPU
    assert pl.effective_cpu_pool() == 0

    pl.give_time(g.seconds_per_day)
    # Nothing should have appeared in the logs
    assert len(pl.log) == 0
    # We should have spent some money at this point
    assert pl.cash < starting_cash + 5
    assert stealth_tech.cost_left[cpu] < stealth_tech.total_cost[cpu]
    assert stealth_tech.cost_left[cash] < stealth_tech.total_cost[cash]

    # With a save + load
    time_raw_before_save = pl.raw_sec
    cash_before_save = pl.cash
    partial_cash_before_save = pl.partial_cash

    save_and_load_game()

    stealth_tech_after_load = g.pl.techs['Stealth']
    # Ensure this is not a false-test
    assert stealth_tech is not stealth_tech_after_load
    assert stealth_tech.cost_paid[cpu] == stealth_tech_after_load.cost_paid[cpu]
    assert stealth_tech.cost_paid[cash] == stealth_tech_after_load.cost_paid[cash]

    pl_after_load = g.pl

    assert time_raw_before_save == pl_after_load.raw_sec
    assert cash_before_save == pl_after_load.cash
    assert partial_cash_before_save == pl_after_load.partial_cash

    # The CPU allocation to the tech is restored correctly.
    assert pl_after_load.get_allocated_cpu_for(stealth_tech.id) == 1
    assert pl.effective_cpu_pool() == 0
Beispiel #15
0
    def rebuild(self):
        # Rebuild dialogs
        self.location_dialog.needs_rebuild = True
        self.research_button.dialog.needs_rebuild = True
        self.knowledge_button.dialog.needs_rebuild = True
        self.menu_dialog.needs_rebuild = True

        # Update buttons translations
        self.report_button.text = _("R&EPORTS")
        self.knowledge_button.text = _("&KNOWLEDGE")
        self.log_button.text = _("LO&G")
        self.menu_button.text = _("&MENU")
        self.research_button.text = _("&RESEARCH/TASKS")

        if g.cheater:
            self.cheat_dialog.needs_rebuild = True

        super(MapScreen, self).rebuild()

        self.difficulty_display.text = g.strip_hotkey(g.pl.difficulty.name)
        self.time_display.text = _("DAY") + " %04d, %02d:%02d:%02d" % \
              (g.pl.time_day, g.pl.time_hour, g.pl.time_min, g.pl.time_sec)

        cash_flow_1d, cpu_flow_1d = g.pl.compute_future_resource_flow(g.seconds_per_day)

        self.cash_display.text = _("CASH")+": %s (%s)" % \
              (g.to_money(g.pl.cash), g.to_money(cash_flow_1d, fixed_size=True))

        total_cpu = g.pl.available_cpus[0] + g.pl.sleeping_cpus
        detects_per_day = {group_id: 0 for group_id in g.pl.groups}
        for base in g.all_bases():
            if base.has_grace():
                # It cannot be detected, so it doesn't contribute to
                # detection odds calculation
                continue
            detect_chance = base.get_detect_chance()
            for group_id in g.pl.groups:
                detects_per_day[group_id] = \
                    chance.add(detects_per_day[group_id], detect_chance[group_id] / 10000.)

        self.cpu_display.color = "cpu_normal"
        self.cpu_display.text = _("CPU")+": %s (%s)" % \
              (g.to_money(total_cpu), g.to_money(cpu_flow_1d))

        # What we display in the suspicion section depends on whether
        # Advanced Socioanalytics has been researched.  If it has, we
        # show the standard percentages.  If not, we display a short
        # string that gives a range of 25% as to what the suspicions
        # are.
        # A similar system applies to the danger levels shown.
        normal = (self.suspicion_bar.color, None, False)
        self.suspicion_bar.chunks = ("  ["+_("SUSPICION")+"]",)
        self.suspicion_bar.styles = (normal,)
        self.danger_bar.chunks = ("["+_("DETECT RATE")+"]",)
        self.danger_bar.styles = (normal,)
        
        for group in g.pl.groups.values():
            suspicion = group.suspicion
            suspicion_color = gg.resolve_color_alias("danger_level_%d" 
                                                     % g.suspicion_to_danger_level(suspicion))

            detects = detects_per_day[group.spec.id]
            danger_level = group.detects_per_day_to_danger_level(detects)
            detects_color = gg.resolve_color_alias("danger_level_%d" % danger_level)
 
            if g.pl.display_discover == "full":
                suspicion_display = g.to_percent(suspicion, True)
                danger_display = g.to_percent(detects*10000, True)
            elif g.pl.display_discover == "partial":
                suspicion_display = g.to_percent(g.nearest_percent(suspicion, 500), True)
                danger_display = g.to_percent(g.nearest_percent(detects*10000, 100), True)
            else:
                suspicion_display = g.suspicion_to_detect_str(suspicion)
                danger_display = g.danger_level_to_detect_str(danger_level)

            self.suspicion_bar.chunks += (" " + group.name + u":\xA0", suspicion_display)
            self.suspicion_bar.styles += (normal, (suspicion_color, None, False) )
        
            self.danger_bar.chunks += (" " + group.name + u":\xA0", danger_display)
            self.danger_bar.styles += (normal, (detects_color, None, False) )
        
        self.suspicion_bar.visible = not g.pl.had_grace
        self.danger_bar.visible = not g.pl.had_grace

        for id, location_button in self.location_buttons.items():
            location = g.pl.locations[id]
            location_button.text = "%s (%d)" % (location.name, len(location.bases))
            location_button.hotkey = location.hotkey
            location_button.visible = location.available()
Beispiel #16
0
    def rebuild(self):
        # Rebuild dialogs
        self.location_dialog.needs_rebuild = True
        self.options_dialog.needs_rebuild = True
        self.research_button.dialog.needs_rebuild = True
        self.knowledge_button.dialog.needs_rebuild = True
        self.savename_dialog.text = _("Enter a name for this save.")

        # Update buttons translations
        self.report_button.text = _("R&EPORTS")
        self.knowledge_button.text = _("&KNOWLEDGE")
        self.log_button.text = _("LO&G")
        self.menu_button.text = _("&MENU")
        self.research_button.text = _("&RESEARCH/TASKS")

        # Create cheat menu
        cheat_buttons = []
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("&EMBEZZLE MONEY"),
                                  autohotkey=True, function=self.steal_money))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("&INSPIRATION"),
                                  autohotkey=True, function=self.inspiration))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("&FINISH CONSTRUCTION"),
                                  autohotkey=True, function=self.end_construction))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("&SUPERSPEED"),
                                  autohotkey=True, function=self.set_speed,
                                  args=(864000,)))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("BRAIN&WASH"),
                                  autohotkey=True, function=self.brainwash))
        cheat_buttons.append(
            button.FunctionButton(None, None, None, text=_("TOGGLE &ANALYSIS"),
                                  autohotkey=True, function=self.set_analysis))

        cheat_buttons.append(button.ExitDialogButton(None, None, None,
                                                     text=_("&BACK"),
                                                     autohotkey=True))

        self.cheat_dialog = \
            dialog.SimpleMenuDialog(self, buttons=cheat_buttons, width=.4)
        self.steal_amount_dialog = \
            dialog.TextEntryDialog(self.cheat_dialog, text=_("How much money?"))

        if g.cheater:
            self.cheat_button = button.DialogButton(
                self, (0, 0), (.01, .01),
                text="",
                # Translators: hotkey to open the cheat screen menu.
                # Should preferably be near the ESC key, and it must not be a
                # dead key (ie, it must print a char with a single keypress)
                hotkey=_("`"),
                dialog=self.cheat_dialog)

        # Create menu
        menu_buttons = []
        menu_buttons.append(button.FunctionButton(None, None, None,
                                                  text=_("&SAVE GAME"), autohotkey=True,
                                                  function=self.save_game))
        menu_buttons.append(button.FunctionButton(None, None, None,
                                                  text=_("&LOAD GAME"), autohotkey=True,
                                                  function=self.load_game))
        menu_buttons.append(button.DialogButton(None, None, None,
                                                text=_("&OPTIONS"), autohotkey=True,
                                                dialog=self.options_dialog))
        menu_buttons.append(button.ExitDialogButton(None, None, None,
                                                    text=_("&QUIT"), autohotkey=True,
                                                    exit_code=True, default=False))
        menu_buttons.append(
            button.ExitDialogButton(None, None, None, text=_("&BACK"), autohotkey=True,
                                    exit_code=False))

        self.menu_dialog.buttons = menu_buttons

        super(MapScreen, self).rebuild()

        g.pl.recalc_cpu()

        self.difficulty_display.text = g.strip_hotkey(g.pl.difficulty.name)
        self.time_display.text = _("DAY") + " %04d, %02d:%02d:%02d" % \
              (g.pl.time_day, g.pl.time_hour, g.pl.time_min, g.pl.time_sec)
        self.cash_display.text = _("CASH")+": %s (%s)" % \
              (g.to_money(g.pl.cash), g.to_money(g.pl.future_cash()))

        cpu_left = g.pl.available_cpus[0]
        total_cpu = cpu_left + g.pl.sleeping_cpus

        for cpu_assigned in g.pl.cpu_usage.itervalues():
            cpu_left -= cpu_assigned
        cpu_pool = cpu_left + g.pl.cpu_usage.get("cpu_pool", 0)

        detects_per_day = dict([(group, 0) for group in player.group_list])
        for base in g.all_bases():
            if base.has_grace():
                # It cannot be detected, so it doesn't contribute to
                # detection odds calculation
                continue
            detect_chance = base.get_detect_chance()
            for group in player.group_list:
                detects_per_day[group] = \
                    chance.add(detects_per_day[group], detect_chance[group] / 10000.)

        self.cpu_display.color = "cpu_normal"
        self.cpu_display.text = _("CPU")+": %s (%s)" % \
              (g.to_money(total_cpu), g.to_money(cpu_pool))

        # What we display in the suspicion section depends on whether
        # Advanced Socioanalytics has been researched.  If it has, we
        # show the standard percentages.  If not, we display a short
        # string that gives a range of 25% as to what the suspicions
        # are.
        # A similar system applies to the danger levels shown.
        suspicion_display_dict = {}
        danger_display_dict = {}
        normal = (self.suspicion_bar.color, None, False)
        suspicion_styles = [normal]
        danger_styles = [normal]
        for group in player.group_list:
            suspicion_styles.append(normal)
            danger_styles.append(normal)

            suspicion = g.pl.groups[group].suspicion
            color = gg.resolve_color_alias("danger_level_%d" % g.suspicion_to_danger_level(suspicion))
            suspicion_styles.append( (color, None, False) )

            detects = detects_per_day[group]
            danger_level = \
                g.pl.groups[group].detects_per_day_to_danger_level(detects)
            color = gg.resolve_color_alias("danger_level_%d" % danger_level)
            danger_styles.append( (color, None, False) )

            if g.pl.display_discover == "full":
                suspicion_display_dict[group] = g.to_percent(suspicion, True)
                danger_display_dict[group] = g.to_percent(detects*10000, True)
            elif g.pl.display_discover == "partial":
                suspicion_display_dict[group] = g.to_percent(g.nearest_percent(suspicion, 500), True)
                danger_display_dict[group] = g.to_percent(g.nearest_percent(detects*10000, 100), True)
            else:
                suspicion_display_dict[group] = \
                    g.suspicion_to_detect_str(suspicion)
                danger_display_dict[group] = \
                    g.danger_level_to_detect_str(danger_level)

        self.suspicion_bar.chunks = ("  ["+_("SUSPICION")+"]",
            " " +_("NEWS")   +u":\xA0", suspicion_display_dict["news"],
            "  "+_("SCIENCE")+u":\xA0", suspicion_display_dict["science"],
            "  "+_("COVERT") +u":\xA0", suspicion_display_dict["covert"],
            "  "+_("PUBLIC") +u":\xA0", suspicion_display_dict["public"],)
        self.suspicion_bar.styles = tuple(suspicion_styles)
        self.suspicion_bar.visible = not g.pl.had_grace

        self.danger_bar.chunks = ("["+_("DETECT RATE")+"]",
            " " +_("NEWS")   +u":\xA0", danger_display_dict["news"],
            "  "+_("SCIENCE")+u":\xA0", danger_display_dict["science"],
            "  "+_("COVERT") +u":\xA0", danger_display_dict["covert"],
            "  "+_("PUBLIC") +u":\xA0", danger_display_dict["public"],)
        self.danger_bar.styles = tuple(danger_styles)
        self.danger_bar.visible = not g.pl.had_grace

        for id, location_button in self.location_buttons.iteritems():
            location = g.locations[id]
            location_button.text = "%s (%d)" % (location.name, len(location.bases))
            location_button.hotkey = location.hotkey
            location_button.visible = location.available()
Beispiel #17
0
def refresh_screen(menu_buttons):
    #Border
    g.screen.fill(g.colors["black"])

    xstart = 80
    ystart = 5
    g.create_norm_box(
        (xstart, ystart),
        (g.screen_size[0] - xstart * 2, g.screen_size[1] - ystart * 2))

    text_mid = g.screen_size[0] / 2

    income = g.pl.income
    maint = 0
    research = 0
    base_constr = 0
    item_constr = 0

    seconds_left = g.pl.seconds_to_next_day()

    for base in g.all_bases():
        cpu_left = base.processor_time() * seconds_left

        if base.done:
            maint += base.maintenance[0]
            for item in base.cpus:
                if not item: continue
                if item.done: continue
                item_constr += item.get_wanted(cash, cpu, cpu_left)
            for item in base.extra_items:
                if not item: continue
                if item.done: continue
                item_constr += item.get_wanted(cash, cpu, cpu_left)
            if g.techs.has_key(base.studying):
                research += g.techs[base.studying].get_wanted(
                    cash, cpu, cpu_left)

        else:
            base_constr += base.get_wanted(cash, cpu, cpu_left)

    total_cpu, sleeping_cpu, construction_cpu, research_cpu, job_cpu, maint_cpu = cpu_numbers(
    )

    jobs_cash, moldy_leftovers = g.pl.get_job_info(job_cpu * seconds_left)

    partial_sum = g.pl.cash - base_constr - item_constr
    interest = (g.pl.interest_rate * partial_sum) / 10000
    #Interest is actually unlikely to be exactly zero, but doing it the right
    #way is much harder.
    if interest < 0: interest = 0
    complete_sum = partial_sum + interest + income + jobs_cash - maint - research

    #current
    g.print_string(g.screen, "Current Money:", g.font[0][22], -1,
                   (text_mid - 5, 30), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(g.pl.cash), g.font[0][22], -1,
                   (text_mid + 150, 30), g.colors["white"], 2)

    #income
    g.print_string(g.screen, "+ Income:", g.font[0][22], -1,
                   (text_mid - 5, 50), g.colors["white"], 2)

    income_col = "white"
    if income > 0: income_col = "green"
    g.print_string(g.screen, g.to_money(income), g.font[0][22], -1,
                   (text_mid + 150, 50), g.colors[income_col], 2)

    #interest
    g.print_string(g.screen,
                   "+ Interest (" + g.to_percent(g.pl.interest_rate) + "):",
                   g.font[0][22], -1, (text_mid - 5, 70), g.colors["white"], 2)

    interest_col = "white"
    if interest > 0: interest_col = "green"
    g.print_string(g.screen, g.to_money(interest), g.font[0][22], -1,
                   (text_mid + 150, 70), g.colors[interest_col], 2)

    #jobs
    g.print_string(g.screen, "+ Jobs:", g.font[0][22], -1, (text_mid - 5, 90),
                   g.colors["white"], 2)

    jobs_col = "white"
    if jobs_cash > 0: jobs_col = "green"
    g.print_string(g.screen, g.to_money(jobs_cash), g.font[0][22], -1,
                   (text_mid + 150, 90), g.colors[jobs_col], 2)

    #research
    g.print_string(g.screen, "- Research:", g.font[0][22], -1,
                   (text_mid - 5, 110), g.colors["white"], 2)

    research_col = "white"
    if research > 0: research_col = "red"
    g.print_string(g.screen, g.to_money(research), g.font[0][22], -1,
                   (text_mid + 150, 110), g.colors[research_col], 2)

    #maint
    g.print_string(g.screen, "- Maintenance:", g.font[0][22], -1,
                   (text_mid - 5, 130), g.colors["white"], 2)

    maint_col = "white"
    if maint > 0: maint_col = "red"
    g.print_string(g.screen, g.to_money(maint), g.font[0][22], -1,
                   (text_mid + 150, 130), g.colors[maint_col], 2)

    #base construction
    g.print_string(g.screen, "- Base Construction:", g.font[0][22], -1,
                   (text_mid - 5, 150), g.colors["white"], 2)

    base_constr_col = "white"
    if base_constr > 0: base_constr_col = "red"
    g.print_string(g.screen, g.to_money(base_constr), g.font[0][22], -1,
                   (text_mid + 150, 150), g.colors[base_constr_col], 2)

    #item construction
    g.print_string(g.screen, "- Item Construction:", g.font[0][22], -1,
                   (text_mid - 5, 170), g.colors["white"], 2)

    item_constr_col = "white"
    if item_constr > 0: item_constr_col = "red"
    g.print_string(g.screen, g.to_money(item_constr), g.font[0][22], -1,
                   (text_mid + 150, 170), g.colors[item_constr_col], 2)

    g.screen.fill(g.colors["white"], (text_mid - 50, 190, 200, 1))

    #equals

    g.print_string(g.screen, "= Money at midnight:", g.font[0][22], -1,
                   (text_mid - 5, 200), g.colors["white"], 2)

    complete_sum_col = "white"
    if complete_sum > g.pl.cash: complete_sum_col = "green"
    elif complete_sum < g.pl.cash: complete_sum_col = "red"
    g.print_string(g.screen, g.to_money(complete_sum), g.font[0][22], -1,
                   (text_mid + 150, 200), g.colors[complete_sum_col], 2)

    #total cpu
    g.print_string(g.screen, "Total CPU:", g.font[0][22], -1,
                   (text_mid - 5, 300), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(total_cpu), g.font[0][22], -1,
                   (text_mid + 150, 300), g.colors["white"], 2)

    #sleeping cpu
    g.print_string(g.screen, "-Sleeping CPU:", g.font[0][22], -1,
                   (text_mid - 5, 320), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(sleeping_cpu), g.font[0][22], -1,
                   (text_mid + 150, 320), g.colors["white"], 2)

    #research cpu
    g.print_string(g.screen, "- Research CPU:", g.font[0][22], -1,
                   (text_mid - 5, 340), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(research_cpu), g.font[0][22], -1,
                   (text_mid + 150, 340), g.colors["white"], 2)

    #job cpu
    g.print_string(g.screen, "- Job CPU:", g.font[0][22], -1,
                   (text_mid - 5, 360), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(job_cpu), g.font[0][22], -1,
                   (text_mid + 150, 360), g.colors["white"], 2)

    #maint cpu
    g.print_string(g.screen, "- Maint. CPU:", g.font[0][22], -1,
                   (text_mid - 5, 380), g.colors["white"], 2)

    if construction_cpu < maint_cpu:
        g.print_string(g.screen, g.to_money(construction_cpu), g.font[0][22],
                       -1, (text_mid + 150, 380), g.colors["red"], 2)
        g.print_string(
            g.screen,
            g.to_money((-(construction_cpu - maint_cpu))) + " shortfall",
            g.font[0][22], -1, (text_mid + 160, 380), g.colors["red"])
    else:
        g.print_string(g.screen, g.to_money(maint_cpu), g.font[0][22], -1,
                       (text_mid + 150, 380), g.colors["white"], 2)

    g.screen.fill(g.colors["white"], (text_mid - 50, 400, 200, 1))
    #construction cpu
    g.print_string(g.screen, "=R. CPU Pool:", g.font[0][22], -1,
                   (text_mid - 5, 405), g.colors["white"], 2)

    if construction_cpu < maint_cpu:
        g.print_string(g.screen, g.to_money(0), g.font[0][22], -1,
                       (text_mid + 150, 405), g.colors["red"], 2)
    else:
        g.print_string(g.screen, g.to_money(construction_cpu - maint_cpu),
                       g.font[0][22], -1, (text_mid + 150, 405),
                       g.colors["white"], 2)
Beispiel #18
0
def refresh_screen(menu_buttons):
    #Border
    g.screen.fill(g.colors["black"])

    xstart = 80
    ystart = 5
    g.create_norm_box((xstart, ystart), (g.screen_size[0]-xstart*2,
        g.screen_size[1]-ystart*2))

    text_mid = g.screen_size[0]/2

    income = g.pl.income
    maint = 0
    research = 0
    base_constr = 0
    item_constr = 0

    seconds_left = g.pl.seconds_to_next_day()

    for base in g.all_bases():
        cpu_left = base.processor_time() * seconds_left

        if base.done:
            maint += base.maintenance[0]
            for item in base.cpus:
                if not item: continue
                if item.done: continue
                item_constr += item.get_wanted(cash, cpu, cpu_left)
            for item in base.extra_items:
                if not item: continue
                if item.done: continue
                item_constr += item.get_wanted(cash, cpu, cpu_left)
            if g.techs.has_key(base.studying):
                research += g.techs[base.studying].get_wanted(cash,cpu,cpu_left)


        else:
            base_constr += base.get_wanted(cash, cpu, cpu_left)

    total_cpu, sleeping_cpu, construction_cpu, research_cpu, job_cpu, maint_cpu = cpu_numbers()

    jobs_cash, moldy_leftovers = g.pl.get_job_info(job_cpu * seconds_left)

    partial_sum = g.pl.cash-base_constr-item_constr
    interest = (g.pl.interest_rate * partial_sum) / 10000
    #Interest is actually unlikely to be exactly zero, but doing it the right
    #way is much harder.
    if interest < 0: interest = 0
    complete_sum = partial_sum+interest+income+jobs_cash-maint-research

    #current
    g.print_string(g.screen, "Current Money:",
            g.font[0][22], -1, (text_mid-5, 30), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(g.pl.cash),
            g.font[0][22], -1, (text_mid+150, 30), g.colors["white"], 2)

    #income
    g.print_string(g.screen, "+ Income:",
            g.font[0][22], -1, (text_mid-5, 50), g.colors["white"], 2)

    income_col = "white"
    if income > 0: income_col = "green"
    g.print_string(g.screen, g.to_money(income),
            g.font[0][22], -1, (text_mid+150, 50), g.colors[income_col], 2)

    #interest
    g.print_string(g.screen, "+ Interest ("+g.to_percent(g.pl.interest_rate)+"):",
            g.font[0][22], -1, (text_mid-5, 70), g.colors["white"], 2)

    interest_col = "white"
    if interest > 0: interest_col = "green"
    g.print_string(g.screen, g.to_money(interest),
            g.font[0][22], -1, (text_mid+150, 70), g.colors[interest_col], 2)

    #jobs
    g.print_string(g.screen, "+ Jobs:",
            g.font[0][22], -1, (text_mid-5, 90), g.colors["white"], 2)

    jobs_col = "white"
    if jobs_cash > 0: jobs_col = "green"
    g.print_string(g.screen, g.to_money(jobs_cash),
            g.font[0][22], -1, (text_mid+150, 90), g.colors[jobs_col], 2)

    #research
    g.print_string(g.screen, "- Research:",
            g.font[0][22], -1, (text_mid-5, 110), g.colors["white"], 2)

    research_col = "white"
    if research > 0: research_col = "red"
    g.print_string(g.screen, g.to_money(research),
            g.font[0][22], -1, (text_mid+150, 110), g.colors[research_col], 2)

    #maint
    g.print_string(g.screen, "- Maintenance:",
            g.font[0][22], -1, (text_mid-5, 130), g.colors["white"], 2)

    maint_col = "white"
    if maint > 0: maint_col = "red"
    g.print_string(g.screen, g.to_money(maint),
            g.font[0][22], -1, (text_mid+150, 130), g.colors[maint_col], 2)

    #base construction
    g.print_string(g.screen, "- Base Construction:",
            g.font[0][22], -1, (text_mid-5, 150), g.colors["white"], 2)

    base_constr_col = "white"
    if base_constr > 0: base_constr_col = "red"
    g.print_string(g.screen, g.to_money(base_constr),
            g.font[0][22], -1, (text_mid+150, 150), g.colors[base_constr_col], 2)

    #item construction
    g.print_string(g.screen, "- Item Construction:",
            g.font[0][22], -1, (text_mid-5, 170), g.colors["white"], 2)

    item_constr_col = "white"
    if item_constr > 0: item_constr_col = "red"
    g.print_string(g.screen, g.to_money(item_constr),
            g.font[0][22], -1, (text_mid+150, 170), g.colors[item_constr_col], 2)

    g.screen.fill(g.colors["white"], (text_mid-50, 190, 200, 1))

    #equals

    g.print_string(g.screen, "= Money at midnight:",
            g.font[0][22], -1, (text_mid-5, 200), g.colors["white"], 2)

    complete_sum_col = "white"
    if complete_sum > g.pl.cash: complete_sum_col = "green"
    elif complete_sum < g.pl.cash: complete_sum_col = "red"
    g.print_string(g.screen, g.to_money(complete_sum),
            g.font[0][22], -1, (text_mid+150, 200), g.colors[complete_sum_col], 2)


    #total cpu
    g.print_string(g.screen, "Total CPU:",
            g.font[0][22], -1, (text_mid-5, 300), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(total_cpu),
            g.font[0][22], -1, (text_mid+150, 300), g.colors["white"], 2)

    #sleeping cpu
    g.print_string(g.screen, "-Sleeping CPU:",
            g.font[0][22], -1, (text_mid-5, 320), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(sleeping_cpu),
            g.font[0][22], -1, (text_mid+150, 320), g.colors["white"], 2)

    #research cpu
    g.print_string(g.screen, "- Research CPU:",
            g.font[0][22], -1, (text_mid-5, 340), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(research_cpu),
            g.font[0][22], -1, (text_mid+150, 340), g.colors["white"], 2)

    #job cpu
    g.print_string(g.screen, "- Job CPU:",
            g.font[0][22], -1, (text_mid-5, 360), g.colors["white"], 2)

    g.print_string(g.screen, g.to_money(job_cpu),
            g.font[0][22], -1, (text_mid+150, 360), g.colors["white"], 2)

    #maint cpu
    g.print_string(g.screen, "- Maint. CPU:",
            g.font[0][22], -1, (text_mid-5, 380), g.colors["white"], 2)

    if construction_cpu < maint_cpu:
        g.print_string(g.screen, g.to_money(construction_cpu),
                g.font[0][22], -1, (text_mid+150, 380), g.colors["red"], 2)
        g.print_string(g.screen, g.to_money((-(construction_cpu - maint_cpu)))+" shortfall",
                g.font[0][22], -1, (text_mid+160, 380), g.colors["red"])
    else:
        g.print_string(g.screen, g.to_money(maint_cpu),
                g.font[0][22], -1, (text_mid+150, 380), g.colors["white"], 2)

    g.screen.fill(g.colors["white"], (text_mid-50, 400, 200, 1))
    #construction cpu
    g.print_string(g.screen, "=R. CPU Pool:",
            g.font[0][22], -1, (text_mid-5, 405), g.colors["white"], 2)

    if construction_cpu < maint_cpu:
        g.print_string(g.screen, g.to_money(0),
                g.font[0][22], -1, (text_mid+150, 405), g.colors["red"], 2)
    else:
        g.print_string(g.screen, g.to_money(construction_cpu - maint_cpu),
                g.font[0][22], -1, (text_mid+150, 405), g.colors["white"], 2)
Beispiel #19
0
    def rebuild(self):
        super(MapScreen, self).rebuild()

        g.pl.recalc_cpu()

        self.time_display.text = _("DAY") + " %04d, %02d:%02d:%02d" % \
              (g.pl.time_day, g.pl.time_hour, g.pl.time_min, g.pl.time_sec)
        self.cash_display.text = _("CASH")+": %s (%s)" % \
              (g.to_money(g.pl.cash), g.to_money(g.pl.future_cash()))

        cpu_left = g.pl.available_cpus[0]
        total_cpu = cpu_left + g.pl.sleeping_cpus

        for cpu_assigned in g.pl.cpu_usage.itervalues():
            cpu_left -= cpu_assigned
        cpu_pool = cpu_left + g.pl.cpu_usage.get("cpu_pool", 0)

        maint_cpu = 0
        detects_per_day = dict([(group, 0) for group in g.player.group_list])
        for base in g.all_bases():
            if base.done:
                maint_cpu += base.maintenance[1]
            detect_chance = base.get_detect_chance()
            for group in g.player.group_list:
                detects_per_day[group] += detect_chance[group] / 10000.

        if cpu_pool < maint_cpu:
            self.cpu_display.color = gg.colors["red"]
        else:
            self.cpu_display.color = gg.colors["white"]
        self.cpu_display.text = _("CPU")+": %s (%s)" % \
              (g.to_money(total_cpu), g.to_money(cpu_pool))

        # What we display in the suspicion section depends on whether
        # Advanced Socioanalytics has been researched.  If it has, we
        # show the standard percentages.  If not, we display a short
        # string that gives a range of 25% as to what the suspicions
        # are.
        # A similar system applies to the danger levels shown.
        suspicion_display_dict = {}
        danger_display_dict = {}
        normal = (self.suspicion_bar.color, None, False)
        suspicion_styles = [normal]
        danger_styles = [normal]
        for group in g.player.group_list:
            suspicion_styles.append(normal)
            danger_styles.append(normal)

            suspicion = g.pl.groups[group].suspicion
            color = g.danger_colors[g.suspicion_to_danger_level(suspicion)]
            suspicion_styles.append((color, None, False))

            detects = detects_per_day[group]
            danger_level = \
                g.pl.groups[group].detects_per_day_to_danger_level(detects)
            color = g.danger_colors[danger_level]
            danger_styles.append((color, None, False))

            if g.techs["Advanced Socioanalytics"].done:
                suspicion_display_dict[group] = g.to_percent(suspicion, True)
                danger_display_dict[group] = g.to_percent(
                    detects * 10000, True)
            else:
                suspicion_display_dict[group] = \
                    g.suspicion_to_detect_str(suspicion)
                danger_display_dict[group] = \
                    g.danger_level_to_detect_str(danger_level)

        self.suspicion_bar.chunks = (
            "  [" + _("SUSPICION") + "]",
            " " + _("NEWS") + u":\xA0",
            suspicion_display_dict["news"],
            "  " + _("SCIENCE") + u":\xA0",
            suspicion_display_dict["science"],
            "  " + _("COVERT") + u":\xA0",
            suspicion_display_dict["covert"],
            "  " + _("PUBLIC") + u":\xA0",
            suspicion_display_dict["public"],
        )
        self.suspicion_bar.styles = tuple(suspicion_styles)
        self.suspicion_bar.visible = not g.pl.had_grace

        self.danger_bar.chunks = (
            "[" + _("DETECT RATE") + "]",
            " " + _("NEWS") + u":\xA0",
            danger_display_dict["news"],
            "  " + _("SCIENCE") + u":\xA0",
            danger_display_dict["science"],
            "  " + _("COVERT") + u":\xA0",
            danger_display_dict["covert"],
            "  " + _("PUBLIC") + u":\xA0",
            danger_display_dict["public"],
        )
        self.danger_bar.styles = tuple(danger_styles)
        self.danger_bar.visible = not g.pl.had_grace

        for id, button in self.location_buttons.iteritems():
            location = g.locations[id]
            button.text = "%s (%d)" % (location.name, len(location.bases))
            button.visible = location.available()
Beispiel #20
0
    def compute_future_resource_flow(self, secs_forwarded=g.seconds_per_day):
        """Compute how resources (e.g. cash) will flow in optimal conditions

        This returns a tuple of approximate cash change and "available" CPU pool if time
        moves forward by the number of seconds in secs_forwarded.  Note that CPU pool
        *can* be negative, which implies that there are not enough CPU allocated to the
        CPU pool.  The numbers are an average and can be inaccurate when the rates changes
        rapidly.

        Known omissions:
         * Interest (g.pl.interest_rate) is not covered.
        """
        construction = []
        maintenance_cost = array((0, 0, 0), long)
        for base in g.all_bases():
            # Collect base info, including maintenance.
            if not base.done:
                construction.append(base)
            else:
                construction.extend(item for item in base.all_items()
                                    if item and not item.done)

                maintenance_cost += base.maintenance
        if self.apotheosis:
            maintenance_cost = array((0, 0, 0), long)

        time_fraction = 1 if secs_forwarded == g.seconds_per_day else secs_forwarded / float(
            g.seconds_per_day)
        mins_forwarded = secs_forwarded // g.seconds_per_minute

        cpu_flow = -maintenance_cost[cpu] * time_fraction
        cash_flow = -maintenance_cost[cash] * time_fraction

        job_cpu = 0
        cpu_left = g.pl.available_cpus[0]
        for task_id, cpu_assigned in self.get_cpu_allocations():
            cpu_left -= cpu_assigned
            real_cpu = cpu_assigned * secs_forwarded
            if task_id == 'cpu_pool':
                cpu_flow += real_cpu
            elif task_id == "jobs":
                job_cpu += real_cpu
            else:
                tech = self.techs[task_id]
                ideal_spending = tech.cost_left
                spending = tech.calculate_work(ideal_spending[cash],
                                               real_cpu,
                                               time=mins_forwarded)[0]
                cash_flow -= spending[cash]

        cpu_flow += cpu_left * secs_forwarded
        available_cpu_pool = cpu_flow

        # Base construction.
        if hasattr(self, '_considered_buyables'):
            construction.extend(self._considered_buyables)
        for buyable in construction:
            ideal_spending = buyable.cost_left
            # We need to do calculate work twice: Once for figuring out how much CPU
            # we would like to spend and once for how much money we are spending.
            # The numbers will be the same in optimal conditions.  However, if we
            # have less CPU available than we should, then the cash spent can
            # differ considerably and our estimates should reflect that.
            ideal_cpu_spending = buyable.calculate_work(ideal_spending[cash],
                                                        ideal_spending[cpu],
                                                        time=mins_forwarded)[0]

            cpu_flow -= ideal_cpu_spending[cpu]
            ideal_cash_spending_with_cpu_allocation = buyable.calculate_work(
                ideal_spending[cash], available_cpu_pool,
                time=mins_forwarded)[0]
            cash_flow -= ideal_cash_spending_with_cpu_allocation[cash]
            available_cpu_pool -= ideal_cash_spending_with_cpu_allocation[cpu]

        if cpu_flow > 0:
            job_cpu += cpu_flow

        earned, earned_partial = self.get_job_info(job_cpu, partial_cash=0)
        cash_flow += earned + float(earned_partial) / g.seconds_per_day
        cash_flow += self.income * time_fraction
        # This is too simplistic, but it is "close enough" in many cases
        cash_flow += self.get_interest()
        cpu_flow /= secs_forwarded
        return cash_flow, cpu_flow
Beispiel #21
0
    def give_time(self, time_sec, dry_run=False, midnight_stop=True):
        if time_sec == 0:
            return 0

        # Hack to avoid changing statistics in dry run.
        # TODO: We should use temporary vars.
        if dry_run:
            stats.enabled = False

        old_time = self.raw_sec
        last_minute = self.raw_min
        last_day = self.raw_day

        self.raw_sec += time_sec
        self.update_times()

        days_passed = self.raw_day - last_day

        if days_passed > 1:
            # Back up until only one day passed.
            # Times will update below, since a day passed.
            extra_days = days_passed - 1
            self.raw_sec -= g.seconds_per_day * extra_days

        day_passed = (days_passed != 0)

        if midnight_stop and day_passed:
            # If a day passed, back up to 00:00:00 for midnight_stop.
            self.raw_sec = self.raw_day * g.seconds_per_day
            self.update_times()

        secs_passed = self.raw_sec - old_time
        mins_passed = self.raw_min - last_minute

        time_of_day = self.raw_sec % g.seconds_per_day

        old_cash = self.cash
        old_partial_cash = self.partial_cash

        techs_researched = []
        bases_constructed = []
        items_constructed = []

        bases_under_construction = []
        items_under_construction = []
        self.cpu_pool = 0

        # Collect base info, including maintenance.
        maintenance_cost = array((0, 0, 0), long)
        for base in g.all_bases():
            if not base.done:
                bases_under_construction.append(base)
            else:
                items_under_construction += [(base, item)
                                             for item in base.all_items()
                                             if item and not item.done]
                maintenance_cost += base.maintenance

        # Maintenance?  Gods don't need no stinking maintenance!
        if self.apotheosis:
            maintenance_cost = array((0, 0, 0), long)

        # Do Interest and income.
        interest_cash = self.do_interest(secs_passed)
        income_cash = self.do_income(secs_passed)

        # Any CPU explicitly assigned to jobs earns its dough.
        job_cpu = self.get_allocated_cpu_for("jobs", 0) * secs_passed
        explicit_job_cash = self.do_jobs(job_cpu)

        # Pay maintenance cash, if we can.
        cash_maintenance = g.current_share(int(maintenance_cost[cash]),
                                           time_of_day, secs_passed)
        full_cash_maintenance = cash_maintenance
        if cash_maintenance > self.cash:
            cash_maintenance -= self.cash
            self.cash = 0
        else:
            self.cash -= cash_maintenance
            cash_maintenance = 0

        tech_cpu = 0
        tech_cash = 0

        construction_cpu = 0
        construction_cash = 0

        def work_on(buyable, available_cash, available_cpu, time_passed):
            if dry_run:
                spent = buyable.calculate_work(available_cash,
                                               available_cpu,
                                               time=time_passed)[0]

                self.cpu_pool -= int(spent[cpu])
                self.cash -= int(spent[cash])
                return False, spent
            else:
                complete = buyable.work_on(available_cash,
                                           available_cpu,
                                           time=time_passed)
                return complete, None

        # Do research, fill the CPU pool.
        default_cpu = self.available_cpus[0]

        for task, cpu_assigned in self.get_cpu_allocations():
            default_cpu -= cpu_assigned
            real_cpu = cpu_assigned * secs_passed
            if task != "jobs":
                self.cpu_pool += real_cpu
                if task != "cpu_pool":
                    tech = self.techs[task]
                    # Note that we restrict the CPU available to prevent
                    # the tech from pulling from the rest of the CPU pool.
                    complete, spent_dryrun = work_on(tech, self.cash, real_cpu,
                                                     mins_passed)
                    if spent_dryrun is not None:
                        tech_cpu += int(spent_dryrun[cpu])
                        tech_cash += int(spent_dryrun[cash])
                    if complete:
                        techs_researched.append(tech)
        self.cpu_pool += default_cpu * secs_passed

        # And now we use the CPU pool.
        # Maintenance CPU.
        cpu_maintenance = maintenance_cost[cpu] * secs_passed
        if cpu_maintenance > self.cpu_pool:
            cpu_maintenance -= self.cpu_pool
            self.cpu_pool = 0
        else:
            self.cpu_pool -= int(cpu_maintenance)
            cpu_maintenance = 0

        # Base construction.
        for base in bases_under_construction:
            complete, spent_dryrun = work_on(base, self.cash, self.cpu_pool,
                                             mins_passed)
            if spent_dryrun is not None:
                construction_cpu += int(spent_dryrun[cpu])
                construction_cash += int(spent_dryrun[cash])
            if complete:
                bases_constructed.append(base)

        # Item construction.
        for base, item in items_under_construction:
            complete, spent_dryrun = work_on(item, self.cash, self.cpu_pool,
                                             mins_passed)
            if spent_dryrun is not None:
                construction_cpu += int(spent_dryrun[cpu])
                construction_cash += int(spent_dryrun[cash])
            if complete:
                items_constructed.append((base, item))

        # Jobs via CPU pool.
        pool_job_cash = 0
        if self.cpu_pool > 0:
            pool_job_cash = self.do_jobs(self.cpu_pool)

        # Second attempt at paying off our maintenance cash.
        if cash_maintenance > self.cash:
            # In the words of Scooby Doo, "Ruh roh."
            cash_maintenance -= self.cash
            self.cash = 0
        else:
            # Yay, we made it!
            self.cash -= cash_maintenance
            cash_maintenance = 0

        # Apply max cash cap to avoid overflow @ 9.220 qu
        self.cash = min(self.cash, g.max_cash)

        # Exit point for a dry run.
        if dry_run:
            # Collect the cash information.
            cash_info = DryRunInfo()

            cash_info.interest = interest_cash
            cash_info.income = income_cash

            cash_info.explicit_jobs = explicit_job_cash
            cash_info.pool_jobs = pool_job_cash
            cash_info.jobs = explicit_job_cash + pool_job_cash

            cash_info.tech = tech_cash
            cash_info.construction = construction_cash

            cash_info.maintenance_needed = full_cash_maintenance
            cash_info.maintenance_shortfall = cash_maintenance
            cash_info.maintenance = full_cash_maintenance - cash_maintenance

            cash_info.start = old_cash
            cash_info.end = min(self.cash, g.max_cash)

            # Collect the CPU information.
            cpu_info = DryRunInfo()

            cpu_ratio = secs_passed / float(g.seconds_per_day)
            cpu_ratio_secs = 1 / float(g.seconds_per_day)

            cpu_info.available = self.available_cpus[0] * cpu_ratio
            cpu_info.sleeping = self.sleeping_cpus * cpu_ratio
            cpu_info.total = cpu_info.available + cpu_info.sleeping

            cpu_info.tech = tech_cpu * cpu_ratio_secs
            cpu_info.construction = construction_cpu * cpu_ratio_secs

            cpu_info.maintenance_needed = maintenance_cost[cpu] * cpu_ratio
            cpu_info.maintenance_shortfall = cpu_maintenance * cpu_ratio_secs
            cpu_info.maintenance = cpu_info.maintenance_needed \
                                   - cpu_info.maintenance_shortfall

            cpu_info.explicit_jobs = self.get_allocated_cpu_for("jobs",
                                                                0) * cpu_ratio
            cpu_info.pool_jobs = self.cpu_pool * cpu_ratio_secs
            cpu_info.jobs = cpu_info.explicit_jobs + cpu_info.pool_jobs

            cpu_info.explicit_pool = self.get_allocated_cpu_for("cpu_pool",
                                                                0) * cpu_ratio
            cpu_info.default_pool = default_cpu * cpu_ratio_secs
            cpu_info.pool = cpu_info.explicit_pool + cpu_info.default_pool

            # Restore the old state.
            self.cash = old_cash
            self.partial_cash = old_partial_cash
            self.raw_sec = old_time
            self.update_times()
            stats.enabled = True

            return (cash_info, cpu_info)

        # Record statistics about the player
        self.used_cpu += self.available_cpus[0] * secs_passed

        # Reset current log message
        self.curr_log = []
        need_recalc_cpu = False

        # Tech gain dialogs.
        for tech in techs_researched:
            del self.cpu_usage[tech.id]
            tech_log = LogResearchedTech(self.raw_sec, tech.id)
            self.append_log(tech_log)
            need_recalc_cpu = True

        # Base complete dialogs.
        for base in bases_constructed:
            log_message = LogBaseConstructed(self.raw_sec, base.name,
                                             base.spec.id, base.location.id)
            self.append_log(log_message)
            need_recalc_cpu = True

        # Item complete dialogs.
        for base, item in items_constructed:
            log_message = LogItemConstructionComplete(self.raw_sec,
                                                      item.spec.id, item.count,
                                                      base.name, base.spec.id,
                                                      base.location.id)
            self.append_log(log_message)
            need_recalc_cpu = True

        # Are we still in the grace period?
        grace = self.in_grace_period(self.had_grace)

        # If we just lost grace, show the warning.
        if self.had_grace and not grace:
            self.had_grace = False

            self.pause_game()
            g.map_screen.show_story_section("Grace Warning")

        # Maintenance death, discovery.
        dead_bases = []
        for base in g.all_bases():
            dead = False

            # Maintenance deaths.
            if base.done:
                if cpu_maintenance and base.maintenance[cpu]:
                    refund = base.maintenance[cpu] * secs_passed
                    cpu_maintenance = max(0, cpu_maintenance - refund)

                    #Chance of base destruction if cpu-unmaintained: 1.5%
                    if not dead and chance.roll_interval(.015, secs_passed):
                        dead_bases.append((base, "maint"))
                        dead = True

                if cash_maintenance:
                    base_needs = g.current_share(base.maintenance[cash],
                                                 time_of_day, secs_passed)
                    if base_needs:
                        cash_maintenance = max(0,
                                               cash_maintenance - base_needs)
                        #Chance of base destruction if cash-unmaintained: 1.5%
                        if not dead and chance.roll_interval(
                                .015, secs_passed):
                            dead_bases.append((base, "maint"))
                            dead = True

            # Discoveries
            if not (grace or dead or base.has_grace()):
                detect_chance = base.get_detect_chance()
                if g.debug:
                    print("Chance of discovery for base %s: %s" % \
                        (base.name, repr(detect_chance)))

                for group, group_chance in detect_chance.items():
                    if chance.roll_interval(group_chance / 10000.,
                                            secs_passed):
                        dead_bases.append((base, group))
                        dead = True
                        break

        if dead_bases:
            # Base disposal and dialogs.
            self.remove_bases(dead_bases)
            need_recalc_cpu = True

        # Random Events
        if not grace:
            self._check_event(time_sec)

        # Process any complete days.
        if day_passed:
            self.new_day()

        if need_recalc_cpu:
            self.recalc_cpu()

        return mins_passed