Fix issue with 35303 being un-completable & Try to fix fulfilled quest conditions being met

This commit is contained in:
KingRainbow44 2023-05-31 22:11:27 -04:00
parent 73c23707b4
commit 4113b42707
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
12 changed files with 112 additions and 87 deletions

View File

@ -3,6 +3,8 @@ package emu.grasscutter.data.binout;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.common.DynamicFloat; import emu.grasscutter.data.common.DynamicFloat;
import emu.grasscutter.game.props.ElementType; import emu.grasscutter.game.props.ElementType;
import lombok.ToString;
import java.io.Serializable; import java.io.Serializable;
public class AbilityModifier implements Serializable { public class AbilityModifier implements Serializable {
@ -43,6 +45,7 @@ public class AbilityModifier implements Serializable {
public ElementType elementType; public ElementType elementType;
public DynamicFloat elementDurability = DynamicFloat.ZERO; public DynamicFloat elementDurability = DynamicFloat.ZERO;
@ToString
public static class AbilityModifierAction implements Serializable { public static class AbilityModifierAction implements Serializable {
public enum Type { public enum Type {
ActCameraRadialBlur, ActCameraRadialBlur,

View File

@ -6,12 +6,11 @@ import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.proto.AbilityStringOuterClass.AbilityString; import emu.grasscutter.net.proto.AbilityStringOuterClass.AbilityString;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.objects.Object2FloatMap; import it.unimi.dsi.fastutil.objects.*;
import it.unimi.dsi.fastutil.objects.Object2FloatOpenHashMap;
import java.util.HashMap;
import java.util.Map;
import lombok.Getter; import lombok.Getter;
import java.util.*;
public class Ability { public class Ability {
@Getter private AbilityData data; @Getter private AbilityData data;
@Getter private GameEntity owner; @Getter private GameEntity owner;
@ -54,4 +53,10 @@ public class Ability {
return null; return null;
} }
@Override
public String toString() {
return "Ability Name: %s; Entity Owner: %s; Player Owner: %s".formatted(
data.abilityName, owner, playerOwner);
}
} }

View File

@ -17,11 +17,12 @@ import emu.grasscutter.net.proto.AbilityScalarTypeOuterClass.AbilityScalarType;
import emu.grasscutter.net.proto.AbilityScalarValueEntryOuterClass.AbilityScalarValueEntry; import emu.grasscutter.net.proto.AbilityScalarValueEntryOuterClass.AbilityScalarValueEntry;
import emu.grasscutter.net.proto.ModifierActionOuterClass.ModifierAction; import emu.grasscutter.net.proto.ModifierActionOuterClass.ModifierAction;
import io.netty.util.concurrent.FastThreadLocalThread; import io.netty.util.concurrent.FastThreadLocalThread;
import java.util.HashMap;
import java.util.concurrent.*;
import lombok.Getter; import lombok.Getter;
import org.reflections.Reflections; import org.reflections.Reflections;
import java.util.HashMap;
import java.util.concurrent.*;
public final class AbilityManager extends BasePlayerManager { public final class AbilityManager extends BasePlayerManager {
private static final HashMap<AbilityModifierAction.Type, AbilityActionHandler> actionHandlers = private static final HashMap<AbilityModifierAction.Type, AbilityActionHandler> actionHandlers =
@ -486,18 +487,20 @@ public final class AbilityManager extends BasePlayerManager {
if (key.startsWith("SGV_")) return; // Server does not allow to change this variables I think if (key.startsWith("SGV_")) return; // Server does not allow to change this variables I think
switch (entry.getValueType().getNumber()) { switch (entry.getValueType().getNumber()) {
case AbilityScalarType.ABILITY_SCALAR_TYPE_FLOAT_VALUE: case AbilityScalarType.ABILITY_SCALAR_TYPE_FLOAT_VALUE -> {
if (!Float.isNaN(entry.getFloatValue())) if (!Float.isNaN(entry.getFloatValue()))
entity.getGlobalAbilityValues().put(key, 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()); entity.getGlobalAbilityValues().put(key, (float) entry.getUintValue());
break; default -> {
default:
return; return;
} }
} }
entity.onAbilityValueUpdate();
}
private void invokeAction( private void invokeAction(
AbilityModifierAction action, GameEntity target, GameEntity sourceEntity) {} AbilityModifierAction action, GameEntity target, GameEntity sourceEntity) {}

View File

@ -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;
}
}

View File

@ -29,6 +29,7 @@ public final class ActionCopyGlobalValue extends AbilityActionHandler {
// Apply the new global value. // Apply the new global value.
destination.getGlobalAbilityValues().put(action.dstKey, value); destination.getGlobalAbilityValues().put(action.dstKey, value);
destination.onAbilityValueUpdate();
return true; return true;
} }
} }

View File

@ -31,6 +31,7 @@ public class ActionSetGlobalValueToOverrideMap extends AbilityActionHandler {
} }
entity.getGlobalAbilityValues().put(globalValueKey, globalValue); entity.getGlobalAbilityValues().put(globalValueKey, globalValue);
entity.onAbilityValueUpdate();
// TODO: ChangeServerGlobalValueNotify // TODO: ChangeServerGlobalValueNotify

View File

@ -1,19 +1,14 @@
package emu.grasscutter.game.entity; package emu.grasscutter.game.entity;
import emu.grasscutter.GameConstants; import emu.grasscutter.*;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.avatar.AvatarData; import emu.grasscutter.data.excels.avatar.*;
import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.inventory.EquipType; import emu.grasscutter.game.inventory.*;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.EntityIdType; import emu.grasscutter.game.props.*;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.quest.enums.*;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.world.*;
import emu.grasscutter.game.world.Position;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.AbilityControlBlockOuterClass.AbilityControlBlock; import emu.grasscutter.net.proto.AbilityControlBlockOuterClass.AbilityControlBlock;
import emu.grasscutter.net.proto.AbilityEmbryoOuterClass.AbilityEmbryo; import emu.grasscutter.net.proto.AbilityEmbryoOuterClass.AbilityEmbryo;
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo; 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.SceneEntityInfoOuterClass.SceneEntityInfo;
import emu.grasscutter.net.proto.VectorOuterClass.Vector; import emu.grasscutter.net.proto.VectorOuterClass.Vector;
import emu.grasscutter.server.event.player.PlayerMoveEvent; import emu.grasscutter.server.event.player.PlayerMoveEvent;
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify; import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.server.packet.send.PacketEntityFightPropChangeReasonNotify;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import emu.grasscutter.utils.helpers.ProtoHelper; import emu.grasscutter.utils.helpers.ProtoHelper;
import it.unimi.dsi.fastutil.ints.Int2FloatMap; import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import lombok.Getter; import lombok.*;
import lombok.val;
public class EntityAvatar extends GameEntity { public class EntityAvatar extends GameEntity {
@Getter private final Avatar avatar; @Getter private final Avatar avatar;
@ -398,4 +390,20 @@ public class EntityAvatar extends GameEntity {
// Set position and rotation. // Set position and rotation.
super.move(event.getDestination(), 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);
}
}
}
} }

