Skip to content

Commit

Permalink
Integrate new achievement checking system.
Browse files Browse the repository at this point in the history
  • Loading branch information
MikuAuahDark committed Jan 22, 2025
1 parent e000b99 commit dcbf75e
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 110 deletions.
6 changes: 3 additions & 3 deletions npps4/game/lbonus.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ async def lbonus_execute(context: idol.SchoolIdolUserParams) -> LoginBonusRespon
lbonuses_day.add(current_datetime.day)
# Do achievement check
achievement_list.extend(
await achievement.check_type_27(context, current_user, login_count)
+ await achievement.check_type_29(context, current_user)
+ await achievement.check_type_53_recursive(context, current_user)
await achievement.check(
context, current_user, achievement.AchievementUpdateLoginBonus(login_days=login_count)
)
)
accomplished_rewards.extend(
[await achievement.get_achievement_rewards(context, ach) for ach in achievement_list.accomplished]
Expand Down
56 changes: 27 additions & 29 deletions npps4/game/live.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,35 +693,26 @@ async def live_reward(context: idol.SchoolIdolUserParams, request: LiveRewardReq
unit_deck_full_info.append((await unit.get_unit_data_full_info(context, unit_data))[0])

# Check achievement
accomplished_achievement = (
await achievement.check_type_1(context, current_user, True)
+ await achievement.check_type_2(context, current_user, live_setting.difficulty, True)
# album.trigger_achievement call below checks type 18 through 22.
+ await album.trigger_achievement(context, current_user, obtained=True, idolized=True, max_love=True)
+ await achievement.check_type_30(context, current_user)
+ await achievement.check_type_32(context, current_user, live_setting.live_track_id)
# TODO: Check type 33
+ await achievement.check_type_37(context, current_user, live_setting.live_track_id, True)
+ await achievement.check_type_50(
context,
current_user,
live_setting.live_track_id,
live_setting.difficulty,
live_setting.attribute_icon_id,
score_rank,
combo_rank,
unit_deck_unit_ids,
True,
)
+ await achievement.check_type_58(context, current_user, True)
unit_ids_tuple, unit_type_ids_tuple = await unit.tupleize_unit_id_and_type(context, unit_deck_unit_ids)
live_ach_update = achievement.AchievementUpdateLiveClear(
live_track_id=live_setting.live_track_id,
difficulty=live_setting.difficulty,
attribute=live_setting.attribute_icon_id,
score_rank=score_rank,
combo_rank=combo_rank,
swing=bool(live_setting.swing_flag),
team_unit_ids=unit_ids_tuple,
team_unit_type_ids=unit_type_ids_tuple,
)
if score_rank < 5:
accomplished_achievement.extend(await achievement.check_type_3(context, current_user, score_rank, True))
if combo_rank < 5:
accomplished_achievement.extend(await achievement.check_type_4(context, current_user, combo_rank, True))
for unit_type_id in unit_types_in_deck:
accomplished_achievement.extend(await achievement.check_type_7(context, current_user, unit_type_id, True))
accomplished_achievement.extend(await achievement.check_type_53_recursive(context, current_user))
achievement_update = [
live_ach_update,
achievement.AchievementUpdateNewUnit(),
achievement.AchievementUpdateUnitMaxLove(),
]
if len(next_level_info) > 1:
achievement_update.append(achievement.AchievementUpdateLevelUp(rank=current_user.level))

accomplished_achievement = await achievement.check(context, current_user, *achievement_update)
accomplished_achievement.fix()

# Process achievement rewards part 1
Expand All @@ -733,12 +724,19 @@ async def live_reward(context: idol.SchoolIdolUserParams, request: LiveRewardReq
)

# Check achievement part 2
scenario_updates = []
unlocked_scenario = await scenario.count(context, current_user)
for reward_list in temp_achievement_rewards:
for reward_data in reward_list:
if reward_data.add_type == const.ADD_TYPE.SCENARIO:
unlocked_scenario = unlocked_scenario + 1
accomplished_achievement.extend(await achievement.check_type_59(context, current_user, unlocked_scenario))
scenario_updates.append(
achievement.AchievementUpdateItemCollect(
add_type=const.ADD_TYPE.SCENARIO, item_id=reward_data.item_id
)
)

accomplished_achievement.extend(await achievement.check(context, current_user, *scenario_updates))

# Process achievement rewards part 2
accomplished_achievement_rewards = [
Expand Down
36 changes: 25 additions & 11 deletions npps4/game/reward.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,24 @@ async def reward_open(context: idol.SchoolIdolUserParams, request: RewardOpenReq
supp_units = await unit.get_all_supporter_unit(context, current_user)
success = bool(add_result)

achievement_list = achievement.AchievementContext()
album_trigger = []
achievement_update = []
if success:
await reward.remove_incentive(context, incentive)
if item_data.add_type == const.ADD_TYPE.UNIT:
# Trigger achievement
achievement_list = await album.trigger_achievement(
context, current_user, obtained=True, idolized=True, max_love=True, max_level=True
) + await achievement.check_type_53_recursive(context, current_user)
if item_data.add_type == const.ADD_TYPE.UNIT and len(album_trigger) == 0:
album_trigger.append(achievement.AchievementUpdateNewUnit())
album_trigger.append(achievement.AchievementUpdateUnitRankUp(unit_ids=[]))

achievement_update.append(
achievement.AchievementUpdateItemCollect(
add_type=item_data.add_type, item_id=item_data.item_id, amount=item_data.amount
)
)
else:
raise idol.error.by_code(idol.error.ERROR_CODE_LIMIT_OVER)

achievement_list = await achievement.check(context, current_user, *album_trigger, *achievement_update)

# Give achievement rewards
accomplished_rewards = [
await achievement.get_achievement_rewards(context, ach) for ach in achievement_list.accomplished
Expand Down Expand Up @@ -220,6 +227,7 @@ async def reward_openall(context: idol.SchoolIdolUserParams, request: RewardList
reward_count = len(incentives)
reward_item_list: list[RewardIncentiveItem] = []
need_check_unit_ach = False
achievement_update = []

for incentive in incentives:
item_data = await reward.resolve_incentive(context, current_user, incentive)
Expand All @@ -234,12 +242,18 @@ async def reward_openall(context: idol.SchoolIdolUserParams, request: RewardList
if item_data.add_type == const.ADD_TYPE.UNIT:
need_check_unit_ach = True

achievement_list = achievement.AchievementContext()
achievement_update.append(
achievement.AchievementUpdateItemCollect(
add_type=item_data.add_type, item_id=item_data.item_id, amount=item_data.amount
)
)

if need_check_unit_ach:
# Trigger achievement
achievement_list = await album.trigger_achievement(
context, current_user, obtained=True, idolized=True, max_love=True, max_level=True
) + await achievement.check_type_53_recursive(context, current_user)
achievement_update.append(achievement.AchievementUpdateNewUnit())
achievement_update.append(achievement.AchievementUpdateUnitRankUp(unit_ids=[]))

achievement_list = await achievement.check(context, current_user, *achievement_update)

# Give achievement rewards
accomplished_rewards = [
await achievement.get_achievement_rewards(context, ach) for ach in achievement_list.accomplished
Expand Down
12 changes: 5 additions & 7 deletions npps4/game/scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,11 @@ async def scenario_reward(context: idol.SchoolIdolUserParams, request: ScenarioR
await scenario.complete(context, current_user, request.scenario_id)

# Trigger achievement
finished_scenario_count = await scenario.count_completed(context, current_user)
# FIXME: Recursive checking
achievement_list = (
await achievement.check_type_23(context, current_user, request.scenario_id)
+ await achievement.check_type_57(context, current_user, finished_scenario_count)
+ await achievement.check_type_53_recursive(context, current_user)
+ await achievement.check_type_30(context, current_user)
achievement_list = await achievement.check(
context,
current_user,
achievement.AchievementUpdateFinishScenario(scenario_id=request.scenario_id),
achievement.AchievementUpdateLevelUp(rank=current_user.level),
)

# Give achievement rewards
Expand Down
8 changes: 7 additions & 1 deletion npps4/game/secretbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,13 @@ async def secretbox_gachapon(context: idol.SchoolIdolUserParams, request: Secret
lowest_rarity = min(lowest_rarity, LOWEST_RARITY_SORT_ORDER[reward_data.as_item_reward.unit_rarity_id - 1])

# Trigger achievement
achievement_list = await album.trigger_achievement(context, current_user, idolized=True)
achievement_list = await achievement.check(
context,
current_user,
achievement.AchievementUpdateSecretbox(secretbox_id=secretbox_id, amount=secretbox_button.unit_count),
achievement.AchievementUpdateNewUnit(),
achievement.AchievementUpdateUnitRankUp(unit_ids=[]),
)
accomplished_rewards = [
await achievement.get_achievement_rewards(context, ach) for ach in achievement_list.accomplished
]
Expand Down
15 changes: 12 additions & 3 deletions npps4/game/unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,9 @@ async def unit_rankup(context: idol.SchoolIdolUserParams, request: UnitRankUpReq
raise idol.error.IdolError(detail="not enough money")

await album.update(context, current_user, source_unit.unit_id, rank_max=True)
achievement_list = await album.trigger_achievement(context, current_user, idolized=True)
achievement_list = await achievement.check(
context, current_user, achievement.AchievementUpdateUnitRankUp(unit_ids=[source_unit.unit_id])
)
accomplished_rewards = [
await achievement.get_achievement_rewards(context, ach) for ach in achievement_list.accomplished
]
Expand Down Expand Up @@ -646,7 +648,12 @@ async def unit_merge(context: idol.SchoolIdolUserParams, request: UnitMergeReque
# Update album and trigger achievement
after_unit, _ = await unit.get_unit_data_full_info(context, source_unit)
await album.update(context, current_user, source_unit.unit_id, rank_level_max=after_unit.is_level_max)
achievement_list = await album.trigger_achievement(context, current_user, idolized=True)
achievement_list = await achievement.check(
context,
current_user,
achievement.AchievementUpdateUnitRankUp(unit_ids=[]),
achievement.AchievementUpdateUnitMerge(unit_owning_user_id=source_unit.id, skill_level=after_unit.skill_level),
)
accomplished_rewards = [
await achievement.get_achievement_rewards(context, ach) for ach in achievement_list.accomplished
]
Expand Down Expand Up @@ -725,7 +732,9 @@ async def unit_exchangepointrankup(
raise idol.error.IdolError(detail="max SIS reached")

await album.update(context, current_user, source_unit.unit_id, rank_max=True)
achievement_list = await album.trigger_achievement(context, current_user, idolized=True)
achievement_list = await achievement.check(
context, current_user, achievement.AchievementUpdateUnitRankUp(unit_ids=[source_unit.unit_id])
)
accomplished_rewards = [
await achievement.get_achievement_rewards(context, ach) for ach in achievement_list.accomplished
]
Expand Down
24 changes: 9 additions & 15 deletions npps4/system/achievement.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import sqlalchemy

from . import advanced
from . import album
from . import common
from . import item
from . import item_model
Expand Down Expand Up @@ -123,8 +124,7 @@ class AchievementUpdateSecretbox:
class AchievementUpdateNewUnit:
"""Instantiate this to perform checks on achievement with "New Unique Unit" trigger."""

unit_ids: list[int]
"""List of units"""
pass


@dataclasses.dataclass(kw_only=True)
Expand All @@ -139,16 +139,14 @@ class AchievementUpdateUnitRankUp:
class AchievementUpdateUnitMaxLevel:
"""Instantiate this to perform checks on achievement with "Max Level" trigger."""

unit_ids: list[int]
"""List of units"""
pass


@dataclasses.dataclass(kw_only=True)
class AchievementUpdateUnitMaxLove:
"""Instantiate this to perform checks on achievement with "Max Bond" trigger."""

unit_ids: list[int]
"""List of units"""
pass


@dataclasses.dataclass(kw_only=True)
Expand Down Expand Up @@ -189,7 +187,7 @@ class AchievementUpdateItemCollect:

add_type: const.ADD_TYPE
item_id: int
amount: int
amount: int = 1


@dataclasses.dataclass(kw_only=True)
Expand Down Expand Up @@ -459,8 +457,7 @@ async def update(
data: AchievementUpdateNewUnit,
achievement_info: achievement.Achievement,
) -> int:
# TODO: Query album
return oldvalue + len(data.unit_ids)
return await album.count_album_with(context, user)

async def is_accomplished(
self, context: idol.BasicSchoolIdolContext, value: int, achievement_info: achievement.Achievement
Expand Down Expand Up @@ -491,8 +488,7 @@ async def update(
data: AchievementUpdateUnitRankUp,
achievement_info: achievement.Achievement,
) -> int:
# TODO: Query album
return oldvalue + len(data.unit_ids)
return await album.count_album_with(context, user, main.Album.rank_max_flag == True)

async def is_accomplished(
self, context: idol.BasicSchoolIdolContext, value: int, achievement_info: achievement.Achievement
Expand Down Expand Up @@ -523,8 +519,7 @@ async def update(
data: AchievementUpdateUnitMaxLove,
achievement_info: achievement.Achievement,
) -> int:
# TODO: Query album
return oldvalue + len(data.unit_ids)
return await album.count_album_with(context, user, main.Album.love_max_flag == True)

async def is_accomplished(
self, context: idol.BasicSchoolIdolContext, value: int, achievement_info: achievement.Achievement
Expand Down Expand Up @@ -555,8 +550,7 @@ async def update(
data: AchievementUpdateUnitMaxLevel,
achievement_info: achievement.Achievement,
) -> int:
# TODO: Query album
return oldvalue + len(data.unit_ids)
return await album.count_album_with(context, user, main.Album.rank_level_max_flag == True)

async def is_accomplished(
self, context: idol.BasicSchoolIdolContext, value: int, achievement_info: achievement.Achievement
Expand Down
44 changes: 3 additions & 41 deletions npps4/system/album.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import sqlalchemy

from . import achievement
from .. import idol
from ..db import main
from ..db import unit
Expand Down Expand Up @@ -47,7 +46,9 @@ async def all_series(context: idol.BasicSchoolIdolContext):
return {i.album_series_id: list() for i in result.scalars()}


async def count_album_with(context: idol.BasicSchoolIdolContext, user: main.User, *criteria):
async def count_album_with(
context: idol.BasicSchoolIdolContext, user: main.User, *criteria: sqlalchemy.ColumnElement[bool]
):
q = (
sqlalchemy.select(sqlalchemy.func.count())
.select_from(main.Album)
Expand All @@ -57,45 +58,6 @@ async def count_album_with(context: idol.BasicSchoolIdolContext, user: main.User
return qc.scalar() or 0


async def trigger_achievement(
context: idol.BasicSchoolIdolContext,
user: main.User,
*,
obtained: bool = False,
idolized: bool = False,
max_love: bool = False,
max_level: bool = False,
):
"""
Check for achievement type 18 through 21
"""

ach_ctx = achievement.AchievementContext()

if obtained:
count = await count_album_with(context, user)
result = await achievement.check_type_18(context, user, count)
ach_ctx.extend(result)

if idolized:
count = await count_album_with(context, user, main.Album.rank_max_flag == True)
result = await achievement.check_type_19(context, user, count)
ach_ctx.extend(result)

if max_love:
count = await count_album_with(context, user, main.Album.love_max_flag == True)
result = await achievement.check_type_20(context, user, count)
ach_ctx.extend(result)

if max_level:
count = await count_album_with(context, user, main.Album.rank_level_max_flag == True)
result = await achievement.check_type_21(context, user, count)
ach_ctx.extend(result)

ach_ctx.fix()
return ach_ctx


async def has_ever_got_unit(context: idol.BasicSchoolIdolContext, user: main.User, unit_id: int):
q = sqlalchemy.select(main.Album).where(main.Album.user_id == user.id, main.Album.unit_id == unit_id)
result = await context.db.main.execute(q)
Expand Down
Loading

0 comments on commit dcbf75e

Please sign in to comment.