import math from core.chat_blob import ChatBlob from core.command_param_types import Int from core.decorators import instance, command from core.dict_object import DictObject # noinspection DuplicatedCode @instance() class ImplantController: def __init__(self): self.grades = ["shiny", "bright", "faded"] self.normal_ability_req = {1: 6, 200: 404, 201: 426, 300: 1095} self.normal_treatment_req = {1: 11, 200: 951, 201: 1001, 300: 2051} self.jobe_ability_req = {1: 6, 200: 464, 201: 476, 300: 1231} self.jobe_treatment_req = {1: 11, 200: 1005, 201: 1001, 300: 2051} self.ability_shiny_bonus = {1: 5, 200: 55, 201: 55, 300: 73} self.ability_bright_bonus = {1: 3, 200: 33, 201: 33, 300: 44} self.ability_faded_bonus = {1: 2, 200: 22, 201: 22, 300: 29} self.skill_shiny_bonus = {1: 6, 200: 105, 201: 106, 300: 141} self.skill_bright_bonus = {1: 3, 200: 63, 201: 63, 300: 85} self.skill_faded_bonus = {1: 2, 200: 42, 201: 42, 300: 57} self.normal_build_shiny = {1: 4, 200: 800, 201: 994, 300: 1575} self.normal_build_bright = {1: 3, 200: 600, 201: 753, 300: 1125} self.normal_build_faded = {1: 2, 200: 400, 201: 552, 300: 825} self.jobe_build_shiny = {1: 6, 200: 1250, 201: 1356, 300: 2025} self.jobe_build_bright = {1: 4, 200: 950, 201: 1055, 300: 1575} self.jobe_build_faded = {1: 3, 200: 650, 201: 753, 300: 1125} self.clean_np = {1: 1, 200: 200} self.clean_be = {1: 4, 200: 950} def inject(self, registry): self.db = registry.get_instance("db") self.util = registry.get_instance("util") self.text = registry.get_instance("text") self.command_alias_service = registry.get_instance("command_alias_service") def pre_start(self): self.db.load_sql_file(self.module_dir + "/sql/" + "Ability.sql", pre_optimized=True) self.db.create_view("Ability") self.db.load_sql_file(self.module_dir + "/sql/" + "Cluster.sql", pre_optimized=True) self.db.create_view("Cluster") self.db.load_sql_file(self.module_dir + "/sql/" + "ClusterImplantMap.sql", pre_optimized=True) self.db.create_view("ClusterImplantMap") self.db.load_sql_file(self.module_dir + "/sql/" + "ClusterType.sql", pre_optimized=True) self.db.create_view("ClusterType") self.db.load_sql_file(self.module_dir + "/sql/" + "EffectTypeMatrix.sql", pre_optimized=True) self.db.create_view("EffectTypeMatrix") self.db.load_sql_file(self.module_dir + "/sql/" + "EffectValue.sql", pre_optimized=True) self.db.create_view("EffectValue") self.db.load_sql_file(self.module_dir + "/sql/" + "ImplantMatrix.sql", pre_optimized=True) self.db.create_view("ImplantMatrix") self.db.load_sql_file(self.module_dir + "/sql/" + "ImplantType.sql", pre_optimized=True) self.db.create_view("ImplantType") self.db.load_sql_file(self.module_dir + "/sql/" + "Profession.sql", pre_optimized=True) self.db.create_view("Profession") self.db.load_sql_file(self.module_dir + "/sql/" + "Symbiant.sql", pre_optimized=True) self.db.create_view("Symbiant") self.db.load_sql_file(self.module_dir + "/sql/" + "SymbiantAbilityMatrix.sql", pre_optimized=True) self.db.create_view("SymbiantAbilityMatrix") self.db.load_sql_file(self.module_dir + "/sql/" + "SymbiantClusterMatrix.sql", pre_optimized=True) self.db.create_view("SymbiantClusterMatrix") self.db.load_sql_file(self.module_dir + "/sql/" + "SymbiantProfessionMatrix.sql", pre_optimized=True) self.db.create_view("SymbiantProfessionMatrix") self.db.load_sql_file(self.module_dir + "/sql/" + "implant_requirements.sql", pre_optimized=True) self.db.create_view("implant_requirement") def start(self): self.command_alias_service.add_alias("implants", "implant") @command(command="implant", params=[Int("ql")], access_level="member", description="Shows information about an implant at given QL") def implant_cmd(self, _, ql): if ql > 300 or ql < 1: return "Implant QL must be between 1 and 300." implant = self.get_implant_by_ql(ql) blob = self.format_implant(implant) return ChatBlob(f"Implant QL {implant.ql} ({implant.ability} Ability, {implant.treatment} Treatment)", blob) @command(command="implant", params=[Int("ability"), Int("treatment")], access_level="member", description="Shows highest QL implant for a given ability and treatment") def implant_requirement_cmd(self, _, ability, treatment): implant = self.get_implant_by_requirements(ability, treatment) if not implant: return "You do not have enough ability or treatment to wear an implant." blob = self.format_implant(implant) return ChatBlob(f"Implant QL {implant.ql} ({implant.ability} Ability, {implant.treatment} Treatment)", blob) def get_implant_by_requirements(self, ability, treatment): row = self.db.query_single("SELECT ql FROM implant_requirement " "WHERE ability <= ? AND treatment <= ? " "ORDER BY ql DESC LIMIT 1", [ability, treatment]) if row: return self.get_implant_by_ql(row.ql) else: return None def format_implant(self, implant): blob = "Requirements to Wear\n" blob += f"{implant.treatment} Treatment\n" blob += f"{implant.ability} Ability\n" blob += "\nAbility Cluster Bonuses\n" blob += f"{implant.ability_shiny} Shiny " \ f"({implant.ability_shiny_min} - {implant.ability_shiny_max})\n" blob += f"{implant.ability_bright} Bright " \ f"({implant.ability_bright_min} - {implant.ability_bright_max})\n" blob += f"{implant.ability_faded} Faded " \ f"({implant.ability_faded_min} - {implant.ability_faded_max})\n" blob += "\nSkill Cluster Bonuses\n" blob += f"{implant.skill_shiny} Shiny " \ f"({implant.skill_shiny_min} - {implant.skill_shiny_max})\n" blob += f"{implant.skill_bright} Bright " \ f"({implant.skill_bright_min} - {implant.skill_bright_max})\n" blob += f"{implant.skill_faded} Faded " \ f"({implant.skill_faded_min} - {implant.skill_faded_max})\n" blob += "\nRequirements to Clean\n" if implant.ql <= 200: blob += f"{implant.clean_break_and_entry} Break&Entry\n" blob += f"{implant.clean_nano_programming} NanoProgramming\n" else: blob += "Refined implants cannot be cleaned\n" blob += "\nMax Requirements to Build (actual requirements may be lower)\n" blob += f"{implant.build_shiny} NanoProgramming for Shiny\n" blob += f"{implant.build_bright} NanoProgramming for Bright\n" blob += f"{implant.build_faded} NanoProgramming for Faded\n" blob += "\nMin Cluster QL\n" blob += f"{implant.minimum_cluster_shiny} Shiny\n" blob += f"{implant.minimum_cluster_bright} Bright\n" blob += f"{implant.minimum_cluster_faded} Faded\n" if implant.ql >= 99: blob += "\nJobe Requirements\n" blob += "\nRequirements to Wear\n" blob += f"{implant.jobe_treatment} Treatment\n" blob += f"{implant.jobe_ability} Ability\n" blob += "\nMax Requirements to Build (actual requirements may be lower)\n" blob += f"{implant.jobe_build_shiny} NanoProgramming for Shiny\n" blob += f"{implant.jobe_build_bright} NanoProgramming for Bright\n" blob += f"{implant.jobe_build_faded} NanoProgramming for Faded\n" blob += "\nJobe implants cannot be cleaned\n" blob += f"\n\nBased on the !impql command written for " \ f"{self.text.make_chatcmd('Ttst', '/tell ttst help')} by Lucier" return blob def get_implant_by_ql(self, ql): implant = DictObject({}) implant.ql = ql implant.treatment = int(self.util.interpolate_value(ql, self.normal_treatment_req)) implant.ability = int(self.util.interpolate_value(ql, self.normal_ability_req)) implant.jobe_treatment = self.util.interpolate_value(ql, self.jobe_treatment_req) implant.jobe_ability = self.util.interpolate_value(ql, self.jobe_ability_req) implant.ability_shiny = self.util.interpolate_value(ql, self.ability_shiny_bonus) implant.ability_shiny_min, implant.ability_shiny_max = self.get_range(ql, implant.ability_shiny, self.ability_shiny_bonus) implant.ability_bright = self.util.interpolate_value(ql, self.ability_bright_bonus) implant.ability_bright_min, implant.ability_bright_max = self.get_range(ql, implant.ability_bright, self.ability_bright_bonus) implant.ability_faded = self.util.interpolate_value(ql, self.ability_faded_bonus) implant.ability_faded_min, implant.ability_faded_max = self.get_range(ql, implant.ability_faded, self.ability_faded_bonus) implant.skill_shiny = self.util.interpolate_value(ql, self.skill_shiny_bonus) implant.skill_shiny_min, implant.skill_shiny_max = self.get_range(ql, implant.skill_shiny, self.skill_shiny_bonus) implant.skill_bright = self.util.interpolate_value(ql, self.skill_bright_bonus) implant.skill_bright_min, implant.skill_bright_max = self.get_range(ql, implant.skill_bright, self.skill_bright_bonus) implant.skill_faded = self.util.interpolate_value(ql, self.skill_faded_bonus) implant.skill_faded_min, implant.skill_faded_max = self.get_range(ql, implant.skill_faded, self.skill_faded_bonus) implant.clean_break_and_entry = self.util.interpolate_value(ql, self.clean_be) implant.clean_nano_programming = self.util.interpolate_value(ql, self.clean_np) implant.build_shiny = self.util.interpolate_value(ql, self.normal_build_shiny) implant.build_bright = self.util.interpolate_value(ql, self.normal_build_bright) implant.build_faded = self.util.interpolate_value(ql, self.normal_build_faded) implant.jobe_build_shiny = self.util.interpolate_value(ql, self.jobe_build_shiny) implant.jobe_build_bright = self.util.interpolate_value(ql, self.jobe_build_bright) implant.jobe_build_faded = self.util.interpolate_value(ql, self.jobe_build_faded) if ql >= 201: implant.minimum_cluster_shiny = max(201, math.floor(ql * 0.86)) implant.minimum_cluster_bright = max(201, math.floor(ql * 0.84)) implant.minimum_cluster_faded = max(201, math.floor(ql * 0.82)) else: implant.minimum_cluster_shiny = math.floor(ql * 0.86) implant.minimum_cluster_bright = math.floor(ql * 0.84) implant.minimum_cluster_faded = math.floor(ql * 0.82) return implant def get_range(self, ql, value, interpolation): min_ql = ql max_ql = ql while self.util.interpolate_value(min_ql - 1, interpolation) == value: min_ql -= 1 while self.util.interpolate_value(max_ql + 1, interpolation) == value: max_ql += 1 return [min_ql, max_ql]