View File

@ -1,15 +1,9 @@
package emu.grasscutter.game.entity; package emu.grasscutter.game.entity;
import emu.grasscutter.game.ability.Ability; import emu.grasscutter.game.ability.*;
import emu.grasscutter.game.ability.AbilityModifierController;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ElementType; import emu.grasscutter.game.props.*;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.world.*;
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.net.proto.FightPropPairOuterClass.FightPropPair; import emu.grasscutter.net.proto.FightPropPairOuterClass.FightPropPair;
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq; import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo; 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.SceneEntityInfoOuterClass.SceneEntityInfo;
import emu.grasscutter.net.proto.VectorOuterClass.Vector; import emu.grasscutter.net.proto.VectorOuterClass.Vector;
import emu.grasscutter.scripts.data.controller.EntityController; import emu.grasscutter.scripts.data.controller.EntityController;
import emu.grasscutter.server.event.entity.EntityDamageEvent; import emu.grasscutter.server.event.entity.*;
import emu.grasscutter.server.event.entity.EntityDeathEvent;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import it.unimi.dsi.fastutil.ints.Int2FloatMap; import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import lombok.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
public abstract class GameEntity { public abstract class GameEntity {
@Getter private final Scene scene; @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(); public abstract SceneEntityInfo toProto();
} }

