feat(task):修改领取技能卡的选择逻辑2
This commit is contained in:
parent
00427292e0
commit
3e698a6ae7
|
@ -1,16 +1,47 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class CharacterId(Enum):
|
||||
"""偶像 ID。"""
|
||||
hski = "hski" # Hanami Saki, 花海咲季
|
||||
ttmr = "ttmr" # Tsukimura Temari, 月村手毬
|
||||
fktn = "fktn" # Fujita Kotone, 藤田ことね
|
||||
amao = "amao" # Arimura Mao, 有村麻央
|
||||
kllj = "kllj" # Katsuragi Lilja, 葛城リーリヤ
|
||||
kcna = "kcna" # Kuramoto China, 倉本千奈
|
||||
ssmk = "ssmk" # Shiun Sumika, 紫云清夏
|
||||
shro = "shro" # Shinosawa Hiro, 篠澤広
|
||||
hrnm = "hrnm" # Himesaki Rinami, 姫崎莉波
|
||||
hume = "hume" # Hanami Ume, 花海佑芽
|
||||
jsna = "jsna" # Juo Sena, 十王星南
|
||||
hmsz = "hmsz" # Hataya Misuzu, 秦谷美鈴
|
||||
hski = "hski" # Hanami Saki, 花海咲季
|
||||
ttmr = "ttmr" # Tsukimura Temari, 月村手毬
|
||||
fktn = "fktn" # Fujita Kotone, 藤田ことね
|
||||
amao = "amao" # Arimura Mao, 有村麻央
|
||||
kllj = "kllj" # Katsuragi Lilja, 葛城リーリヤ
|
||||
kcna = "kcna" # Kuramoto China, 倉本千奈
|
||||
ssmk = "ssmk" # Shiun Sumika, 紫云清夏
|
||||
shro = "shro" # Shinosawa Hiro, 篠澤広
|
||||
hrnm = "hrnm" # Himesaki Rinami, 姫崎莉波
|
||||
hume = "hume" # Hanami Ume, 花海佑芽
|
||||
jsna = "jsna" # Juo Sena, 十王星南
|
||||
hmsz = "hmsz" # Hataya Misuzu, 秦谷美鈴
|
||||
|
||||
|
||||
class ExamEffectType(Enum):
|
||||
"""
|
||||
考试流派。
|
||||
温存根据 ShowExamEffectType 决定
|
||||
"""
|
||||
good_condition = "ProduceExamEffectType_ExamParameterBuff"
|
||||
"""好调"""
|
||||
focus = "ProduceExamEffectType_ExamLessonBuff"
|
||||
"""集中"""
|
||||
good_impression = "ProduceExamEffectType_ExamReview"
|
||||
"""好印象"""
|
||||
motivation = "ProduceExamEffectType_ExamCardPlayAggressive"
|
||||
"""干劲"""
|
||||
confidence = "ProduceExamEffectType_ExamConcentration"
|
||||
"""强气"""
|
||||
full_power = "ProduceExamEffectType_ExamFullPower"
|
||||
"""全力"""
|
||||
|
||||
|
||||
class ShowExamEffectType(Enum):
|
||||
"""
|
||||
若为 ProduceExamEffectType_ExamPreservation ,则偶像卡推荐流派显示为 温存
|
||||
目前分 全力-温存 和 强气-温存 两种,选择卡牌还是根据 全力/强气 来选择
|
||||
"""
|
||||
unknown = "ProduceExamEffectType_Unknown"
|
||||
"""推荐流派与ExamEffectType对应"""
|
||||
conservation = "ProduceExamEffectType_ExamPreservation"
|
||||
"""推荐流派显示为温存"""
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
from .sqlite import select, select_many
|
||||
from .constants import CharacterId
|
||||
from .constants import ExamEffectType, ShowExamEffectType
|
||||
|
||||
|
||||
@dataclass
|
||||
class IdolCard:
|
||||
"""偶像卡"""
|
||||
id: str
|
||||
skin_id: str
|
||||
exam_effect_type: ExamEffectType
|
||||
show_exam_effect_type: ShowExamEffectType
|
||||
is_another: bool
|
||||
another_name: str | None
|
||||
name: str
|
||||
|
@ -21,6 +24,8 @@ class IdolCard:
|
|||
SELECT
|
||||
IC.id AS cardId,
|
||||
ICS.id AS skinId,
|
||||
IC.examEffectType AS examEffectType,
|
||||
IC.showExamEffectType AS showExamEffectType,
|
||||
Char.lastName || ' ' || Char.firstName || ' ' || IC.name AS name,
|
||||
NOT (IC.originalIdolCardSkinId = ICS.id) AS isAnotherVer,
|
||||
ICS.name AS anotherVerName
|
||||
|
@ -34,11 +39,13 @@ class IdolCard:
|
|||
return cls(
|
||||
id=row["cardId"],
|
||||
skin_id=row["skinId"],
|
||||
exam_effect_type=ExamEffectType(row["examEffectType"]),
|
||||
show_exam_effect_type=ShowExamEffectType(row["showExamEffectType"]),
|
||||
is_another=bool(row["isAnotherVer"]),
|
||||
another_name=row["anotherVerName"],
|
||||
name=row["name"]
|
||||
)
|
||||
|
||||
|
||||
@classmethod
|
||||
def all(cls) -> list['IdolCard']:
|
||||
"""获取所有偶像卡"""
|
||||
|
@ -46,6 +53,8 @@ class IdolCard:
|
|||
SELECT
|
||||
IC.id AS cardId,
|
||||
ICS.id AS skinId,
|
||||
IC.examEffectType AS examEffectType,
|
||||
IC.showExamEffectType AS showExamEffectType,
|
||||
Char.lastName || ' ' || Char.firstName || ' ' || IC.name AS name,
|
||||
NOT (IC.originalIdolCardSkinId = ICS.id) AS isAnotherVer,
|
||||
ICS.name AS anotherVerName
|
||||
|
@ -58,13 +67,17 @@ class IdolCard:
|
|||
results.append(cls(
|
||||
id=row["cardId"],
|
||||
skin_id=row["skinId"],
|
||||
exam_effect_type=ExamEffectType(row["examEffectType"]),
|
||||
show_exam_effect_type=ShowExamEffectType(row["showExamEffectType"]),
|
||||
is_another=bool(row["isAnotherVer"]),
|
||||
another_name=row["anotherVerName"],
|
||||
name=row["name"]
|
||||
))
|
||||
return results
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from pprint import pprint as print
|
||||
|
||||
print(IdolCard.from_skin_id('i_card-skin-fktn-3-006'))
|
||||
print(IdolCard.all())
|
||||
|
|
|
@ -29,25 +29,12 @@ class PlanType(Enum):
|
|||
ANOMALY = "ProducePlanType_Plan3"
|
||||
"""非凡"""
|
||||
|
||||
|
||||
class Archetype(Enum):
|
||||
"""偶像流派"""
|
||||
UNIDENTIFIED = "unidentified"
|
||||
"""未识别"""
|
||||
GOOD_CONDITION = "好調"
|
||||
"""好调"""
|
||||
FOCUS = "集中"
|
||||
"""集中"""
|
||||
GOOD_IMPRESSION = "好印象"
|
||||
"""好印象"""
|
||||
MOTIVATION = "やる気"
|
||||
"""干劲"""
|
||||
CONFIDENCE = "強気"
|
||||
"""强气"""
|
||||
CONSERVATION = "温存"
|
||||
"""温存"""
|
||||
FULL_POWER = "全力"
|
||||
"""全力"""
|
||||
class PlayMovePositionType(Enum):
|
||||
"""卡牌打出后 除外 还是 进入弃牌堆"""
|
||||
LOST = "ProduceCardMovePositionType_Lost"
|
||||
"""除外,洗牌后无法抽到"""
|
||||
GRAVE = "ProduceCardMovePositionType_Grave"
|
||||
"""进入弃牌堆,洗牌后仍能抽到"""
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -64,6 +51,8 @@ class SkillCard:
|
|||
"""卡牌名称。"""
|
||||
once: bool
|
||||
"""此卡牌在考试或课程中是否只会出现一次。"""
|
||||
play_move_position_type: PlayMovePositionType
|
||||
"""此卡牌在考试或课程中使用后除外还是进入弃牌堆。"""
|
||||
origin_idol_card: str | None
|
||||
"""此卡牌所属的偶像卡。"""
|
||||
origin_support_card: str | None
|
||||
|
@ -80,12 +69,12 @@ class SkillCard:
|
|||
def is_from_idol_card(self) -> bool:
|
||||
"""此卡牌是否来自偶像卡。"""
|
||||
return self.origin_idol_card is not None
|
||||
|
||||
|
||||
@property
|
||||
def is_from_support_card(self) -> bool:
|
||||
"""此卡牌是否来自支援卡。"""
|
||||
return self.origin_support_card is not None
|
||||
|
||||
|
||||
@property
|
||||
def asset_ids(self) -> list[str]:
|
||||
"""
|
||||
|
@ -94,7 +83,7 @@ class SkillCard:
|
|||
if not self.is_character_asset:
|
||||
return [self.asset_id]
|
||||
return [f'{self.asset_id}-{ii.value}' for ii in CharacterId]
|
||||
|
||||
|
||||
@classmethod
|
||||
def all(cls) -> list['SkillCard']:
|
||||
"""获取所有技能卡"""
|
||||
|
@ -106,6 +95,7 @@ class SkillCard:
|
|||
category AS cardType,
|
||||
name,
|
||||
noDeckDuplication AS once,
|
||||
playMovePositionType,
|
||||
originIdolCardId AS idolCardId,
|
||||
originSupportCardId AS supportCardId,
|
||||
isCharacterAsset
|
||||
|
@ -120,12 +110,13 @@ class SkillCard:
|
|||
card_type=CardType(row["cardType"]),
|
||||
name=row["name"],
|
||||
once=bool(row["once"]),
|
||||
play_move_position_type=PlayMovePositionType(row["playMovePositionType"]),
|
||||
origin_idol_card=row["idolCardId"],
|
||||
origin_support_card=row["supportCardId"],
|
||||
is_character_asset=bool(row["isCharacterAsset"])
|
||||
))
|
||||
return results
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_asset_id(cls, asset_id: str) -> 'SkillCard | None':
|
||||
"""根据资源 ID 查询 SkillCard。"""
|
||||
|
@ -141,6 +132,7 @@ class SkillCard:
|
|||
category AS cardType,
|
||||
name,
|
||||
noDeckDuplication AS once,
|
||||
playMovePositionType,
|
||||
originIdolCardId AS idolCardId,
|
||||
originSupportCardId AS supportCardId,
|
||||
isCharacterAsset
|
||||
|
@ -156,6 +148,7 @@ class SkillCard:
|
|||
card_type=CardType(row["cardType"]),
|
||||
name=row["name"],
|
||||
once=bool(row["once"]),
|
||||
play_move_position_type=PlayMovePositionType(row["playMovePositionType"]),
|
||||
origin_idol_card=row["idolCardId"],
|
||||
origin_support_card=row["supportCardId"],
|
||||
is_character_asset=bool(row["isCharacterAsset"])
|
||||
|
|
|
@ -17,9 +17,10 @@ logger = logging.getLogger(__name__)
|
|||
_db: ImageDatabase | None = None
|
||||
|
||||
# OpenCV HSV 颜色范围
|
||||
RED_DOT = ((157, 205, 255), (179, 255, 255)) # 红点
|
||||
ORANGE_SELECT_BORDER = ((9, 50, 106), (19, 255, 255)) # 当前选中的偶像的橙色边框
|
||||
WHITE_BACKGROUND = ((0, 0, 234), (179, 40, 255)) # 白色背景
|
||||
RED_DOT = ((157, 205, 255), (179, 255, 255)) # 红点
|
||||
ORANGE_SELECT_BORDER = ((9, 50, 106), (19, 255, 255)) # 当前选中的偶像的橙色边框
|
||||
WHITE_BACKGROUND = ((0, 0, 234), (179, 40, 255)) # 白色背景
|
||||
|
||||
|
||||
def extract_idols(img: MatLike) -> list[RectTuple]:
|
||||
"""
|
||||
|
@ -48,6 +49,7 @@ def extract_idols(img: MatLike) -> list[RectTuple]:
|
|||
rects.append((x, y, w, h))
|
||||
return rects
|
||||
|
||||
|
||||
def display_rects(img: MatLike, rects: list[RectTuple]) -> MatLike:
|
||||
"""Draw rectangles on the image and display them."""
|
||||
result = img.copy()
|
||||
|
@ -56,10 +58,11 @@ def display_rects(img: MatLike, rects: list[RectTuple]) -> MatLike:
|
|||
# Draw rectangle with green color and 2px thickness
|
||||
cv2.rectangle(result, (x, y), (x + w, y + h), (0, 255, 0), 2)
|
||||
# Optionally add text label
|
||||
cv2.putText(result, f"{w}x{h}", (x, y - 5),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
|
||||
cv2.putText(result, f"{w}x{h}", (x, y - 5),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
|
||||
return result
|
||||
|
||||
|
||||
def draw_idol_preview(img: MatLike, rects: list[RectTuple], db: ImageDatabase, idol_path: str) -> MatLike:
|
||||
"""
|
||||
在预览图上绘制所有匹配到的偶像。
|
||||
|
@ -72,31 +75,32 @@ def draw_idol_preview(img: MatLike, rects: list[RectTuple], db: ImageDatabase, i
|
|||
"""
|
||||
# 创建一个与原图大小相同的白色背景图片
|
||||
preview_img = np.ones_like(img) * 255
|
||||
|
||||
|
||||
# 在预览图上绘制所有匹配到的偶像
|
||||
for rect in rects:
|
||||
x, y, w, h = rect
|
||||
idol_img = img[y:y+h, x:x+w]
|
||||
idol_img = img[y:y + h, x:x + w]
|
||||
match = db.match(idol_img, 20)
|
||||
if not match:
|
||||
continue
|
||||
file = os.path.join(idol_path, match.key)
|
||||
found_img = cv2_imread(file)
|
||||
|
||||
|
||||
# 将找到的偶像图片缩放至与检测到的矩形大小相同
|
||||
resized_found_img = cv2.resize(found_img, (w, h))
|
||||
|
||||
|
||||
# 将缩放后的图片放到预览图上对应位置
|
||||
preview_img[y:y+h, x:x+w] = resized_found_img
|
||||
|
||||
preview_img[y:y + h, x:x + w] = resized_found_img
|
||||
|
||||
# 在预览图上绘制矩形框
|
||||
cv2.rectangle(preview_img, (x, y), (x + w, y + h), (0, 255, 0), 2)
|
||||
|
||||
|
||||
# 可选:添加偶像ID标签
|
||||
cv2.putText(preview_img, match.key.split('.')[0], (x, y - 5),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
|
||||
cv2.putText(preview_img, match.key.split('.')[0], (x, y - 5),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
|
||||
return preview_img
|
||||
|
||||
|
||||
def idols_db() -> ImageDatabase:
|
||||
global _db
|
||||
if _db is None:
|
||||
|
@ -106,6 +110,7 @@ def idols_db() -> ImageDatabase:
|
|||
_db = ImageDatabase(FileDataSource(str(path)), db_path, HistDescriptor(8), name='idols')
|
||||
return _db
|
||||
|
||||
|
||||
@action('定位偶像', screenshot_mode='manual-inherit')
|
||||
def locate_idol(skin_id: str):
|
||||
device.screenshot()
|
||||
|
@ -124,7 +129,7 @@ def locate_idol(skin_id: str):
|
|||
img = device.screenshot()
|
||||
# 只保留 BoxIdolOverviewIdols 区域
|
||||
mask = np.zeros_like(img)
|
||||
mask[y:y+h, x:x+w] = img[y:y+h, x:x+w]
|
||||
mask[y:y + h, x:x + w] = img[y:y + h, x:x + w]
|
||||
img = mask
|
||||
# 检测 & 查询
|
||||
rects = extract_idols(img)
|
||||
|
@ -133,7 +138,7 @@ def locate_idol(skin_id: str):
|
|||
# cv2.waitKey(0)
|
||||
for rect in rects:
|
||||
rx, ry, rw, rh = rect
|
||||
idol_img = img[ry:ry+rh, rx:rx+rw]
|
||||
idol_img = img[ry:ry + rh, rx:rx + rw]
|
||||
match = db.match(idol_img, 20)
|
||||
logger.debug('Result rect: %s, match: %s', repr(rect), repr(match))
|
||||
# Key 格式:{skin_id}_{index}
|
||||
|
@ -146,7 +151,24 @@ def locate_idol(skin_id: str):
|
|||
|
||||
# # 使用新函数绘制预览图
|
||||
# preview_img = draw_idol_preview(img, rects, db, path)
|
||||
|
||||
|
||||
|
||||
@action('重新培育页面识别偶像卡', screenshot_mode='manual-inherit')
|
||||
def find_idol_skin_id_on_resume_produce(img: MatLike) -> str | None:
|
||||
"""
|
||||
在 继续培育 界面查找偶像皮肤id
|
||||
默认 数据库中的key 为 偶像皮肤id_\d.png
|
||||
:return:
|
||||
"""
|
||||
db = idols_db()
|
||||
rx, ry, rw, rh = R.Produce.BoxResumeDialogIdolCard.xywh
|
||||
idol_img = img[ry:ry + rh, rx:rx + rw]
|
||||
match = db.match(idol_img, 20)
|
||||
if match:
|
||||
return match.key.rsplit("_", 1)[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def test():
|
||||
from kotonebot.backend.context import init_context, manual_context
|
||||
|
@ -154,7 +176,8 @@ def test():
|
|||
manual_context().begin()
|
||||
locate_idol('i_card-skin-fktn-3-006')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from kotonebot.util import cv2_imread
|
||||
|
||||
test()
|
||||
test()
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
from kotonebot.kaa.skill_card.enum_constant import CardName, PlanType, CardType
|
||||
|
||||
|
||||
@dataclass
|
||||
class CardTemplate:
|
||||
"""
|
||||
卡牌模板
|
||||
理论上应该保存到数据库上,相关属性就不需要识别
|
||||
"""
|
||||
# 卡牌名称
|
||||
name: CardName
|
||||
# 卡牌职业分类,感性、理性等
|
||||
plan_type: PlanType
|
||||
# 卡牌作用类型,a卡,m卡等
|
||||
card_type: CardType
|
||||
# 一回一次
|
||||
once: bool = False
|
||||
|
||||
# 以下信息可能在以后会用到,这里先不写了
|
||||
# good_condition: bool = False # 好调
|
||||
# focus: bool = False # 集中
|
||||
#
|
||||
# good_impression: bool = False # 好印象
|
||||
# motivation: bool = False # 干劲
|
||||
#
|
||||
# confidence: bool = False # 强气
|
||||
# conservation: bool = False # 温存
|
||||
# full_power: bool = False # 全力
|
||||
#
|
||||
# energy: bool = False # 护盾
|
||||
|
||||
|
||||
# TODO 从数据库中读取对应的卡牌信息,读取完成后更新 card_template_dict
|
||||
card_collection = [
|
||||
# unidentified 当识别过程无法找到对应的卡时,使用这个而不是眠气卡
|
||||
CardTemplate(CardName.unidentified, PlanType.common, CardType.trouble, once=False),
|
||||
|
||||
# common
|
||||
CardTemplate(CardName.c_n_0, PlanType.common, CardType.trouble, once=True),
|
||||
CardTemplate(CardName.c_n_1, PlanType.common, CardType.active, once=False),
|
||||
CardTemplate(CardName.c_n_2, PlanType.common, CardType.active, once=False),
|
||||
CardTemplate(CardName.c_n_3, PlanType.common, CardType.mental, once=True),
|
||||
|
||||
CardTemplate(CardName.c_r_1, PlanType.common, CardType.mental, once=False),
|
||||
CardTemplate(CardName.c_r_2, PlanType.common, CardType.mental, once=True),
|
||||
|
||||
CardTemplate(CardName.c_sr_1, PlanType.common, CardType.active, once=False),
|
||||
CardTemplate(CardName.c_sr_2, PlanType.common, CardType.mental, once=True),
|
||||
CardTemplate(CardName.c_sr_3, PlanType.common, CardType.mental, once=True),
|
||||
|
||||
CardTemplate(CardName.c_ssr_1, PlanType.common, CardType.mental, once=True),
|
||||
CardTemplate(CardName.c_ssr_2, PlanType.common, CardType.mental, once=True),
|
||||
CardTemplate(CardName.c_ssr_3, PlanType.common, CardType.mental, once=True),
|
||||
CardTemplate(CardName.c_ssr_4, PlanType.common, CardType.mental, once=True),
|
||||
|
||||
# sense
|
||||
CardTemplate(CardName.s_n_1, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_n_2, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_n_3, PlanType.sense, CardType.mental, once=False),
|
||||
CardTemplate(CardName.s_n_4, PlanType.sense, CardType.mental, once=False),
|
||||
|
||||
CardTemplate(CardName.s_r_1, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_r_2, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_r_3, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_r_4, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_r_5, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_r_6, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_r_7, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_r_8, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_r_9, PlanType.sense, CardType.mental, once=False),
|
||||
CardTemplate(CardName.s_r_10, PlanType.sense, CardType.mental, once=False),
|
||||
CardTemplate(CardName.s_r_11, PlanType.sense, CardType.mental, once=False),
|
||||
CardTemplate(CardName.s_r_12, PlanType.sense, CardType.mental, once=True),
|
||||
|
||||
CardTemplate(CardName.s_sr_1, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_sr_2, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_sr_3, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_sr_4, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_sr_5, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_sr_6, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_sr_7, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_sr_8, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_sr_9, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_sr_10, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_sr_11, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_sr_12, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_sr_13, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_sr_14, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_sr_15, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_sr_16, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_sr_17, PlanType.sense, CardType.mental, once=False),
|
||||
CardTemplate(CardName.s_sr_18, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_sr_19, PlanType.sense, CardType.mental, once=False),
|
||||
|
||||
CardTemplate(CardName.s_ssr_1, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_ssr_2, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_ssr_3, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_ssr_4, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_ssr_5, PlanType.sense, CardType.active, once=True),
|
||||
CardTemplate(CardName.s_ssr_6, PlanType.sense, CardType.active, once=False),
|
||||
CardTemplate(CardName.s_ssr_7, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_ssr_8, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_ssr_9, PlanType.sense, CardType.mental, once=True),
|
||||
CardTemplate(CardName.s_ssr_10, PlanType.sense, CardType.mental, once=True),
|
||||
|
||||
# logic
|
||||
CardTemplate(CardName.l_n_1, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_n_2, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_n_3, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_n_4, PlanType.logic, CardType.mental, once=False),
|
||||
|
||||
CardTemplate(CardName.l_r_1, PlanType.logic, CardType.active, once=False),
|
||||
CardTemplate(CardName.l_r_2, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_r_3, PlanType.logic, CardType.active, once=False),
|
||||
CardTemplate(CardName.l_r_4, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_r_5, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_r_6, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_r_7, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_r_8, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_r_9, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_r_10, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_r_11, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_r_12, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_r_13, PlanType.logic, CardType.mental, once=True),
|
||||
|
||||
CardTemplate(CardName.l_sr_1, PlanType.logic, CardType.active, once=False),
|
||||
CardTemplate(CardName.l_sr_2, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_sr_3, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_sr_4, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_sr_5, PlanType.logic, CardType.active, once=False),
|
||||
CardTemplate(CardName.l_sr_6, PlanType.logic, CardType.active, once=False),
|
||||
CardTemplate(CardName.l_sr_7, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_sr_8, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_sr_9, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_sr_10, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_sr_11, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_sr_12, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_sr_13, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_sr_14, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_sr_15, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_sr_16, PlanType.logic, CardType.mental, once=False),
|
||||
CardTemplate(CardName.l_sr_17, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_sr_18, PlanType.logic, CardType.mental, once=False),
|
||||
|
||||
CardTemplate(CardName.l_ssr_1, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_ssr_2, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_ssr_3, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_ssr_4, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_ssr_5, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_ssr_6, PlanType.logic, CardType.active, once=True),
|
||||
CardTemplate(CardName.l_ssr_7, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_ssr_8, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_ssr_9, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_ssr_10, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_ssr_11, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_ssr_12, PlanType.logic, CardType.mental, once=True),
|
||||
CardTemplate(CardName.l_ssr_13, PlanType.logic, CardType.mental, once=True),
|
||||
|
||||
# anomaly
|
||||
CardTemplate(CardName.a_n_1, PlanType.anomaly, CardType.active, once=False),
|
||||
CardTemplate(CardName.a_n_2, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_n_3, PlanType.anomaly, CardType.active, once=False),
|
||||
CardTemplate(CardName.a_n_4, PlanType.anomaly, CardType.mental, once=False),
|
||||
CardTemplate(CardName.a_n_5, PlanType.anomaly, CardType.mental, once=False),
|
||||
|
||||
CardTemplate(CardName.a_r_1, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_r_2, PlanType.anomaly, CardType.active, once=False),
|
||||
CardTemplate(CardName.a_r_3, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_r_4, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_r_5, PlanType.anomaly, CardType.active, once=False),
|
||||
CardTemplate(CardName.a_r_6, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_r_7, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_r_8, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_r_9, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_r_10, PlanType.anomaly, CardType.mental, once=True),
|
||||
|
||||
CardTemplate(CardName.a_sr_1, PlanType.anomaly, CardType.active, once=False),
|
||||
CardTemplate(CardName.a_sr_2, PlanType.anomaly, CardType.active, once=False),
|
||||
CardTemplate(CardName.a_sr_3, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_sr_4, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_sr_5, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_sr_6, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_sr_7, PlanType.anomaly, CardType.active, once=False),
|
||||
CardTemplate(CardName.a_sr_8, PlanType.anomaly, CardType.active, once=False),
|
||||
CardTemplate(CardName.a_sr_9, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_sr_10, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_sr_11, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_sr_12, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_sr_13, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_sr_14, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_sr_15, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_sr_16, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_sr_17, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_sr_18, PlanType.anomaly, CardType.mental, once=False),
|
||||
CardTemplate(CardName.a_sr_19, PlanType.anomaly, CardType.mental, once=True),
|
||||
|
||||
CardTemplate(CardName.a_ssr_1, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_ssr_2, PlanType.anomaly, CardType.active, once=False),
|
||||
CardTemplate(CardName.a_ssr_3, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_ssr_4, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_ssr_5, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_ssr_6, PlanType.anomaly, CardType.active, once=True),
|
||||
CardTemplate(CardName.a_ssr_7, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_ssr_8, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_ssr_9, PlanType.anomaly, CardType.mental, once=True),
|
||||
CardTemplate(CardName.a_ssr_10, PlanType.anomaly, CardType.mental, once=True),
|
||||
]
|
||||
|
||||
card_template_dict = {card.name: card for card in card_collection}
|
|
@ -1,25 +1,23 @@
|
|||
|
||||
from kotonebot.kaa.common import ConfigBaseModel
|
||||
|
||||
from kotonebot.kaa.skill_card.enum_constant import Archetype, CardName
|
||||
from kotonebot.kaa.db.constants import ExamEffectType
|
||||
|
||||
|
||||
# TODO: 这个文件应该写在 kotonebot.kaa.common 的 BaseConfig文件中
|
||||
# TODO:用户可以设置自己的流派卡组,把卡填入下面的设置中,未填入的卡默认不选。
|
||||
# 单流派卡组设置
|
||||
class SingleDeckConfig(ConfigBaseModel):
|
||||
# 角色流派
|
||||
archetype: Archetype
|
||||
# 角色流派。目前只考虑ExamEffectType,温存目前分全力温存和强气温存,所以没有温存设置。
|
||||
archetype: ExamEffectType
|
||||
# 当可选卡不在设置中,是否优先选择其中的一次性卡?false会直接进行刷新
|
||||
select_once_card_before_refresh: bool = True
|
||||
# 核心卡,在商店页面会购买
|
||||
core_cards: list[CardName] = []
|
||||
core_cards: list[str] = []
|
||||
# 高优先度卡
|
||||
high_priority_cards: list[CardName] = []
|
||||
high_priority_cards: list[str] = []
|
||||
# 中优先度卡
|
||||
medium_priority_cards: list[CardName] = []
|
||||
medium_priority_cards: list[str] = []
|
||||
# 低优先度卡
|
||||
low_priority_cards: list[CardName] = []
|
||||
low_priority_cards: list[str] = []
|
||||
|
||||
|
||||
# 所有卡组设置
|
||||
|
|
|
@ -1,40 +1,4 @@
|
|||
from enum import Enum, IntEnum
|
||||
|
||||
|
||||
# 卡牌作用类型
|
||||
class CardType(Enum):
|
||||
mental = "MentalSkillCard" # M卡
|
||||
active = "ActiveSkillCard" # A卡
|
||||
trouble = "TroubleSkillCard" # T卡
|
||||
unidentified = "Unidentified" # 未识别
|
||||
|
||||
|
||||
# 卡牌职业分类
|
||||
class PlanType(Enum):
|
||||
common = "Common" # 通用
|
||||
sense = "Sense" # 感性
|
||||
logic = "Logic" # 理性
|
||||
anomaly = "Anomaly" # 非凡
|
||||
|
||||
|
||||
# 偶像流派
|
||||
class Archetype(Enum):
|
||||
# 未识别
|
||||
unidentified = "unidentified"
|
||||
# 好调
|
||||
good_condition = "好調"
|
||||
# 集中
|
||||
focus = "集中"
|
||||
# 好印象
|
||||
good_impression = "好印象"
|
||||
# 干劲
|
||||
motivation = "やる気"
|
||||
# 强气
|
||||
confidence = "強気"
|
||||
# 温存
|
||||
conservation = "温存"
|
||||
# 全力
|
||||
full_power = "全力"
|
||||
from enum import IntEnum
|
||||
|
||||
|
||||
# 卡牌抉择优先度,越大优先度越低
|
||||
|
@ -44,236 +8,3 @@ class CardPriority(IntEnum):
|
|||
medium = 2
|
||||
low = 3
|
||||
other = 99
|
||||
|
||||
|
||||
# 卡牌名称(标识)
|
||||
class CardName(Enum):
|
||||
unidentified = "Unidentified"
|
||||
|
||||
# common:N 卡
|
||||
c_n_0 = "眠気"
|
||||
c_n_1 = "アピールの基本"
|
||||
c_n_2 = "ポーズの基本"
|
||||
|
||||
c_n_3 = "表現の基本"
|
||||
|
||||
# common:R 卡
|
||||
c_r_1 = "気合十分!"
|
||||
c_r_2 = "ファーストステップ"
|
||||
|
||||
# common:SR 卡
|
||||
c_sr_1 = "前途洋々"
|
||||
|
||||
c_sr_2 = "アイドル宣言"
|
||||
c_sr_3 = "ハイテンション"
|
||||
|
||||
# common:SSR 卡
|
||||
c_ssr_1 = "テレビ出演"
|
||||
c_ssr_2 = "叶えたい夢"
|
||||
c_ssr_3 = "アイドル魂"
|
||||
c_ssr_4 = "仕切り直し"
|
||||
|
||||
# sense:N 卡
|
||||
s_n_1 = "挑戦"
|
||||
s_n_2 = "試行錯誤"
|
||||
|
||||
s_n_3 = "振る舞いの基本"
|
||||
s_n_4 = "表情の基本"
|
||||
|
||||
# sense:R 卡
|
||||
s_r_1 = "軽い足取り"
|
||||
s_r_2 = "愛嬌"
|
||||
s_r_3 = "準備運動"
|
||||
s_r_4 = "ファンサ"
|
||||
s_r_5 = "勢い任せ"
|
||||
s_r_6 = "ハイタッチ"
|
||||
s_r_7 = "トークタイム"
|
||||
s_r_8 = "エキサイト"
|
||||
|
||||
s_r_9 = "バランス感覚"
|
||||
s_r_10 = "楽観的"
|
||||
s_r_11 = "深呼吸"
|
||||
s_r_12 = "ひと呼吸"
|
||||
|
||||
# sense:SR 卡
|
||||
s_sr_1 = "決めポーズ"
|
||||
s_sr_2 = "アドリブ"
|
||||
s_sr_3 = "情熱ターン"
|
||||
s_sr_4 = "飛躍"
|
||||
s_sr_5 = "祝福"
|
||||
s_sr_6 = "スタートダッシュ"
|
||||
s_sr_7 = "スタンドプレー"
|
||||
s_sr_8 = "シュプレヒコール"
|
||||
s_sr_9 = "立ち位置チェック"
|
||||
|
||||
s_sr_10 = "眼力"
|
||||
s_sr_11 = "大声援"
|
||||
s_sr_12 = "演出計画"
|
||||
s_sr_13 = "願いの力"
|
||||
s_sr_14 = "静かな意志"
|
||||
s_sr_15 = "始まりの合図"
|
||||
s_sr_16 = "意地"
|
||||
s_sr_17 = "存在感"
|
||||
s_sr_18 = "成功への道筋"
|
||||
s_sr_19 = "スポットライト"
|
||||
|
||||
# sense:SSR 卡
|
||||
s_ssr_1 = "コール&レスポンス"
|
||||
s_ssr_2 = "バズワード"
|
||||
s_ssr_3 = "成就"
|
||||
s_ssr_4 = "魅惑のパフォーマンス"
|
||||
s_ssr_5 = "至高のエンタメ"
|
||||
s_ssr_6 = "覚醒"
|
||||
|
||||
s_ssr_7 = "国民的アイドル"
|
||||
s_ssr_8 = "魅惑の視線"
|
||||
s_ssr_9 = "鳴り止まない拍手"
|
||||
s_ssr_10 = "天真爛漫"
|
||||
|
||||
# logic:N 卡
|
||||
l_n_1 = "可愛い仕草"
|
||||
l_n_2 = "気分転換"
|
||||
|
||||
l_n_3 = "目線の基本"
|
||||
l_n_4 = "意識の基本"
|
||||
|
||||
# logic:R 卡
|
||||
l_r_1 = "今日もおはよう"
|
||||
l_r_2 = "ゆるふわおしゃべり"
|
||||
l_r_3 = "もう少しだけ"
|
||||
l_r_4 = "手拍子"
|
||||
l_r_5 = "元気な挨拶"
|
||||
l_r_6 = "デイドリーミング"
|
||||
|
||||
l_r_7 = "リスタート"
|
||||
l_r_8 = "えいえいおー"
|
||||
l_r_9 = "リズミカル"
|
||||
l_r_10 = "思い出し笑い"
|
||||
l_r_11 = "パステル気分"
|
||||
l_r_12 = "励まし"
|
||||
l_r_13 = "幸せのおまじない"
|
||||
|
||||
# logic:SR 卡
|
||||
l_sr_1 = "ラブリーウインク"
|
||||
l_sr_2 = "ありがとうの言葉"
|
||||
l_sr_3 = "ハートの合図"
|
||||
l_sr_4 = "キラメキ"
|
||||
l_sr_5 = "みんな大好き"
|
||||
l_sr_6 = "きらきら紙吹雪"
|
||||
|
||||
l_sr_7 = "あふれる思い出"
|
||||
l_sr_8 = "ふれあい"
|
||||
l_sr_9 = "幸せな時間"
|
||||
l_sr_10 = "ファンシーチャーム"
|
||||
l_sr_11 = "ワクワクが止まらない"
|
||||
l_sr_12 = "本番前夜"
|
||||
l_sr_13 = "ひなたぼっこ"
|
||||
l_sr_14 = "イメトレ"
|
||||
l_sr_15 = "やる気は満点"
|
||||
l_sr_16 = "ゆめみごこち"
|
||||
l_sr_17 = "止められない想い"
|
||||
l_sr_18 = "オトメゴコロ"
|
||||
|
||||
# logic:SSR 卡
|
||||
l_ssr_1 = "200%スマイル"
|
||||
l_ssr_2 = "開花"
|
||||
l_ssr_3 = "届いて!"
|
||||
l_ssr_4 = "輝くキミへ"
|
||||
l_ssr_5 = "あのときの約束"
|
||||
l_ssr_6 = "キセキの魔法"
|
||||
|
||||
l_ssr_7 = "私がスター"
|
||||
l_ssr_8 = "星屑センセーション"
|
||||
l_ssr_9 = "ノートの端の決意"
|
||||
l_ssr_10 = "手書きのメッセージ"
|
||||
l_ssr_11 = "トキメキ"
|
||||
l_ssr_12 = "虹色ドリーマー"
|
||||
l_ssr_13 = "夢色リップ"
|
||||
|
||||
# anomaly:N 卡
|
||||
a_n_1 = "挨拶の基本"
|
||||
a_n_2 = "はげしく"
|
||||
a_n_3 = "スパート"
|
||||
a_n_4 = "メントレの基本"
|
||||
a_n_5 = "イメージの基本"
|
||||
# anomaly:R 卡
|
||||
a_r_1 = "ジャストアピール"
|
||||
a_r_2 = "スターライト"
|
||||
a_r_3 = "一歩"
|
||||
a_r_4 = "ラッキー♪"
|
||||
a_r_5 = "積み重ね"
|
||||
a_r_6 = "精一杯"
|
||||
|
||||
a_r_7 = "ハッピー♪"
|
||||
a_r_8 = "嬉しい誤算"
|
||||
a_r_9 = "涙の思い出"
|
||||
a_r_10 = "セッティング"
|
||||
|
||||
# anomaly:SR 卡
|
||||
a_sr_1 = "せーのっ!"
|
||||
a_sr_2 = "アッチェレランド"
|
||||
a_sr_3 = "はじけるパッション"
|
||||
a_sr_4 = "汗と成長"
|
||||
a_sr_5 = "第一印象"
|
||||
a_sr_6 = "オープニングアクト"
|
||||
a_sr_7 = "始まりの笑顔"
|
||||
a_sr_8 = "トレンドリーダー"
|
||||
a_sr_9 = "理想のテンポ"
|
||||
a_sr_10 = "トレーニングの成果"
|
||||
|
||||
a_sr_11 = "潜在能力"
|
||||
a_sr_12 = "カウントダウン"
|
||||
a_sr_13 = "モチベ"
|
||||
a_sr_14 = "プライド"
|
||||
a_sr_15 = "盛り上げ上手"
|
||||
a_sr_16 = "インフルエンサー"
|
||||
a_sr_17 = "忍耐力"
|
||||
a_sr_18 = "切磋琢磨"
|
||||
a_sr_19 = "タフネス"
|
||||
# anomaly:SSR 卡
|
||||
a_ssr_1 = "翔び立て!"
|
||||
a_ssr_2 = "総合芸術"
|
||||
a_ssr_3 = "心・技・体"
|
||||
a_ssr_4 = "輝け!"
|
||||
a_ssr_5 = "クライマックス"
|
||||
a_ssr_6 = "全身全霊"
|
||||
|
||||
a_ssr_7 = "アイドルになります"
|
||||
a_ssr_8 = "一心不乱"
|
||||
a_ssr_9 = "頂点へ"
|
||||
a_ssr_10 = "覚悟"
|
||||
|
||||
|
||||
archetype_dict = {x.value: x for x in Archetype}
|
||||
card_name_dict = {x.value: x for x in CardName}
|
||||
|
||||
# 一些因为ocr读取有问题而暂时添加的匹配
|
||||
card_name_dict.update(
|
||||
{
|
||||
# 卡名读取有误
|
||||
"天真燗漫": CardName.s_ssr_10,
|
||||
"元気な挨": CardName.l_r_5,
|
||||
"えいえいお一": CardName.l_r_8,
|
||||
"フクワクが止まらない": CardName.l_sr_11,
|
||||
"ラッキーの": CardName.a_r_4, # 名字后面的音符符号
|
||||
"ハッピー・": CardName.a_r_7, # 名字后面的音符符号
|
||||
"切礎琢磨": CardName.a_sr_18,
|
||||
|
||||
# 强化卡名读取有误
|
||||
"デイドリーミングャ": CardName.l_r_6,
|
||||
"ラッキー・": CardName.a_r_4, # 名字后面的音符符号
|
||||
"切瑳琢磨": CardName.a_sr_18,
|
||||
"バズワードャ": CardName.s_ssr_2, # 名字后面的音符符号
|
||||
"輝くキミヘ": CardName.l_ssr_4, # 片假名
|
||||
"天真欄漫": CardName.s_ssr_10,
|
||||
"頂点ヘ": CardName.a_ssr_9, # 片假名
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def get_archetype(s: str):
|
||||
return archetype_dict.get(s, Archetype.unidentified)
|
||||
|
||||
|
||||
def get_card_name(s: str):
|
||||
return card_name_dict.get(s, CardName.unidentified)
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from dataclasses import dataclass
|
||||
from logging import getLogger
|
||||
|
||||
from kotonebot.kaa.db.constants import ExamEffectType
|
||||
from kotonebot.kaa.skill_card.card_deck_config import DeckConfig, SingleDeckConfig
|
||||
from kotonebot.kaa.skill_card.enum_constant import Archetype, CardName, CardPriority
|
||||
from kotonebot.kaa.skill_card.enum_constant import CardPriority
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
@ -12,17 +13,17 @@ class GlobalIdolSetting:
|
|||
def __init__(self):
|
||||
# 是否需要刷新全局配置,理论上新开培育、重新培育都需要更新
|
||||
self.need_update: bool = True
|
||||
self.idol_archetype: Archetype = Archetype.good_impression
|
||||
self.idol_archetype: ExamEffectType = ExamEffectType.good_impression
|
||||
self.card_deck: dict = {}
|
||||
self.select_once_card_before_refresh = True
|
||||
|
||||
def new_play(self):
|
||||
self.need_update = True
|
||||
self.select_once_card_before_refresh = True
|
||||
self.card_deck = {}
|
||||
self.card_deck.clear()
|
||||
logger.info("New game, wait for update")
|
||||
|
||||
def update_deck(self, idol_archetype: Archetype, config: DeckConfig):
|
||||
def update_deck(self, idol_archetype: ExamEffectType, config: DeckConfig):
|
||||
"""
|
||||
根据流派选择初始化对应的卡组配置,如果自定义有就使用自定义,没有就使用预设
|
||||
:param idol_archetype: 偶像流派
|
||||
|
@ -54,10 +55,10 @@ class GlobalIdolSetting:
|
|||
self.card_deck.update({card: CardPriority.core for card in card_deck_config.core_cards})
|
||||
self.select_once_card_before_refresh = card_deck_config.select_once_card_before_refresh
|
||||
|
||||
def get_card_priority(self, card_name: CardName) -> CardPriority:
|
||||
def get_card_priority(self, card_id: str) -> CardPriority:
|
||||
"""
|
||||
根据卡名来查看此卡的选卡优先级
|
||||
:param card_name: 卡名
|
||||
:param card_id: 卡id
|
||||
:return: 优先级,越小越高,不在配置卡组则返回other(99)
|
||||
"""
|
||||
return self.card_deck.get(card_name, CardPriority.other)
|
||||
return self.card_deck.get(card_id, CardPriority.other)
|
||||
|
|
|
@ -1,90 +1,41 @@
|
|||
from logging import getLogger
|
||||
from dataclasses import dataclass
|
||||
|
||||
from kotonebot.kaa.db.skill_card import SkillCard
|
||||
from kotonebot.kaa.tasks import R
|
||||
from kotonebot import Interval, device, Countdown, ocr, action, image
|
||||
from kotonebot.backend.core import HintBox
|
||||
from kotonebot.kaa.skill_card.enum_constant import CardName, get_card_name
|
||||
from kotonebot.kaa.skill_card.card_data import CardTemplate, card_template_dict
|
||||
from kotonebot.kaa.db.skill_card import PlayMovePositionType
|
||||
from kotonebot.kaa.game_ui.skill_card_select import SkillCardElement
|
||||
from kotonebot.kaa.skill_card.enum_constant import CardPriority
|
||||
from kotonebot.kaa.skill_card_action.global_idol_setting_action import idol_setting
|
||||
from kotonebot.primitives import Rect
|
||||
|
||||
# 技能卡选择页面,点击技能卡后,技能卡的名字的范围
|
||||
SelectCardNameArea = HintBox(x1=70, y1=478, x2=570, y2=538, source_resolution=(720, 1280))
|
||||
# 商店页面,选择商品后,商品名的范围
|
||||
ShopItemNameArea = HintBox(x1=195, y1=170, x2=625, y2=215, source_resolution=(720, 1280))
|
||||
# 强化或删除技能卡时,技能卡的名字的范围
|
||||
EnhancementCardNameArea = HintBox(x1=180, y1=100, x2=630, y2=145, source_resolution=(720, 1280))
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ActualCard:
|
||||
rect: Rect
|
||||
name: str
|
||||
skill_card: CardTemplate
|
||||
priority: int
|
||||
skill_card_element: SkillCardElement
|
||||
priority: CardPriority
|
||||
|
||||
@staticmethod
|
||||
def create_by(rect: Rect, card: SkillCard | None) -> 'ActualCard':
|
||||
def create_by(card: SkillCardElement) -> 'ActualCard':
|
||||
"""
|
||||
:param rect: 技能卡的位置
|
||||
:param title: 读取到的技能卡的名字
|
||||
:param card: 读取到的技能卡信息
|
||||
:return: cls
|
||||
"""
|
||||
if card:
|
||||
name = card.name.replace(' ', '').replace('+', '')
|
||||
card_name = get_card_name(name)
|
||||
else:
|
||||
card_name = CardName.unidentified
|
||||
priority = idol_setting.get_card_priority(card.skill_card.id)
|
||||
return ActualCard(card, priority)
|
||||
|
||||
if card_name == CardName.unidentified:
|
||||
logger.warning(f'Unrecognized skill card:{name}, rect={rect}')
|
||||
else:
|
||||
logger.info(f'Recognized skill card:{card_name.value}')
|
||||
def __lt__(self, other):
|
||||
return self.priority < other.priority
|
||||
|
||||
skill_card = card_template_dict[card_name]
|
||||
priority = idol_setting.get_card_priority(card_name)
|
||||
return ActualCard(rect, name, skill_card, priority)
|
||||
|
||||
|
||||
# class CardReader:
|
||||
# """
|
||||
# 此类用于识别技能卡。
|
||||
# """
|
||||
|
||||
# def __init__(self, rect: HintBox = SelectCardNameArea):
|
||||
# """
|
||||
# :param rect: 识别文本范围
|
||||
# """
|
||||
# self.rect = rect
|
||||
# self.it = Interval()
|
||||
# self.wait_cd = Countdown(sec=5)
|
||||
|
||||
# def click_and_read_cards(self, card_rects: list[Rect]) -> list[ActualCard]:
|
||||
# """
|
||||
# 对输入的card_rects进行点击,再对点击后的图像的指定位置self.rect 读取文本,实例化为ActualCard。
|
||||
|
||||
# :param card_rects: 技能卡点击位置
|
||||
# :return: ActualCard list
|
||||
# """
|
||||
# result = []
|
||||
# for rect in card_rects:
|
||||
# actual_card = self.read_card(rect)
|
||||
# logger.info(actual_card)
|
||||
# result.append(actual_card)
|
||||
# return result
|
||||
|
||||
# @action('读取技能卡', screenshot_mode='manual-inherit')
|
||||
# def read_card(self, card_rect: Rect) -> ActualCard:
|
||||
# title = []
|
||||
# self.it.reset()
|
||||
# self.wait_cd.reset()
|
||||
# while len(title) == 0 and not self.wait_cd.expired():
|
||||
# device.click(card_rect)
|
||||
# self.it.wait()
|
||||
# img = device.screenshot()
|
||||
# title = ocr.raw().ocr(img, rect=self.rect)
|
||||
# return ActualCard.create_by(card_rect, title.squash().text)
|
||||
def select(self) -> bool:
|
||||
"""
|
||||
选卡时可以选择
|
||||
:return:
|
||||
"""
|
||||
return self.priority != CardPriority.other
|
||||
|
||||
def lost(self):
|
||||
"""
|
||||
是否为 除外 卡
|
||||
:return:
|
||||
"""
|
||||
return self.skill_card_element.skill_card.play_move_position_type == PlayMovePositionType.LOST
|
||||
|
|
|
@ -1,297 +1,252 @@
|
|||
{
|
||||
"pre_built_deck": [
|
||||
{
|
||||
"archetype": "好調",
|
||||
"archetype": "ProduceExamEffectType_ExamParameterBuff",
|
||||
"select_once_card_before_refresh": false,
|
||||
"core_cards": [
|
||||
"至高のエンタメ",
|
||||
"国民的アイドル",
|
||||
"魅惑の視線"
|
||||
"p_card-01-act-3_049",
|
||||
"p_card-01-men-3_006",
|
||||
"p_card-01-men-3_036"
|
||||
],
|
||||
"high_priority_cards": [
|
||||
"アイドル宣言",
|
||||
"アイドル魂",
|
||||
"仕切り直し",
|
||||
"ひと呼吸",
|
||||
"願いの力",
|
||||
"静かな意志",
|
||||
"始まりの合図",
|
||||
"存在感",
|
||||
"シュプレヒコール",
|
||||
"コール&レスポンス",
|
||||
"成就",
|
||||
"鳴り止まない拍手",
|
||||
"天真爛漫",
|
||||
"魅惑のパフォーマンス"
|
||||
"p_card-00-men-2_012",
|
||||
"p_card-00-men-3_003",
|
||||
"p_card-00-men-3_005",
|
||||
"p_card-01-men-1_034",
|
||||
"p_card-01-men-2_038",
|
||||
"p_card-01-men-2_035",
|
||||
"p_card-01-men-2_036",
|
||||
"p_card-01-men-2_037",
|
||||
"p_card-01-act-2_001",
|
||||
"p_card-01-act-3_030",
|
||||
"p_card-01-act-3_029",
|
||||
"p_card-01-men-3_033",
|
||||
"p_card-01-men-3_035",
|
||||
"p_card-01-act-3_010"
|
||||
],
|
||||
"medium_priority_cards": [
|
||||
"眼力",
|
||||
"大声援",
|
||||
"演出計画",
|
||||
"意地",
|
||||
"ハイタッチ",
|
||||
"トークタイム",
|
||||
"エキサイト",
|
||||
"祝福"
|
||||
"p_card-01-men-2_039",
|
||||
"p_card-01-men-2_043",
|
||||
"p_card-01-men-2_034",
|
||||
"p_card-01-men-2_040",
|
||||
"p_card-01-act-1_020",
|
||||
"p_card-01-act-1_021",
|
||||
"p_card-01-act-1_036",
|
||||
"p_card-01-act-2_042"
|
||||
],
|
||||
"low_priority_cards": [
|
||||
"決めポーズ",
|
||||
"飛躍",
|
||||
"立ち位置チェック",
|
||||
"成功への道筋",
|
||||
"ファーストステップ",
|
||||
"テレビ出演",
|
||||
"叶えたい夢"
|
||||
"p_card-01-act-2_003",
|
||||
"p_card-01-act-2_033",
|
||||
"p_card-01-act-2_059",
|
||||
"p_card-01-men-2_041",
|
||||
"p_card-00-men-1_007",
|
||||
"p_card-00-men-3_012",
|
||||
"p_card-00-men-3_011"
|
||||
]
|
||||
},
|
||||
{
|
||||
"archetype": "集中",
|
||||
"archetype": "ProduceExamEffectType_ExamLessonBuff",
|
||||
"select_once_card_before_refresh": false,
|
||||
"core_cards": [
|
||||
"至高のエンタメ",
|
||||
"国民的アイドル",
|
||||
"魅惑の視線"
|
||||
"p_card-01-act-3_049",
|
||||
"p_card-01-men-3_006",
|
||||
"p_card-01-men-3_036"
|
||||
],
|
||||
"high_priority_cards": [
|
||||
"アイドル宣言",
|
||||
"アイドル魂",
|
||||
"仕切り直し",
|
||||
"ひと呼吸",
|
||||
"願いの力",
|
||||
"静かな意志",
|
||||
"始まりの合図",
|
||||
"存在感",
|
||||
"シュプレヒコール",
|
||||
"コール&レスポンス",
|
||||
"成就",
|
||||
"鳴り止まない拍手",
|
||||
"天真爛漫",
|
||||
"魅惑のパフォーマンス"
|
||||
"p_card-00-men-2_012",
|
||||
"p_card-00-men-3_003",
|
||||
"p_card-00-men-3_005",
|
||||
"p_card-01-men-1_034",
|
||||
"p_card-01-men-2_038",
|
||||
"p_card-01-men-2_035",
|
||||
"p_card-01-men-2_036",
|
||||
"p_card-01-men-2_037",
|
||||
"p_card-01-act-2_001",
|
||||
"p_card-01-act-3_030",
|
||||
"p_card-01-act-3_029",
|
||||
"p_card-01-men-3_033",
|
||||
"p_card-01-men-3_035",
|
||||
"p_card-01-act-3_010"
|
||||
],
|
||||
"medium_priority_cards": [
|
||||
"眼力",
|
||||
"大声援",
|
||||
"演出計画",
|
||||
"意地",
|
||||
"ハイタッチ",
|
||||
"トークタイム",
|
||||
"エキサイト",
|
||||
"祝福"
|
||||
"p_card-01-men-2_039",
|
||||
"p_card-01-men-2_043",
|
||||
"p_card-01-men-2_034",
|
||||
"p_card-01-men-2_040",
|
||||
"p_card-01-act-1_020",
|
||||
"p_card-01-act-1_021",
|
||||
"p_card-01-act-1_036",
|
||||
"p_card-01-act-2_042"
|
||||
],
|
||||
"low_priority_cards": [
|
||||
"決めポーズ",
|
||||
"飛躍",
|
||||
"立ち位置チェック",
|
||||
"成功への道筋",
|
||||
"ファーストステップ",
|
||||
"テレビ出演",
|
||||
"叶えたい夢"
|
||||
"p_card-01-act-2_003",
|
||||
"p_card-01-act-2_033",
|
||||
"p_card-01-act-2_059",
|
||||
"p_card-01-men-2_041",
|
||||
"p_card-00-men-1_007",
|
||||
"p_card-00-men-3_012",
|
||||
"p_card-00-men-3_011"
|
||||
]
|
||||
},
|
||||
{
|
||||
"archetype": "好印象",
|
||||
"archetype": "ProduceExamEffectType_ExamReview",
|
||||
"select_once_card_before_refresh": false,
|
||||
"core_cards": [
|
||||
"輝くキミへ",
|
||||
"私がスター",
|
||||
"星屑センセーション",
|
||||
"夢色リップ"
|
||||
"p_card-02-act-3_050",
|
||||
"p_card-02-men-3_002",
|
||||
"p_card-02-men-3_004",
|
||||
"p_card-02-men-3_040"
|
||||
],
|
||||
"high_priority_cards": [
|
||||
"アイドル宣言",
|
||||
"アイドル魂",
|
||||
"仕切り直し",
|
||||
"止められない想い",
|
||||
"キラメキ",
|
||||
"ファンシーチャーム",
|
||||
"ワクワクが止まらない",
|
||||
"ノートの端の決意",
|
||||
"トキメキ",
|
||||
"虹色ドリーマー",
|
||||
"みんな大好き",
|
||||
"ゆめみごこち",
|
||||
"オトメゴコロ"
|
||||
"p_card-00-men-2_012",
|
||||
"p_card-00-men-3_003",
|
||||
"p_card-00-men-3_005",
|
||||
"p_card-02-men-2_056",
|
||||
"p_card-02-act-2_048",
|
||||
"p_card-02-men-2_058",
|
||||
"p_card-02-men-2_004",
|
||||
"p_card-02-men-3_041",
|
||||
"p_card-02-men-3_043",
|
||||
"p_card-02-men-3_042",
|
||||
"p_card-02-act-2_049",
|
||||
"p_card-02-men-2_057",
|
||||
"p_card-02-men-2_060"
|
||||
],
|
||||
"medium_priority_cards": [
|
||||
"手拍子",
|
||||
"幸せのおまじない",
|
||||
"やる気は満点",
|
||||
"本番前夜",
|
||||
"200%スマイル",
|
||||
"キセキの魔法"
|
||||
"p_card-02-act-1_003",
|
||||
"p_card-02-men-1_035",
|
||||
"p_card-02-men-2_051",
|
||||
"p_card-02-men-2_054",
|
||||
"p_card-02-act-3_001",
|
||||
"p_card-02-act-3_052"
|
||||
],
|
||||
"low_priority_cards": [
|
||||
"ラブリーウインク",
|
||||
"幸せな時間",
|
||||
"ひなたぼっこ",
|
||||
"イメトレ",
|
||||
"ファーストステップ",
|
||||
"テレビ出演",
|
||||
"叶えたい夢"
|
||||
"p_card-02-act-2_046",
|
||||
"p_card-02-men-2_050",
|
||||
"p_card-02-men-2_052",
|
||||
"p_card-02-men-2_008",
|
||||
"p_card-00-men-1_007",
|
||||
"p_card-00-men-3_012",
|
||||
"p_card-00-men-3_011"
|
||||
]
|
||||
},
|
||||
{
|
||||
"archetype": "やる気",
|
||||
"archetype": "ProduceExamEffectType_ExamCardPlayAggressive",
|
||||
"select_once_card_before_refresh": false,
|
||||
"core_cards": [
|
||||
"私がスター",
|
||||
"夢色リップ",
|
||||
"デイドリーミング",
|
||||
"きらきら紙吹雪"
|
||||
"p_card-02-men-3_002",
|
||||
"p_card-02-men-3_040",
|
||||
"p_card-02-act-1_037",
|
||||
"p_card-02-act-2_062"
|
||||
],
|
||||
"high_priority_cards": [
|
||||
"アイドル宣言",
|
||||
"アイドル魂",
|
||||
"仕切り直し",
|
||||
"止められない想い",
|
||||
"ワクワクが止まらない",
|
||||
"ひなたぼっこ",
|
||||
"イメトレ",
|
||||
"届いて!",
|
||||
"ノートの端の決意",
|
||||
"トキメキ"
|
||||
"p_card-00-men-2_012",
|
||||
"p_card-00-men-3_003",
|
||||
"p_card-00-men-3_005",
|
||||
"p_card-02-men-2_056",
|
||||
"p_card-02-men-2_004",
|
||||
"p_card-02-men-2_052",
|
||||
"p_card-02-men-2_008",
|
||||
"p_card-02-act-3_039",
|
||||
"p_card-02-men-3_041",
|
||||
"p_card-02-men-3_043"
|
||||
],
|
||||
"medium_priority_cards": [
|
||||
"開花",
|
||||
"手書きのメッセージ",
|
||||
"あのときの約束",
|
||||
"ありがとうの言葉",
|
||||
"本番前夜"
|
||||
"p_card-02-act-3_038",
|
||||
"p_card-02-men-3_044",
|
||||
"p_card-02-act-3_045",
|
||||
"p_card-02-act-2_047",
|
||||
"p_card-02-men-2_054"
|
||||
],
|
||||
"low_priority_cards": [
|
||||
"元気な挨拶",
|
||||
"リズミカル",
|
||||
"やる気は満点",
|
||||
"ファーストステップ",
|
||||
"テレビ出演",
|
||||
"叶えたい夢"
|
||||
"p_card-02-act-1_004",
|
||||
"p_card-02-men-1_006",
|
||||
"p_card-02-men-2_051",
|
||||
"p_card-00-men-1_007",
|
||||
"p_card-00-men-3_012",
|
||||
"p_card-00-men-3_011"
|
||||
]
|
||||
},
|
||||
{
|
||||
"archetype": "強気",
|
||||
"archetype": "ProduceExamEffectType_ExamConcentration",
|
||||
"select_once_card_before_refresh": false,
|
||||
"core_cards": [
|
||||
"アイドルになります",
|
||||
"一心不乱"
|
||||
"p_card-03-men-3_058",
|
||||
"p_card-03-men-3_061"
|
||||
],
|
||||
"high_priority_cards": [
|
||||
"アイドル宣言",
|
||||
"アイドル魂",
|
||||
"仕切り直し",
|
||||
"第一印象",
|
||||
"プライド",
|
||||
"盛り上げ上手",
|
||||
"インフルエンサー",
|
||||
"タフネス",
|
||||
"総合芸術",
|
||||
"心・技・体",
|
||||
"クライマックス",
|
||||
"全身全霊",
|
||||
"頂点へ"
|
||||
"p_card-00-men-2_012",
|
||||
"p_card-00-men-3_003",
|
||||
"p_card-00-men-3_005",
|
||||
"p_card-03-act-2_081",
|
||||
"p_card-03-men-2_066",
|
||||
"p_card-03-men-2_076",
|
||||
"p_card-03-men-2_080",
|
||||
"p_card-03-men-2_074",
|
||||
"p_card-03-act-3_054",
|
||||
"p_card-03-act-3_056",
|
||||
"p_card-03-act-3_055",
|
||||
"p_card-03-act-3_065",
|
||||
"p_card-03-men-3_062"
|
||||
],
|
||||
"medium_priority_cards": [
|
||||
"精一杯",
|
||||
"ハッピー♪",
|
||||
"嬉しい誤算",
|
||||
"オープニングアクト",
|
||||
"カウントダウン",
|
||||
"忍耐力"
|
||||
"p_card-03-act-1_044",
|
||||
"p_card-03-men-1_039",
|
||||
"p_card-03-men-1_049",
|
||||
"p_card-03-act-2_063",
|
||||
"p_card-03-act-2_073",
|
||||
"p_card-03-men-2_077"
|
||||
],
|
||||
"low_priority_cards": [
|
||||
"涙の思い出",
|
||||
"はじけるパッション",
|
||||
"理想のテンポ",
|
||||
"ファーストステップ",
|
||||
"テレビ出演",
|
||||
"叶えたい夢"
|
||||
"p_card-03-men-1_048",
|
||||
"p_card-03-act-2_068",
|
||||
"p_card-03-act-2_067",
|
||||
"p_card-00-men-1_007",
|
||||
"p_card-00-men-3_012",
|
||||
"p_card-00-men-3_011"
|
||||
]
|
||||
},
|
||||
{
|
||||
"archetype": "温存",
|
||||
"archetype": "ProduceExamEffectType_ExamFullPower",
|
||||
"select_once_card_before_refresh": false,
|
||||
"core_cards": [
|
||||
"モチベ",
|
||||
"アイドルになります"
|
||||
"p_card-03-men-2_075",
|
||||
"p_card-03-men-3_058"
|
||||
],
|
||||
"high_priority_cards": [
|
||||
"アイドル宣言",
|
||||
"アイドル魂",
|
||||
"仕切り直し",
|
||||
"プライド",
|
||||
"盛り上げ上手",
|
||||
"インフルエンサー",
|
||||
"タフネス",
|
||||
"翔び立て!",
|
||||
"心・技・体",
|
||||
"輝け!",
|
||||
"全身全霊",
|
||||
"頂点へ",
|
||||
"覚悟"
|
||||
"p_card-00-men-2_012",
|
||||
"p_card-00-men-3_003",
|
||||
"p_card-00-men-3_005",
|
||||
"p_card-03-men-2_066",
|
||||
"p_card-03-men-2_076",
|
||||
"p_card-03-men-2_080",
|
||||
"p_card-03-men-2_074",
|
||||
"p_card-03-act-3_057",
|
||||
"p_card-03-act-3_056",
|
||||
"p_card-03-act-3_053",
|
||||
"p_card-03-act-3_065",
|
||||
"p_card-03-men-3_062",
|
||||
"p_card-03-men-3_063"
|
||||
],
|
||||
"medium_priority_cards": [
|
||||
"ハッピー♪",
|
||||
"嬉しい誤算",
|
||||
"涙の思い出",
|
||||
"セッティング",
|
||||
"オープニングアクト",
|
||||
"トレーニングの成果",
|
||||
"潜在能力",
|
||||
"カウントダウン",
|
||||
"忍耐力",
|
||||
"クライマックス"
|
||||
"p_card-03-men-1_049",
|
||||
"p_card-03-men-1_048",
|
||||
"p_card-03-men-1_051",
|
||||
"p_card-03-act-2_063",
|
||||
"p_card-03-act-2_071",
|
||||
"p_card-03-men-2_064",
|
||||
"p_card-03-men-2_077",
|
||||
"p_card-03-act-3_055"
|
||||
],
|
||||
"low_priority_cards": [
|
||||
"ジャストアピール",
|
||||
"積み重ね",
|
||||
"アッチェレランド",
|
||||
"はじけるパッション",
|
||||
"トレンドリーダー",
|
||||
"ファーストステップ",
|
||||
"テレビ出演",
|
||||
"叶えたい夢"
|
||||
]
|
||||
},
|
||||
{
|
||||
"archetype": "全力",
|
||||
"select_once_card_before_refresh": false,
|
||||
"core_cards": [
|
||||
"モチベ",
|
||||
"アイドルになります"
|
||||
],
|
||||
"high_priority_cards": [
|
||||
"アイドル宣言",
|
||||
"アイドル魂",
|
||||
"仕切り直し",
|
||||
"プライド",
|
||||
"盛り上げ上手",
|
||||
"インフルエンサー",
|
||||
"タフネス",
|
||||
"翔び立て!",
|
||||
"心・技・体",
|
||||
"輝け!",
|
||||
"全身全霊",
|
||||
"頂点へ",
|
||||
"覚悟"
|
||||
],
|
||||
"medium_priority_cards": [
|
||||
"嬉しい誤算",
|
||||
"涙の思い出",
|
||||
"セッティング",
|
||||
"オープニングアクト",
|
||||
"トレーニングの成果",
|
||||
"潜在能力",
|
||||
"忍耐力",
|
||||
"クライマックス"
|
||||
],
|
||||
"low_priority_cards": [
|
||||
"ジャストアピール",
|
||||
"積み重ね",
|
||||
"アッチェレランド",
|
||||
"はじけるパッション",
|
||||
"トレンドリーダー",
|
||||
"ファーストステップ",
|
||||
"テレビ出演",
|
||||
"叶えたい夢"
|
||||
"p_card-03-act-1_038",
|
||||
"p_card-03-act-1_042",
|
||||
"p_card-03-act-2_072",
|
||||
"p_card-03-act-2_068",
|
||||
"p_card-03-act-2_082",
|
||||
"p_card-00-men-1_007",
|
||||
"p_card-00-men-3_012",
|
||||
"p_card-00-men-3_011"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
@ -2,10 +2,8 @@ import json
|
|||
import os
|
||||
from logging import getLogger
|
||||
|
||||
from kotonebot import Interval, Countdown, ocr, contains, device, action
|
||||
from kotonebot.backend.core import HintBox
|
||||
from kotonebot.kaa.db import IdolCard
|
||||
from kotonebot.kaa.skill_card.card_deck_config import DeckConfig
|
||||
from kotonebot.kaa.skill_card.enum_constant import Archetype, archetype_dict, get_archetype
|
||||
from kotonebot.kaa.skill_card.global_idol_setting import GlobalIdolSetting
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
@ -26,64 +24,16 @@ idol_setting = GlobalIdolSetting()
|
|||
# TODO: 这里应该从配置文件中读取
|
||||
deck_config = get_default_config()
|
||||
|
||||
# P手帳
|
||||
PGuide = HintBox(x1=595, y1=610, x2=690, y2=735, source_resolution=(720, 1280))
|
||||
# 編成
|
||||
Builder = HintBox(x1=530, y1=1080, x2=610, y2=1140, source_resolution=(720, 1280))
|
||||
# 流派
|
||||
IdolArchetype = HintBox(x1=515, y1=455, x2=655, y2=495, source_resolution=(720, 1280))
|
||||
# P手帳退出
|
||||
PGuideExit = HintBox(x1=320, y1=1155, x2=400, y2=1235, source_resolution=(720, 1280))
|
||||
|
||||
|
||||
@action('根据日程更新偶像流派', screenshot_mode='manual-inherit')
|
||||
def update_archetype_by_schedule():
|
||||
def update_archetype_by_idol_skin_id(idol_skin_id: str):
|
||||
"""
|
||||
根据日程更新偶像流派
|
||||
根据偶像皮肤id,更新全局偶像信息
|
||||
:param idol_skin_id:
|
||||
:return:
|
||||
"""
|
||||
if not idol_setting.need_update:
|
||||
return
|
||||
it = Interval()
|
||||
wait_cd = Countdown(sec=5).start()
|
||||
device.screenshot()
|
||||
|
||||
while not ocr.find(contains("P手帳"), rect=PGuide):
|
||||
if wait_cd.expired():
|
||||
logger.warning("not found: P手帳, update deck failed")
|
||||
return
|
||||
it.wait()
|
||||
device.screenshot()
|
||||
device.click(PGuide)
|
||||
it.wait()
|
||||
device.screenshot()
|
||||
|
||||
wait_cd.reset()
|
||||
while not ocr.find(contains("編成"), rect=Builder):
|
||||
if wait_cd.expired():
|
||||
break
|
||||
it.wait()
|
||||
device.screenshot()
|
||||
device.click(Builder)
|
||||
it.wait()
|
||||
|
||||
wait_cd.reset()
|
||||
while not wait_cd.expired():
|
||||
it.wait()
|
||||
img = device.screenshot()
|
||||
if text := ocr.raw().ocr(img, rect=IdolArchetype):
|
||||
archetype = get_archetype(text.squash().text)
|
||||
if archetype != Archetype.unidentified:
|
||||
idol_setting.update_deck(archetype, deck_config)
|
||||
break
|
||||
if idol_setting.need_update:
|
||||
logger.warning("Not found archetype, update deck failed")
|
||||
|
||||
# 如果在手册页面,尝试退出
|
||||
it.wait()
|
||||
wait_cd.reset()
|
||||
device.screenshot()
|
||||
while ocr.find(contains("編成"), rect=Builder) and not wait_cd.expired():
|
||||
device.click(PGuideExit)
|
||||
it.wait()
|
||||
device.screenshot()
|
||||
idol_setting.new_play()
|
||||
idol_card = IdolCard.from_skin_id(idol_skin_id)
|
||||
if idol_card:
|
||||
idol_setting.update_deck(idol_card.exam_effect_type, deck_config)
|
||||
else:
|
||||
logger.warning(f"Can`t found archetype by skin id: {idol_skin_id}")
|
|
@ -4,9 +4,7 @@ from kotonebot import device, image, Interval, ocr, contains, Countdown, action
|
|||
from kotonebot.backend.core import HintBox
|
||||
from kotonebot.kaa.game_ui import dialog, badge
|
||||
from kotonebot.kaa.game_ui.skill_card_select import extract_cards
|
||||
from kotonebot.kaa.skill_card.enum_constant import CardPriority
|
||||
from kotonebot.kaa.skill_card_action.card_reader import ActualCard
|
||||
from kotonebot.kaa.skill_card_action.global_idol_setting_action import idol_setting
|
||||
from kotonebot.kaa.tasks import R
|
||||
from kotonebot.primitives import Rect
|
||||
|
||||
|
@ -39,33 +37,31 @@ def select_skill_card():
|
|||
continue
|
||||
|
||||
img = device.screenshot()
|
||||
match_results = image.find_multi([
|
||||
R.InPurodyuusu.A,
|
||||
R.InPurodyuusu.M
|
||||
])
|
||||
if match_results:
|
||||
cards = extract_cards(img)
|
||||
cards = [ActualCard.create_by(card.rect, card.skill_card) for card in cards]
|
||||
skill_card_elements = extract_cards(img)
|
||||
if skill_card_elements:
|
||||
cards = [ActualCard.create_by(skill_card_element) for skill_card_element in skill_card_elements]
|
||||
cards = sorted(cards, reverse=True)
|
||||
target_card = cards[0]
|
||||
select_suggest = False
|
||||
|
||||
target_card = sorted(cards, key=lambda x: x.priority)[0]
|
||||
select_other = target_card.priority == CardPriority.other
|
||||
|
||||
# 非卡组配置的卡时,判断是否需要刷新
|
||||
if select_other:
|
||||
# 若考虑先刷新,则尝试刷新,刷新成功则重新识别卡
|
||||
if not idol_setting.select_once_card_before_refresh:
|
||||
if try_refresh_skill_card(target_card.rect):
|
||||
it.wait()
|
||||
continue
|
||||
# 选择一回一次的卡,如果没有,尝试刷新,刷新成功则重新识别卡
|
||||
if once_cards := [card for card in cards if card.skill_card.once]:
|
||||
target_card = once_cards[0]
|
||||
elif try_refresh_skill_card(target_card.rect):
|
||||
# 非卡组配置的卡时,尝试刷新
|
||||
if not target_card.select():
|
||||
if try_refresh_skill_card(target_card.skill_card_element.rect):
|
||||
it.wait()
|
||||
continue
|
||||
|
||||
logger.info(f"select {target_card.name}")
|
||||
device.click(target_card.rect)
|
||||
# 如果没刷新次数,尝试选取除外卡
|
||||
if once_cards := [card for card in cards if card.lost()]:
|
||||
target_card = once_cards[0]
|
||||
else:
|
||||
select_suggest = True
|
||||
if select_suggest:
|
||||
# 既没有刷新,也没有除外卡,选择推荐卡
|
||||
card_rect = find_recommended_card_rect([card.skill_card_element.rect for card in cards])
|
||||
logger.info(f"select recommended card")
|
||||
device.click(card_rect)
|
||||
else:
|
||||
logger.info(f"select {target_card.skill_card_element.skill_card.name}")
|
||||
device.click(target_card.skill_card_element.rect)
|
||||
it.wait()
|
||||
|
||||
else:
|
||||
|
@ -81,6 +77,26 @@ def select_skill_card():
|
|||
logger.warning("Skill card select failed")
|
||||
|
||||
|
||||
@action('寻找推荐卡', screenshot_mode='manual-inherit')
|
||||
def find_recommended_card_rect(cards: list[Rect]) -> Rect:
|
||||
# 判断是否有推荐卡
|
||||
rec_badges = image.find_all(R.InPurodyuusu.TextRecommend)
|
||||
rec_badges = [card.rect for card in rec_badges]
|
||||
if rec_badges:
|
||||
matches = badge.match(cards, rec_badges, 'mb')
|
||||
logger.debug("Recommend card badge matches: %s", matches)
|
||||
# 选第一个推荐卡
|
||||
target_match = next(filter(lambda m: m.badge is not None, matches), None)
|
||||
if target_match:
|
||||
target_card = target_match.object
|
||||
else:
|
||||
target_card = cards[0]
|
||||
else:
|
||||
logger.debug("No recommend badge found. Pick first card.")
|
||||
target_card = cards[0]
|
||||
return target_card
|
||||
|
||||
|
||||
@action('刷新技能卡', screenshot_mode='manual-inherit')
|
||||
def try_refresh_skill_card(first_card: Rect) -> bool:
|
||||
"""
|
||||
|
|
|
@ -24,63 +24,62 @@ logger = getLogger(__name__)
|
|||
@action('领取技能卡', screenshot_mode='manual-inherit')
|
||||
def acquire_skill_card():
|
||||
"""获取技能卡(スキルカード)"""
|
||||
select_skill_card()
|
||||
# TODO: 识别卡片内容,而不是固定选卡
|
||||
# TODO: 不硬编码坐标
|
||||
# logger.debug("Locating all skill cards...")
|
||||
#
|
||||
# it = Interval()
|
||||
# cards = None
|
||||
# card_clicked = False
|
||||
# target_card = None
|
||||
#
|
||||
# while True:
|
||||
# device.screenshot()
|
||||
# it.wait()
|
||||
#
|
||||
# # 是否显示技能卡选择指导的对话框
|
||||
# # [kotonebot-resource/sprites/jp/in_purodyuusu/screenshot_show_skill_card_select_guide_dialog.png]
|
||||
# if image.find(R.InPurodyuusu.TextSkillCardSelectGuideDialogTitle):
|
||||
# # 默认就是显示,直接确认
|
||||
# dialog.yes()
|
||||
# continue
|
||||
# if not cards:
|
||||
# cards = image.find_all_multi([
|
||||
# R.InPurodyuusu.A,
|
||||
# R.InPurodyuusu.M
|
||||
# ])
|
||||
# if not cards:
|
||||
# logger.warning("No skill cards found. Skip acquire.")
|
||||
# return
|
||||
# cards = sorted(cards, key=lambda x: (x.position[0], x.position[1]))
|
||||
# logger.info(f"Found {len(cards)} skill cards")
|
||||
# # 判断是否有推荐卡
|
||||
# rec_badges = image.find_all(R.InPurodyuusu.TextRecommend)
|
||||
# rec_badges = [card.rect for card in rec_badges]
|
||||
# if rec_badges:
|
||||
# cards = [card.rect for card in cards]
|
||||
# matches = badge.match(cards, rec_badges, 'mb')
|
||||
# logger.debug("Recommend card badge matches: %s", matches)
|
||||
# # 选第一个推荐卡
|
||||
# target_match = next(filter(lambda m: m.badge is not None, matches), None)
|
||||
# if target_match:
|
||||
# target_card = target_match.object
|
||||
# else:
|
||||
# target_card = cards[0]
|
||||
# else:
|
||||
# logger.debug("No recommend badge found. Pick first card.")
|
||||
# target_card = cards[0].rect
|
||||
# continue
|
||||
# if not card_clicked and target_card is not None:
|
||||
# logger.debug("Click target skill card")
|
||||
# device.click(target_card)
|
||||
# card_clicked = True
|
||||
# sleep(0.2)
|
||||
# continue
|
||||
# if acquire_btn := image.find(R.InPurodyuusu.AcquireBtnDisabled):
|
||||
# logger.debug("Click acquire button")
|
||||
# device.click(acquire_btn)
|
||||
# break
|
||||
logger.debug("Locating all skill cards...")
|
||||
|
||||
it = Interval()
|
||||
cards = None
|
||||
card_clicked = False
|
||||
target_card = None
|
||||
|
||||
while True:
|
||||
device.screenshot()
|
||||
it.wait()
|
||||
|
||||
# 是否显示技能卡选择指导的对话框
|
||||
# [kotonebot-resource/sprites/jp/in_purodyuusu/screenshot_show_skill_card_select_guide_dialog.png]
|
||||
if image.find(R.InPurodyuusu.TextSkillCardSelectGuideDialogTitle):
|
||||
# 默认就是显示,直接确认
|
||||
dialog.yes()
|
||||
continue
|
||||
if not cards:
|
||||
cards = image.find_all_multi([
|
||||
R.InPurodyuusu.A,
|
||||
R.InPurodyuusu.M
|
||||
])
|
||||
if not cards:
|
||||
logger.warning("No skill cards found. Skip acquire.")
|
||||
return
|
||||
cards = sorted(cards, key=lambda x: (x.position[0], x.position[1]))
|
||||
logger.info(f"Found {len(cards)} skill cards")
|
||||
# 判断是否有推荐卡
|
||||
rec_badges = image.find_all(R.InPurodyuusu.TextRecommend)
|
||||
rec_badges = [card.rect for card in rec_badges]
|
||||
if rec_badges:
|
||||
cards = [card.rect for card in cards]
|
||||
matches = badge.match(cards, rec_badges, 'mb')
|
||||
logger.debug("Recommend card badge matches: %s", matches)
|
||||
# 选第一个推荐卡
|
||||
target_match = next(filter(lambda m: m.badge is not None, matches), None)
|
||||
if target_match:
|
||||
target_card = target_match.object
|
||||
else:
|
||||
target_card = cards[0]
|
||||
else:
|
||||
logger.debug("No recommend badge found. Pick first card.")
|
||||
target_card = cards[0].rect
|
||||
continue
|
||||
if not card_clicked and target_card is not None:
|
||||
logger.debug("Click target skill card")
|
||||
device.click(target_card)
|
||||
card_clicked = True
|
||||
sleep(0.2)
|
||||
continue
|
||||
if acquire_btn := image.find(R.InPurodyuusu.AcquireBtnDisabled):
|
||||
logger.debug("Click acquire button")
|
||||
device.click(acquire_btn)
|
||||
break
|
||||
|
||||
@action('选择P物品', screenshot_mode='auto')
|
||||
def select_p_item():
|
||||
|
@ -261,7 +260,7 @@ def fast_acquisitions() -> AcquisitionType | None:
|
|||
logger.debug("Check skill card select...")
|
||||
if image.find(R.InPurodyuusu.TextSkillCard):
|
||||
logger.info("Acquire skill card found")
|
||||
acquire_skill_card()
|
||||
select_skill_card()
|
||||
return "PSkillCardSelect"
|
||||
# P物品选择
|
||||
logger.debug("Check PItem select...")
|
||||
|
|
|
@ -3,7 +3,6 @@ from typing_extensions import assert_never
|
|||
from typing import Literal
|
||||
|
||||
from kotonebot.kaa.game_ui.schedule import Schedule
|
||||
from kotonebot.kaa.skill_card_action.global_idol_setting_action import update_archetype_by_schedule
|
||||
from kotonebot.kaa.tasks import R
|
||||
from ..actions import loading
|
||||
from kotonebot.kaa.game_ui import WhiteFilter, dialog
|
||||
|
@ -736,7 +735,6 @@ def hajime_from_stage(stage: ProduceStage, type: Literal['regular', 'pro', 'mast
|
|||
remaining_week = texts.squash().replace('ó', '6').numbers()
|
||||
if not remaining_week:
|
||||
raise UnrecoverableError("Failed to detect week. text=" + repr(texts.squash()))
|
||||
update_archetype_by_schedule()
|
||||
# 判断阶段
|
||||
match type:
|
||||
case 'regular':
|
||||
|
|
|
@ -3,7 +3,7 @@ from itertools import cycle
|
|||
from typing import Optional, Literal
|
||||
from typing_extensions import assert_never
|
||||
|
||||
from kotonebot.kaa.skill_card_action.global_idol_setting_action import idol_setting
|
||||
from kotonebot.kaa.skill_card_action.global_idol_setting_action import update_archetype_by_idol_skin_id
|
||||
from kotonebot.ui import user
|
||||
from kotonebot.util import Countdown, Interval
|
||||
from kotonebot.backend.context.context import wait
|
||||
|
@ -13,7 +13,7 @@ from kotonebot.kaa.tasks import R
|
|||
from kotonebot.kaa.common import conf
|
||||
from kotonebot.kaa.game_ui import dialog
|
||||
from ..actions.scenes import at_home, goto_home
|
||||
from kotonebot.kaa.game_ui.idols_overview import locate_idol
|
||||
from kotonebot.kaa.game_ui.idols_overview import locate_idol, find_idol_skin_id_on_resume_produce
|
||||
from ..produce.in_purodyuusu import hajime_pro, hajime_regular, hajime_master, resume_pro_produce, resume_regular_produce, \
|
||||
resume_master_produce
|
||||
from kotonebot import device, image, ocr, task, action, sleep, contains, regex
|
||||
|
@ -168,6 +168,12 @@ def resume_produce():
|
|||
raise ValueError('Failed to detect weeks after multiple retries.')
|
||||
if current_week is None:
|
||||
raise ValueError('Failed to detect current_week.')
|
||||
|
||||
# 更新全局偶像信息
|
||||
img = device.screenshot()
|
||||
skin_id = find_idol_skin_id_on_resume_produce(img)
|
||||
update_archetype_by_idol_skin_id(skin_id)
|
||||
|
||||
# 点击 再開する
|
||||
# [kotonebot-resource/sprites/jp/produce/produce_resume.png]
|
||||
logger.info('Click resume button.')
|
||||
|
@ -201,7 +207,6 @@ def do_produce(
|
|||
if not at_home():
|
||||
goto_home()
|
||||
|
||||
idol_setting.new_play()
|
||||
device.screenshot()
|
||||
# 有进行中培育的情况
|
||||
if ocr.find(contains('中'), rect=R.Produce.BoxProduceOngoing):
|
||||
|
@ -209,6 +214,8 @@ def do_produce(
|
|||
resume_produce()
|
||||
return True
|
||||
|
||||
# 新培育时更新偶像信息
|
||||
update_archetype_by_idol_skin_id(idol_skin_id)
|
||||
# 0. 进入培育页面
|
||||
mode_text = mode.upper()
|
||||
if mode_text == 'MASTER':
|
||||
|
|
Loading…
Reference in New Issue