Initial Release of IGNCore version 2.5
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
import math
|
||||
|
||||
from core.chat_blob import ChatBlob
|
||||
from core.command_param_types import Const, Int
|
||||
from core.decorators import instance, command
|
||||
from core.dict_object import DictObject
|
||||
|
||||
|
||||
@instance()
|
||||
class LadderController:
|
||||
def __init__(self):
|
||||
self.grades = ["shiny", "bright", "faded"]
|
||||
|
||||
def inject(self, registry):
|
||||
self.db = registry.get_instance("db")
|
||||
self.util = registry.get_instance("util")
|
||||
self.text = registry.get_instance("text")
|
||||
|
||||
@command(command="ladder", params=[Const("treatment"), Int("starting_amount")], access_level="member",
|
||||
description="Show sequence of laddering implants for treatment",
|
||||
extended_description="The starting amount should be the treatment or "
|
||||
"ability you have with all nano buffs, "
|
||||
"perks, and items-buffing equipment equipped, "
|
||||
"but minus any buffs from implants that you have equipped.")
|
||||
def ladder_treatment_cmd(self, _, _1, treatment):
|
||||
if treatment < 11:
|
||||
return "Base treatment must be at least <highlight>11</highlight>."
|
||||
|
||||
prefix = "skill_"
|
||||
result = self.optimized_steps(prefix, treatment, self.get_implant_by_max_treatment)
|
||||
|
||||
blob = self.format_steps("treatment", result.steps, treatment,
|
||||
(treatment + self.calculate_total(result.slots, prefix)))
|
||||
|
||||
return ChatBlob("Laddering Treatment", blob)
|
||||
|
||||
@command(command="ladder", params=[Const("ability"), Int("starting_amount")], access_level="member",
|
||||
description="Show sequence of laddering implants for ability",
|
||||
extended_description="The starting amount should be the treatment or "
|
||||
"ability you have with all nano buffs, "
|
||||
"perks, and items-buffing equipment equipped, "
|
||||
"but minus any buffs from implants you have equipped.")
|
||||
def ladder_ability_cmd(self, _, _1, ability):
|
||||
if ability < 6:
|
||||
return "Base ability must be at least <highlight>6</highlight>."
|
||||
|
||||
prefix = "ability_"
|
||||
result = self.optimized_steps(prefix, ability, self.get_implant_by_max_ability)
|
||||
|
||||
blob = self.format_steps("ability", result.steps, ability,
|
||||
(ability + self.calculate_total(result.slots, prefix)))
|
||||
|
||||
return ChatBlob("Laddering Ability", blob)
|
||||
|
||||
def format_steps(self, label, steps, starting, ending):
|
||||
blob = f"Starting {label}: <highlight>{starting}</highlight>\n\n"
|
||||
blob += "-------------------\n\n"
|
||||
for (action, grade, implant) in steps:
|
||||
blob += f"{action.capitalize()} {grade} QL <highlight>{implant.ql:d}</highlight>\n\n"
|
||||
|
||||
blob += "-------------------\n\n"
|
||||
blob += "Ending %s: <highlight>%s</highlight>\n\n" % (label, ending)
|
||||
blob += "\nInspired by a command written by Lucier of the same name"
|
||||
|
||||
return blob
|
||||
|
||||
def optimized_steps(self, prefix, base_value, get_max_implant):
|
||||
grade_combinations = [self.grades,
|
||||
["shiny", "faded", "bright"],
|
||||
["bright", "shiny", "faded"],
|
||||
["bright", "faded", "shiny"],
|
||||
["faded", "shiny", "bright"],
|
||||
["faded", "bright", "shiny"]]
|
||||
|
||||
best = None
|
||||
for grade_combo in grade_combinations:
|
||||
result = self.get_steps(prefix, base_value, get_max_implant,
|
||||
lambda current_grade: self.get_next_grade(current_grade, grade_combo))
|
||||
if not best:
|
||||
best = result
|
||||
else:
|
||||
result_value = self.calculate_total(result.slots, prefix)
|
||||
best_value = self.calculate_total(best.slots, prefix)
|
||||
if result_value > best_value:
|
||||
# this is here as a sanity check, but it appears
|
||||
# that the result is always the same no matter which order you insert the implants
|
||||
best = result
|
||||
elif best_value == result_value and len(result.steps) < len(best.steps):
|
||||
# this optimizes for the least amount of steps/implants
|
||||
best = result
|
||||
|
||||
return best
|
||||
|
||||
def get_steps(self, prefix, base_value, get_max_implant, get_next_grade):
|
||||
slots = DictObject({"shiny": None,
|
||||
"bright": None,
|
||||
"faded": None})
|
||||
|
||||
steps = []
|
||||
|
||||
num_skipped = 0
|
||||
current_grade = None
|
||||
while num_skipped < 3:
|
||||
current_grade = get_next_grade(current_grade)
|
||||
|
||||
# find next highest possible implant
|
||||
new_implant = get_max_implant(self.calculate_total(slots, prefix, current_grade) + base_value)
|
||||
|
||||
if not slots.get(current_grade):
|
||||
steps.append(["add", current_grade, new_implant])
|
||||
slots[current_grade] = new_implant
|
||||
elif new_implant.get(prefix + current_grade) > slots.get(current_grade).get(prefix + current_grade):
|
||||
steps.append(["remove", current_grade, slots.get(current_grade)])
|
||||
steps.append(["add", current_grade, new_implant])
|
||||
slots[current_grade] = new_implant
|
||||
else:
|
||||
num_skipped += 1
|
||||
|
||||
return DictObject({"slots": slots,
|
||||
"steps": steps})
|
||||
|
||||
def get_next_grade(self, current_grade, grades):
|
||||
if not current_grade:
|
||||
next_index = 0
|
||||
else:
|
||||
next_index = grades.index(current_grade) + 1
|
||||
if next_index >= len(grades):
|
||||
next_index = 0
|
||||
|
||||
return grades[next_index]
|
||||
|
||||
def get_implant_by_max_treatment(self, treatment):
|
||||
return self.db.query_single("SELECT * from implant_requirement "
|
||||
"WHERE treatment <= ? "
|
||||
"ORDER BY ql DESC "
|
||||
"LIMIT 1",
|
||||
[treatment])
|
||||
|
||||
def get_implant_by_max_ability(self, ability):
|
||||
return self.db.query_single("SELECT * from implant_requirement "
|
||||
"WHERE ability <= ? "
|
||||
"ORDER BY ql DESC "
|
||||
"LIMIT 1",
|
||||
[ability])
|
||||
|
||||
def get_cluser_min_ql(self, ql, grade):
|
||||
if grade == "shiny":
|
||||
result = math.floor(ql * 0.86)
|
||||
elif grade == "bright":
|
||||
result = math.floor(ql * 0.84)
|
||||
elif grade == "faded":
|
||||
result = math.floor(ql * 0.82)
|
||||
else:
|
||||
raise Exception("Unknown grade: '%s'" % grade)
|
||||
|
||||
if ql >= 201:
|
||||
return max(201, result)
|
||||
else:
|
||||
return result
|
||||
|
||||
def calculate_total(self, slots, prefix, skip_grade=None):
|
||||
value = 0
|
||||
for grade in self.grades:
|
||||
if grade != skip_grade:
|
||||
implant = slots.get(grade)
|
||||
if implant:
|
||||
value += implant.get(prefix + grade)
|
||||
|
||||
return value
|
||||
Reference in New Issue
Block a user