mirror of
https://github.com/Lost-MSth/Arcaea-server.git
synced 2025-12-14 08:06:23 +08:00
[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
This commit is contained in:
@@ -12,7 +12,7 @@ class Config:
|
|||||||
|
|
||||||
SONG_FILE_HASH_PRE_CALCULATE = True
|
SONG_FILE_HASH_PRE_CALCULATE = True
|
||||||
|
|
||||||
GAME_API_PREFIX = '/akeome/24'
|
GAME_API_PREFIX = '/samusugiru/26'
|
||||||
|
|
||||||
ALLOW_APPVERSION = [] # list[str]
|
ALLOW_APPVERSION = [] # list[str]
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from .config_manager import Config
|
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'
|
ARCAEA_LOG_DATBASE_VERSION = 'v1.1'
|
||||||
|
|
||||||
|
|
||||||
@@ -11,6 +11,7 @@ class Constant:
|
|||||||
MAX_STAMINA = 12
|
MAX_STAMINA = 12
|
||||||
|
|
||||||
STAMINA_RECOVER_TICK = 1800000
|
STAMINA_RECOVER_TICK = 1800000
|
||||||
|
FRAGSTAM_RECOVER_TICK = 23 * 3600 * 1000
|
||||||
|
|
||||||
COURSE_STAMINA_COST = 4
|
COURSE_STAMINA_COST = 4
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from .item import ItemCore
|
|||||||
from .song import Chart
|
from .song import Chart
|
||||||
from .sql import Connect, Query, Sql
|
from .sql import Connect, Query, Sql
|
||||||
from .util import get_today_timestamp, md5
|
from .util import get_today_timestamp, md5
|
||||||
from .world import WorldPlay, BeyondWorldPlay
|
from .world import WorldPlay, BeyondWorldPlay, BreachedWorldPlay
|
||||||
|
|
||||||
|
|
||||||
class Score:
|
class Score:
|
||||||
@@ -500,8 +500,14 @@ class UserPlay(UserScore):
|
|||||||
|
|
||||||
# 世界模式判断
|
# 世界模式判断
|
||||||
if self.is_world_mode:
|
if self.is_world_mode:
|
||||||
self.world_play = WorldPlay(
|
self.user.select_user_about_world_play()
|
||||||
self.c, self.user, self) if self.beyond_gauge == 0 else BeyondWorldPlay(self.c, self.user, self)
|
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()
|
self.world_play.update()
|
||||||
|
|
||||||
# 课题模式判断
|
# 课题模式判断
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ class Map:
|
|||||||
self.map_id: str = map_id
|
self.map_id: str = map_id
|
||||||
self.is_legacy: bool = None
|
self.is_legacy: bool = None
|
||||||
self.is_beyond: bool = None
|
self.is_beyond: bool = None
|
||||||
|
self.is_breached: bool = None
|
||||||
self.beyond_health: int = None
|
self.beyond_health: int = None
|
||||||
self.character_affinity: list = []
|
self.character_affinity: list = []
|
||||||
self.affinity_multiplier: list = []
|
self.affinity_multiplier: list = []
|
||||||
@@ -119,6 +120,11 @@ class Map:
|
|||||||
self.require_localunlock_challengeid: str = None
|
self.require_localunlock_challengeid: str = None
|
||||||
self.chain_info: dict = None
|
self.chain_info: dict = None
|
||||||
|
|
||||||
|
# self.requires: list[dict] = None
|
||||||
|
|
||||||
|
self.disable_over: bool = None
|
||||||
|
self.new_law: str = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rewards(self) -> list:
|
def rewards(self) -> list:
|
||||||
if self.__rewards is None:
|
if self.__rewards is None:
|
||||||
@@ -145,6 +151,7 @@ class Map:
|
|||||||
'map_id': self.map_id,
|
'map_id': self.map_id,
|
||||||
'is_legacy': self.is_legacy,
|
'is_legacy': self.is_legacy,
|
||||||
'is_beyond': self.is_beyond,
|
'is_beyond': self.is_beyond,
|
||||||
|
'is_breached': self.is_breached,
|
||||||
'beyond_health': self.beyond_health,
|
'beyond_health': self.beyond_health,
|
||||||
'character_affinity': self.character_affinity,
|
'character_affinity': self.character_affinity,
|
||||||
'affinity_multiplier': self.affinity_multiplier,
|
'affinity_multiplier': self.affinity_multiplier,
|
||||||
@@ -165,11 +172,16 @@ class Map:
|
|||||||
}
|
}
|
||||||
if self.chain_info is not None:
|
if self.chain_info is not None:
|
||||||
r['chain_info'] = self.chain_info
|
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
|
return r
|
||||||
|
|
||||||
def from_dict(self, raw_dict: dict) -> 'Map':
|
def from_dict(self, raw_dict: dict) -> 'Map':
|
||||||
self.is_legacy = raw_dict.get('is_legacy')
|
self.is_legacy = raw_dict.get('is_legacy', False)
|
||||||
self.is_beyond = raw_dict.get('is_beyond')
|
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.beyond_health = raw_dict.get('beyond_health')
|
||||||
self.character_affinity = raw_dict.get('character_affinity', [])
|
self.character_affinity = raw_dict.get('character_affinity', [])
|
||||||
self.affinity_multiplier = raw_dict.get('affinity_multiplier', [])
|
self.affinity_multiplier = raw_dict.get('affinity_multiplier', [])
|
||||||
@@ -189,6 +201,9 @@ class Map:
|
|||||||
'require_localunlock_challengeid', '')
|
'require_localunlock_challengeid', '')
|
||||||
self.chain_info = raw_dict.get('chain_info')
|
self.chain_info = raw_dict.get('chain_info')
|
||||||
self.steps = [Step().from_dict(s) for s in raw_dict.get('steps')]
|
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
|
return self
|
||||||
|
|
||||||
def select_map_info(self):
|
def select_map_info(self):
|
||||||
@@ -696,13 +711,12 @@ class BaseWorldPlay(WorldSkillMixin):
|
|||||||
def final_progress(self) -> float:
|
def final_progress(self) -> float:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def update(self) -> None:
|
def before_update(self) -> None:
|
||||||
'''世界模式更新'''
|
|
||||||
if self.user_play.prog_boost_multiply != 0:
|
if self.user_play.prog_boost_multiply != 0:
|
||||||
self.user.update_user_one_column('prog_boost', 0)
|
self.user.update_user_one_column('prog_boost', 0)
|
||||||
|
|
||||||
self.user_play.clear_play_state()
|
self.user_play.clear_play_state()
|
||||||
self.user.select_user_about_world_play()
|
# self.user.select_user_about_world_play()
|
||||||
|
|
||||||
self.character_used = Character()
|
self.character_used = Character()
|
||||||
|
|
||||||
@@ -720,10 +734,9 @@ class BaseWorldPlay(WorldSkillMixin):
|
|||||||
self.character_used.prog.set_parameter(50, 50, 50)
|
self.character_used.prog.set_parameter(50, 50, 50)
|
||||||
self.character_used.overdrive.set_parameter(50, 50, 50)
|
self.character_used.overdrive.set_parameter(50, 50, 50)
|
||||||
|
|
||||||
self.user.current_map.select_map_info()
|
# self.user.current_map.select_map_info()
|
||||||
self.before_calculate()
|
|
||||||
self.user.current_map.climb(self.final_progress)
|
def after_update(self) -> None:
|
||||||
self.after_climb()
|
|
||||||
|
|
||||||
for i in self.user.current_map.rewards_for_climbing: # 物品分发
|
for i in self.user.current_map.rewards_for_climbing: # 物品分发
|
||||||
for j in i['items']:
|
for j in i['items']:
|
||||||
@@ -747,6 +760,14 @@ class BaseWorldPlay(WorldSkillMixin):
|
|||||||
|
|
||||||
self.user.current_map.update()
|
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):
|
class WorldPlay(BaseWorldPlay):
|
||||||
def __init__(self, c=None, user=None, user_play=None) -> None:
|
def __init__(self, c=None, user=None, user_play=None) -> None:
|
||||||
@@ -819,9 +840,9 @@ class WorldPlay(BaseWorldPlay):
|
|||||||
def progress_normalized(self) -> float:
|
def progress_normalized(self) -> float:
|
||||||
return self.base_progress * (self.partner_adjusted_prog / 50)
|
return self.base_progress * (self.partner_adjusted_prog / 50)
|
||||||
|
|
||||||
def update(self) -> None:
|
def after_update(self) -> None:
|
||||||
'''世界模式更新'''
|
'''世界模式更新'''
|
||||||
super().update()
|
super().after_update()
|
||||||
|
|
||||||
# 更新byd大招蓄力条
|
# 更新byd大招蓄力条
|
||||||
self.user.beyond_boost_gauge += self.beyond_boost_gauge_addition
|
self.user.beyond_boost_gauge += self.beyond_boost_gauge_addition
|
||||||
@@ -892,12 +913,83 @@ class BeyondWorldPlay(BaseWorldPlay):
|
|||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def update(self) -> None:
|
def after_update(self) -> None:
|
||||||
super().update()
|
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:
|
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
|
self.user.beyond_boost_gauge -= self.user_play.beyond_boost_gauge_usage
|
||||||
if abs(self.user.beyond_boost_gauge) <= 1e-5:
|
if abs(self.user.beyond_boost_gauge) <= 1e-5:
|
||||||
self.user.beyond_boost_gauge = 0
|
self.user.beyond_boost_gauge = 0
|
||||||
self.user.update_user_one_column(
|
self.user.update_user_one_column(
|
||||||
'beyond_boost_gauge', self.user.beyond_boost_gauge)
|
'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()
|
||||||
|
|||||||
@@ -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']
|
'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",
|
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",
|
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)]
|
course_banners = ['course_banner_' + str(i) for i in range(1, 12)]
|
||||||
|
|
||||||
|
|||||||
@@ -1594,5 +1594,23 @@
|
|||||||
],
|
],
|
||||||
"orig_price": 100,
|
"orig_price": 100,
|
||||||
"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
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -2,6 +2,7 @@ from time import time
|
|||||||
|
|
||||||
from flask import Blueprint, request
|
from flask import Blueprint, request
|
||||||
|
|
||||||
|
from core.constant import Constant
|
||||||
from core.error import InputError, ItemUnavailable, PostError
|
from core.error import InputError, ItemUnavailable, PostError
|
||||||
from core.item import ItemFactory, Stamina6
|
from core.item import ItemFactory, Stamina6
|
||||||
from core.purchase import Purchase, PurchaseList
|
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)
|
return ItemUnavailable('Buying stamina by fragment is not available yet.', 905)
|
||||||
|
|
||||||
user.update_user_one_column(
|
user.update_user_one_column(
|
||||||
'next_fragstam_ts', now + 24 * 3600 * 1000)
|
'next_fragstam_ts', now + Constant.FRAGSTAM_RECOVER_TICK)
|
||||||
s = Stamina6(c)
|
s = Stamina6(c)
|
||||||
s.user_claim_item(user)
|
s.user_claim_item(user)
|
||||||
return success_return({
|
return success_return({
|
||||||
|
|||||||
Reference in New Issue
Block a user