Skip to content

Commit

Permalink
Fire mission progression events during story skip (#847)
Browse files Browse the repository at this point in the history
Closes #829. Ensure that we fire the corresponding mission events when
updating player state during the story skip process.

Also:
- Fix royal regimen displaying completed but unclaimed quests as active
- Minor naming nitpicks, micro-optimization of LINQ in StorySkipService
- Force braces for 1-line if statements after I read about `goto fail`

https://en.wikipedia.org/wiki/Unreachable_code#goto_fail_bug
  • Loading branch information
SapiensAnatis authored May 30, 2024
1 parent 16a102d commit a22b330
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ csharp_preferred_modifier_order = public,private,protected,internal,static,exter
csharp_style_prefer_readonly_struct = true

# Code-block preferences
csharp_prefer_braces = when_multiline:warning
csharp_prefer_braces = true:warning
csharp_prefer_simple_using_statement = true:warning
csharp_style_namespace_declarations = file_scoped:warning
csharp_style_prefer_method_group_conversion = true:warning
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using DragaliaAPI.Database.Entities;
using DragaliaAPI.Database.Utils;
using DragaliaAPI.Features.StorySkip;
using DragaliaAPI.Shared.Features.StorySkip;
using DragaliaAPI.Shared.MasterAsset.Models.Missions;
using Microsoft.EntityFrameworkCore;
using static DragaliaAPI.Shared.Features.StorySkip.StorySkipRewards;

Expand Down Expand Up @@ -57,6 +59,11 @@ await this
.ApiContext.PlayerFortBuilds.Where(x => x.ViewerId == this.ViewerId)
.ExecuteDeleteAsync();

await this.Client.PostMsgpack(
"mission/unlock_drill_mission_group",
new MissionUnlockDrillMissionGroupRequest(1)
);

StorySkipSkipResponse data = (
await this.Client.PostMsgpack<StorySkipSkipResponse>("story_skip/skip")
).Data;
Expand Down Expand Up @@ -98,5 +105,17 @@ await this.Client.PostMsgpack<StorySkipSkipResponse>("story_skip/skip")
fort.Level.Should().Be(fortConfig.Level);
}
}

int clearCh1Quest23Mission = 100200;
this.ApiContext.PlayerMissions.Should()
.Contain(x => x.Id == clearCh1Quest23Mission)
.Which.State.Should()
.Be(MissionState.Completed);

int upgradeHalidomToLv3Mission = 105500;
this.ApiContext.PlayerMissions.Should()
.Contain(x => x.Id == upgradeHalidomToLv3Mission)
.Which.State.Should()
.Be(MissionState.Completed);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ IEnumerable<int> newCompletedMissionList
{
DbPlayerMission? activeMission = allMissions
.OrderBy(x => x.Id)
.FirstOrDefault(x => x.State < MissionState.Claimed);
.FirstOrDefault(x => x.State < MissionState.Completed);

if (activeMission != null)
{
Expand Down
112 changes: 94 additions & 18 deletions DragaliaAPI/DragaliaAPI/Features/StorySkip/StorySkipService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
using DragaliaAPI.Database.Entities;
using DragaliaAPI.Database.Repositories;
using DragaliaAPI.Features.Fort;
using DragaliaAPI.Features.Missions;
using DragaliaAPI.Features.Story;
using DragaliaAPI.Shared.Definitions.Enums;
using DragaliaAPI.Shared.Features.StorySkip;
using DragaliaAPI.Shared.MasterAsset;
using DragaliaAPI.Shared.MasterAsset.Models;
using DragaliaAPI.Shared.MasterAsset.Models.Missions;
using DragaliaAPI.Shared.MasterAsset.Models.Story;
using Microsoft.EntityFrameworkCore;
using static DragaliaAPI.Shared.Features.StorySkip.StorySkipRewards;
Expand All @@ -20,17 +22,17 @@ public class StorySkipService(
ILogger<StorySkipService> logger,
IQuestRepository questRepository,
IStoryRepository storyRepository,
IUserDataRepository userDataRepository
IUserDataRepository userDataRepository,
IMissionProgressionService missionProgressionService,
FortDataService fortDataService
)
{
private static readonly FrozenSet<QuestData> questDatas = MasterAsset
.QuestData.Enumerable.Where(x =>
x.Gid < 10011 && x.Id > 100000000 && x.Id.ToString().Substring(6, 1) == "1"
)
private static readonly FrozenSet<QuestData> QuestDatas = MasterAsset
.QuestData.Enumerable.Where(x => x.Gid < 10011 && IsNormalModeQuest(x.Id))
.ToFrozenSet();

private static readonly FrozenSet<QuestStory> questStories = MasterAsset
.QuestStory.Enumerable.Where(x => x.GroupId is < 10011)
private static readonly FrozenSet<QuestStory> QuestStories = MasterAsset
.QuestStory.Enumerable.Where(x => x.GroupId < 10011)
.ToFrozenSet();

public async Task IncreaseFortLevels(long viewerId)
Expand All @@ -41,6 +43,8 @@ public async Task IncreaseFortLevels(long viewerId)
.Builds.Where(x => x.ViewerId == viewerId)
.ToListAsync();

int currentFortLevel = await fortDataService.GetTotalFortLevel();

List<DbFortBuild> newUserForts = new();

foreach ((FortPlants fortPlant, FortConfig fortConfig) in fortConfigs)
Expand All @@ -51,10 +55,24 @@ public async Task IncreaseFortLevels(long viewerId)
{
if (fortToUpdate.Level < fortConfig.Level)
{
currentFortLevel += fortConfig.Level - fortToUpdate.Level;

logger.LogDebug("Updating fort at BuildId {buildId}", fortToUpdate.BuildId);
fortToUpdate.Level = fortConfig.Level;
fortToUpdate.BuildStartDate = DateTimeOffset.UnixEpoch;
fortToUpdate.BuildEndDate = DateTimeOffset.UnixEpoch;

missionProgressionService.EnqueueEvent(
MissionCompleteType.FortPlantLevelUp,
total: fortConfig.Level,
parameter: (int)fortToUpdate.PlantId
);

missionProgressionService.EnqueueEvent(
MissionCompleteType.FortLevelUp,
1,
currentFortLevel
);
}
}

Expand All @@ -75,6 +93,27 @@ public async Task IncreaseFortLevels(long viewerId)
LastIncomeDate = DateTimeOffset.UnixEpoch
};
newUserForts.Add(newUserFort);

currentFortLevel += 1;

missionProgressionService.EnqueueEvent(
MissionCompleteType.FortPlantBuilt,
1,
fortsToUpdate.Count + 1,
(int)fortPlant
);

missionProgressionService.EnqueueEvent(
MissionCompleteType.FortPlantLevelUp,
total: fortConfig.Level,
parameter: (int)fortPlant
);

missionProgressionService.EnqueueEvent(
MissionCompleteType.FortLevelUp,
1,
currentFortLevel
);
}
}