View File

@ -1,15 +1,10 @@
package emu.grasscutter.game.quest; package emu.grasscutter.game.quest;
import dev.morphia.annotations.Entity; import dev.morphia.annotations.*;
import dev.morphia.annotations.Id;
import dev.morphia.annotations.Indexed;
import dev.morphia.annotations.Transient;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.MainQuestData; import emu.grasscutter.data.binout.*;
import emu.grasscutter.data.binout.MainQuestData.SubQuestData; import emu.grasscutter.data.binout.MainQuestData.*;
import emu.grasscutter.data.binout.MainQuestData.TalkData;
import emu.grasscutter.data.binout.ScriptSceneData;
import emu.grasscutter.data.excels.RewardData; import emu.grasscutter.data.excels.RewardData;
import emu.grasscutter.data.excels.quest.QuestData; import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
@ -19,16 +14,13 @@ import emu.grasscutter.game.quest.enums.*;
import emu.grasscutter.game.world.Position; import emu.grasscutter.game.world.Position;
import emu.grasscutter.net.proto.ChildQuestOuterClass.ChildQuest; import emu.grasscutter.net.proto.ChildQuestOuterClass.ChildQuest;
import emu.grasscutter.net.proto.ParentQuestOuterClass.ParentQuest; import emu.grasscutter.net.proto.ParentQuestOuterClass.ParentQuest;
import emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify; import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify;
import emu.grasscutter.server.packet.send.PacketQuestUpdateQuestVarNotify;
import emu.grasscutter.utils.ConversionUtils; import emu.grasscutter.utils.ConversionUtils;
import lombok.*;
import org.bson.types.ObjectId;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.Getter;
import lombok.val;
import org.bson.types.ObjectId;
@Entity(value = "quests", useDiscriminator = false) @Entity(value = "quests", useDiscriminator = false)
public class GameMainQuest { public class GameMainQuest {
@ -377,7 +369,7 @@ public class GameMainQuest {
public void checkProgress() { public void checkProgress() {
for (var quest : getChildQuests().values()) { for (var quest : getChildQuests().values()) {
if (quest.getState() == QuestState.QUEST_STATE_UNFINISHED) { if (quest.getState() == QuestState.QUEST_STATE_UNFINISHED) {
questManager.checkQuestAlreadyFullfilled(quest); questManager.checkQuestAlreadyFulfilled(quest);
} }
} }
} }
@ -502,7 +494,8 @@ public class GameMainQuest {
subQuestWithCond.getQuestData().getFinishCondComb(), subQuestWithCond.getQuestData().getFinishCondComb(),
subQuestWithCond.getFinishProgressList()); subQuestWithCond.getFinishProgressList());
if (this.getQuestManager().getLoggedQuests().contains(subQuestWithCond.getSubQuestId())) { var questManager = this.getQuestManager();
if (questManager != null && questManager.getLoggedQuests().contains(subQuestWithCond.getSubQuestId())) {
Grasscutter.getLogger() Grasscutter.getLogger()
.debug( .debug(
">>> Quest {} will be {} as a result of content trigger {} ({}, {}).", ">>> Quest {} will be {} as a result of content trigger {} ({}, {}).",

View File

@ -1,33 +1,24 @@
package emu.grasscutter.game.quest; package emu.grasscutter.game.quest;
import dev.morphia.annotations.Entity; import dev.morphia.annotations.*;
import dev.morphia.annotations.Transient;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.ChapterData; import emu.grasscutter.data.excels.*;
import emu.grasscutter.data.excels.TriggerExcelConfigData;
import emu.grasscutter.data.excels.quest.QuestData; import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType; import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.quest.enums.QuestCond; import emu.grasscutter.game.quest.enums.*;
import emu.grasscutter.game.quest.enums.QuestContent;
import emu.grasscutter.game.quest.enums.QuestState;
import emu.grasscutter.net.proto.ChapterStateOuterClass; import emu.grasscutter.net.proto.ChapterStateOuterClass;
import emu.grasscutter.net.proto.QuestOuterClass.Quest; import emu.grasscutter.net.proto.QuestOuterClass.Quest;
import emu.grasscutter.scripts.data.SceneGroup; import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.server.packet.send.PacketChapterStateNotify; import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.server.packet.send.PacketDelQuestNotify;
import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.IntIntImmutablePair; import it.unimi.dsi.fastutil.ints.IntIntImmutablePair;
import java.util.HashMap; import lombok.*;
import java.util.List;
import java.util.Map;
import javax.script.Bindings; import javax.script.Bindings;
import lombok.Getter; import java.util.*;
import lombok.Setter;
import lombok.val;
@Entity @Entity
public class GameQuest { public class GameQuest {
@ -110,7 +101,7 @@ public class GameQuest {
this.getQuestData() this.getQuestData()
.getBeginExec() .getBeginExec()
.forEach(e -> getOwner().getServer().getQuestSystem().triggerExec(this, e, e.getParam())); .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); Grasscutter.getLogger().debug("Quest {} is started", subQuestId);
this.save(); this.save();
@ -331,4 +322,12 @@ public class GameQuest {
return proto.build(); return proto.build();
} }
@Override
public String toString() {
return "Main Quest: %s; Sub Quest: %s; State: %s"
.formatted(this.getMainQuestId(),
this.getSubQuestId(),
this.getState());
}
} }

View File

@ -351,7 +351,7 @@ public class QuestManager extends BasePlayerManager {
// Forcefully start // Forcefully start
quest.start(); quest.start();
// Check conditions. // Check conditions.
this.checkQuestAlreadyFullfilled(quest); this.checkQuestAlreadyFulfilled(quest);
return 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 * TODO move content checks to use static informations where possible to allow direct already fulfilled checking
* @param quest The ID of the quest. * @param quest The ID of the quest.
*/ */
public void checkQuestAlreadyFullfilled(GameQuest quest){ public void checkQuestAlreadyFulfilled(GameQuest quest){
Grasscutter.getGameServer().getScheduler().scheduleDelayedTask(() -> { Grasscutter.getThreadPool().submit(() -> {
for (var condition : quest.getQuestData().getFinishCond()){ for (var condition : quest.getQuestData().getFinishCond()){
switch (condition.getType()) { switch (condition.getType()) {
case QUEST_CONTENT_OBTAIN_ITEM, QUEST_CONTENT_ITEM_LESS_THAN -> { 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()); case QUEST_CONTENT_PLAYER_LEVEL_UP -> queueEvent(condition.getType(), player.getLevel());
} }
} }
}, 1); });
} }
public List<QuestGroupSuite> getSceneGroupSuite(int sceneId) { public List<QuestGroupSuite> getSceneGroupSuite(int sceneId) {

View File

@ -127,8 +127,8 @@ public class QuestSystem extends BaseGameSystem {
if (!handler.execute(quest, execParam, params)) { if (!handler.execute(quest, execParam, params)) {
Grasscutter.getLogger() Grasscutter.getLogger()
.debug( .debug(
"exec trigger failed {} at {}", "Execute trigger failed for {} at {}.",
execParam.getType().getValue(), execParam.getType().name(),
quest.getQuestData()); quest.getQuestData());
} }
}); });