From 4113b427070e3b6f264a0d8007b75d92aa9928aa Mon Sep 17 00:00:00 2001 From: KingRainbow44 Date: Wed, 31 May 2023 22:11:27 -0400 Subject: [PATCH] Fix issue with 35303 being un-completable & Try to fix fulfilled quest conditions being met --- .../data/binout/AbilityModifier.java | 3 ++ .../emu/grasscutter/game/ability/Ability.java | 13 ++++-- .../game/ability/AbilityManager.java | 17 ++++---- .../actions/ActionAvatarSkillStart.java | 17 ++++++++ .../actions/ActionCopyGlobalValue.java | 1 + .../ActionSetGlobalValueToOverrideMap.java | 1 + .../grasscutter/game/entity/EntityAvatar.java | 40 +++++++++++-------- .../grasscutter/game/entity/GameEntity.java | 35 +++++++--------- .../grasscutter/game/quest/GameMainQuest.java | 27 +++++-------- .../emu/grasscutter/game/quest/GameQuest.java | 33 ++++++++------- .../grasscutter/game/quest/QuestManager.java | 8 ++-- .../grasscutter/game/quest/QuestSystem.java | 4 +- 12 files changed, 112 insertions(+), 87 deletions(-) create mode 100644 src/main/java/emu/grasscutter/game/ability/actions/ActionAvatarSkillStart.java diff --git a/src/main/java/emu/grasscutter/data/binout/AbilityModifier.java b/src/main/java/emu/grasscutter/data/binout/AbilityModifier.java index 1df594c5e..14c4b8704 100644 --- a/src/main/java/emu/grasscutter/data/binout/AbilityModifier.java +++ b/src/main/java/emu/grasscutter/data/binout/AbilityModifier.java @@ -3,6 +3,8 @@ package emu.grasscutter.data.binout; import com.google.gson.annotations.SerializedName; import emu.grasscutter.data.common.DynamicFloat; import emu.grasscutter.game.props.ElementType; +import lombok.ToString; + import java.io.Serializable; public class AbilityModifier implements Serializable { @@ -43,6 +45,7 @@ public class AbilityModifier implements Serializable { public ElementType elementType; public DynamicFloat elementDurability = DynamicFloat.ZERO; + @ToString public static class AbilityModifierAction implements Serializable { public enum Type { ActCameraRadialBlur, diff --git a/src/main/java/emu/grasscutter/game/ability/Ability.java b/src/main/java/emu/grasscutter/game/ability/Ability.java index eb070119f..be292c7e2 100644 --- a/src/main/java/emu/grasscutter/game/ability/Ability.java +++ b/src/main/java/emu/grasscutter/game/ability/Ability.java @@ -6,12 +6,11 @@ import emu.grasscutter.game.entity.GameEntity; import emu.grasscutter.game.player.Player; import emu.grasscutter.net.proto.AbilityStringOuterClass.AbilityString; import emu.grasscutter.utils.Utils; -import it.unimi.dsi.fastutil.objects.Object2FloatMap; -import it.unimi.dsi.fastutil.objects.Object2FloatOpenHashMap; -import java.util.HashMap; -import java.util.Map; +import it.unimi.dsi.fastutil.objects.*; import lombok.Getter; +import java.util.*; + public class Ability { @Getter private AbilityData data; @Getter private GameEntity owner; @@ -54,4 +53,10 @@ public class Ability { return null; } + + @Override + public String toString() { + return "Ability Name: %s; Entity Owner: %s; Player Owner: %s".formatted( + data.abilityName, owner, playerOwner); + } } diff --git a/src/main/java/emu/grasscutter/game/ability/AbilityManager.java b/src/main/java/emu/grasscutter/game/ability/AbilityManager.java index f6c914d15..72f814c74 100644 --- a/src/main/java/emu/grasscutter/game/ability/AbilityManager.java +++ b/src/main/java/emu/grasscutter/game/ability/AbilityManager.java @@ -17,11 +17,12 @@ import emu.grasscutter.net.proto.AbilityScalarTypeOuterClass.AbilityScalarType; import emu.grasscutter.net.proto.AbilityScalarValueEntryOuterClass.AbilityScalarValueEntry; import emu.grasscutter.net.proto.ModifierActionOuterClass.ModifierAction; import io.netty.util.concurrent.FastThreadLocalThread; -import java.util.HashMap; -import java.util.concurrent.*; import lombok.Getter; import org.reflections.Reflections; +import java.util.HashMap; +import java.util.concurrent.*; + public final class AbilityManager extends BasePlayerManager { private static final HashMap actionHandlers = @@ -486,16 +487,18 @@ public final class AbilityManager extends BasePlayerManager { if (key.startsWith("SGV_")) return; // Server does not allow to change this variables I think switch (entry.getValueType().getNumber()) { - case AbilityScalarType.ABILITY_SCALAR_TYPE_FLOAT_VALUE: + case AbilityScalarType.ABILITY_SCALAR_TYPE_FLOAT_VALUE -> { if (!Float.isNaN(entry.getFloatValue())) entity.getGlobalAbilityValues().put(key, entry.getFloatValue()); - break; - case AbilityScalarType.ABILITY_SCALAR_TYPE_UINT_VALUE: + } + case AbilityScalarType.ABILITY_SCALAR_TYPE_UINT_VALUE -> entity.getGlobalAbilityValues().put(key, (float) entry.getUintValue()); - break; - default: + default -> { return; + } } + + entity.onAbilityValueUpdate(); } private void invokeAction( diff --git a/src/main/java/emu/grasscutter/game/ability/actions/ActionAvatarSkillStart.java b/src/main/java/emu/grasscutter/game/ability/actions/ActionAvatarSkillStart.java new file mode 100644 index 000000000..6899d2e09 --- /dev/null +++ b/src/main/java/emu/grasscutter/game/ability/actions/ActionAvatarSkillStart.java @@ -0,0 +1,17 @@ +package emu.grasscutter.game.ability.actions; + +import com.google.protobuf.ByteString; +import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction; +import emu.grasscutter.game.ability.Ability; +import emu.grasscutter.game.entity.GameEntity; + +@AbilityAction(AbilityModifierAction.Type.AvatarSkillStart) +public final class ActionAvatarSkillStart extends AbilityActionHandler { + @Override + public boolean execute( + Ability ability, AbilityModifierAction action, + ByteString abilityData, GameEntity target + ) { + return false; + } +} diff --git a/src/main/java/emu/grasscutter/game/ability/actions/ActionCopyGlobalValue.java b/src/main/java/emu/grasscutter/game/ability/actions/ActionCopyGlobalValue.java index f37ea7922..432086f21 100644 --- a/src/main/java/emu/grasscutter/game/ability/actions/ActionCopyGlobalValue.java +++ b/src/main/java/emu/grasscutter/game/ability/actions/ActionCopyGlobalValue.java @@ -29,6 +29,7 @@ public final class ActionCopyGlobalValue extends AbilityActionHandler { // Apply the new global value. destination.getGlobalAbilityValues().put(action.dstKey, value); + destination.onAbilityValueUpdate(); return true; } } diff --git a/src/main/java/emu/grasscutter/game/ability/actions/ActionSetGlobalValueToOverrideMap.java b/src/main/java/emu/grasscutter/game/ability/actions/ActionSetGlobalValueToOverrideMap.java index 7cdad06e7..f2982cade 100644 --- a/src/main/java/emu/grasscutter/game/ability/actions/ActionSetGlobalValueToOverrideMap.java +++ b/src/main/java/emu/grasscutter/game/ability/actions/ActionSetGlobalValueToOverrideMap.java @@ -31,6 +31,7 @@ public class ActionSetGlobalValueToOverrideMap extends AbilityActionHandler { } entity.getGlobalAbilityValues().put(globalValueKey, globalValue); + entity.onAbilityValueUpdate(); // TODO: ChangeServerGlobalValueNotify diff --git a/src/main/java/emu/grasscutter/game/entity/EntityAvatar.java b/src/main/java/emu/grasscutter/game/entity/EntityAvatar.java index f8844adba..d567ae378 100644 --- a/src/main/java/emu/grasscutter/game/entity/EntityAvatar.java +++ b/src/main/java/emu/grasscutter/game/entity/EntityAvatar.java @@ -1,19 +1,14 @@ package emu.grasscutter.game.entity; -import emu.grasscutter.GameConstants; -import emu.grasscutter.Grasscutter; +import emu.grasscutter.*; import emu.grasscutter.data.GameData; -import emu.grasscutter.data.excels.avatar.AvatarData; -import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData; +import emu.grasscutter.data.excels.avatar.*; import emu.grasscutter.game.avatar.Avatar; -import emu.grasscutter.game.inventory.EquipType; -import emu.grasscutter.game.inventory.GameItem; +import emu.grasscutter.game.inventory.*; import emu.grasscutter.game.player.Player; -import emu.grasscutter.game.props.EntityIdType; -import emu.grasscutter.game.props.FightProperty; -import emu.grasscutter.game.props.PlayerProperty; -import emu.grasscutter.game.world.Position; -import emu.grasscutter.game.world.Scene; +import emu.grasscutter.game.props.*; +import emu.grasscutter.game.quest.enums.*; +import emu.grasscutter.game.world.*; import emu.grasscutter.net.proto.AbilityControlBlockOuterClass.AbilityControlBlock; import emu.grasscutter.net.proto.AbilityEmbryoOuterClass.AbilityEmbryo; import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo; @@ -32,14 +27,11 @@ import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo; import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo; import emu.grasscutter.net.proto.VectorOuterClass.Vector; import emu.grasscutter.server.event.player.PlayerMoveEvent; -import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify; -import emu.grasscutter.server.packet.send.PacketEntityFightPropChangeReasonNotify; -import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; +import emu.grasscutter.server.packet.send.*; import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.helpers.ProtoHelper; import it.unimi.dsi.fastutil.ints.Int2FloatMap; -import lombok.Getter; -import lombok.val; +import lombok.*; public class EntityAvatar extends GameEntity { @Getter private final Avatar avatar; @@ -398,4 +390,20 @@ public class EntityAvatar extends GameEntity { // Set position and rotation. super.move(event.getDestination(), rotation); } + + @Override + public void onAbilityValueUpdate() { + super.onAbilityValueUpdate(); + + // TODO: Replace with a proper implementation/call. + // Check if the condition for 35303 is met. + if (this.getGlobalAbilityValues().containsKey("_ABILITY_UziExplode_Count")) { + var count = this.getGlobalAbilityValues().get("_ABILITY_UziExplode_Count"); + if (count == 2f) { + this.getGlobalAbilityValues().remove("_ABILITY_UziExplode_Count"); + this.getPlayer().getQuestManager() + .queueEvent(QuestContent.QUEST_CONTENT_SKILL, 10006); + } + } + } } diff --git a/src/main/java/emu/grasscutter/game/entity/GameEntity.java b/src/main/java/emu/grasscutter/game/entity/GameEntity.java index 480a0e7e7..5e66c6b91 100644 --- a/src/main/java/emu/grasscutter/game/entity/GameEntity.java +++ b/src/main/java/emu/grasscutter/game/entity/GameEntity.java @@ -1,15 +1,9 @@ package emu.grasscutter.game.entity; -import emu.grasscutter.game.ability.Ability; -import emu.grasscutter.game.ability.AbilityModifierController; +import emu.grasscutter.game.ability.*; import emu.grasscutter.game.player.Player; -import emu.grasscutter.game.props.ElementType; -import emu.grasscutter.game.props.FightProperty; -import emu.grasscutter.game.props.LifeState; -import emu.grasscutter.game.world.Position; -import emu.grasscutter.game.world.Scene; -import emu.grasscutter.game.world.SpawnDataEntry; -import emu.grasscutter.game.world.World; +import emu.grasscutter.game.props.*; +import emu.grasscutter.game.world.*; import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair; import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq; import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; @@ -17,18 +11,12 @@ import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState; import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo; import emu.grasscutter.net.proto.VectorOuterClass.Vector; import emu.grasscutter.scripts.data.controller.EntityController; -import emu.grasscutter.server.event.entity.EntityDamageEvent; -import emu.grasscutter.server.event.entity.EntityDeathEvent; +import emu.grasscutter.server.event.entity.*; import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; -import it.unimi.dsi.fastutil.ints.Int2FloatMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import lombok.Getter; -import lombok.Setter; +import it.unimi.dsi.fastutil.ints.*; +import lombok.*; + +import java.util.*; public abstract class GameEntity { @Getter private final Scene scene; @@ -268,5 +256,12 @@ public abstract class GameEntity { } } + /** + * Invoked when a global ability value is updated. + */ + public void onAbilityValueUpdate() { + // Does nothing. + } + public abstract SceneEntityInfo toProto(); } diff --git a/src/main/java/emu/grasscutter/game/quest/GameMainQuest.java b/src/main/java/emu/grasscutter/game/quest/GameMainQuest.java index 44cbceffd..f73fc7475 100644 --- a/src/main/java/emu/grasscutter/game/quest/GameMainQuest.java +++ b/src/main/java/emu/grasscutter/game/quest/GameMainQuest.java @@ -1,15 +1,10 @@ package emu.grasscutter.game.quest; -import dev.morphia.annotations.Entity; -import dev.morphia.annotations.Id; -import dev.morphia.annotations.Indexed; -import dev.morphia.annotations.Transient; +import dev.morphia.annotations.*; import emu.grasscutter.Grasscutter; import emu.grasscutter.data.GameData; -import emu.grasscutter.data.binout.MainQuestData; -import emu.grasscutter.data.binout.MainQuestData.SubQuestData; -import emu.grasscutter.data.binout.MainQuestData.TalkData; -import emu.grasscutter.data.binout.ScriptSceneData; +import emu.grasscutter.data.binout.*; +import emu.grasscutter.data.binout.MainQuestData.*; import emu.grasscutter.data.excels.RewardData; import emu.grasscutter.data.excels.quest.QuestData; import emu.grasscutter.database.DatabaseHelper; @@ -19,16 +14,13 @@ import emu.grasscutter.game.quest.enums.*; import emu.grasscutter.game.world.Position; import emu.grasscutter.net.proto.ChildQuestOuterClass.ChildQuest; import emu.grasscutter.net.proto.ParentQuestOuterClass.ParentQuest; -import emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify; -import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify; -import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify; -import emu.grasscutter.server.packet.send.PacketQuestUpdateQuestVarNotify; +import emu.grasscutter.server.packet.send.*; import emu.grasscutter.utils.ConversionUtils; +import lombok.*; +import org.bson.types.ObjectId; + import java.util.*; import java.util.stream.Collectors; -import lombok.Getter; -import lombok.val; -import org.bson.types.ObjectId; @Entity(value = "quests", useDiscriminator = false) public class GameMainQuest { @@ -377,7 +369,7 @@ public class GameMainQuest { public void checkProgress() { for (var quest : getChildQuests().values()) { if (quest.getState() == QuestState.QUEST_STATE_UNFINISHED) { - questManager.checkQuestAlreadyFullfilled(quest); + questManager.checkQuestAlreadyFulfilled(quest); } } } @@ -502,7 +494,8 @@ public class GameMainQuest { subQuestWithCond.getQuestData().getFinishCondComb(), subQuestWithCond.getFinishProgressList()); - if (this.getQuestManager().getLoggedQuests().contains(subQuestWithCond.getSubQuestId())) { + var questManager = this.getQuestManager(); + if (questManager != null && questManager.getLoggedQuests().contains(subQuestWithCond.getSubQuestId())) { Grasscutter.getLogger() .debug( ">>> Quest {} will be {} as a result of content trigger {} ({}, {}).", diff --git a/src/main/java/emu/grasscutter/game/quest/GameQuest.java b/src/main/java/emu/grasscutter/game/quest/GameQuest.java index c3e72e140..9db0cff9d 100644 --- a/src/main/java/emu/grasscutter/game/quest/GameQuest.java +++ b/src/main/java/emu/grasscutter/game/quest/GameQuest.java @@ -1,33 +1,24 @@ package emu.grasscutter.game.quest; -import dev.morphia.annotations.Entity; -import dev.morphia.annotations.Transient; +import dev.morphia.annotations.*; import emu.grasscutter.Grasscutter; import emu.grasscutter.data.GameData; -import emu.grasscutter.data.excels.ChapterData; -import emu.grasscutter.data.excels.TriggerExcelConfigData; +import emu.grasscutter.data.excels.*; import emu.grasscutter.data.excels.quest.QuestData; import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType; import emu.grasscutter.game.player.Player; import emu.grasscutter.game.props.ActionReason; -import emu.grasscutter.game.quest.enums.QuestCond; -import emu.grasscutter.game.quest.enums.QuestContent; -import emu.grasscutter.game.quest.enums.QuestState; +import emu.grasscutter.game.quest.enums.*; import emu.grasscutter.net.proto.ChapterStateOuterClass; import emu.grasscutter.net.proto.QuestOuterClass.Quest; import emu.grasscutter.scripts.data.SceneGroup; -import emu.grasscutter.server.packet.send.PacketChapterStateNotify; -import emu.grasscutter.server.packet.send.PacketDelQuestNotify; -import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify; +import emu.grasscutter.server.packet.send.*; import emu.grasscutter.utils.Utils; import it.unimi.dsi.fastutil.ints.IntIntImmutablePair; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import lombok.*; + import javax.script.Bindings; -import lombok.Getter; -import lombok.Setter; -import lombok.val; +import java.util.*; @Entity public class GameQuest { @@ -110,7 +101,7 @@ public class GameQuest { this.getQuestData() .getBeginExec() .forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam())); - this.getOwner().getQuestManager().checkQuestAlreadyFullfilled(this); + this.getOwner().getQuestManager().checkQuestAlreadyFulfilled(this); Grasscutter.getLogger().debug("Quest {} is started", subQuestId); this.save(); @@ -331,4 +322,12 @@ public class GameQuest { return proto.build(); } + + @Override + public String toString() { + return "Main Quest: %s; Sub Quest: %s; State: %s" + .formatted(this.getMainQuestId(), + this.getSubQuestId(), + this.getState()); + } } diff --git a/src/main/java/emu/grasscutter/game/quest/QuestManager.java b/src/main/java/emu/grasscutter/game/quest/QuestManager.java index a3f34185d..4132aee05 100644 --- a/src/main/java/emu/grasscutter/game/quest/QuestManager.java +++ b/src/main/java/emu/grasscutter/game/quest/QuestManager.java @@ -351,7 +351,7 @@ public class QuestManager extends BasePlayerManager { // Forcefully start quest.start(); // Check conditions. - this.checkQuestAlreadyFullfilled(quest); + this.checkQuestAlreadyFulfilled(quest); return quest; } @@ -462,8 +462,8 @@ public class QuestManager extends BasePlayerManager { * TODO move content checks to use static informations where possible to allow direct already fulfilled checking * @param quest The ID of the quest. */ - public void checkQuestAlreadyFullfilled(GameQuest quest){ - Grasscutter.getGameServer().getScheduler().scheduleDelayedTask(() -> { + public void checkQuestAlreadyFulfilled(GameQuest quest){ + Grasscutter.getThreadPool().submit(() -> { for (var condition : quest.getQuestData().getFinishCond()){ switch (condition.getType()) { case QUEST_CONTENT_OBTAIN_ITEM, QUEST_CONTENT_ITEM_LESS_THAN -> { @@ -486,7 +486,7 @@ public class QuestManager extends BasePlayerManager { case QUEST_CONTENT_PLAYER_LEVEL_UP -> queueEvent(condition.getType(), player.getLevel()); } } - }, 1); + }); } public List getSceneGroupSuite(int sceneId) { diff --git a/src/main/java/emu/grasscutter/game/quest/QuestSystem.java b/src/main/java/emu/grasscutter/game/quest/QuestSystem.java index f44b9b881..9ed8a7ca4 100644 --- a/src/main/java/emu/grasscutter/game/quest/QuestSystem.java +++ b/src/main/java/emu/grasscutter/game/quest/QuestSystem.java @@ -127,8 +127,8 @@ public class QuestSystem extends BaseGameSystem { if (!handler.execute(quest, execParam, params)) { Grasscutter.getLogger() .debug( - "exec trigger failed {} at {}", - execParam.getType().getValue(), + "Execute trigger failed for {} at {}.", + execParam.getType().name(), quest.getQuestData()); } });