Expand All @@ -93,7 +132,7 @@ public async Task<int> ProcessQuestCompletions(long viewerId)
.ToListAsync();

List<DbQuest> newUserQuests = new();
foreach (QuestData questData in questDatas)
foreach (QuestData questData in QuestDatas)
{
bool questExists = userQuests.Where(x => x.QuestId == questData.Id).Any();
if (questExists == false)
Expand All @@ -117,13 +156,32 @@ public async Task<int> ProcessQuestCompletions(long viewerId)
LastDailyResetTime = DateTimeOffset.UnixEpoch
};
newUserQuests.Add(userQuest);

missionProgressionService.OnQuestCleared(
questData.Id,
questData.Gid,
questData.QuestPlayModeType,
1,
1
);
}
else
{
DbQuest userQuest = userQuests.Where(x => x.QuestId == questData.Id).First();
bool isFirstClear = userQuest.State < 3;
if (isFirstClear)
{
wyrmite += 10;

missionProgressionService.OnQuestCleared(
questData.Id,
questData.Gid,
questData.QuestPlayModeType,
1,
1
);
}

if (!userQuest.IsMissionClear1)
{
userQuest.IsMissionClear1 = true;
Expand All @@ -142,7 +200,7 @@ public async Task<int> ProcessQuestCompletions(long viewerId)
wyrmite += 5;
}

if (userQuest.BestClearTime == -1)
if (userQuest.BestClearTime < 0)
{
userQuest.BestClearTime = 36000;
}
Expand Down Expand Up @@ -171,10 +229,13 @@ public async Task<int> ProcessStoryCompletions(long viewerId)
.ToListAsync();

List<DbPlayerStoryState> newUserStories = new();
foreach (QuestStory questStory in questStories)
foreach (QuestStory questStory in QuestStories)
{
bool storyExists = userStories.Where(x => x.StoryId == questStory.Id).Any();
if (storyExists == false)
DbPlayerStoryState? storyState = userStories.FirstOrDefault(x =>
x.StoryId == questStory.Id
);

if (storyState is null)
{
wyrmite += 25;
DbPlayerStoryState userStory =
Expand All @@ -186,6 +247,14 @@ public async Task<int> ProcessStoryCompletions(long viewerId)
State = StoryState.Read
};
newUserStories.Add(userStory);

missionProgressionService.OnQuestStoryCleared(questStory.Id);
}
else if (storyState.State != StoryState.Read)
{
storyState.State = StoryState.Read;

missionProgressionService.OnQuestStoryCleared(questStory.Id);
}
}

Expand Down Expand Up @@ -291,23 +360,30 @@ public async Task RewardDragons(long viewerId)

public async Task UpdateUserData(int wyrmite)
{
const int MaxLevel = 60;
const int MaxExp = 69990;
const int maxLevel = 60;
const int maxExp = 69990;
DbPlayerUserData data = await userDataRepository.GetUserDataAsync();
data.TutorialFlag = 16640603;
data.TutorialStatus = 60999;
data.StaminaSingle = 999;
data.StaminaMulti = 99;
data.Crystal += wyrmite;

if (data.Exp < MaxExp)
if (data.Exp < maxExp)
{
data.Exp = MaxExp;
data.Exp = maxExp;
}

if (data.Level < MaxLevel)
if (data.Level < maxLevel)
{
data.Level = MaxLevel;
data.Level = maxLevel;
}
}

private static bool IsNormalModeQuest(int questId)
{
// Select quest with a subgroup like 100010|107| instead of 100010|207| (the latter is hard mode)
int subgroup = questId % 1000;
return subgroup is > 100 and < 200;
}
}

0 comments on commit a22b330

Please sign in to comment.