From 9d096f480b7431d1e02cbcbc1b208e7fcddfe8d9 Mon Sep 17 00:00:00 2001 From: Lost-MSth Date: Tue, 30 Jan 2024 15:16:26 +0800 Subject: [PATCH] [Enhance] Breached World - Add support for Breached World Map - Change the recover time of using fragments buying stamina to 23 hours - For Arcaea 5.3.0 --- latest version/core/config_manager.py | 2 +- latest version/core/constant.py | 3 +- latest version/core/score.py | 12 ++- latest version/core/world.py | 120 +++++++++++++++++++--- latest version/database/init/arc_data.py | 4 +- latest version/database/init/singles.json | 18 ++++ latest version/server/purchase.py | 3 +- 7 files changed, 140 insertions(+), 22 deletions(-) diff --git a/latest version/core/config_manager.py b/latest version/core/config_manager.py index fa5cb2a..6c4fd35 100644 --- a/latest version/core/config_manager.py +++ b/latest version/core/config_manager.py @@ -12,7 +12,7 @@ class Config: SONG_FILE_HASH_PRE_CALCULATE = True - GAME_API_PREFIX = '/akeome/24' + GAME_API_PREFIX = '/samusugiru/26' ALLOW_APPVERSION = [] # list[str] diff --git a/latest version/core/constant.py b/latest version/core/constant.py index 8f2b4b4..7a3045a 100644 --- a/latest version/core/constant.py +++ b/latest version/core/constant.py @@ -1,6 +1,6 @@ from .config_manager import Config -ARCAEA_SERVER_VERSION = 'v2.11.3.2' +ARCAEA_SERVER_VERSION = 'v2.11.3.3' ARCAEA_LOG_DATBASE_VERSION = 'v1.1' @@ -11,6 +11,7 @@ class Constant: MAX_STAMINA = 12 STAMINA_RECOVER_TICK = 1800000 + FRAGSTAM_RECOVER_TICK = 23 * 3600 * 1000 COURSE_STAMINA_COST = 4 diff --git a/latest version/core/score.py b/latest version/core/score.py index fb5fc86..21f23e9 100644 --- a/latest version/core/score.py +++ b/latest version/core/score.py @@ -11,7 +11,7 @@ from .item import ItemCore from .song import Chart from .sql import Connect, Query, Sql from .util import get_today_timestamp, md5 -from .world import WorldPlay, BeyondWorldPlay +from .world import WorldPlay, BeyondWorldPlay, BreachedWorldPlay class Score: @@ -500,8 +500,14 @@ class UserPlay(UserScore): # 世界模式判断 if self.is_world_mode: - self.world_play = WorldPlay( - self.c, self.user, self) if self.beyond_gauge == 0 else BeyondWorldPlay(self.c, self.user, self) + self.user.select_user_about_world_play() + self.user.current_map.select_map_info() + if self.user.current_map.is_breached: + self.world_play = BreachedWorldPlay(self.c, self.user, self) + elif self.user.current_map.is_beyond: + self.world_play = BeyondWorldPlay(self.c, self.user, self) + else: + self.world_play = WorldPlay(self.c, self.user, self) self.world_play.update() # 课题模式判断 diff --git a/latest version/core/world.py b/latest version/core/world.py index 93ff3e5..0ce81f3 100644 --- a/latest version/core/world.py +++ b/latest version/core/world.py @@ -99,6 +99,7 @@ class Map: self.map_id: str = map_id self.is_legacy: bool = None self.is_beyond: bool = None + self.is_breached: bool = None self.beyond_health: int = None self.character_affinity: list = [] self.affinity_multiplier: list = [] @@ -119,6 +120,11 @@ class Map: self.require_localunlock_challengeid: str = None self.chain_info: dict = None + # self.requires: list[dict] = None + + self.disable_over: bool = None + self.new_law: str = None + @property def rewards(self) -> list: if self.__rewards is None: @@ -145,6 +151,7 @@ class Map: 'map_id': self.map_id, 'is_legacy': self.is_legacy, 'is_beyond': self.is_beyond, + 'is_breached': self.is_breached, 'beyond_health': self.beyond_health, 'character_affinity': self.character_affinity, 'affinity_multiplier': self.affinity_multiplier, @@ -165,11 +172,16 @@ class Map: } if self.chain_info is not None: r['chain_info'] = self.chain_info + if self.disable_over: + r['disable_over'] = self.disable_over + if self.new_law is not None and self.new_law != '': + r['new_law'] = self.new_law return r def from_dict(self, raw_dict: dict) -> 'Map': - self.is_legacy = raw_dict.get('is_legacy') - self.is_beyond = raw_dict.get('is_beyond') + self.is_legacy = raw_dict.get('is_legacy', False) + self.is_beyond = raw_dict.get('is_beyond', False) + self.is_breached = raw_dict.get('is_breached', False) self.beyond_health = raw_dict.get('beyond_health') self.character_affinity = raw_dict.get('character_affinity', []) self.affinity_multiplier = raw_dict.get('affinity_multiplier', []) @@ -189,6 +201,9 @@ class Map: 'require_localunlock_challengeid', '') self.chain_info = raw_dict.get('chain_info') self.steps = [Step().from_dict(s) for s in raw_dict.get('steps')] + + self.disable_over = raw_dict.get('disable_over') + self.new_law = raw_dict.get('new_law') return self def select_map_info(self): @@ -696,13 +711,12 @@ class BaseWorldPlay(WorldSkillMixin): def final_progress(self) -> float: raise NotImplementedError - def update(self) -> None: - '''世界模式更新''' + def before_update(self) -> None: if self.user_play.prog_boost_multiply != 0: self.user.update_user_one_column('prog_boost', 0) self.user_play.clear_play_state() - self.user.select_user_about_world_play() + # self.user.select_user_about_world_play() self.character_used = Character() @@ -720,10 +734,9 @@ class BaseWorldPlay(WorldSkillMixin): self.character_used.prog.set_parameter(50, 50, 50) self.character_used.overdrive.set_parameter(50, 50, 50) - self.user.current_map.select_map_info() - self.before_calculate() - self.user.current_map.climb(self.final_progress) - self.after_climb() + # self.user.current_map.select_map_info() + + def after_update(self) -> None: for i in self.user.current_map.rewards_for_climbing: # 物品分发 for j in i['items']: @@ -747,6 +760,14 @@ class BaseWorldPlay(WorldSkillMixin): self.user.current_map.update() + def update(self) -> None: + '''世界模式更新''' + self.before_update() + self.before_calculate() + self.user.current_map.climb(self.final_progress) + self.after_climb() + self.after_update() + class WorldPlay(BaseWorldPlay): def __init__(self, c=None, user=None, user_play=None) -> None: @@ -819,9 +840,9 @@ class WorldPlay(BaseWorldPlay): def progress_normalized(self) -> float: return self.base_progress * (self.partner_adjusted_prog / 50) - def update(self) -> None: + def after_update(self) -> None: '''世界模式更新''' - super().update() + super().after_update() # 更新byd大招蓄力条 self.user.beyond_boost_gauge += self.beyond_boost_gauge_addition @@ -892,12 +913,83 @@ class BeyondWorldPlay(BaseWorldPlay): return r - def update(self) -> None: - super().update() - + def after_update(self) -> None: + super().after_update() if self.user_play.beyond_boost_gauge_usage != 0 and self.user_play.beyond_boost_gauge_usage <= self.user.beyond_boost_gauge: self.user.beyond_boost_gauge -= self.user_play.beyond_boost_gauge_usage if abs(self.user.beyond_boost_gauge) <= 1e-5: self.user.beyond_boost_gauge = 0 self.user.update_user_one_column( 'beyond_boost_gauge', self.user.beyond_boost_gauge) + + +class WorldLawMixin: + def breached_before_calculate(self) -> None: + factory_dict = { + 'over100_step50': self._over100_step50, + 'frag50': self._frag50, + 'lowlevel': self._lowlevel, + 'antiheroism': self._antiheroism + } + if self.user.current_map.new_law in factory_dict: + factory_dict[self.user.current_map.new_law]() + + def _over100_step50(self) -> None: + '''PROG = OVER + STEP / 2''' + self.new_law_prog = self.character_used.overdrive_value + \ + self.character_used.prog_value / 2 + + def _frag50(self) -> None: + '''PROG x= FRAG''' + self.new_law_prog = self.character_used.frag_value + + def _lowlevel(self) -> None: + '''PROG x= max(1.0, 2.0 - 0.1 x LEVEL)''' + self.new_law_prog = 50 * \ + max(1, 2 - 0.1 * self.character_used.level.level) + + def _antiheroism(self) -> None: + '''PROG = OVER - ||OVER-FRAG|-|OVER-STEP||''' + over = self.character_used.overdrive_value + x = abs(over - self.character_used.frag_value) + y = abs(over - self.character_used.prog_value) + self.new_law_prog = over - abs(x - y) + + +class BreachedWorldPlay(BeyondWorldPlay, WorldLawMixin): + def __init__(self, c=None, user=None, user_play=None) -> None: + super().__init__(c, user, user_play) + self.new_law_prog: float = None + + @property + def new_law_multiply(self) -> float: + if self.new_law_prog is None: + return 1 + return self.new_law_prog / 50 + + @property + def affinity_multiplier(self) -> float: + return 1 + + @property + def progress_normalized(self) -> float: + if self.user.current_map.disable_over: + return self.base_progress * self.new_law_multiply + + overdrive = self.character_used.overdrive_value + if self.over_skill_increase: + overdrive += self.over_skill_increase + return self.base_progress * (overdrive / 50) * self.new_law_multiply + + def to_dict(self) -> dict: + r = super().to_dict() + r['new_law_multiply'] = self.new_law_multiply + return r + + def update(self) -> None: + self.before_update() + self.before_calculate() + self.breached_before_calculate() + self.user.current_map.climb(self.final_progress) + self.after_climb() + self.after_update() diff --git a/latest version/database/init/arc_data.py b/latest version/database/init/arc_data.py index 3a3f66d..df8d1b5 100644 --- a/latest version/database/init/arc_data.py +++ b/latest version/database/init/arc_data.py @@ -69,10 +69,10 @@ class InitData: 'core_ambivalent', 'core_scarlet', 'core_groove', 'core_generic', 'core_binary', 'core_colorful', 'core_course_skip_purchase', 'core_umbral', 'core_wacca', 'core_sunset'] world_songs = ["babaroque", "shadesoflight", "kanagawa", "lucifer", "anokumene", "ignotus", "rabbitintheblackroom", "qualia", "redandblue", "bookmaker", "darakunosono", "espebranch", "blacklotus", "givemeanightmare", "vividtheory", "onefr", "gekka", "vexaria3", "infinityheaven3", "fairytale3", "goodtek3", "suomi", "rugie", "faintlight", "harutopia", "goodtek", "dreaminattraction", "syro", "diode", "freefall", "grimheart", "blaster", - "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight", "lapis", "solitarydream", "lumia3", "purpleverse", "moonheart3", "glow", "enchantedlove", "take", "lifeispiano", "vandalism", "nexttoyou3", "lostcivilization3", "turbocharger", "bookmaker3", "laqryma3", "kyogenkigo", "hivemind", "seclusion", "quonwacca3", "bluecomet", "energysynergymatrix", "gengaozo", "lastendconductor3", "antithese3", "qualia3", "kanagawa3", "heavensdoor3", "pragmatism3", "nulctrl", "avril", "ddd", "merlin3", "omakeno3", "nekonote", "sanskia", 'altair', 'mukishitsu', 'trapcrow', 'redandblue3', 'ignotus3', 'singularity3', 'dropdead3', 'arcahv', 'freefall3', 'partyvinyl3', 'tsukinimurakumo', 'mantis', 'worldfragments', 'astrawalkthrough', 'chronicle', 'trappola3', 'letsrock', 'shadesoflight3', 'teriqma3', 'impact3', 'lostemotion', 'gimmick', 'lawlesspoint', 'hybris', 'ultimatetaste', 'rgb', 'matenrou', 'dynitikos', 'amekagura', 'fantasy', 'aloneandlorn', 'felys', 'onandon', 'hotarubinoyuki'] + "cyberneciacatharsis", "monochromeprincess", "revixy", "vector", "supernova", "nhelv", "purgatorium3", "dement3", "crossover", "guardina", "axiumcrisis", "worldvanquisher", "sheriruth", "pragmatism", "gloryroad", "etherstrike", "corpssansorganes", "lostdesire", "blrink", "essenceoftwilight", "lapis", "solitarydream", "lumia3", "purpleverse", "moonheart3", "glow", "enchantedlove", "take", "lifeispiano", "vandalism", "nexttoyou3", "lostcivilization3", "turbocharger", "bookmaker3", "laqryma3", "kyogenkigo", "hivemind", "seclusion", "quonwacca3", "bluecomet", "energysynergymatrix", "gengaozo", "lastendconductor3", "antithese3", "qualia3", "kanagawa3", "heavensdoor3", "pragmatism3", "nulctrl", "avril", "ddd", "merlin3", "omakeno3", "nekonote", "sanskia", 'altair', 'mukishitsu', 'trapcrow', 'redandblue3', 'ignotus3', 'singularity3', 'dropdead3', 'arcahv', 'freefall3', 'partyvinyl3', 'tsukinimurakumo', 'mantis', 'worldfragments', 'astrawalkthrough', 'chronicle', 'trappola3', 'letsrock', 'shadesoflight3', 'teriqma3', 'impact3', 'lostemotion', 'gimmick', 'lawlesspoint', 'hybris', 'ultimatetaste', 'rgb', 'matenrou', 'dynitikos', 'amekagura', 'fantasy', 'aloneandlorn', 'felys', 'onandon', 'hotarubinoyuki', 'oblivia3', 'libertas3', 'einherjar3', 'purpleverse3', 'viciousheroism3', 'inkarusi3', 'cyberneciacatharsis3'] world_unlocks = ["scenery_chap1", "scenery_chap2", - "scenery_chap3", "scenery_chap4", "scenery_chap5", "scenery_chap6", "scenery_chap7"] + "scenery_chap3", "scenery_chap4", "scenery_chap5", "scenery_chap6", "scenery_chap7", "scenery_beyond"] course_banners = ['course_banner_' + str(i) for i in range(1, 12)] diff --git a/latest version/database/init/singles.json b/latest version/database/init/singles.json index 68d39f8..1215d4c 100644 --- a/latest version/database/init/singles.json +++ b/latest version/database/init/singles.json @@ -1594,5 +1594,23 @@ ], "orig_price": 100, "price": 100 + }, + { + "name": "lunarossa", + "items": [ + { + "type": "single", + "id": "lunarossa", + "is_available": true + }, + { + "type": "core", + "amount": 1, + "id": "core_generic", + "is_available": true + } + ], + "orig_price": 100, + "price": 100 } ] \ No newline at end of file diff --git a/latest version/server/purchase.py b/latest version/server/purchase.py index b45b315..083eeb8 100644 --- a/latest version/server/purchase.py +++ b/latest version/server/purchase.py @@ -2,6 +2,7 @@ from time import time from flask import Blueprint, request +from core.constant import Constant from core.error import InputError, ItemUnavailable, PostError from core.item import ItemFactory, Stamina6 from core.purchase import Purchase, PurchaseList @@ -130,7 +131,7 @@ def purchase_stamina(user_id, buy_stamina_type): return ItemUnavailable('Buying stamina by fragment is not available yet.', 905) user.update_user_one_column( - 'next_fragstam_ts', now + 24 * 3600 * 1000) + 'next_fragstam_ts', now + Constant.FRAGSTAM_RECOVER_TICK) s = Stamina6(c) s.user_claim_item(user) return success_return({