示例#1
0
    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
示例#2
0
    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