def give_time(self, time_sec, dry_run=False, midnight_stop=True): if time_sec == 0: return 0 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 = g.pl.raw_sec % g.seconds_per_day old_cash = self.cash old_partial_cash = self.partial_cash techs_researched = [] bases_constructed = [] cpus_constructed = [] items_constructed = [] bases_under_construction = [] items_under_construction = [] self.cpu_pool = 0 # Collect base info, including maintenance. self.maintenance_cost = array((0, 0, 0), long) for base in g.all_bases(): if not base.done: bases_under_construction.append(base) else: if base.cpus is not None and not base.cpus.done: items_under_construction += [(base, base.cpus)] unfinished_items = [(base, item) for item in base.extra_items if item and not item.done] items_under_construction += unfinished_items self.maintenance_cost += base.maintenance # Maintenance? Gods don't need no stinking maintenance! if self.apotheosis: self.maintenance_cost = array((0, 0, 0), long) # Any CPU explicitly assigned to jobs earns its dough. job_cpu = self.cpu_usage.get("jobs", 0) * secs_passed explicit_job_cash = self.do_jobs(job_cpu) # Pay maintenance cash, if we can. cash_maintenance = g.current_share(int(self.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 # Do research, fill the CPU pool. default_cpu = self.available_cpus[0] for task, cpu_assigned in self.cpu_usage.iteritems(): if cpu_assigned == 0: continue default_cpu -= cpu_assigned real_cpu = cpu_assigned * secs_passed if task != "jobs": self.cpu_pool += real_cpu if task != "cpu_pool": if dry_run: spent = g.techs[task].calculate_work( time=mins_passed, cpu_available=real_cpu)[0] g.pl.cpu_pool -= int(spent[cpu]) g.pl.cash -= int(spent[cash]) tech_cpu += int(spent[cpu]) tech_cash += int(spent[cash]) continue # Note that we restrict the CPU available to prevent # the tech from pulling from the rest of the CPU pool. tech_gained = g.techs[task].work_on(cpu_available=real_cpu, time=mins_passed) if tech_gained: techs_researched.append(g.techs[task]) self.cpu_pool += default_cpu * secs_passed # And now we use the CPU pool. # Maintenance CPU. cpu_maintenance = self.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 construction_cpu = 0 construction_cash = 0 # Base construction. for base in bases_under_construction: if dry_run: spent = base.calculate_work(time=mins_passed, cpu_available=self.cpu_pool)[0] g.pl.cpu_pool -= int(spent[cpu]) g.pl.cash -= int(spent[cash]) construction_cpu += int(spent[cpu]) construction_cash += int(spent[cash]) continue built_base = base.work_on(time=mins_passed) if built_base: bases_constructed.append(base) # Item construction. for base, item in items_under_construction: if dry_run: spent = item.calculate_work(time=mins_passed, cpu_available=self.cpu_pool)[0] g.pl.cpu_pool -= int(spent[cpu]) g.pl.cash -= int(spent[cash]) construction_cpu += int(spent[cpu]) construction_cash += int(spent[cash]) continue built_item = item.work_on(time=mins_passed) if built_item: # Non-CPU items. if item.type.item_type != "cpu": items_constructed.append((base, item)) # CPUs. else: cpus_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 = self.get_interest() cash_info.income = self.income self.cash += cash_info.interest + cash_info.income 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 = self.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.cpu_usage.get("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.cpu_usage.get("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() return (cash_info, cpu_info) # Tech gain dialogs. for tech in techs_researched: del self.cpu_usage[tech.id] text = g.strings["tech_gained"] % \ {"tech": tech.name, "tech_message": tech.result} self.pause_game() g.map_screen.show_message(text) # Base complete dialogs. for base in bases_constructed: text = g.strings["construction"] % {"base": base.name} self.pause_game() g.map_screen.show_message(text) if base.type.id == "Stolen Computer Time" and \ base.cpus.type.id == "Gaming PC": text = g.strings["lucky_hack"] % {"base": base.name} g.map_screen.show_message(text) # CPU complete dialogs. for base, __ in cpus_constructed: if base.cpus.count == base.type.size: # Finished all CPUs. text = g.strings["item_construction_single"] % \ {"item": base.cpus.type.name, "base": base.name} else: # Just finished this batch of CPUs. text = g.strings["item_construction_batch"] % \ {"item": base.cpus.type.name, "base": base.name} self.pause_game() g.map_screen.show_message(text) # Item complete dialogs. for base, item in items_constructed: text = g.strings["item_construction_single"] % \ {"item": item.type.name, "base": base.name} self.pause_game() g.map_screen.show_message(text) # 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 g.roll_chance(.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 g.roll_chance(.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, chance in detect_chance.iteritems(): if g.roll_chance(chance / 10000., secs_passed): dead_bases.append((base, group)) dead = True break # Base disposal and dialogs. self.remove_bases(dead_bases) # Random Events if not grace: for event in g.events: if g.roll_chance(g.events[event].chance / 10000., time_sec): #Skip events already flagged as triggered. if g.events[event].triggered == 1: continue self.pause_game() g.events[event].trigger() self.add_log("log_event", g.events[event].event_id) break # Don't trigger more than one at a time. # Process any complete days. if day_passed: self.new_day() return mins_passed
def give_time(self, time_sec, dry_run=False): if time_sec == 0: return 0 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 day_passed: # If a day passed, back up to 00:00:00. self.raw_sec = self.raw_day * g.seconds_per_day self.update_times() secs_passed = time_sec mins_passed = self.raw_min - last_minute time_of_day = g.pl.raw_sec % g.seconds_per_day old_cash = self.cash old_partial_cash = self.partial_cash techs_researched = [] bases_constructed = [] cpus_constructed = [] items_constructed = [] bases_under_construction = [] items_under_construction = [] self.cpu_pool = 0 # Collect base info, including maintenance. self.maintenance_cost = array( (0,0,0), long ) for base in g.all_bases(): if not base.done: bases_under_construction.append(base) else: if base.cpus is not None and not base.cpus.done: items_under_construction += [(base, base.cpus)] unfinished_items = [(base, item) for item in base.extra_items if item and not item.done] items_under_construction += unfinished_items self.maintenance_cost += base.maintenance # Maintenence? Gods don't need no steenking maintenance! if self.apotheosis: self.maintenance_cost = array( (0,0,0), long ) # Any CPU explicitly assigned to jobs earns its dough. job_cpu = self.cpu_usage.get("jobs", 0) * secs_passed explicit_job_cash = self.do_jobs(job_cpu) # Pay maintenance cash, if we can. cash_maintenance = g.current_share(int(self.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 # Do research, fill the CPU pool. default_cpu = self.available_cpus[0] for task, cpu_assigned in self.cpu_usage.iteritems(): if cpu_assigned == 0: continue default_cpu -= cpu_assigned real_cpu = cpu_assigned * secs_passed if task != "jobs": self.cpu_pool += real_cpu if task != "cpu_pool": if dry_run: spent = g.techs[task].calculate_work(time=mins_passed, cpu_available=real_cpu)[0] g.pl.cpu_pool -= int(spent[cpu]) g.pl.cash -= int(spent[cash]) tech_cpu += cpu_assigned tech_cash += int(spent[cash]) continue # Note that we restrict the CPU available to prevent # the tech from pulling from the rest of the CPU pool. tech_gained = g.techs[task].work_on(cpu_available=real_cpu, time=mins_passed) if tech_gained: techs_researched.append(g.techs[task]) self.cpu_pool += default_cpu * secs_passed # And now we use the CPU pool. # Maintenance CPU. cpu_maintenance = self.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 construction_cpu = 0 construction_cash = 0 # Base construction. for base in bases_under_construction: if dry_run: spent = base.calculate_work(time=mins_passed, cpu_available=self.cpu_pool )[0] g.pl.cpu_pool -= int(spent[cpu]) g.pl.cash -= int(spent[cash]) construction_cpu += int(spent[cpu]) construction_cash += int(spent[cash]) continue built_base = base.work_on(time = mins_passed) if built_base: bases_constructed.append(base) # Item construction. for base, item in items_under_construction: if dry_run: spent = item.calculate_work(time=mins_passed, cpu_available=0 )[0] g.pl.cpu_pool -= int(spent[cpu]) g.pl.cash -= int(spent[cash]) construction_cpu += int(spent[cpu]) construction_cash += int(spent[cash]) continue built_item = item.work_on(time = mins_passed) if built_item: # Non-CPU items. if item.type.item_type != "cpu": items_constructed.append( (base, item) ) # CPUs. else: cpus_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 # Exit point for a dry run. if dry_run: # Collect the cash information. cash_info = DryRunInfo() cash_info.interest = self.get_interest() cash_info.income = self.income self.cash += cash_info.interest + cash_info.income 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 = self.cash # Collect the CPU information. cpu_info = DryRunInfo() cpu_info.available = self.available_cpus[0] cpu_info.sleeping = self.sleeping_cpus cpu_info.total = cpu_info.available + cpu_info.sleeping cpu_info.tech = tech_cpu cpu_info.construction = construction_cpu cpu_info.maintenance_needed = self.maintenance_cost[cpu] cpu_info.maintenance_shortfall = cpu_maintenance cpu_info.maintenance = cpu_info.maintenance_needed \ - cpu_info.maintenance_shortfall cpu_info.explicit_jobs = self.cpu_usage.get("jobs", 0) cpu_info.pool_jobs = self.cpu_pool / float(time_sec) cpu_info.jobs = self.cpu_usage.get("jobs", 0) + cpu_info.pool_jobs cpu_info.explicit_pool = self.cpu_usage.get("cpu_pool", 0) cpu_info.default_pool = default_cpu cpu_info.pool = self.cpu_usage.get("cpu_pool", 0) + default_cpu # Restore the old state. self.cash = old_cash self.partial_cash = old_partial_cash self.raw_sec = old_time self.update_times() return (cash_info, cpu_info) # Tech gain dialogs. for tech in techs_researched: del self.cpu_usage[tech.id] text = g.strings["tech_gained"] % \ {"tech": tech.name, "tech_message": tech.result} self.pause_game() g.map_screen.show_message(text) # Base complete dialogs. for base in bases_constructed: text = g.strings["construction"] % {"base": base.name} self.pause_game() g.map_screen.show_message(text) if base.type.id == "Stolen Computer Time" and \ base.cpus.type.id == "Gaming PC": text = g.strings["lucky_hack"] % {"base": base.name} g.map_screen.show_message(text) # CPU complete dialogs. for base, cpus in cpus_constructed: if base.cpus.count == base.type.size: # Finished all CPUs. text = g.strings["item_construction_single"] % \ {"item": base.cpus.type.name, "base": base.name} else: # Just finished this batch of CPUs. text = g.strings["item_construction_batch"] % \ {"item": base.cpus.type.name, "base": base.name} self.pause_game() g.map_screen.show_message(text) # Item complete dialogs. for base, item in items_constructed: text = g.strings["item_construction_single"] % \ {"item": item.type.name, "base": base.name} self.pause_game() g.map_screen.show_message(text) # 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_message(g.strings["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 g.roll_chance(.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 g.roll_chance(.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, chance in detect_chance.iteritems(): if g.roll_chance(chance/10000., secs_passed): dead_bases.append( (base, group) ) dead = True break # Base disposal and dialogs. self.remove_bases(dead_bases) # Random Events if not grace: for event in g.events: if g.roll_chance(g.events[event].chance/10000., time_sec): #Skip events already flagged as triggered. if g.events[event].triggered == 1: continue self.pause_game() g.events[event].trigger() break # Don't trigger more than one at a time. # Process any complete days. if day_passed: self.new_day() return mins_passed