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
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
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
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
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
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
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")
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
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
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
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
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()
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()
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
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()
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()
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)
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)
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()
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
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