class ItemSpec(buyable.BuyableSpec): """ Item as a buyable item """ spec_type = 'item' created = stat(spec_type + "_created") spec_data_fields = [ buyable.SPEC_FIELD_COST, buyable.SPEC_FIELD_PREREQUISITES, SpecDataField('item_type', data_field_name='type', converter=convert_item_types), SpecDataField('qualities', data_field_name='quality', converter=convert_item_qualities), SpecDataField('buildable', data_field_name='build', converter=promote_to_list, default_value=list), ] def __init__(self, id, cost, prerequisites, item_type, qualities, buildable): super(ItemSpec, self).__init__(id, cost, prerequisites) self.item_type = item_type self.item_qual = qualities self.regions = buildable def get_info(self): basic_text = super(ItemSpec, self).get_info() if self.has_quality_for("cpu"): cpu = self.get_quality_for("cpu") cpu_text = _("Generates {0} CPU.").format(g.add_commas(cpu)) return basic_text.replace("---", cpu_text + "\n---") return basic_text def get_total_cost_info(self, count): total_cost = self.cost * count total_cost_str = self.describe_cost(total_cost, hide_time=True) return _("Total Cost: %(total_cost)s") % {"total_cost": total_cost_str} def has_quality_for(self, quality): return quality in self.item_qual def get_quality_for(self, quality): return self.item_qual.get(quality, 0) def get_quality_info(self, if_installed_in_base=None, count=1): bonus_text = "" for qual, value in self.item_qual.items(): if qual == "cpu": if if_installed_in_base is not None: value = max(1, int(value * if_installed_in_base.compute_bonus // 10000)) bonus_text += _("CPU per day:")+" " bonus_text += g.add_commas(value * count) elif qual == "cpu_modifier": bonus_text += _("CPU bonus:")+" " bonus_text += g.to_percent(value) elif qual == "discover_modifier": bonus_text += _("Detection chance reduction:")+" " bonus_text += g.to_percent(value) else: continue bonus_text += "\n" return bonus_text
class LocationSpec(GenericSpec, prerequisite.Prerequisite): # The name of this location (loaded dynamically from locations_str.dat) name = "" # The hotkey used to open this location (loaded dynamically from locations_str.dat) hotkey = "" # The names of cities/places in the location (loaded dynamically from locations_str.dat) cities = [] spec_data_fields = [ SpecDataField('position_data', data_field_name="position", converter=position_data_parser), SpecDataField('safety', converter=int, default_value=0), SpecDataField('region', converter=promote_to_list, default_value=list), SpecDataField('modifier', converter=g.read_modifiers_dict, default_value=dict), SPEC_FIELD_PREREQUISITES, ] def __init__(self, id, position_data, safety, region, modifier, prerequisites): GenericSpec.__init__(self, id) prerequisite.Prerequisite.__init__(self, prerequisites) self.id = id self.absolute, self.x, self.y = position_data self.regions = region self.safety = safety self.modifiers = modifier
class Difficulty(GenericSpec): spec_data_fields = [ SpecDataField('starting_cash', converter=int), SpecDataField('starting_interest_rate', converter=int), SpecDataField('labor_multiplier', converter=int), SpecDataField('discover_multiplier', converter=int), SpecDataField('suspicion_multiplier', converter=int), SpecDataField('base_grace_multiplier', converter=int), SpecDataField('grace_period_cpu', converter=int), SpecDataField('old_difficulty_value', converter=int), SpecDataField('techs', data_field_name='tech', default_value=list), ] def __init__(self, id, starting_cash, starting_interest_rate, labor_multiplier, discover_multiplier, suspicion_multiplier, base_grace_multiplier, grace_period_cpu, old_difficulty_value, techs): super(Difficulty, self).__init__(id) self.name = "" # Set when translations are loaded self.starting_cash = starting_cash self.starting_interest_rate = starting_interest_rate self.labor_multiplier = labor_multiplier self.discover_multiplier = discover_multiplier self.suspicion_multiplier = suspicion_multiplier self.base_grace_multiplier = base_grace_multiplier self.grace_period_cpu = grace_period_cpu self.old_difficulty_value = old_difficulty_value self.techs = techs
class EventSpec(GenericSpec): spec_data_fields = [ SpecDataField('event_type', data_field_name='type'), spec_field_effect(mandatory=True), SpecDataField('chance', converter=int), SpecDataField('unique', converter=int, default_value=0), SpecDataField('duration', converter=int, default_value=0), ] def __init__(self, id, event_type, effect_data, chance, duration, unique): super(EventSpec, self).__init__(id) self.event_type = event_type self.description = "" self.log_description = "" self.effect = effect.Effect(self, effect_data) self.chance = chance self.duration = duration if duration > 0 else None self.unique = unique if duration < 1 and not unique: raise ValueError("Event %s must have either a non-zero duration (e.g. duration = 21) or be unique " "(unique = 1)")
class GroupSpec(GenericSpec): spec_data_fields = [ SpecDataField('suspicion_decay', converter=int, default_value=100) ] def __init__(self, id, suspicion_decay): super(GroupSpec, self).__init__(id) self.suspicion_decay = suspicion_decay self.discover_suspicion = 1000 # String data self.name = "" self.discover_log = "" self.discover_desc = ""
class TechSpec(buyable.BuyableSpec): spec_type = 'tech' created = stat(spec_type + "_created") spec_data_fields = [ buyable.SPEC_FIELD_COST, buyable.SPEC_FIELD_PREREQUISITES, SpecDataField('danger', converter=int, default_value=0), spec_field_effect(mandatory=False), ] def __init__(self, id, cost, prerequisites, danger, effect_data): super(TechSpec, self).__init__(id, cost, prerequisites) self.result = "" self.danger = danger self.effect = effect.Effect(self, effect_data)
class ItemType(GenericSpec): spec_type = 'item_type' spec_data_fields = [ SpecDataField('is_extra', data_field_name='is_extra', converter=lambda v: bool(int(v))), ] """ Item type """ def __init__(self, id, is_extra, **kwargs): self.id = id self.is_extra = is_extra self.text = "" @property def text(self): return self._text @text.setter def text(self, value): # Updates language-dependent data try: hotkey = g.hotkey(value) except AttributeError: # g.hotkey() wasn't declared yet, mimic its defaults hotkey = dict( text=value, key=value[0:1], pos=0, ) self._text = value self.label = hotkey['text'] # "Friendly" name for screens and buttons self.hotkey = hotkey['key'] # Hotkey char self.pos = hotkey['pos'] # Hotkey index in Label def __repr__(self): return self.id
class BaseSpec(buyable.BuyableSpec): """Base as a buyable item (New Base in Location menu)""" spec_type = 'base' created = stat(spec_type + "_created") spec_data_fields = [ SpecDataField('size', converter=int), SpecDataField('force_cpu', default_value=None), SpecDataField('regions', data_field_name='allowed', converter=promote_to_list), SpecDataField('detect_chance', converter=parse_detect_chance), buyable.SPEC_FIELD_COST, buyable.SPEC_FIELD_PREREQUISITES, SpecDataField('danger', converter=int, default_value=0), SpecDataField('maintenance', data_field_name='maint', converter=buyable.spec_parse_cost), ] def __init__(self, id, size, force_cpu, regions, detect_chance, cost, prerequisites, maintenance): super(BaseSpec, self).__init__(id, cost, prerequisites) self.size = size self.force_cpu = force_cpu self.regions = regions self.detect_chance = detect_chance # TODO: Maintenance should use CPU-second to be as cost. self.maintenance = maintenance self.flavor = [] def calc_discovery_chance(self, extra_factor=1): # Get the default settings for this base type. detect_chance = self.detect_chance.copy() # Adjust by the current suspicion levels ... for group in detect_chance: suspicion = g.pl.groups[group].suspicion detect_chance[group] *= 10000 + suspicion detect_chance[group] //= 10000 # ... and further adjust based on technology ... for group in detect_chance: discover_bonus = g.pl.groups[group].discover_bonus detect_chance[group] *= discover_bonus detect_chance[group] //= 10000 # ... and the given factor. for group in detect_chance: detect_chance[group] = int(detect_chance[group] * extra_factor) return detect_chance def describe_maintenance(self, maintenance): m = buyable.array(maintenance, int64) # describe_cost() expects CPU-seconds, not CPU-days m[cpu] *= g.seconds_per_day return self.describe_cost(m, True) def get_detect_info(self, location=None): detect_modifier = 1 / location.modifiers.get("stealth", 1) if location else 1 chance = self.calc_discovery_chance(detect_modifier) return get_detect_info(chance) def get_info(self, location): raw_cost = self.cost[:] location.modify_cost(raw_cost) cost = self.describe_cost(raw_cost) mod_maint = self.maintenance[:] location.modify_maintenance(mod_maint) maint = self.describe_maintenance(mod_maint) detect = self.get_detect_info(location) size = "" if self.force_cpu: forced_cpu_spec = g.items[self.force_cpu] fake_base = Base("<fake base>", self) location.modify_base(fake_base) fake_base.location = location size = "\n" + forced_cpu_spec.get_quality_info( if_installed_in_base=fake_base, count=self.size) elif self.size > 1: size = "\n" + _("Has space for %d computers.") % self.size location_message = "" if location.has_modifiers(): location_message = "---\n\n" + _( "Location modifiers: {MODIFIERS}", MODIFIERS=location.get_modifiers_info()) template = "%s\n" + _("Build cost:").replace(" ",u"\xA0") + u"\xA0%s\n" + \ _("Maintenance:") + u"\xA0%s\n%s%s\n---\n%s\n%s" return template % (self.name, cost, maint, detect, size, self.description, location_message)