def repair_entries(self): adv_module, _ = core.simulate.load_adv_module(self.advname) element = load_adv_json(self.advname)['c']['ele'] for duration in list(self.keys()): for kind in list(self[duration].keys()): if kind.endswith('pref'): continue self.repair_entry(adv_module, element, self[duration][kind], duration, kind) for duration in list(self.keys()): for kind in list(self[duration].keys()): # if duration != '180': # try: # self.repair_entry(adv_module, element, self['180'][kind], duration, kind, do_compare=True) # except KeyError: # pass # for affkind, basekind in (('affliction', 'base'), ('mono_affliction', 'mono_base')): # try: # self.repair_entry(adv_module, element, self[duration][basekind], duration, affkind, do_compare=True) # except KeyError: # pass for basekind in ('base', 'buffer', 'affliction'): monokind = f'mono_{basekind}' if not basekind in self[duration]: continue if not EQUIP_ENTRY_MAP[monokind].acceptable( self[duration][basekind], element): continue try: current_entry = self[duration][monokind] if not current_entry.better_than( self[duration][basekind]): self[duration][monokind] = deepcopy( self[duration][basekind]) except KeyError: self[duration][monokind] = deepcopy( self[duration][basekind]) self.update_tdps_threshold(duration) save_equip_json(self.advname, self)
def save_equip(adv, real_d, repair=False, etype=None): adv.duration = int(adv.duration) if adv.duration not in (60, 120, 180): return if any([k in adv.conf for k in ABNORMAL_COND]): return if any([wp in BANNED_PRINTS for wp in adv.slots.a.qual_lst]): return etype = etype or 'base' eleaff = core.simulate.ELE_AFFLICT[adv.slots.c.ele] if adv.sim_afflict: if adv.sim_afflict != {eleaff} or \ adv.conf_init.sim_afflict[eleaff] != 1: return else: etype = etype if repair else 'affliction' dkey = str(adv.duration) adv_qual = adv.name equip = load_equip_json(adv_qual) cached = None acl_list = adv.conf.acl if not isinstance(acl_list, list): acl_list = [ line.strip() for line in acl_list.split('\n') if line.strip() ] ndps = sum(map(lambda v: sum(v.values()), adv.logs.damage.values())) / real_d nteam = adv.logs.team_buff / real_d new_equip = { 'dps': ndps, 'team': nteam, 'tdps': None, 'slots.a': adv.slots.a.qual_lst, 'slots.d': adv.slots.d.qual, 'acl': acl_list, 'coabs': adv.slots.c.coab_list, 'share': adv.skillshare_list } try: cached = equip[dkey][etype] cdps = cached.get('dps', 0) cteam = cached.get('team', 0) repair = repair or same_build_different_dps(cached, new_equip) except KeyError: try: cached = equip[dkey]['base'] cdps = cached.get('dps', 0) cteam = cached.get('team', 0) repair = repair or same_build_different_dps(cached, new_equip) except KeyError: cdps = 0 cteam = 0 ncomp = ndps + nteam * TDPS_WEIGHT ccomp = cdps + cteam * TDPS_WEIGHT if not repair and ncomp < ccomp: if etype == 'base' and nteam > cteam: etype = 'buffer' try: cached = equip[dkey][etype] cdps = cached.get('dps', 0) cteam = cached.get('team', 0) except KeyError: pass if nteam < cteam: return if nteam == cteam: if cdps > ndps: return else: return if not repair and (etype == 'base' and nteam < cteam and 'buffer' not in equip[dkey]): equip[dkey]['buffer'] = cached equip[dkey]['buffer']['tdps'] = (ndps - cdps) / (cteam - nteam) if dkey not in equip: equip[dkey] = {} equip[dkey][etype] = new_equip if etype == 'base': try: cdps = equip[dkey][eleaff]['dps'] if cdps < ndps: del equip[dkey][eleaff] except KeyError: pass try: cdps = equip[dkey]['buffer']['dps'] cteam = equip[dkey]['buffer']['team'] if cteam <= nteam: del equip[dkey]['buffer'] except KeyError: pass try: dps_delta = equip[dkey]['base']['dps'] - equip[dkey]['buffer']['dps'] team_delta = equip[dkey]['buffer']['team'] - equip[dkey]['base']['team'] try: equip[dkey]['buffer']['tdps'] = dps_delta / team_delta except ZeroDivisionError: equip[dkey]['buffer']['tdps'] = 99999999 except KeyError: pass if 'buffer' in equip[ dkey] and equip[dkey]['buffer']['tdps'] < BUFFER_THRESHOLD: equip[dkey]['pref'] = 'buffer' equip[dkey]['base']['tdps'] = equip[dkey]['buffer']['tdps'] else: equip[dkey]['pref'] = 'base' save_equip_json(adv_qual, equip)
def save_equip(adv, real_d, repair=False): adv.duration = int(adv.duration) if adv.duration not in (60, 120, 180): return if 'sim_buffbot' in adv.conf: return if 'afflict_res' in adv.conf and 'afflict_res' not in adv.conf_base: return if 'dragonbattle' in adv.conf: return if 'classbane' in adv.conf: return if 'hp' in adv.conf: return if any([wp in BANNED_PRINTS for wp in adv.slots.a.qual_lst]): return etype = 'base' eleaff = core.simulate.ELE_AFFLICT[adv.slots.c.ele] if adv.sim_afflict: if adv.sim_afflict != {eleaff} or \ adv.conf_init.sim_afflict[eleaff] != 1: return else: etype = 'affliction' dkey = str(adv.duration) adv_qual = adv.__class__.__name__ equip = load_equip_json(adv_qual) cached = None acl_list = adv.conf.acl if not isinstance(acl_list, list): acl_list = [ line.strip() for line in acl_list.split('\n') if line.strip() ] ndps = sum(map(lambda v: sum(v.values()), adv.logs.damage.values())) / real_d nteam = adv.logs.team_buff / real_d new_equip = { 'dps': ndps, 'team': nteam, 'tdps': None, 'slots.a': adv.slots.a.qual_lst, 'slots.d': adv.slots.d.qual, 'acl': acl_list, 'coabs': adv.slots.c.coab_list, 'share': adv.skillshare_list } try: cached = equip[dkey][etype] cdps = cached.get('dps', 0) cteam = cached.get('team', 0) repair = same_build_different_dps(cached, new_equip) except KeyError: try: cached = equip[dkey]['base'] cdps = cached.get('dps', 0) cteam = cached.get('team', 0) repair = same_build_different_dps(cached, new_equip) except KeyError: cdps = 0 cteam = 0 if not repair and ndps < cdps: if etype == 'base' and nteam > cteam: etype = 'buffer' try: cached = equip[dkey][etype] cdps = cached.get('dps', 0) cteam = cached.get('team', 0) except KeyError: pass if nteam < cteam: return if nteam == cteam: if cdps > ndps: return else: return if etype == 'base' and nteam < cteam and 'buffer' not in equip[dkey]: equip[dkey]['buffer'] = cached equip[dkey]['buffer']['tdps'] = (ndps - cdps) / (cteam - nteam) if dkey not in equip: equip[dkey] = {} equip[dkey][etype] = new_equip if etype == 'base': try: cdps = equip[dkey][eleaff]['dps'] if cdps < ndps: del equip[dkey][eleaff] except KeyError: pass try: cdps = equip[dkey]['buffer']['dps'] cteam = equip[dkey]['buffer']['team'] if cteam <= nteam: del equip[dkey]['buffer'] except KeyError: pass try: dps_delta = equip[dkey]['base']['dps'] - equip[dkey]['buffer']['dps'] team_delta = equip[dkey]['buffer']['team'] - equip[dkey]['base']['team'] try: equip[dkey]['buffer']['tdps'] = dps_delta / team_delta except ZeroDivisionError: equip[dkey]['buffer']['tdps'] = 99999999 except KeyError: pass # if 'buffer' in equip[dkey] and equip[dkey]['buffer']['team'] > 1.1: if 'buffer' in equip[dkey] and equip[dkey]['buffer']['tdps'] < 40000: equip[dkey]['pref'] = 'buffer' equip[dkey]['base']['tdps'] = equip[dkey]['buffer']['tdps'] else: equip[dkey]['pref'] = 'base' save_equip_json(adv_qual, equip)
def repair_entries(self): adv_module, _ = core.simulate.load_adv_module(self.advname) element = load_adv_json(self.advname)["c"]["ele"] for duration in list(self.keys()): if not int(duration) in DURATIONS: del self[duration] for duration in list(self.keys()): for kind in list(self[duration].keys()): if kind.endswith("pref"): continue if self.check_skip_entry(self[duration][kind], duration, kind, SKIP_IF_IDENTICAL, do_compare=False)[0]: continue if self.check_skip_entry(self[duration][kind], duration, kind, SKIP_IF_SAME_COAB, do_compare=False)[0]: continue self.repair_entry(adv_module, element, self[duration][kind], duration, kind) for duration in list(self.keys()): for basekind in ("base", "buffer", "affliction", "noaffliction"): monokind = f"mono_{basekind}" if not basekind in self[duration]: try: del self[duration][monokind] except KeyError: continue continue if not EQUIP_ENTRY_MAP[monokind].acceptable( self[duration][basekind], element): if monokind not in self[duration]: # try auto populate filtered_entry = filtered_monoele_coabs( self[duration][basekind], element) if len(filtered_entry["coabs"]) == 3: # same amount of coab, no need to populate continue advcoabs = get_adv_coability(self.advname) for coab in DEFAULT_MONO_COABS[element]: if len(filtered_entry["coabs"]) == 3: break if coab not in filtered_entry[ "coabs"] and coab not in advcoabs: filtered_entry["coabs"].append(coab) self.repair_entry(adv_module, element, filtered_entry, duration, monokind) continue # try: # current_entry = self[duration][monokind] # if not current_entry.better_than(self[duration][basekind]): # self[duration][monokind] = EQUIP_ENTRY_MAP[monokind](filter_coab_only(self[duration][basekind])) # except KeyError: # self[duration][monokind] = EQUIP_ENTRY_MAP[monokind](filter_coab_only(self[duration][basekind])) self.update_tdps_threshold(duration) if not self.debug: save_equip_json(self.advname, self)
def accept_new_entry(self, adv, real_d): if self.advname != adv.name: raise RuntimeError( f"adv/equip name mismatch {self.advname} != {adv.name}") duration = int(adv.duration) if duration not in DURATIONS: return duration = str(duration) kicked_entries = [] need_write = False if duration not in self: self[duration] = {"pref": "base", "mono_pref": "mono_base"} # first pass for kind, entryclass in EQUIP_ENTRY_MAP.items(): if self.debug: print("~" * 60) print(f"{kind}") if not entryclass.eligible(adv): if self.debug: print(f"not eligible") continue new_entry = entryclass.build_from_sim(adv, real_d) if self.debug: pprint(new_entry) if not entryclass.acceptable(new_entry, adv.slots.c.ele): if self.debug: print(f"not acceptable") continue skip, need_write = self.check_skip_entry(new_entry, duration, kind, SKIP_IF_IDENTICAL, need_write=need_write) if skip: continue skip, need_write = self.check_skip_entry(new_entry, duration, kind, SKIP_IF_SAME_COAB, need_write=need_write) if skip: continue try: current_entry = self[duration][kind] except KeyError: self[duration][kind] = new_entry need_write = True if self.debug: print(f"fill empty slot {duration, kind}") continue same_build_different_dps = current_entry.same_build_different_dps( new_entry) better_than = new_entry.better_than(current_entry) if same_build_different_dps or better_than: if self.debug: print("better than existing/same build different dps") self[duration][kind] = deepcopy(new_entry) need_write = True if better_than: try: if self.debug: print(f"kick to {KICK_TO[kind]}") for kicked_kind in KICK_TO[kind]: kicked_entries.append((kicked_kind, current_entry)) except KeyError: pass # kicked entries for kind, kicked in kicked_entries: entryclass = EQUIP_ENTRY_MAP[kind] if not entryclass.acceptable(kicked, adv.slots.c.ele): continue if kind.startswith("mono_"): kicked = entryclass(filter_coab_only(kicked)) skip, need_write = self.check_skip_entry(kicked, duration, kind, SKIP_IF_SAME_COAB, need_write=need_write) if skip: continue else: kicked = entryclass(deepcopy(kicked)) try: current_entry = self[duration][kind] except KeyError: self[duration][kind] = kicked need_write = True continue if not current_entry.better_than(kicked): self[duration][kind] = kicked need_write = True tdps_write = self.update_tdps_threshold(duration) need_write = need_write or tdps_write if not self.debug and need_write: save_equip_json(self.advname, self)
def accept_new_entry(self, adv, real_d): if self.advname != adv.name: raise RuntimeError( f'adv/equip name mismatch {self.advname} != {adv.name}') duration = str(int(adv.duration)) kicked_entries = [] need_write = False if duration not in self: self[duration] = {'pref': 'base', 'mono_pref': 'mono_base'} # first pass for kind, entryclass in EQUIP_ENTRY_MAP.items(): if not entryclass.eligible(adv): continue new_entry = build_entry_from_sim(entryclass, adv, real_d) if not entryclass.acceptable(new_entry, adv.slots.c.ele): continue if self.debug: print('~' * 60) print(kind, adv.sim_afflict) pprint(new_entry) try: current_entry = self[duration][kind] except KeyError: self[duration][kind] = new_entry need_write = True if self.debug: print('fill empty slot') continue if current_entry.same_build_different_dps( new_entry) or not current_entry.better_than(new_entry): if self.debug: print('better than existing/same build different dps') self[duration][kind] = deepcopy(new_entry) need_write = True try: if self.debug: print(f'kick to {KICK_TO[kind]}') for kicked_kind in KICK_TO[kind]: kicked_entries.append((kicked_kind, current_entry)) except KeyError: pass # kicked entries for kind, kicked in kicked_entries: entryclass = EQUIP_ENTRY_MAP[kind] if not entryclass.acceptable(kicked, adv.slots.c.ele): continue kicked = entryclass(deepcopy(kicked)) try: current_entry = self[duration][kind] except KeyError: self[duration][kind] = kicked need_write = True continue if not current_entry.better_than(kicked): self[duration][kind] = kicked need_write = True tdps_write = self.update_tdps_threshold(duration) need_write = need_write or tdps_write if not self.debug and need_write: save_equip_json(self.advname, self)