Format code

This commit is contained in:
KingRainbow44
2023-04-02 21:34:07 -04:00
parent b03870ab48
commit a3970f8e43
104 changed files with 15623 additions and 15004 deletions

View File

@@ -105,7 +105,9 @@ public final class GameData {
private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataMap =
new Int2ObjectLinkedOpenHashMap<>();
@Getter private static final Int2ObjectMap<AvatarReplaceCostumeData> avatarReplaceCostumeDataMap = new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<AvatarReplaceCostumeData> avatarReplaceCostumeDataMap =
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap =
@@ -226,8 +228,12 @@ public final class GameData {
@Getter
private static final Int2ObjectMap<GatherData> gatherDataMap = new Int2ObjectOpenHashMap<>();
@Getter @Deprecated // This is to prevent people from using this map. This is for the resource loader only!
private static final Int2ObjectMap<GuideTriggerData> guideTriggerDataMap = new Int2ObjectOpenHashMap<>();
@Getter
@Deprecated // This is to prevent people from using this map. This is for the resource loader
// only!
private static final Int2ObjectMap<GuideTriggerData> guideTriggerDataMap =
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<HomeWorldBgmData> homeWorldBgmDataMap =
@@ -253,8 +259,10 @@ public final class GameData {
@Getter
private static final Int2ObjectMap<MonsterDescribeData> monsterDescribeDataMap =
new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<MonsterSpecialNameData> monsterSpecialNameDataMap =
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<MonsterSpecialNameData> monsterSpecialNameDataMap =
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<MusicGameBasicData> musicGameBasicDataMap =
@@ -412,8 +420,12 @@ public final class GameData {
@Getter private static final List<OpenStateData> openStateList = new ArrayList<>();
@Getter private static final Map<Integer, List<Integer>> scenePointsPerScene = new HashMap<>();
@Getter private static final Map<String, ScriptSceneData> scriptSceneDataMap = new HashMap<>();
@Getter private static final Map<String, GuideTriggerData> guideTriggerDataStringMap = new HashMap<>();
@Getter private static final Map<String, ConfigLevelEntity> configLevelEntityDataMap = new HashMap<>();
@Getter
private static final Map<String, GuideTriggerData> guideTriggerDataStringMap = new HashMap<>();
@Getter
private static final Map<String, ConfigLevelEntity> configLevelEntityDataMap = new HashMap<>();
@Getter
private static final Int2ObjectMap<IntSet> proudSkillGroupLevels = new Int2ObjectOpenHashMap<>();

View File

@@ -579,42 +579,52 @@ public class ResourceLoader {
}
}
private static void loadConfigData(){
private static void loadConfigData() {
loadConfigData(GameData.getAvatarConfigData(), "BinOutput/Avatar/", ConfigEntityAvatar.class);
loadConfigData(GameData.getMonsterConfigData(), "BinOutput/Monster/", ConfigEntityMonster.class);
loadConfigDataMap(GameData.getGadgetConfigData(), "BinOutput/Gadget/", ConfigEntityGadget.class);
loadConfigData(
GameData.getMonsterConfigData(), "BinOutput/Monster/", ConfigEntityMonster.class);
loadConfigDataMap(
GameData.getGadgetConfigData(), "BinOutput/Gadget/", ConfigEntityGadget.class);
}
private static <T extends ConfigEntityBase> void loadConfigData(Map<String,T> targetMap, String folderPath, Class<T> configClass) {
private static <T extends ConfigEntityBase> void loadConfigData(
Map<String, T> targetMap, String folderPath, Class<T> configClass) {
val className = configClass.getName();
try(val stream = Files.newDirectoryStream(getResourcePath(folderPath), "*.json")) {
stream.forEach(path -> {
try {
val name = path.getFileName().toString().replace(".json", "");
targetMap.put(name, JsonUtils.loadToClass(path, configClass));
} catch (Exception e) {
Grasscutter.getLogger().error("failed to load {} entries for {}", className, path.toString(), e);
}
});
try (val stream = Files.newDirectoryStream(getResourcePath(folderPath), "*.json")) {
stream.forEach(
path -> {
try {
val name = path.getFileName().toString().replace(".json", "");
targetMap.put(name, JsonUtils.loadToClass(path, configClass));
} catch (Exception e) {
Grasscutter.getLogger()
.error("failed to load {} entries for {}", className, path.toString(), e);
}
});
Grasscutter.getLogger().debug("Loaded {} {} entries.", GameData.getMonsterConfigData().size(), className);
Grasscutter.getLogger()
.debug("Loaded {} {} entries.", GameData.getMonsterConfigData().size(), className);
} catch (IOException e) {
Grasscutter.getLogger().error("Failed to load {} folder.", className);
}
}
private static <T extends ConfigEntityBase> void loadConfigDataMap(Map<String,T> targetMap, String folderPath, Class<T> configClass) {
private static <T extends ConfigEntityBase> void loadConfigDataMap(
Map<String, T> targetMap, String folderPath, Class<T> configClass) {
val className = configClass.getName();
try(val stream = Files.newDirectoryStream(getResourcePath(folderPath), "*.json")) {
stream.forEach(path -> {
try {
targetMap.putAll(JsonUtils.loadToMap(path, String.class, configClass));
} catch (Exception e) {
Grasscutter.getLogger().error("failed to load {} entries for {}", className, path.toString(), e);
}
});
try (val stream = Files.newDirectoryStream(getResourcePath(folderPath), "*.json")) {
stream.forEach(
path -> {
try {
targetMap.putAll(JsonUtils.loadToMap(path, String.class, configClass));
} catch (Exception e) {
Grasscutter.getLogger()
.error("failed to load {} entries for {}", className, path.toString(), e);
}
});
Grasscutter.getLogger().debug("Loaded {} {} entries.", GameData.getMonsterConfigData().size(), className);
Grasscutter.getLogger()
.debug("Loaded {} {} entries.", GameData.getMonsterConfigData().size(), className);
} catch (IOException e) {
Grasscutter.getLogger().error("Failed to load {} folder.", className);
}

View File

@@ -1,7 +1,6 @@
package emu.grasscutter.data.common;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.dungeon.DailyDungeonData;
@@ -19,17 +18,30 @@ public final class PointData {
@Getter private Position rot;
@Getter private Position size;
@SerializedName(value="dungeonIds", alternate={"JHHFPGJNMIN"})
@Getter private int[] dungeonIds;
@SerializedName(
value = "dungeonIds",
alternate = {"JHHFPGJNMIN"})
@Getter
private int[] dungeonIds;
@SerializedName(value="dungeonRandomList", alternate={"OIBKFJNBLHO"})
@Getter private int[] dungeonRandomList;
@SerializedName(
value = "dungeonRandomList",
alternate = {"OIBKFJNBLHO"})
@Getter
private int[] dungeonRandomList;
@SerializedName(value="groupIDs", alternate={"HFOBOOHKBGF"})
@Getter private int[] groupIDs;
@SerializedName(
value = "groupIDs",
alternate = {"HFOBOOHKBGF"})
@Getter
private int[] groupIDs;
@SerializedName(value="tranSceneId", alternate={"JHBICGBAPIH"})
@Getter @Setter private int tranSceneId;
@SerializedName(
value = "tranSceneId",
alternate = {"JHBICGBAPIH"})
@Getter
@Setter
private int tranSceneId;
public String getType() {
return $type;

View File

@@ -1,11 +1,6 @@
package emu.grasscutter.data.excels.monster;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
@@ -14,12 +9,27 @@ import emu.grasscutter.data.common.PropGrowCurve;
import emu.grasscutter.data.excels.GadgetData;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.MonsterType;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import lombok.Getter;
@ResourceType(name = "MonsterExcelConfigData.json", loadPriority = LoadPriority.LOW)
@Getter
public class MonsterData extends GameResource {
static public Set<FightProperty> definedFightProperties = Set.of(FightProperty.FIGHT_PROP_BASE_HP, FightProperty.FIGHT_PROP_BASE_ATTACK, FightProperty.FIGHT_PROP_BASE_DEFENSE, FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT, FightProperty.FIGHT_PROP_FIRE_SUB_HURT, FightProperty.FIGHT_PROP_ELEC_SUB_HURT, FightProperty.FIGHT_PROP_WATER_SUB_HURT, FightProperty.FIGHT_PROP_GRASS_SUB_HURT, FightProperty.FIGHT_PROP_WIND_SUB_HURT, FightProperty.FIGHT_PROP_ROCK_SUB_HURT, FightProperty.FIGHT_PROP_ICE_SUB_HURT);
public static Set<FightProperty> definedFightProperties =
Set.of(
FightProperty.FIGHT_PROP_BASE_HP,
FightProperty.FIGHT_PROP_BASE_ATTACK,
FightProperty.FIGHT_PROP_BASE_DEFENSE,
FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT,
FightProperty.FIGHT_PROP_FIRE_SUB_HURT,
FightProperty.FIGHT_PROP_ELEC_SUB_HURT,
FightProperty.FIGHT_PROP_WATER_SUB_HURT,
FightProperty.FIGHT_PROP_GRASS_SUB_HURT,
FightProperty.FIGHT_PROP_WIND_SUB_HURT,
FightProperty.FIGHT_PROP_ROCK_SUB_HURT,
FightProperty.FIGHT_PROP_ICE_SUB_HURT);
@Getter(onMethod_ = @Override)
private int id;
@@ -42,8 +52,10 @@ public class MonsterData extends GameResource {
@SerializedName("hpBase")
private float baseHp;
@SerializedName("attackBase")
private float baseAttack;
@SerializedName("defenseBase")
private float baseDefense;
@@ -84,11 +96,12 @@ public class MonsterData extends GameResource {
this.describeData = GameData.getMonsterDescribeDataMap().get(this.getDescribeId());
if (this.describeData == null){
if (this.describeData == null) {
return;
}
for(Entry<Integer, MonsterSpecialNameData> entry: GameData.getMonsterSpecialNameDataMap().entrySet()) {
if (entry.getValue().getSpecialNameLabId() == this.getDescribeData().getSpecialNameLabId()){
for (Entry<Integer, MonsterSpecialNameData> entry :
GameData.getMonsterSpecialNameDataMap().entrySet()) {
if (entry.getValue().getSpecialNameLabId() == this.getDescribeData().getSpecialNameLabId()) {
this.specialNameId = entry.getKey();
break;
}

View File

@@ -13,9 +13,16 @@ public class MonsterDescribeData extends GameResource {
private int id;
private long nameTextMapHash;
@SerializedName(value = "titleId", alternate={"titleID"})
@SerializedName(
value = "titleId",
alternate = {"titleID"})
private int titleId;
@SerializedName(value = "specialNameLabId", alternate={"specialNameLabID"})
@SerializedName(
value = "specialNameLabId",
alternate = {"specialNameLabID"})
private int specialNameLabId;
private MonsterSpecialNameData specialNameData;
}

View File

@@ -22,7 +22,6 @@ import emu.grasscutter.game.mail.Mail;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.world.SceneGroupInstance;
import java.util.List;
import java.util.stream.Stream;
@@ -457,8 +456,9 @@ public final class DatabaseHelper {
}
public static SceneGroupInstance loadGroupInstance(int groupId, Player owner) {
return DatabaseManager.getGameDatastore().find(SceneGroupInstance.class)
.filter(Filters.and(Filters.eq("ownerUid", owner.getUid()),
Filters.eq("groupId", groupId))).first();
return DatabaseManager.getGameDatastore()
.find(SceneGroupInstance.class)
.filter(Filters.and(Filters.eq("ownerUid", owner.getUid()), Filters.eq("groupId", groupId)))
.first();
}
}

View File

@@ -106,7 +106,7 @@ public class PlayerActivityData {
/**
* @return True when the progress of this watcher has reached the total progress.
*/
public boolean isFinished(){
public boolean isFinished() {
return this.curProgress >= this.totalProgress;
}

View File

@@ -43,14 +43,13 @@ import emu.grasscutter.utils.ProtoHelper;
import it.unimi.dsi.fastutil.ints.*;
import java.util.*;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.val;
import org.bson.types.ObjectId;
import javax.annotation.Nonnull;
@Entity(value = "avatars", useDiscriminator = false)
public class Avatar {
@Transient @Getter private final Int2ObjectMap<GameItem> equips;
@@ -237,8 +236,7 @@ public class Avatar {
}
/**
* Changes this avatar's skill depot.
* Does not notify the player of the change.
* Changes this avatar's skill depot. Does not notify the player of the change.
*
* @param skillDepot The new skill depot.
*/
@@ -250,7 +248,7 @@ public class Avatar {
* Changes this avatar's skill depot.
*
* @param skillDepot The new skill depot.
* @param notify Whether to notify the player of the change.
* @param notify Whether to notify the player of the change.
*/
public void setSkillDepotData(AvatarSkillDepotData skillDepot, boolean notify) {
// Set id and depot
@@ -275,7 +273,8 @@ public class Avatar {
}
/**
* Changes the avatar's element to the target element, if the character has values for it set in the candSkillDepot
* Changes the avatar's element to the target element, if the character has values for it set in
* the candSkillDepot
*
* @param elementTypeToChange element to change to
* @return false if failed or already using that element, true if it actually changed
@@ -285,8 +284,7 @@ public class Avatar {
var candSkillDepotIndex = elementTypeToChange.getDepotIndex();
// if no candidate skill to change or index out of bound
if (candSkillDepotIdsList == null ||
candSkillDepotIndex >= candSkillDepotIdsList.size()) {
if (candSkillDepotIdsList == null || candSkillDepotIndex >= candSkillDepotIdsList.size()) {
return false;
}

View File

@@ -6,10 +6,11 @@ import emu.grasscutter.server.packet.send.PacketDungeonSettleNotify;
public class BasicDungeonSettleListener implements DungeonSettleListener {
@Override
public void onDungeonSettle(DungeonManager dungeonManager, BaseDungeonResult.DungeonEndReason endReason) {
public void onDungeonSettle(
DungeonManager dungeonManager, BaseDungeonResult.DungeonEndReason endReason) {
var scene = dungeonManager.getScene();
var dungeonData = dungeonManager.getDungeonData();
var time = scene.getSceneTimeSeconds() - dungeonManager.getStartSceneTime() ;
var time = scene.getSceneTimeSeconds() - dungeonManager.getStartSceneTime();
// TODO time taken and chests handling
DungeonEndStats stats = new DungeonEndStats(scene.getKilledMonsterCount(), time, 0, endReason);

View File

@@ -24,20 +24,17 @@ import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
import lombok.Getter;
import lombok.NonNull;
import lombok.val;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* TODO handle time limits
* TODO handle respawn points
* TODO handle team wipes and respawns
* TODO check monster level and levelConfigMap
* TODO handle time limits TODO handle respawn points TODO handle team wipes and respawns TODO check
* monster level and levelConfigMap
*/
public final class DungeonManager {
@Getter private final Scene scene;
@@ -71,14 +68,12 @@ public final class DungeonManager {
if (getScene().getWorld().getServer().getDungeonSystem().triggerCondition(cond, params)) {
finishedConditions[i] = 1;
}
}
}
if (isFinishedSuccessfully()) {
finishDungeon();
}
}
public boolean isFinishedSuccessfully() {
@@ -86,7 +81,7 @@ public final class DungeonManager {
}
public int getLevelForMonster(int id) {
//TODO should use levelConfigMap? and how?
// TODO should use levelConfigMap? and how?
return dungeonData.getShowLevel();
}
@@ -98,15 +93,16 @@ public final class DungeonManager {
return false;
}
scene.broadcastPacket(new PacketDungeonWayPointNotify(activeDungeonWayPoints.add(pointId), activeDungeonWayPoints));
scene.broadcastPacket(
new PacketDungeonWayPointNotify(
activeDungeonWayPoints.add(pointId), activeDungeonWayPoints));
newestWayPoint = pointId;
Grasscutter.getLogger().debug("[unimplemented respawn] activated respawn point {}", pointId);
return true;
}
@Nullable
public Position getRespawnLocation() {
@Nullable public Position getRespawnLocation() {
if (newestWayPoint == 0) { // validity is checked before setting it, so if != 0 its always valid
return null;
}
@@ -123,7 +119,9 @@ public final class DungeonManager {
}
public boolean getStatueDrops(Player player, boolean useCondensed, int groupId) {
if (!isFinishedSuccessfully() || dungeonData.getRewardPreviewData() == null || dungeonData.getRewardPreviewData().getPreviewItems().length == 0) {
if (!isFinishedSuccessfully()
|| dungeonData.getRewardPreviewData() == null
|| dungeonData.getRewardPreviewData().getPreviewItems().length == 0) {
return false;
}
@@ -132,7 +130,6 @@ public final class DungeonManager {
return false;
}
if (!handleCost(player, useCondensed)) {
return false;
}
@@ -198,8 +195,10 @@ public final class DungeonManager {
// Roll items for this group.
// Here, we have to handle stacking, or the client will not display results correctly.
// For now, we use the following logic: If the possible drop item are a list of multiple items,
// we roll them separately. If not, we stack them. This should work out in practice, at least
// For now, we use the following logic: If the possible drop item are a list of multiple
// items,
// we roll them separately. If not, we stack them. This should work out in practice, at
// least
// for the currently existing set of dungeons.
if (entry.getItems().size() == 1) {
rewards.add(new GameItem(entry.getItems().get(0), amount));
@@ -207,7 +206,8 @@ public final class DungeonManager {
for (int i = 0; i < amount; i++) {
// int itemIndex = ThreadLocalRandom.current().nextInt(0, entry.getItems().size());
// int itemId = entry.getItems().get(itemIndex);
int itemId = Utils.drawRandomListElement(entry.getItems(), entry.getItemProbabilities());
int itemId =
Utils.drawRandomListElement(entry.getItems(), entry.getItemProbabilities());
rewards.add(new GameItem(itemId, 1));
}
}
@@ -215,7 +215,8 @@ public final class DungeonManager {
}
// Otherwise, we fall back to the preview data.
else {
Grasscutter.getLogger().info("No drop data found or dungeon {}, falling back to preview data ...", dungeonId);
Grasscutter.getLogger()
.info("No drop data found or dungeon {}, falling back to preview data ...", dungeonId);
for (ItemParamData param : dungeonData.getRewardPreviewData().getPreviewItems()) {
rewards.add(new GameItem(param.getId(), Math.max(param.getCount(), 1)));
}
@@ -228,14 +229,18 @@ public final class DungeonManager {
if (getDungeonData() == null) return;
switch (getDungeonData().getType()) {
// case DUNGEON_PLOT is handled by quest execs
// case DUNGEON_PLOT is handled by quest execs
case DUNGEON_ACTIVITY -> {
switch (getDungeonData().getPlayType()) {
case DUNGEON_PLAY_TYPE_TRIAL_AVATAR -> {
val activityHandler = player.getActivityManager()
.getActivityHandlerAs(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR, TrialAvatarActivityHandler.class);
activityHandler.ifPresent(trialAvatarActivityHandler ->
this.trialTeam = trialAvatarActivityHandler.getTrialAvatarDungeonTeam());
val activityHandler =
player
.getActivityManager()
.getActivityHandlerAs(
ActivityType.NEW_ACTIVITY_TRIAL_AVATAR, TrialAvatarActivityHandler.class);
activityHandler.ifPresent(
trialAvatarActivityHandler ->
this.trialTeam = trialAvatarActivityHandler.getTrialAvatarDungeonTeam());
}
}
}
@@ -247,7 +252,7 @@ public final class DungeonManager {
}
}
public void unsetTrialTeam(Player player){
public void unsetTrialTeam(Player player) {
if (this.trialTeam == null) return;
player.getTeamManager().removeTrialAvatar();
@@ -256,10 +261,14 @@ public final class DungeonManager {
public void startDungeon() {
this.startSceneTime = scene.getSceneTimeSeconds();
scene.getPlayers().forEach(p -> {
p.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_ENTER_DUNGEON, dungeonData.getId());
applyTrialTeam(p);
});
scene
.getPlayers()
.forEach(
p -> {
p.getQuestManager()
.queueEvent(QuestContent.QUEST_CONTENT_ENTER_DUNGEON, dungeonData.getId());
applyTrialTeam(p);
});
}
public void finishDungeon() {
@@ -268,18 +277,26 @@ public final class DungeonManager {
}
public void notifyEndDungeon(boolean successfully) {
scene.getPlayers().forEach(p -> {
// Quest trigger
p.getQuestManager().queueEvent(successfully ?
QuestContent.QUEST_CONTENT_FINISH_DUNGEON : QuestContent.QUEST_CONTENT_FAIL_DUNGEON,
dungeonData.getId());
scene
.getPlayers()
.forEach(
p -> {
// Quest trigger
p.getQuestManager()
.queueEvent(
successfully
? QuestContent.QUEST_CONTENT_FINISH_DUNGEON
: QuestContent.QUEST_CONTENT_FAIL_DUNGEON,
dungeonData.getId());
// Battle pass trigger
if (dungeonData.getType().isCountsToBattlepass() && successfully) {
p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_FINISH_DUNGEON);
}
});
scene.getScriptManager().callEvent(new ScriptArgs(0, EventType.EVENT_DUNGEON_SETTLE, successfully ? 1 : 0));
// Battle pass trigger
if (dungeonData.getType().isCountsToBattlepass() && successfully) {
p.getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_FINISH_DUNGEON);
}
});
scene
.getScriptManager()
.callEvent(new ScriptArgs(0, EventType.EVENT_DUNGEON_SETTLE, successfully ? 1 : 0));
}
public void quitDungeon() {

View File

@@ -16,13 +16,13 @@ import emu.grasscutter.server.packet.send.PacketDungeonEntryInfoRsp;
import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.List;
import lombok.val;
import org.reflections.Reflections;
import java.util.List;
public class DungeonSystem extends BaseGameSystem {
private static final BasicDungeonSettleListener basicDungeonSettleObserver = new BasicDungeonSettleListener();
private static final BasicDungeonSettleListener basicDungeonSettleObserver =
new BasicDungeonSettleListener();
private final Int2ObjectMap<DungeonBaseHandler> passCondHandlers;
public DungeonSystem(GameServer server) {
@@ -32,7 +32,10 @@ public class DungeonSystem extends BaseGameSystem {
}
public void registerHandlers() {
this.registerHandlers(this.passCondHandlers, "emu.grasscutter.game.dungeons.pass_condition", DungeonBaseHandler.class);
this.registerHandlers(
this.passCondHandlers,
"emu.grasscutter.game.dungeons.pass_condition",
DungeonBaseHandler.class);
}
public <T> void registerHandlers(Int2ObjectMap<T> map, String packageName, Class<T> clazz) {
@@ -70,11 +73,13 @@ public class DungeonSystem extends BaseGameSystem {
player.sendPacket(new PacketDungeonEntryInfoRsp(player, entry.getPointData()));
}
public boolean triggerCondition(DungeonPassConfigData.DungeonPassCondition condition, int... params) {
public boolean triggerCondition(
DungeonPassConfigData.DungeonPassCondition condition, int... params) {
var handler = passCondHandlers.get(condition.getCondType().ordinal());
if (handler == null) {
Grasscutter.getLogger().debug("Could not trigger condition {} at {}", condition.getCondType(), params);
Grasscutter.getLogger()
.debug("Could not trigger condition {} at {}", condition.getCondType(), params);
return false;
}
@@ -87,7 +92,12 @@ public class DungeonSystem extends BaseGameSystem {
if (data == null) {
return false;
}
Grasscutter.getLogger().info("{}({}) is trying to enter dungeon {}" ,player.getNickname(),player.getUid(),dungeonId);
Grasscutter.getLogger()
.info(
"{}({}) is trying to enter dungeon {}",
player.getNickname(),
player.getUid(),
dungeonId);
int sceneId = data.getSceneId();
var scene = player.getScene();
@@ -102,16 +112,20 @@ public class DungeonSystem extends BaseGameSystem {
return true;
}
/**
* used in tower dungeons handoff
*/
public boolean handoffDungeon(Player player, int dungeonId, List<DungeonSettleListener> dungeonSettleListeners) {
/** used in tower dungeons handoff */
public boolean handoffDungeon(
Player player, int dungeonId, List<DungeonSettleListener> dungeonSettleListeners) {
DungeonData data = GameData.getDungeonDataMap().get(dungeonId);
if (data == null) {
return false;
}
Grasscutter.getLogger().info("{}({}) is trying to enter tower dungeon {}" ,player.getNickname(),player.getUid(),dungeonId);
Grasscutter.getLogger()
.info(
"{}({}) is trying to enter tower dungeon {}",
player.getNickname(),
player.getUid(),
dungeonId);
if (player.getWorld().transferPlayerToScene(player, data.getSceneId(), data)) {
dungeonSettleListeners.forEach(player.getScene()::addDungeonSettleObserver);
@@ -122,7 +136,7 @@ public class DungeonSystem extends BaseGameSystem {
public void exitDungeon(Player player) {
Scene scene = player.getScene();
if (scene==null || scene.getSceneType() != SceneType.SCENE_DUNGEON) {
if (scene == null || scene.getSceneType() != SceneType.SCENE_DUNGEON) {
return;
}
@@ -131,7 +145,7 @@ public class DungeonSystem extends BaseGameSystem {
// Get previous position
val dungeonManager = scene.getDungeonManager();
DungeonData dungeonData = dungeonManager != null ? dungeonManager.getDungeonData() : null;
DungeonData dungeonData = dungeonManager != null ? dungeonManager.getDungeonData() : null;
Position prevPos = new Position(GameConstants.START_POSITION);
if (dungeonData != null) {
@@ -140,7 +154,7 @@ public class DungeonSystem extends BaseGameSystem {
if (entry != null) {
prevPos.set(entry.getPointData().getTranPos());
}
if(!dungeonManager.isFinishedSuccessfully()){
if (!dungeonManager.isFinishedSuccessfully()) {
dungeonManager.quitDungeon();
}
@@ -150,7 +164,6 @@ public class DungeonSystem extends BaseGameSystem {
player.getTeamManager().cleanTemporaryTeam();
player.getTowerManager().clearEntry();
// Transfer player back to world
player.getWorld().transferPlayerToScene(player, prevScene, prevPos);
}

View File

@@ -1,7 +1,6 @@
package emu.grasscutter.game.dungeons;
import emu.grasscutter.game.dungeons.dungeon_results.BaseDungeonResult.DungeonEndReason;
import emu.grasscutter.game.world.SceneGroupInstance;
import emu.grasscutter.game.dungeons.dungeon_results.TowerResult;
import emu.grasscutter.server.packet.send.PacketDungeonSettleNotify;
import emu.grasscutter.server.packet.send.PacketTowerFloorRecordChangeNotify;
@@ -12,27 +11,30 @@ public class TowerDungeonSettleListener implements DungeonSettleListener {
public void onDungeonSettle(DungeonManager dungeonManager, DungeonEndReason endReason) {
var scene = dungeonManager.getScene();
var dungeonData = dungeonManager.getDungeonData();
if (scene.getLoadedGroups().stream().anyMatch(g -> {
var variables = scene.getScriptManager().getVariables(g.id);
return variables != null && variables.containsKey("stage") && variables.get("stage") == 1;
})) {
if (scene.getLoadedGroups().stream()
.anyMatch(
g -> {
var variables = scene.getScriptManager().getVariables(g.id);
return variables != null
&& variables.containsKey("stage")
&& variables.get("stage") == 1;
})) {
return;
}
var towerManager = scene.getPlayers().get(0).getTowerManager();
towerManager.notifyCurLevelRecordChangeWhenDone(3);
scene.broadcastPacket(new PacketTowerFloorRecordChangeNotify(
towerManager.getCurrentFloorId(),
3,
towerManager.canEnterScheduleFloor()
));
scene.broadcastPacket(
new PacketTowerFloorRecordChangeNotify(
towerManager.getCurrentFloorId(), 3, towerManager.canEnterScheduleFloor()));
var challenge = scene.getChallenge();
var dungeonStats = new DungeonEndStats(scene.getKilledMonsterCount(), challenge.getFinishedTime(), 0, endReason);
var dungeonStats =
new DungeonEndStats(
scene.getKilledMonsterCount(), challenge.getFinishedTime(), 0, endReason);
var result = new TowerResult(dungeonData, dungeonStats, towerManager, challenge);
scene.broadcastPacket(new PacketDungeonSettleNotify(result));
}
}

View File

@@ -17,7 +17,6 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.Getter;
import lombok.Setter;
import lombok.val;
@Getter
@Setter
@@ -88,27 +87,40 @@ public class WorldChallenge {
var scene = this.getScene();
var dungeonManager = scene.getDungeonManager();
if (dungeonManager != null && dungeonManager.getDungeonData() != null) {
scene.getPlayers().forEach(p -> p.getActivityManager().triggerWatcher(
WatcherTriggerType.TRIGGER_FINISH_CHALLENGE,
String.valueOf(dungeonManager.getDungeonData().getId()),
String.valueOf(this.getGroup().id),
String.valueOf(this.getChallengeId())
));
scene
.getPlayers()
.forEach(
p ->
p.getActivityManager()
.triggerWatcher(
WatcherTriggerType.TRIGGER_FINISH_CHALLENGE,
String.valueOf(dungeonManager.getDungeonData().getId()),
String.valueOf(this.getGroup().id),
String.valueOf(this.getChallengeId())));
}
scene.getScriptManager().callEvent(
// TODO record the time in PARAM2 and used in action
new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_SUCCESS).setParam2(finishedTime));
this.getScene().triggerDungeonEvent(DungeonPassConditionType.DUNGEON_COND_FINISH_CHALLENGE, getChallengeId(), getChallengeIndex());
scene
.getScriptManager()
.callEvent(
// TODO record the time in PARAM2 and used in action
new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_SUCCESS)
.setParam2(finishedTime));
this.getScene()
.triggerDungeonEvent(
DungeonPassConditionType.DUNGEON_COND_FINISH_CHALLENGE,
getChallengeId(),
getChallengeIndex());
this.challengeTriggers.forEach(t -> t.onFinish(this));
}
public void fail(){
public void fail() {
if (!this.inProgress()) return;
this.finish(true);
this.getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_FAIL));
this.getScene()
.getScriptManager()
.callEvent(new ScriptArgs(this.getGroup().id, EventType.EVENT_CHALLENGE_FAIL));
challengeTriggers.forEach(t -> t.onFinish(this));
}
@@ -144,11 +156,10 @@ public class WorldChallenge {
}
public void onGroupTriggerDeath(SceneTrigger trigger) {
if(!this.inProgress()) return;
if (!this.inProgress()) return;
var triggerGroup = trigger.getCurrentGroup();
if (triggerGroup == null ||
triggerGroup.id != getGroup().id) {
if (triggerGroup == null || triggerGroup.id != getGroup().id) {
return;
}

View File

@@ -4,10 +4,9 @@ import emu.grasscutter.data.GameData;
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.data.SceneGroup;
import lombok.val;
import java.util.ArrayList;
import java.util.List;
import lombok.val;
public abstract class ChallengeFactory {
private static final List<ChallengeFactoryHandler> challengeFactoryHandlers = new ArrayList<>();
@@ -21,15 +20,24 @@ public abstract class ChallengeFactory {
challengeFactoryHandlers.add(new TriggerInTimeChallengeFactoryHandler());
}
public static WorldChallenge getChallenge(int localChallengeId, int challengeDataId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group){
public static WorldChallenge getChallenge(
int localChallengeId,
int challengeDataId,
int param3,
int param4,
int param5,
int param6,
Scene scene,
SceneGroup group) {
val challengeData = GameData.getDungeonChallengeConfigDataMap().get(challengeDataId);
val challengeType = challengeData.getChallengeType();
for(var handler : challengeFactoryHandlers){
if(!handler.isThisType(challengeType)){
for (var handler : challengeFactoryHandlers) {
if (!handler.isThisType(challengeType)) {
continue;
}
return handler.build(localChallengeId, challengeDataId, param3, param4, param5, param6, scene, group);
return handler.build(
localChallengeId, challengeDataId, param3, param4, param5, param6, scene, group);
}
return null;
}

View File

@@ -7,5 +7,14 @@ import emu.grasscutter.scripts.data.SceneGroup;
public interface ChallengeFactoryHandler {
boolean isThisType(ChallengeType challengeType);
WorldChallenge build(int challengeIndex, int challengeId, int param3, int param4, int param5, int param6, Scene scene, SceneGroup group);
WorldChallenge build(
int challengeIndex,
int challengeId,
int param3,
int param4,
int param5,
int param6,
Scene scene,
SceneGroup group);
}

View File

@@ -1,18 +1,17 @@
package emu.grasscutter.game.dungeons.challenge.factory;
import static emu.grasscutter.game.dungeons.challenge.enums.ChallengeType.CHALLENGE_KILL_COUNT_GUARD_HP;
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
import emu.grasscutter.game.dungeons.challenge.enums.ChallengeType;
import emu.grasscutter.game.dungeons.challenge.trigger.GuardTrigger;
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterCountTrigger;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.data.SceneGroup;
import java.util.List;
import lombok.val;
import java.util.List;
import static emu.grasscutter.game.dungeons.challenge.enums.ChallengeType.CHALLENGE_KILL_COUNT_GUARD_HP;
public class KillAndGuardChallengeFactoryHandler implements ChallengeFactoryHandler{
public class KillAndGuardChallengeFactoryHandler implements ChallengeFactoryHandler {
@Override
public boolean isThisType(ChallengeType challengeType) {
// ActiveChallenge with 1,188,234101003,12,3030,0
@@ -20,15 +19,24 @@ public class KillAndGuardChallengeFactoryHandler implements ChallengeFactoryHand
}
@Override /*TODO check param4 == monstesToKill*/
public WorldChallenge build(int challengeIndex, int challengeId, int groupId, int monstersToKill, int gadgetCFGId, int unused, Scene scene, SceneGroup group) {
public WorldChallenge build(
int challengeIndex,
int challengeId,
int groupId,
int monstersToKill,
int gadgetCFGId,
int unused,
Scene scene,
SceneGroup group) {
val realGroup = scene.getScriptManager().getGroupById(groupId);
return new WorldChallenge(
scene, realGroup,
scene,
realGroup,
challengeId, // Id
challengeIndex, // Index
List.of(monstersToKill, 0),
0, // Limit
monstersToKill, // Goal
monstersToKill, // Goal
List.of(new KillMonsterCountTrigger(), new GuardTrigger(gadgetCFGId)));
}
}

View File

@@ -5,11 +5,10 @@ import emu.grasscutter.game.dungeons.challenge.enums.ChallengeType;
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterCountTrigger;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.data.SceneGroup;
import java.util.List;
import lombok.val;
import java.util.List;
public class KillMonsterCountChallengeFactoryHandler implements ChallengeFactoryHandler{
public class KillMonsterCountChallengeFactoryHandler implements ChallengeFactoryHandler {
@Override
public boolean isThisType(ChallengeType challengeType) {
// ActiveChallenge with 1, 1, 241033003, 15, 0, 0
@@ -17,16 +16,24 @@ public class KillMonsterCountChallengeFactoryHandler implements ChallengeFactory
}
@Override
public WorldChallenge build(int challengeIndex, int challengeId, int groupId, int goal, int param5, int param6, Scene scene, SceneGroup group) {
public WorldChallenge build(
int challengeIndex,
int challengeId,
int groupId,
int goal,
int param5,
int param6,
Scene scene,
SceneGroup group) {
val realGroup = scene.getScriptManager().getGroupById(groupId);
return new WorldChallenge(
scene, realGroup,
scene,
realGroup,
challengeId, // Id
challengeIndex, // Index
List.of(goal, groupId),
0, // Limit
goal, // Goal
List.of(new KillMonsterCountTrigger())
);
goal, // Goal
List.of(new KillMonsterCountTrigger()));
}
}

View File

@@ -6,11 +6,10 @@ import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterTrigger;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.data.SceneGroup;
import java.util.List;
import lombok.val;
import java.util.List;
public class KillMonsterInTimeChallengeFactoryHandler implements ChallengeFactoryHandler{
public class KillMonsterInTimeChallengeFactoryHandler implements ChallengeFactoryHandler {
@Override
public boolean isThisType(ChallengeType challengeType) {
// ActiveChallenge with 180, 72, 240, 133220161, 133220161, 0
@@ -18,16 +17,24 @@ public class KillMonsterInTimeChallengeFactoryHandler implements ChallengeFactor
}
@Override
public WorldChallenge build(int challengeIndex, int challengeId, int timeLimit, int groupId, int targetCfgId, int param6, Scene scene, SceneGroup group) {
public WorldChallenge build(
int challengeIndex,
int challengeId,
int timeLimit,
int groupId,
int targetCfgId,
int param6,
Scene scene,
SceneGroup group) {
val realGroup = scene.getScriptManager().getGroupById(groupId);
return new WorldChallenge(
scene, realGroup,
challengeId, // Id
challengeIndex, // Index
List.of(timeLimit),
timeLimit, // Limit
0, // Goal
List.of(new KillMonsterTrigger(targetCfgId), new InTimeTrigger())
);
scene,
realGroup,
challengeId, // Id
challengeIndex, // Index
List.of(timeLimit),
timeLimit, // Limit
0, // Goal
List.of(new KillMonsterTrigger(targetCfgId), new InTimeTrigger()));
}
}

View File

@@ -6,30 +6,37 @@ import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
import emu.grasscutter.game.dungeons.challenge.trigger.KillMonsterCountTrigger;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.data.SceneGroup;
import java.util.List;
import lombok.val;
import java.util.List;
public class KillMonsterTimeChallengeFactoryHandler implements ChallengeFactoryHandler{
public class KillMonsterTimeChallengeFactoryHandler implements ChallengeFactoryHandler {
@Override
public boolean isThisType(ChallengeType challengeType) {
// ActiveChallenge with 180,180,45,133108061,1,0
// ActiveChallenge Fast with 1001, 5, 15, 240004005, 10, 0
return challengeType == ChallengeType.CHALLENGE_KILL_COUNT_IN_TIME ||
challengeType == ChallengeType.CHALLENGE_KILL_COUNT_FAST;
return challengeType == ChallengeType.CHALLENGE_KILL_COUNT_IN_TIME
|| challengeType == ChallengeType.CHALLENGE_KILL_COUNT_FAST;
}
@Override
public WorldChallenge build(int challengeIndex, int challengeId, int timeLimit, int groupId, int targetCount, int param6, Scene scene, SceneGroup group) {
public WorldChallenge build(
int challengeIndex,
int challengeId,
int timeLimit,
int groupId,
int targetCount,
int param6,
Scene scene,
SceneGroup group) {
val realGroup = scene.getScriptManager().getGroupById(groupId);
return new WorldChallenge(
scene, realGroup,
scene,
realGroup,
challengeId, // Id
challengeIndex, // Index
List.of(targetCount, timeLimit),
timeLimit, // Limit
targetCount, // Goal
List.of(new KillMonsterCountTrigger(), new InTimeTrigger())
);
targetCount, // Goal
List.of(new KillMonsterCountTrigger(), new InTimeTrigger()));
}
}

View File

@@ -1,15 +1,14 @@
package emu.grasscutter.game.dungeons.challenge.factory;
import static emu.grasscutter.game.dungeons.challenge.enums.ChallengeType.CHALLENGE_SURVIVE;
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
import emu.grasscutter.game.dungeons.challenge.enums.ChallengeType;
import emu.grasscutter.game.dungeons.challenge.trigger.ForTimeTrigger;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.data.SceneGroup;
import java.util.List;
import static emu.grasscutter.game.dungeons.challenge.enums.ChallengeType.CHALLENGE_SURVIVE;
public class SurviveChallengeFactoryHandler implements ChallengeFactoryHandler {
@Override
public boolean isThisType(ChallengeType challengeType) {
@@ -19,15 +18,23 @@ public class SurviveChallengeFactoryHandler implements ChallengeFactoryHandler {
}
@Override
public WorldChallenge build(int challengeIndex, int challengeId, int timeToSurvive, int unused4, int unused5, int unused6, Scene scene, SceneGroup group) {
public WorldChallenge build(
int challengeIndex,
int challengeId,
int timeToSurvive,
int unused4,
int unused5,
int unused6,
Scene scene,
SceneGroup group) {
return new WorldChallenge(
scene, group,
challengeId, // Id
challengeIndex, // Index
List.of(timeToSurvive),
timeToSurvive, // Limit
0, // Goal
List.of(new ForTimeTrigger())
);
scene,
group,
challengeId, // Id
challengeIndex, // Index
List.of(timeToSurvive),
timeToSurvive, // Limit
0, // Goal
List.of(new ForTimeTrigger()));
}
}

View File

@@ -1,16 +1,15 @@
package emu.grasscutter.game.dungeons.challenge.factory;
import static emu.grasscutter.game.dungeons.challenge.enums.ChallengeType.CHALLENGE_TRIGGER_IN_TIME;
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
import emu.grasscutter.game.dungeons.challenge.enums.ChallengeType;
import emu.grasscutter.game.dungeons.challenge.trigger.InTimeTrigger;
import emu.grasscutter.game.dungeons.challenge.trigger.TriggerGroupTriggerTrigger;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.scripts.data.SceneGroup;
import java.util.List;
import static emu.grasscutter.game.dungeons.challenge.enums.ChallengeType.CHALLENGE_TRIGGER_IN_TIME;
public class TriggerInTimeChallengeFactoryHandler implements ChallengeFactoryHandler {
@Override
public boolean isThisType(ChallengeType challengeType) {
@@ -22,15 +21,23 @@ public class TriggerInTimeChallengeFactoryHandler implements ChallengeFactoryHan
}
@Override
public WorldChallenge build(int challengeIndex, int challengeId, int timeLimit, int param4, int triggerTag, int triggerCount, Scene scene, SceneGroup group) {
public WorldChallenge build(
int challengeIndex,
int challengeId,
int timeLimit,
int param4,
int triggerTag,
int triggerCount,
Scene scene,
SceneGroup group) {
return new WorldChallenge(
scene, group,
scene,
group,
challengeId, // Id
challengeIndex, // Index
List.of(timeLimit, triggerCount),
timeLimit, // Limit
triggerCount, // Goal
List.of(new InTimeTrigger(), new TriggerGroupTriggerTrigger(Integer.toString(triggerTag)))
);
triggerCount, // Goal
List.of(new InTimeTrigger(), new TriggerGroupTriggerTrigger(Integer.toString(triggerTag))));
}
}

View File

@@ -6,11 +6,17 @@ import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.scripts.data.SceneTrigger;
public abstract class ChallengeTrigger {
public void onBegin(WorldChallenge challenge) { }
public void onFinish(WorldChallenge challenge) { }
public void onMonsterDeath(WorldChallenge challenge, EntityMonster monster) { }
public void onGadgetDeath(WorldChallenge challenge, EntityGadget gadget) { }
public void onCheckTimeout(WorldChallenge challenge) { }
public void onGadgetDamage(WorldChallenge challenge, EntityGadget gadget) { }
public void onGroupTrigger(WorldChallenge challenge, SceneTrigger trigger) { }
public void onBegin(WorldChallenge challenge) {}
public void onFinish(WorldChallenge challenge) {}
public void onMonsterDeath(WorldChallenge challenge, EntityMonster monster) {}
public void onGadgetDeath(WorldChallenge challenge, EntityGadget gadget) {}
public void onCheckTimeout(WorldChallenge challenge) {}
public void onGadgetDamage(WorldChallenge challenge, EntityGadget gadget) {}
public void onGroupTrigger(WorldChallenge challenge, SceneTrigger trigger) {}
}

View File

@@ -2,14 +2,14 @@ package emu.grasscutter.game.dungeons.challenge.trigger;
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
import emu.grasscutter.game.entity.EntityGadget;
import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
public class GuardTrigger extends ChallengeTrigger {
private final int entityToProtectCFGId;
private int lastSendPercent = 100;
public GuardTrigger(int entityToProtectCFGId){
public GuardTrigger(int entityToProtectCFGId) {
this.entityToProtectCFGId = entityToProtectCFGId;
}
@@ -19,19 +19,19 @@ public class GuardTrigger extends ChallengeTrigger {
@Override
public void onGadgetDamage(WorldChallenge challenge, EntityGadget gadget) {
if(gadget.getConfigId() != entityToProtectCFGId){
if (gadget.getConfigId() != entityToProtectCFGId) {
return;
}
var curHp = gadget.getFightProperties().get(FightProperty.FIGHT_PROP_CUR_HP.getId());
var maxHp = gadget.getFightProperties().get(FightProperty.FIGHT_PROP_BASE_HP.getId());
int percent = (int) (curHp / maxHp);
if(percent!=lastSendPercent) {
if (percent != lastSendPercent) {
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 2, percent));
lastSendPercent = percent;
}
if(percent <= 0){
if (percent <= 0) {
challenge.fail();
}
}

View File

@@ -6,16 +6,19 @@ import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class KillMonsterTrigger extends ChallengeTrigger{
public class KillMonsterTrigger extends ChallengeTrigger {
private int monsterCfgId;
@Override
public void onBegin(WorldChallenge challenge) {
challenge.getScene().broadcastPacket(new PacketChallengeDataNotify(challenge, 1, challenge.getScore().get()));
challenge
.getScene()
.broadcastPacket(new PacketChallengeDataNotify(challenge, 1, challenge.getScore().get()));
}
@Override
public void onMonsterDeath(WorldChallenge challenge, EntityMonster monster) {
if(monster.getConfigId() == monsterCfgId){
if (monster.getConfigId() == monsterCfgId) {
challenge.done();
}
}

View File

@@ -37,19 +37,21 @@ import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.ProtoHelper;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
@ToString(callSuper = true)
public class EntityGadget extends EntityBaseGadget {
@Getter private final GadgetData gadgetData;
@Getter(onMethod = @__(@Override)) @Setter
@Getter(onMethod = @__(@Override))
@Setter
private int gadgetId;
@Getter private final Position bornPos;
@Getter private final Position bornRot;
@Getter @Setter private GameEntity owner = null;
@@ -58,18 +60,18 @@ public class EntityGadget extends EntityBaseGadget {
@Getter private int state;
@Getter @Setter private int pointType;
@Getter private GadgetContent content;
@Getter(onMethod = @__(@Override), lazy = true)
private final Int2FloatMap fightProperties = new Int2FloatOpenHashMap();
@Getter @Setter private SceneGadget metaGadget;
@Nullable @Getter
private ConfigEntityGadget configGadget;
@Nullable @Getter private ConfigEntityGadget configGadget;
@Getter @Setter private BaseRoute routeConfig;
@Getter @Setter private int stopValue = 0; //Controller related, inited to zero
@Getter @Setter private int startValue = 0; //Controller related, inited to zero
@Getter @Setter private int stopValue = 0; // Controller related, inited to zero
@Getter @Setter private int startValue = 0; // Controller related, inited to zero
@Getter @Setter private int ticksSinceChange;
public EntityGadget(Scene scene, int gadgetId, Position pos) {
this(scene, gadgetId, pos, null, null);
}
@@ -78,7 +80,8 @@ public class EntityGadget extends EntityBaseGadget {
this(scene, gadgetId, pos, rot, null);
}
public EntityGadget(Scene scene, int gadgetId, Position pos, Position rot, GadgetContent content) {
public EntityGadget(
Scene scene, int gadgetId, Position pos, Position rot, GadgetContent content) {
super(scene, pos, rot);
this.gadgetData = GameData.getGadgetDataMap().get(gadgetId);
@@ -93,7 +96,7 @@ public class EntityGadget extends EntityBaseGadget {
this.bornRot = this.getRotation().clone();
this.fillFightProps(configGadget);
if(GameData.getGadgetMappingMap().containsKey(gadgetId)) {
if (GameData.getGadgetMappingMap().containsKey(gadgetId)) {
String controllerName = GameData.getGadgetMappingMap().get(gadgetId).getServerController();
this.setEntityController(EntityControllerScriptManager.getGadgetController(controllerName));
}
@@ -101,20 +104,24 @@ public class EntityGadget extends EntityBaseGadget {
public void setState(int state) {
this.state = state;
//Cache the gadget state
if(metaGadget != null && metaGadget.group != null) {
// Cache the gadget state
if (metaGadget != null && metaGadget.group != null) {
var instance = getScene().getScriptManager().getCachedGroupInstanceById(metaGadget.group.id);
if(instance != null) instance.cacheGadgetState(metaGadget, state);
if (instance != null) instance.cacheGadgetState(metaGadget, state);
}
}
public void updateState(int state) {
if(state == this.getState()) return; //Don't triggers events
if (state == this.getState()) return; // Don't triggers events
this.setState(state);
ticksSinceChange = getScene().getSceneTimeSeconds();
this.getScene().broadcastPacket(new PacketGadgetStateNotify(this, state));
getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EventType.EVENT_GADGET_STATE_CHANGE, state, this.getConfigId()));
getScene()
.getScriptManager()
.callEvent(
new ScriptArgs(
this.getGroupId(), EventType.EVENT_GADGET_STATE_CHANGE, state, this.getConfigId()));
}
@Deprecated(forRemoval = true) // Dont use!
@@ -124,19 +131,22 @@ public class EntityGadget extends EntityBaseGadget {
// TODO refactor
public void buildContent() {
if (this.getContent() != null || this.getGadgetData() == null || this.getGadgetData().getType() == null) {
if (this.getContent() != null
|| this.getGadgetData() == null
|| this.getGadgetData().getType() == null) {
return;
}
this.content = switch (this.getGadgetData().getType()) {
case GatherPoint -> new GadgetGatherPoint(this);
case GatherObject -> new GadgetGatherObject(this);
case Worktop, SealGadget -> new GadgetWorktop(this);
case RewardStatue -> new GadgetRewardStatue(this);
case Chest -> new GadgetChest(this);
case Gadget -> new GadgetObject(this);
default -> null;
};
this.content =
switch (this.getGadgetData().getType()) {
case GatherPoint -> new GadgetGatherPoint(this);
case GatherObject -> new GadgetGatherObject(this);
case Worktop, SealGadget -> new GadgetWorktop(this);
case RewardStatue -> new GadgetRewardStatue(this);
case Chest -> new GadgetChest(this);
case Gadget -> new GadgetObject(this);
default -> null;
};
}
@Override
@@ -155,13 +165,16 @@ public class EntityGadget extends EntityBaseGadget {
@Override
public void onCreate() {
// Lua event
getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EventType.EVENT_GADGET_CREATE, this.getConfigId()));
getScene()
.getScriptManager()
.callEvent(
new ScriptArgs(this.getGroupId(), EventType.EVENT_GADGET_CREATE, this.getConfigId()));
}
@Override
public void onRemoved() {
super.onRemoved();
if(!children.isEmpty()) {
if (!children.isEmpty()) {
getScene().removeEntities(children, VisionTypeOuterClass.VisionType.VISION_TYPE_REMOVE);
children.clear();
}
@@ -177,19 +190,23 @@ public class EntityGadget extends EntityBaseGadget {
if (getScene().getChallenge() != null) {
getScene().getChallenge().onGadgetDeath(this);
}
getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EventType.EVENT_ANY_GADGET_DIE, this.getConfigId()));
getScene()
.getScriptManager()
.callEvent(
new ScriptArgs(this.getGroupId(), EventType.EVENT_ANY_GADGET_DIE, this.getConfigId()));
SceneGroupInstance groupInstance = getScene().getScriptManager().getCachedGroupInstanceById(this.getGroupId());
if(groupInstance != null && metaGadget != null)
SceneGroupInstance groupInstance =
getScene().getScriptManager().getCachedGroupInstanceById(this.getGroupId());
if (groupInstance != null && metaGadget != null)
groupInstance.getDeadEntities().add(metaGadget.config_id);
}
public boolean startPlatform(){
if(routeConfig == null){
public boolean startPlatform() {
if (routeConfig == null) {
return false;
}
if(routeConfig.isStarted()){
if (routeConfig.isStarted()) {
return true;
}
getScene().broadcastPacket(new PacketSceneTimeNotify(getScene()));
@@ -199,12 +216,12 @@ public class EntityGadget extends EntityBaseGadget {
return true;
}
public boolean stopPlatform(){
if(routeConfig == null){
public boolean stopPlatform() {
if (routeConfig == null) {
return false;
}
if(!routeConfig.isStarted()){
if (!routeConfig.isStarted()) {
return true;
}
routeConfig.stopRoute(getScene());
@@ -215,46 +232,56 @@ public class EntityGadget extends EntityBaseGadget {
@Override
public SceneEntityInfo toProto() {
EntityAuthorityInfo authority = EntityAuthorityInfo.newBuilder()
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
.setAiInfo(SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(bornPos.toProto()))
.setBornPos(bornPos.toProto())
.build();
EntityAuthorityInfo authority =
EntityAuthorityInfo.newBuilder()
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
.setAiInfo(
SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(bornPos.toProto()))
.setBornPos(bornPos.toProto())
.build();
SceneEntityInfo.Builder entityInfo = SceneEntityInfo.newBuilder()
.setEntityId(getId())
.setEntityType(ProtEntityType.PROT_ENTITY_TYPE_GADGET)
.setMotionInfo(MotionInfo.newBuilder().setPos(getPosition().toProto()).setRot(getRotation().toProto()).setSpeed(Vector.newBuilder()))
.addAnimatorParaList(AnimatorParameterValueInfoPair.newBuilder())
.setEntityClientData(EntityClientData.newBuilder())
.setEntityAuthorityInfo(authority)
.setLifeState(1);
SceneEntityInfo.Builder entityInfo =
SceneEntityInfo.newBuilder()
.setEntityId(getId())
.setEntityType(ProtEntityType.PROT_ENTITY_TYPE_GADGET)
.setMotionInfo(
MotionInfo.newBuilder()
.setPos(getPosition().toProto())
.setRot(getRotation().toProto())
.setSpeed(Vector.newBuilder()))
.addAnimatorParaList(AnimatorParameterValueInfoPair.newBuilder())
.setEntityClientData(EntityClientData.newBuilder())
.setEntityAuthorityInfo(authority)
.setLifeState(1);
PropPair pair = PropPair.newBuilder()
.setType(PlayerProperty.PROP_LEVEL.getId())
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, 1))
.build();
PropPair pair =
PropPair.newBuilder()
.setType(PlayerProperty.PROP_LEVEL.getId())
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, 1))
.build();
entityInfo.addPropList(pair);
// We do not use the getter to null check because the getter will create a fight prop map if it is null
// We do not use the getter to null check because the getter will create a fight prop map if it
// is null
if (this.fightProperties != null) {
addAllFightPropsToEntityInfo(entityInfo);
}
SceneGadgetInfo.Builder gadgetInfo = SceneGadgetInfo.newBuilder()
.setGadgetId(this.getGadgetId())
.setGroupId(this.getGroupId())
.setConfigId(this.getConfigId())
.setGadgetState(this.getState())
.setIsEnableInteract(true)
.setAuthorityPeerId(this.getScene().getWorld().getHostPeerId());
SceneGadgetInfo.Builder gadgetInfo =
SceneGadgetInfo.newBuilder()
.setGadgetId(this.getGadgetId())
.setGroupId(this.getGroupId())
.setConfigId(this.getConfigId())
.setGadgetState(this.getState())
.setIsEnableInteract(true)
.setAuthorityPeerId(this.getScene().getWorld().getHostPeerId());
if (this.metaGadget != null) {
gadgetInfo.setDraftId(this.metaGadget.draft_id);
}
if(owner != null){
if (owner != null) {
gadgetInfo.setOwnerEntityId(owner.getId());
}
@@ -262,7 +289,7 @@ public class EntityGadget extends EntityBaseGadget {
this.getContent().onBuildProto(gadgetInfo);
}
if(routeConfig!=null){
if (routeConfig != null) {
gadgetInfo.setPlatform(getPlatformInfo());
}
@@ -271,8 +298,8 @@ public class EntityGadget extends EntityBaseGadget {
return entityInfo.build();
}
public PlatformInfoOuterClass.PlatformInfo.Builder getPlatformInfo(){
if(routeConfig != null){
public PlatformInfoOuterClass.PlatformInfo.Builder getPlatformInfo() {
if (routeConfig != null) {
return routeConfig.toProto();
}

View File

@@ -11,20 +11,23 @@ public class EntitySolarIsotomaClientGadget extends EntityClientGadget {
public static final int ELEVATOR_GADGET_ID = 41038002;
@Getter private EntityGadget platformGadget;
public EntitySolarIsotomaClientGadget(Scene scene, Player player, EvtCreateGadgetNotifyOuterClass.EvtCreateGadgetNotify notify) {
public EntitySolarIsotomaClientGadget(
Scene scene, Player player, EvtCreateGadgetNotifyOuterClass.EvtCreateGadgetNotify notify) {
super(scene, player, notify);
}
@Override
public void onCreate() {
//Create solar isotoma elevator and send to all.
this.platformGadget = new EntitySolarIsotomaElevatorPlatform(this, getScene(), ELEVATOR_GADGET_ID, getPosition(), getRotation());
// Create solar isotoma elevator and send to all.
this.platformGadget =
new EntitySolarIsotomaElevatorPlatform(
this, getScene(), ELEVATOR_GADGET_ID, getPosition(), getRotation());
getScene().addEntity(this.platformGadget);
}
@Override
public void onRemoved() {
//Remove solar isotoma elevator entity.
// Remove solar isotoma elevator entity.
getScene().removeEntity(this.platformGadget);
}
}

View File

@@ -25,16 +25,16 @@ import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.ProtoHelper;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
import lombok.Getter;
import lombok.Setter;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import lombok.Getter;
import lombok.Setter;
public class EntityVehicle extends EntityBaseGadget {
@Getter private final Player owner;
@Getter(onMethod = @__(@Override))
private final Int2FloatMap fightProperties;
@@ -45,7 +45,8 @@ public class EntityVehicle extends EntityBaseGadget {
@Getter private final List<VehicleMember> vehicleMembers;
@Nullable @Getter private ConfigEntityGadget configGadget;
public EntityVehicle(Scene scene, Player player, int gadgetId, int pointId, Position pos, Position rot) {
public EntityVehicle(
Scene scene, Player player, int gadgetId, int pointId, Position pos, Position rot) {
super(scene, pos, rot);
this.owner = player;
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
@@ -72,37 +73,49 @@ public class EntityVehicle extends EntityBaseGadget {
@Override
public SceneEntityInfo toProto() {
VehicleInfo vehicle = VehicleInfo.newBuilder()
.setOwnerUid(this.owner.getUid())
.setCurStamina(getCurStamina())
.build();
VehicleInfo vehicle =
VehicleInfo.newBuilder()
.setOwnerUid(this.owner.getUid())
.setCurStamina(getCurStamina())
.build();
EntityAuthorityInfo authority = EntityAuthorityInfo.newBuilder()
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
.setAiInfo(SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(getPosition().toProto()))
.setBornPos(getPosition().toProto())
.build();
EntityAuthorityInfo authority =
EntityAuthorityInfo.newBuilder()
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
.setAiInfo(
SceneEntityAiInfo.newBuilder()
.setIsAiOpen(true)
.setBornPos(getPosition().toProto()))
.setBornPos(getPosition().toProto())
.build();
SceneGadgetInfo.Builder gadgetInfo = SceneGadgetInfo.newBuilder()
.setGadgetId(this.getGadgetId())
.setAuthorityPeerId(this.getOwner().getPeerId())
.setIsEnableInteract(true)
.setVehicleInfo(vehicle);
SceneGadgetInfo.Builder gadgetInfo =
SceneGadgetInfo.newBuilder()
.setGadgetId(this.getGadgetId())
.setAuthorityPeerId(this.getOwner().getPeerId())
.setIsEnableInteract(true)
.setVehicleInfo(vehicle);
SceneEntityInfo.Builder entityInfo = SceneEntityInfo.newBuilder()
.setEntityId(getId())
.setEntityType(ProtEntityType.PROT_ENTITY_TYPE_GADGET)
.setMotionInfo(MotionInfo.newBuilder().setPos(getPosition().toProto()).setRot(getRotation().toProto()).setSpeed(Vector.newBuilder()))
.addAnimatorParaList(AnimatorParameterValueInfoPair.newBuilder())
.setGadget(gadgetInfo)
.setEntityAuthorityInfo(authority)
.setLifeState(1);
SceneEntityInfo.Builder entityInfo =
SceneEntityInfo.newBuilder()
.setEntityId(getId())
.setEntityType(ProtEntityType.PROT_ENTITY_TYPE_GADGET)
.setMotionInfo(
MotionInfo.newBuilder()
.setPos(getPosition().toProto())
.setRot(getRotation().toProto())
.setSpeed(Vector.newBuilder()))
.addAnimatorParaList(AnimatorParameterValueInfoPair.newBuilder())
.setGadget(gadgetInfo)
.setEntityAuthorityInfo(authority)
.setLifeState(1);
PropPair pair = PropPair.newBuilder()
.setType(PlayerProperty.PROP_LEVEL.getId())
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, 47))
.build();
PropPair pair =
PropPair.newBuilder()
.setType(PlayerProperty.PROP_LEVEL.getId())
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, 47))
.build();
this.addAllFightPropsToEntityInfo(entityInfo);
entityInfo.addPropList(pair);

View File

@@ -202,7 +202,7 @@ public abstract class GameEntity {
*/
public void runLuaCallbacks(EntityDamageEvent event) {
if (entityController != null) {
entityController.onBeHurt(this, event.getAttackElementType(), true);//todo is host handling
entityController.onBeHurt(this, event.getAttackElementType(), true); // todo is host handling
}
}

View File

@@ -19,7 +19,8 @@ public final class GadgetRewardStatue extends GadgetContent {
var dungeonManager = player.getScene().getDungeonManager();
if (player.getScene().getChallenge() instanceof DungeonChallenge) {
var useCondensed = req.getResinCostType() == ResinCostTypeOuterClass.ResinCostType.RESIN_COST_TYPE_CONDENSE;
var useCondensed =
req.getResinCostType() == ResinCostTypeOuterClass.ResinCostType.RESIN_COST_TYPE_CONDENSE;
dungeonManager.getStatueDrops(player, useCondensed, getGadget().getGroupId());
}

View File

@@ -9,7 +9,12 @@ import emu.grasscutter.game.world.Scene;
import emu.grasscutter.utils.Position;
public class EntitySolarIsotomaElevatorPlatform extends EntityGadget {
public EntitySolarIsotomaElevatorPlatform(EntitySolarIsotomaClientGadget isotoma, Scene scene, int gadgetId, Position pos, Position rot) {
public EntitySolarIsotomaElevatorPlatform(
EntitySolarIsotomaClientGadget isotoma,
Scene scene,
int gadgetId,
Position pos,
Position rot) {
super(scene, gadgetId, pos, rot);
setOwner(isotoma);
this.setRouteConfig(new AbilityRoute(rot, false, false, pos));
@@ -25,7 +30,7 @@ public class EntitySolarIsotomaElevatorPlatform extends EntityGadget {
var combatProperties = combatData.getProperty();
if (combatProperties.isUseCreatorProperty()) {
//If useCreatorProperty == true, use owner's property;
// If useCreatorProperty == true, use owner's property;
GameEntity ownerEntity = getOwner();
if (ownerEntity != null) {
getFightProperties().putAll(ownerEntity.getFightProperties());

View File

@@ -1,5 +1,7 @@
package emu.grasscutter.game.mail;
import static emu.grasscutter.net.proto.MailItemOuterClass.MailItem.*;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import dev.morphia.annotations.Indexed;
@@ -10,18 +12,15 @@ import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.proto.EquipParamOuterClass.EquipParam;
import emu.grasscutter.net.proto.MailCollectStateOuterClass.MailCollectState;
import emu.grasscutter.net.proto.MailTextContentOuterClass.MailTextContent;
import org.bson.types.ObjectId;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import static emu.grasscutter.net.proto.MailItemOuterClass.MailItem.*;
import org.bson.types.ObjectId;
@Entity(value = "mail", useDiscriminator = false)
public final class Mail {
@Id private ObjectId id;
@Indexed private int ownerUid;
@Id private ObjectId id;
@Indexed private int ownerUid;
public MailContent mailContent;
public List<MailItem> itemList;
public long sendTime;
@@ -33,7 +32,11 @@ public final class Mail {
@Transient private boolean shouldDelete;
public Mail() {
this(new MailContent(), new ArrayList<MailItem>(), (int) Instant.now().getEpochSecond() + 604800); // TODO: add expire time to send mail command
this(
new MailContent(),
new ArrayList<MailItem>(),
(int) Instant.now().getEpochSecond()
+ 604800); // TODO: add expire time to send mail command
}
public Mail(MailContent mailContent, List<MailItem> itemList, long expireTime) {
@@ -44,7 +47,12 @@ public final class Mail {
this(mailContent, itemList, expireTime, importance, 1);
}
public Mail(MailContent mailContent, List<MailItem> itemList, long expireTime, int importance, int state) {
public Mail(
MailContent mailContent,
List<MailItem> itemList,
long expireTime,
int importance,
int state) {
this.mailContent = mailContent;
this.itemList = itemList;
this.sendTime = (int) Instant.now().getEpochSecond();
@@ -69,16 +77,16 @@ public final class Mail {
public MailDataOuterClass.MailData toProto(Player player) {
return MailDataOuterClass.MailData.newBuilder()
.setMailId(player.getMailId(this))
.setMailTextContent(this.mailContent.toProto())
.addAllItemList(this.itemList.stream().map(MailItem::toProto).toList())
.setSendTime((int) this.sendTime)
.setExpireTime((int) this.expireTime)
.setImportance(this.importance)
.setIsRead(this.isRead)
.setIsAttachmentGot(this.isAttachmentGot)
.setCollectState(MailCollectState.MAIL_COLLECT_STATE_NOT_COLLECTIBLE)
.build();
.setMailId(player.getMailId(this))
.setMailTextContent(this.mailContent.toProto())
.addAllItemList(this.itemList.stream().map(MailItem::toProto).toList())
.setSendTime((int) this.sendTime)
.setExpireTime((int) this.expireTime)
.setImportance(this.importance)
.setIsRead(this.isRead)
.setIsAttachmentGot(this.isAttachmentGot)
.setCollectState(MailCollectState.MAIL_COLLECT_STATE_NOT_COLLECTIBLE)
.build();
}
@Entity
@@ -109,10 +117,10 @@ public final class Mail {
public MailTextContent toProto() {
return MailTextContent.newBuilder()
.setTitle(this.title)
.setContent(this.content)
.setSender(this.sender)
.build();
.setTitle(this.title)
.setContent(this.content)
.setSender(this.sender)
.build();
}
}
@@ -143,21 +151,23 @@ public final class Mail {
}
public MailItemOuterClass.MailItem toProto() {
return newBuilder().setEquipParam(EquipParam.newBuilder()
.setItemId(this.itemId)
.setItemNum(this.itemCount)
.setItemLevel(this.itemLevel)
.setPromoteLevel(0)//mock
.build())
.build();
return newBuilder()
.setEquipParam(
EquipParam.newBuilder()
.setItemId(this.itemId)
.setItemNum(this.itemCount)
.setItemLevel(this.itemLevel)
.setPromoteLevel(0) // mock
.build())
.build();
}
}
public void save() {
if (this.expireTime * 1000 < System.currentTimeMillis()) {
DatabaseHelper.deleteMail(this);
} else {
DatabaseHelper.saveMail(this);
}
}
public void save() {
if (this.expireTime * 1000 < System.currentTimeMillis()) {
DatabaseHelper.deleteMail(this);
} else {
DatabaseHelper.saveMail(this);
}
}
}

View File

@@ -13,7 +13,6 @@ import emu.grasscutter.scripts.data.SceneGadget;
import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.Utils;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
@@ -29,32 +28,39 @@ public final class BlossomActivity {
private final int goal;
private int generatedCount;
private final int worldLevel;
private boolean pass=false;
private boolean pass = false;
private final List<EntityMonster> activeMonsters = new ArrayList<>();
private final Queue<Integer> candidateMonsters = new ArrayDeque<>();
private static final int BLOOMING_GADGET_ID = 70210109;
public BlossomActivity(EntityGadget entityGadget, List<Integer> monsters, int timeout, int worldLevel) {
public BlossomActivity(
EntityGadget entityGadget, List<Integer> monsters, int timeout, int worldLevel) {
this.tempSceneGroup = new SceneGroup();
this.tempSceneGroup.id = entityGadget.getId();
this.gadget=entityGadget;
this.step=0;
this.gadget = entityGadget;
this.step = 0;
this.goal = monsters.size();
this.candidateMonsters.addAll(monsters);
this.worldLevel = worldLevel;
ArrayList<ChallengeTrigger> challengeTriggers = new ArrayList<>();
this.challenge = new WorldChallenge(entityGadget.getScene(),
tempSceneGroup,
1,
1,
List.of(goal, timeout),
timeout,
goal, challengeTriggers);
this.challenge =
new WorldChallenge(
entityGadget.getScene(),
tempSceneGroup,
1,
1,
List.of(goal, timeout),
timeout,
goal,
challengeTriggers);
challengeTriggers.add(new KillMonsterCountTrigger());
//this.challengeTriggers.add(new InTimeTrigger());
// this.challengeTriggers.add(new InTimeTrigger());
}
public WorldChallenge getChallenge() {
return this.challenge;
}
public void setMonsters(List<EntityMonster> monsters) {
this.activeMonsters.clear();
this.activeMonsters.addAll(monsters);
@@ -62,26 +68,30 @@ public final class BlossomActivity {
monster.setGroupId(this.tempSceneGroup.id);
}
}
public int getAliveMonstersCount() {
int count=0;
for (EntityMonster monster: activeMonsters) {
int count = 0;
for (EntityMonster monster : activeMonsters) {
if (monster.isAlive()) {
count++;
}
}
return count;
}
public boolean getPass() {
return pass;
}
public void start() {
challenge.start();
}
public void onTick() {
Scene scene = gadget.getScene();
Position pos = gadget.getPosition();
if (getAliveMonstersCount() <= 2) {
if (generatedCount<goal) {
if (generatedCount < goal) {
step++;
var worldLevelData = GameData.getWorldLevelDataMap().get(worldLevel);
@@ -91,11 +101,11 @@ public final class BlossomActivity {
}
List<EntityMonster> newMonsters = new ArrayList<>();
int willSpawn = Utils.randomRange(3,5);
if (generatedCount+willSpawn>goal) {
int willSpawn = Utils.randomRange(3, 5);
if (generatedCount + willSpawn > goal) {
willSpawn = goal - generatedCount;
}
generatedCount+=willSpawn;
generatedCount += willSpawn;
for (int i = 0; i < willSpawn; i++) {
var monsterData = GameData.getMonsterDataMap().get(candidateMonsters.poll());
int level = scene.getEntityLevel(1, worldLevelOverride);
@@ -104,7 +114,7 @@ public final class BlossomActivity {
newMonsters.add(entity);
}
setMonsters(newMonsters);
}else {
} else {
if (getAliveMonstersCount() == 0) {
this.pass = true;
this.challenge.done();
@@ -112,12 +122,15 @@ public final class BlossomActivity {
}
}
}
public EntityGadget getGadget() {
return gadget;
}
public EntityGadget getChest() {
if (chest==null) {
EntityGadget rewardGadget = new EntityGadget(gadget.getScene(), BLOOMING_GADGET_ID, gadget.getPosition());
if (chest == null) {
EntityGadget rewardGadget =
new EntityGadget(gadget.getScene(), BLOOMING_GADGET_ID, gadget.getPosition());
SceneGadget metaGadget = new SceneGadget();
metaGadget.boss_chest = new SceneBossChest();
metaGadget.boss_chest.resin = 20;

View File

@@ -30,11 +30,10 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import lombok.Getter;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;
import lombok.Getter;
public class EnergyManager extends BasePlayerManager {
private static final Int2ObjectMap<List<EnergyDropInfo>> energyDropData =
@@ -390,7 +389,8 @@ public class EnergyManager extends BasePlayerManager {
*/
public boolean refillActiveEnergy() {
var activeEntity = this.player.getTeamManager().getCurrentAvatarEntity();
return activeEntity.addEnergy(activeEntity.getAvatar().getSkillDepot().getEnergySkillData().getCostElemVal());
return activeEntity.addEnergy(
activeEntity.getAvatar().getSkillDepot().getEnergySkillData().getCostElemVal());
}
/**
@@ -402,8 +402,10 @@ public class EnergyManager extends BasePlayerManager {
public void refillTeamEnergy(PropChangeReason changeReason, boolean isFlat) {
for (var entityAvatar : this.player.getTeamManager().getActiveTeam()) {
// giving the exact amount read off the AvatarSkillData.json
entityAvatar.addEnergy(entityAvatar.getAvatar().getSkillDepot()
.getEnergySkillData().getCostElemVal(), changeReason, isFlat);
entityAvatar.addEnergy(
entityAvatar.getAvatar().getSkillDepot().getEnergySkillData().getCostElemVal(),
changeReason,
isFlat);
}
}

View File

@@ -10,8 +10,6 @@ import emu.grasscutter.game.quest.enums.QuestContent;
import emu.grasscutter.game.quest.enums.QuestState;
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
import emu.grasscutter.server.packet.send.*;
import lombok.val;
import java.util.Set;
import java.util.stream.Collectors;
@@ -149,9 +147,7 @@ public final class PlayerProgressManager extends BasePlayerDataManager {
this.player.sendPacket(new PacketSetOpenStateRsp(openState, value));
}
/**
* This force sets an open state, ignoring all conditions and permissions
*/
/** This force sets an open state, ignoring all conditions and permissions */
public void forceSetOpenState(int openState, int value) {
this.setOpenState(openState, value);
}
@@ -247,32 +243,32 @@ public final class PlayerProgressManager extends BasePlayerDataManager {
this.player.sendPacket(new PacketSceneAreaUnlockNotify(sceneId, areaId));
}
/**
* Give replace costume to player (Amber, Jean, Mona, Rosaria)
*/
public void addReplaceCostumes(){
/** Give replace costume to player (Amber, Jean, Mona, Rosaria) */
public void addReplaceCostumes() {
var currentPlayerCostumes = player.getCostumeList();
GameData.getAvatarReplaceCostumeDataMap().keySet().forEach(costumeId -> {
if (GameData.getAvatarCostumeDataMap().get(costumeId) == null || currentPlayerCostumes.contains(costumeId)){
return;
}
this.player.addCostume(costumeId);
});
GameData.getAvatarReplaceCostumeDataMap()
.keySet()
.forEach(
costumeId -> {
if (GameData.getAvatarCostumeDataMap().get(costumeId) == null
|| currentPlayerCostumes.contains(costumeId)) {
return;
}
this.player.addCostume(costumeId);
});
}
/**
* Quest progress
*/
public void addQuestProgress(int id, int count){
/** Quest progress */
public void addQuestProgress(int id, int count) {
var newCount = player.getPlayerProgress().addToCurrentProgress(id, count);
player.save();
player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_ADD_QUEST_PROGRESS, id, newCount);
player
.getQuestManager()
.queueEvent(QuestContent.QUEST_CONTENT_ADD_QUEST_PROGRESS, id, newCount);
}
/**
* Item history
*/
public void addItemObtainedHistory(int id, int count){
/** Item history */
public void addItemObtainedHistory(int id, int count) {
var newCount = player.getPlayerProgress().addToItemHistory(id, count);
player.save();
player.getQuestManager().queueEvent(QuestCond.QUEST_COND_HISTORY_GOT_ANY_ITEM, id, newCount);

View File

@@ -659,14 +659,16 @@ public final class TeamManager extends BasePlayerDataManager {
}
/**
* Applies 10% of the avatar's max HP as damage.
* This occurs when the avatar is killed by the void.
* Applies 10% of the avatar's max HP as damage. This occurs when the avatar is killed by the
* void.
*/
public void applyVoidDamage() {
this.getActiveTeam().forEach(entity -> {
entity.damage(entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * .1f);
player.sendPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
});
this.getActiveTeam()
.forEach(
entity -> {
entity.damage(entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) * .1f);
player.sendPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
});
}
public void onAvatarDie(long dieGuid) {

View File

@@ -1,37 +1,85 @@
package emu.grasscutter.game.props;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import emu.grasscutter.scripts.constants.IntValueEnum;
import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import lombok.Getter;
public enum ElementType implements IntValueEnum {
None (0, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
Fire (1, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10101, "TeamResonance_Fire_Lv2", 1),
Water (2, FightProperty.FIGHT_PROP_CUR_WATER_ENERGY, FightProperty.FIGHT_PROP_MAX_WATER_ENERGY, 10201, "TeamResonance_Water_Lv2", 2),
Grass (3, FightProperty.FIGHT_PROP_CUR_GRASS_ENERGY, FightProperty.FIGHT_PROP_MAX_GRASS_ENERGY, 10501, "TeamResonance_Grass_Lv2", 7),
Electric (4, FightProperty.FIGHT_PROP_CUR_ELEC_ENERGY, FightProperty.FIGHT_PROP_MAX_ELEC_ENERGY, 10401, "TeamResonance_Electric_Lv2", 6),
Ice (5, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY, 10601, "TeamResonance_Ice_Lv2", 4),
Frozen (6, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY),
Wind (7, FightProperty.FIGHT_PROP_CUR_WIND_ENERGY, FightProperty.FIGHT_PROP_MAX_WIND_ENERGY, 10301, "TeamResonance_Wind_Lv2", 3),
Rock (8, FightProperty.FIGHT_PROP_CUR_ROCK_ENERGY, FightProperty.FIGHT_PROP_MAX_ROCK_ENERGY, 10701, "TeamResonance_Rock_Lv2", 5),
AntiFire (9, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
Default (255, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY, 10801, "TeamResonance_AllDifferent");
None(0, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
Fire(
1,
FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY,
FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY,
10101,
"TeamResonance_Fire_Lv2",
1),
Water(
2,
FightProperty.FIGHT_PROP_CUR_WATER_ENERGY,
FightProperty.FIGHT_PROP_MAX_WATER_ENERGY,
10201,
"TeamResonance_Water_Lv2",
2),
Grass(
3,
FightProperty.FIGHT_PROP_CUR_GRASS_ENERGY,
FightProperty.FIGHT_PROP_MAX_GRASS_ENERGY,
10501,
"TeamResonance_Grass_Lv2",
7),
Electric(
4,
FightProperty.FIGHT_PROP_CUR_ELEC_ENERGY,
FightProperty.FIGHT_PROP_MAX_ELEC_ENERGY,
10401,
"TeamResonance_Electric_Lv2",
6),
Ice(
5,
FightProperty.FIGHT_PROP_CUR_ICE_ENERGY,
FightProperty.FIGHT_PROP_MAX_ICE_ENERGY,
10601,
"TeamResonance_Ice_Lv2",
4),
Frozen(6, FightProperty.FIGHT_PROP_CUR_ICE_ENERGY, FightProperty.FIGHT_PROP_MAX_ICE_ENERGY),
Wind(
7,
FightProperty.FIGHT_PROP_CUR_WIND_ENERGY,
FightProperty.FIGHT_PROP_MAX_WIND_ENERGY,
10301,
"TeamResonance_Wind_Lv2",
3),
Rock(
8,
FightProperty.FIGHT_PROP_CUR_ROCK_ENERGY,
FightProperty.FIGHT_PROP_MAX_ROCK_ENERGY,
10701,
"TeamResonance_Rock_Lv2",
5),
AntiFire(9, FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY, FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY),
Default(
255,
FightProperty.FIGHT_PROP_CUR_FIRE_ENERGY,
FightProperty.FIGHT_PROP_MAX_FIRE_ENERGY,
10801,
"TeamResonance_AllDifferent");
private static final Int2ObjectMap<ElementType> map = new Int2ObjectOpenHashMap<>();
private static final Map<String, ElementType> stringMap = new HashMap<>();
static {
// Create bindings for each value.
Stream.of(ElementType.values()).forEach(entry -> {
map.put(entry.getValue(), entry);
stringMap.put(entry.name(), entry);
});
Stream.of(ElementType.values())
.forEach(
entry -> {
map.put(entry.getValue(), entry);
stringMap.put(entry.name(), entry);
});
}
@Getter private final int value;
@@ -45,11 +93,22 @@ public enum ElementType implements IntValueEnum {
this(value, curEnergyProp, maxEnergyProp, 0, null, 1);
}
ElementType(int value, FightProperty curEnergyProp, FightProperty maxEnergyProp, int teamResonanceId, String configName) {
ElementType(
int value,
FightProperty curEnergyProp,
FightProperty maxEnergyProp,
int teamResonanceId,
String configName) {
this(value, curEnergyProp, maxEnergyProp, teamResonanceId, configName, 1);
}
ElementType(int value, FightProperty curEnergyProp, FightProperty maxEnergyProp, int teamResonanceId, String configName, int depotIndex) {
ElementType(
int value,
FightProperty curEnergyProp,
FightProperty maxEnergyProp,
int teamResonanceId,
String configName,
int depotIndex) {
this.value = value;
this.curEnergyProp = curEnergyProp;
this.maxEnergyProp = maxEnergyProp;

View File

@@ -4,7 +4,6 @@ import emu.grasscutter.data.excels.QuestData;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.QuestValueCond;
import emu.grasscutter.game.quest.enums.QuestCond;
import lombok.val;
@QuestValueCond(QuestCond.QUEST_COND_PERSONAL_LINE_UNLOCK)
public class ConditionPersonalLineUnlock extends BaseCondition {
@@ -15,8 +14,7 @@ public class ConditionPersonalLineUnlock extends BaseCondition {
QuestData questData,
QuestData.QuestAcceptCondition condition,
String paramStr,
int... params
) {
int... params) {
var personalLineId = condition.getParam()[0];
return owner.getPersonalLineList().contains(personalLineId);
}

View File

@@ -121,9 +121,9 @@ public final class Scene {
public GameEntity getEntityByConfigId(int configId, int groupId) {
return this.entities.values().stream()
.filter(x -> x.getConfigId() == configId && x.getGroupId() == groupId)
.findFirst()
.orElse(null);
.filter(x -> x.getConfigId() == configId && x.getGroupId() == groupId)
.findFirst()
.orElse(null);
}
/**
@@ -437,35 +437,34 @@ public final class Scene {
this.finishLoading();
this.checkPlayerRespawn();
if (this.tickCount++ % 10 == 0)
broadcastPacket(new PacketSceneTimeNotify(this));
if (this.tickCount++ % 10 == 0) broadcastPacket(new PacketSceneTimeNotify(this));
}
/**
* Validates a player's current position.
* Teleports the player if the player is out of bounds.
*/
/** Validates a player's current position. Teleports the player if the player is out of bounds. */
private void checkPlayerRespawn() {
if (this.getScriptManager().getConfig() == null) return;
var diePos = this.getScriptManager().getConfig().die_y;
// Check players in the scene.
this.players.forEach(player -> {
if (this.getScriptManager().getConfig() == null) return;
this.players.forEach(
player -> {
if (this.getScriptManager().getConfig() == null) return;
// Check if we need a respawn
if (diePos >= player.getPosition().getY()) {
//Respawn the player.
this.respawnPlayer(player);
}
});
// Check if we need a respawn
if (diePos >= player.getPosition().getY()) {
// Respawn the player.
this.respawnPlayer(player);
}
});
// Check entities in the scene.
this.getEntities().forEach((id, entity) -> {
if (diePos >= entity.getPosition().getY()){
this.killEntity(entity);
}
});
this.getEntities()
.forEach(
(id, entity) -> {
if (diePos >= entity.getPosition().getY()) {
this.killEntity(entity);
}
});
}
/**
@@ -503,7 +502,8 @@ public final class Scene {
* @return The respawn rotation for the player.
*/
private Position getRespawnRotation(Player player) {
var lastCheckpointRot = this.dungeonManager != null ? this.dungeonManager.getRespawnRotation() : null;
var lastCheckpointRot =
this.dungeonManager != null ? this.dungeonManager.getRespawnRotation() : null;
return lastCheckpointRot != null ? lastCheckpointRot : this.getDefaultRot(player);
}
@@ -520,20 +520,22 @@ public final class Scene {
// TODO: Respawn the player at the last valid location.
var targetPos = getRespawnLocation(player);
var targetRot = getRespawnRotation(player);
var teleportProps = TeleportProperties.builder()
.sceneId(getId())
.teleportTo(targetPos)
.teleportRot(targetRot)
.teleportType(PlayerTeleportEvent.TeleportType.INTERNAL)
.enterType(EnterTypeOuterClass.EnterType.ENTER_TYPE_GOTO)
.enterReason(dungeonManager != null ? EnterReason.DungeonReviveOnWaypoint : EnterReason.Revival);
var teleportProps =
TeleportProperties.builder()
.sceneId(getId())
.teleportTo(targetPos)
.teleportRot(targetRot)
.teleportType(PlayerTeleportEvent.TeleportType.INTERNAL)
.enterType(EnterTypeOuterClass.EnterType.ENTER_TYPE_GOTO)
.enterReason(
dungeonManager != null ? EnterReason.DungeonReviveOnWaypoint : EnterReason.Revival);
return this.getWorld().transferPlayerToScene(player, teleportProps.build());
}
/**
* Invoked when the scene finishes loading.
* Runs all callbacks that were added with {@link #runWhenFinished(Runnable)}.
* Invoked when the scene finishes loading. Runs all callbacks that were added with {@link
* #runWhenFinished(Runnable)}.
*/
public void finishLoading() {
if (this.finishedLoading) return;
@@ -544,14 +546,15 @@ public final class Scene {
}
/**
* Adds a callback to be executed when the scene is finished loading.
* If the scene is already finished loading, the callback will be executed immediately.
* Adds a callback to be executed when the scene is finished loading. If the scene is already
* finished loading, the callback will be executed immediately.
*
* @param runnable The callback to be executed.
*/
public void runWhenFinished(Runnable runnable) {
if (this.isFinishedLoading()) {
runnable.run();return;
runnable.run();
return;
}
this.afterLoadedCallbacks.add(runnable);
@@ -774,17 +777,18 @@ public final class Scene {
public int loadDynamicGroup(int group_id) {
SceneGroup group = getScriptManager().getGroupById(group_id);
if(group == null || getScriptManager().getGroupInstanceById(group_id) != null) return -1; //Group not found or already instanced
if (group == null || getScriptManager().getGroupInstanceById(group_id) != null)
return -1; // Group not found or already instanced
onLoadGroup(new ArrayList<>(List.of(group)));
if(GameData.getGroupReplacements().containsKey(group_id)) onRegisterGroups();
if (GameData.getGroupReplacements().containsKey(group_id)) onRegisterGroups();
if (group.init_config == null) return -1;
return group.init_config.suite;
}
public boolean unregisterDynamicGroup(int groupId){
public boolean unregisterDynamicGroup(int groupId) {
var group = getScriptManager().getGroupById(groupId);
if (group == null) return false;
@@ -795,70 +799,76 @@ public final class Scene {
public void onRegisterGroups() {
var sceneGroups = this.loadedGroups;
var sceneGroupMap = sceneGroups.stream()
.collect(Collectors.toMap(item -> item.id, item -> item));
var sceneGroupsIds = sceneGroups.stream()
.map(group -> group.id)
.toList();
var dynamicGroups = sceneGroups.stream()
.filter(group -> group.dynamic_load)
.map(group -> group.id)
.toList();
var sceneGroupMap =
sceneGroups.stream().collect(Collectors.toMap(item -> item.id, item -> item));
var sceneGroupsIds = sceneGroups.stream().map(group -> group.id).toList();
var dynamicGroups =
sceneGroups.stream().filter(group -> group.dynamic_load).map(group -> group.id).toList();
//Create the graph
// Create the graph
var nodes = new ArrayList<KahnsSort.Node>();
var groupList = new ArrayList<Integer>();
GameData.getGroupReplacements().values().stream().filter(replacement -> dynamicGroups.contains(replacement.id)).forEach(replacement -> {
Grasscutter.getLogger().info("Graph ordering replacement {}", replacement);
replacement.replace_groups.forEach(group -> {
nodes.add(new KahnsSort.Node(replacement.id, group));
if (!groupList.contains(group))
groupList.add(group);
});
GameData.getGroupReplacements().values().stream()
.filter(replacement -> dynamicGroups.contains(replacement.id))
.forEach(
replacement -> {
Grasscutter.getLogger().info("Graph ordering replacement {}", replacement);
replacement.replace_groups.forEach(
group -> {
nodes.add(new KahnsSort.Node(replacement.id, group));
if (!groupList.contains(group)) groupList.add(group);
});
if (!groupList.contains(replacement.id))
groupList.add(replacement.id);
});
if (!groupList.contains(replacement.id)) groupList.add(replacement.id);
});
KahnsSort.Graph graph = new KahnsSort.Graph(nodes, groupList);
List<Integer> dynamicGroupsOrdered = KahnsSort.doSort(graph);
if (dynamicGroupsOrdered == null) throw new RuntimeException("Invalid group replacement graph");
// Now we can start unloading and loading groups :D
dynamicGroupsOrdered.forEach(group -> {
if (GameData.getGroupReplacements().containsKey((int)group)) { //isGroupJoinReplacement
var data = GameData.getGroupReplacements().get((int)group);
var sceneGroupReplacement = this.loadedGroups.stream().filter(g -> g.id == group).findFirst().orElseThrow();
if (sceneGroupReplacement.is_replaceable != null) {
var it = data.replace_groups.iterator();
while (it.hasNext()) {
var replace_group = it.next();
if (!sceneGroupsIds.contains(replace_group)) continue;
dynamicGroupsOrdered.forEach(
group -> {
if (GameData.getGroupReplacements().containsKey((int) group)) { // isGroupJoinReplacement
var data = GameData.getGroupReplacements().get((int) group);
var sceneGroupReplacement =
this.loadedGroups.stream().filter(g -> g.id == group).findFirst().orElseThrow();
if (sceneGroupReplacement.is_replaceable != null) {
var it = data.replace_groups.iterator();
while (it.hasNext()) {
var replace_group = it.next();
if (!sceneGroupsIds.contains(replace_group)) continue;
// Check if we can replace this group
SceneGroup sceneGroup = sceneGroupMap.get(replace_group);
if (sceneGroup != null && sceneGroup.is_replaceable != null &&
((sceneGroup.is_replaceable.value &&
sceneGroup.is_replaceable.version <= sceneGroupReplacement.is_replaceable.version) ||
sceneGroup.is_replaceable.new_bin_only)) {
this.unloadGroup(scriptManager.getBlocks().get(sceneGroup.block_id), replace_group);
it.remove();
Grasscutter.getLogger().info("Graph ordering: unloaded {}", replace_group);
// Check if we can replace this group
SceneGroup sceneGroup = sceneGroupMap.get(replace_group);
if (sceneGroup != null
&& sceneGroup.is_replaceable != null
&& ((sceneGroup.is_replaceable.value
&& sceneGroup.is_replaceable.version
<= sceneGroupReplacement.is_replaceable.version)
|| sceneGroup.is_replaceable.new_bin_only)) {
this.unloadGroup(
scriptManager.getBlocks().get(sceneGroup.block_id), replace_group);
it.remove();
Grasscutter.getLogger().info("Graph ordering: unloaded {}", replace_group);
}
}
}
}
}
}
});
});
}
public void loadTriggerFromGroup(SceneGroup group, String triggerName) {
// Load triggers and regions
this.getScriptManager().registerTrigger(group.triggers.values().stream()
.filter(p -> p.getName().contains(triggerName)).toList());
this.getScriptManager()
.registerTrigger(
group.triggers.values().stream()
.filter(p -> p.getName().contains(triggerName))
.toList());
group.regions.values().stream()
.filter(q -> q.config_id == Integer.parseInt(triggerName.substring(13)))
.map(region -> new EntityRegion(this, region))
.forEach(getScriptManager()::registerRegion);
.filter(q -> q.config_id == Integer.parseInt(triggerName.substring(13)))
.map(region -> new EntityRegion(this, region))
.forEach(getScriptManager()::registerRegion);
}
public void onLoadGroup(List<SceneGroup> groups) {
@@ -867,7 +877,7 @@ public final class Scene {
}
for (var group : groups) {
if(this.loadedGroups.contains(group)) continue;
if (this.loadedGroups.contains(group)) continue;
// We load the script files for the groups here
this.getScriptManager().loadGroupFromScript(group);
@@ -880,7 +890,7 @@ public final class Scene {
// TODO
var entities = new ArrayList<GameEntity>();
for (var group : groups) {
if(this.loadedGroups.contains(group)) continue;
if (this.loadedGroups.contains(group)) continue;
if (group.init_config == null) {
continue;
@@ -897,20 +907,24 @@ public final class Scene {
var garbageGadgets = group.getGarbageGadgets();
if (garbageGadgets != null) {
entities.addAll(garbageGadgets.stream()
.map(g -> scriptManager.createGadget(group.id, group.block_id, g))
.filter(Objects::nonNull).toList());
entities.addAll(
garbageGadgets.stream()
.map(g -> scriptManager.createGadget(group.id, group.block_id, g))
.filter(Objects::nonNull)
.toList());
}
// Load suites
//int suite = group.findInitSuiteIndex(0);
this.getScriptManager().refreshGroup(groupInstance, 0, false); //This is what the official server does
// int suite = group.findInitSuiteIndex(0);
this.getScriptManager()
.refreshGroup(groupInstance, 0, false); // This is what the official server does
this.loadedGroups.add(group);
}
this.scriptManager.meetEntities(entities);
groups.forEach(g -> scriptManager.callEvent(new ScriptArgs(g.id, EventType.EVENT_GROUP_LOAD, g.id)));
groups.forEach(
g -> scriptManager.callEvent(new ScriptArgs(g.id, EventType.EVENT_GROUP_LOAD, g.id)));
Grasscutter.getLogger().info("Scene {} loaded {} group(s)", this.getId(), groups.size());
}
@@ -944,25 +958,23 @@ public final class Scene {
* @param groupId The group ID.
*/
public void unloadGroup(SceneBlock block, int groupId) {
var toRemove = this.getEntities().values().stream()
.filter(e -> e != null && (
e.getBlockId() == block.id &&
e.getGroupId() == groupId)
).toList();
var toRemove =
this.getEntities().values().stream()
.filter(e -> e != null && (e.getBlockId() == block.id && e.getGroupId() == groupId))
.toList();
if (toRemove.size() > 0) {
toRemove.forEach(this::removeEntityDirectly);
this.broadcastPacket(new PacketSceneEntityDisappearNotify(toRemove, VisionType.VISION_TYPE_REMOVE));
this.broadcastPacket(
new PacketSceneEntityDisappearNotify(toRemove, VisionType.VISION_TYPE_REMOVE));
}
var group = block.groups.get(groupId);
if (group.triggers != null) {
group.triggers.values().forEach(
this.getScriptManager()::deregisterTrigger);
group.triggers.values().forEach(this.getScriptManager()::deregisterTrigger);
}
if (group.regions != null) {
group.regions.values().forEach(
this.getScriptManager()::deregisterRegion);
group.regions.values().forEach(this.getScriptManager()::deregisterRegion);
}
this.scriptManager.getLoadedGroupSetPerBlock().get(block.id).remove(group);
@@ -1093,18 +1105,19 @@ public final class Scene {
return;
}
sceneGroupSuite.forEach(i -> {
var group = scriptManager.getGroupById(i.getGroup());
if (group == null) return;
sceneGroupSuite.forEach(
i -> {
var group = scriptManager.getGroupById(i.getGroup());
if (group == null) return;
var groupInstance = scriptManager.getGroupInstanceById(i.getGroup());
var suite = group.getSuiteByIndex(i.getSuite());
if (suite == null || groupInstance == null) {
return;
}
var groupInstance = scriptManager.getGroupInstanceById(i.getGroup());
var suite = group.getSuiteByIndex(i.getSuite());
if (suite == null || groupInstance == null) {
return;
}
scriptManager.refreshGroup(groupInstance, i.getSuite(), false);
});
scriptManager.refreshGroup(groupInstance, i.getSuite(), false);
});
}
/**

View File

@@ -1,12 +1,5 @@
package emu.grasscutter.game.world;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.bson.types.ObjectId;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import dev.morphia.annotations.Indexed;
@@ -14,20 +7,25 @@ import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.scripts.data.SceneGadget;
import emu.grasscutter.scripts.data.SceneGroup;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import lombok.Getter;
import lombok.Setter;
import org.bson.types.ObjectId;
@Entity(value = "group_instances", useDiscriminator = false)
public final class SceneGroupInstance {
@Id private ObjectId id;
@Indexed private int ownerUid; //This group is owned by the host player
@Indexed private int ownerUid; // This group is owned by the host player
@Getter private int groupId;
@Getter private transient SceneGroup luaGroup;
@Getter @Setter private int targetSuiteId;
@Getter @Setter private int activeSuiteId;
@Getter private Set<Integer> deadEntities; //Config_ids
@Getter private Set<Integer> deadEntities; // Config_ids
private boolean isCached;
@Getter private Map<Integer, Integer> cachedGadgetStates;
@@ -46,11 +44,12 @@ public final class SceneGroupInstance {
this.cachedGadgetStates = new ConcurrentHashMap<>();
this.cachedVariables = new ConcurrentHashMap<>();
this.isCached = false; //This is true when the group is not loaded on scene but caches suite data
this.isCached =
false; // This is true when the group is not loaded on scene but caches suite data
}
@Deprecated // Morphia only!
SceneGroupInstance(){
@Deprecated // Morphia only!
SceneGroupInstance() {
this.cachedVariables = new ConcurrentHashMap<>();
this.deadEntities = new HashSet<>();
this.cachedGadgetStates = new ConcurrentHashMap<>();
@@ -67,12 +66,12 @@ public final class SceneGroupInstance {
public void setCached(boolean value) {
this.isCached = value;
save(); //Save each time a group is registered or unregistered
save(); // Save each time a group is registered or unregistered
}
public void cacheGadgetState(SceneGadget g, int state) {
if(g.persistent) //Only cache when is persistent
cachedGadgetStates.put(g.config_id, state);
if (g.persistent) // Only cache when is persistent
cachedGadgetStates.put(g.config_id, state);
}
public int getCachedGadgetState(SceneGadget g) {

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,8 @@
package emu.grasscutter.scripts;
import emu.grasscutter.Grasscutter;
import java.util.HashMap;
import emu.grasscutter.utils.Position;
import lombok.val;
import java.util.HashMap;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;

View File

@@ -3,26 +3,25 @@ package emu.grasscutter.scripts.data;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.scripts.ScriptLoader;
import emu.grasscutter.utils.Position;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.luaj.vm2.LuaValue;
import javax.script.Bindings;
import javax.script.CompiledScript;
import javax.script.ScriptException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;
import javax.script.Bindings;
import javax.script.CompiledScript;
import javax.script.ScriptException;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.luaj.vm2.LuaValue;
@ToString
@Setter
public final class SceneGroup {
public transient int block_id; // Not an actual variable in the scripts but we will keep it here for reference
public transient int
block_id; // Not an actual variable in the scripts but we will keep it here for reference
public int id;
public int refresh_id;
@@ -46,6 +45,7 @@ public final class SceneGroup {
private transient boolean loaded; // Not an actual variable in the scripts either
private transient CompiledScript script;
private transient Bindings bindings;
public static SceneGroup of(int groupId) {
var group = new SceneGroup();
group.id = groupId;
@@ -73,7 +73,7 @@ public final class SceneGroup {
}
public SceneSuite getSuiteByIndex(int index) {
if(index < 1 || index > suites.size()) {
if (index < 1 || index > suites.size()) {
return null;
}
return this.suites.get(index - 1);
@@ -92,7 +92,9 @@ public final class SceneGroup {
this.bindings = ScriptLoader.getEngine().createBindings();
CompiledScript cs = ScriptLoader.getScript("Scene/" + sceneId + "/scene" + sceneId + "_group" + this.id + ".lua");
CompiledScript cs =
ScriptLoader.getScript(
"Scene/" + sceneId + "/scene" + sceneId + "_group" + this.id + ".lua");
if (cs == null) {
return this;
@@ -105,56 +107,78 @@ public final class SceneGroup {
cs.eval(this.bindings);
// Set
this.monsters = ScriptLoader.getSerializer().toList(SceneMonster.class, this.bindings.get("monsters")).stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.monsters =
ScriptLoader.getSerializer()
.toList(SceneMonster.class, this.bindings.get("monsters"))
.stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.monsters.values().forEach(m -> m.group = this);
this.npcs = ScriptLoader.getSerializer().toList(SceneNPC.class, this.bindings.get("npcs")).stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.npcs =
ScriptLoader.getSerializer().toList(SceneNPC.class, this.bindings.get("npcs")).stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.npcs.values().forEach(m -> m.group = this);
this.gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, this.bindings.get("gadgets")).stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.gadgets =
ScriptLoader.getSerializer()
.toList(SceneGadget.class, this.bindings.get("gadgets"))
.stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.gadgets.values().forEach(m -> m.group = this);
this.triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, this.bindings.get("triggers")).stream()
.collect(Collectors.toMap(SceneTrigger::getName, y -> y, (a, b) -> a));
this.triggers =
ScriptLoader.getSerializer()
.toList(SceneTrigger.class, this.bindings.get("triggers"))
.stream()
.collect(Collectors.toMap(SceneTrigger::getName, y -> y, (a, b) -> a));
this.triggers.values().forEach(t -> t.currentGroup = this);
this.suites = ScriptLoader.getSerializer().toList(SceneSuite.class, this.bindings.get("suites"));
this.regions = ScriptLoader.getSerializer().toList(SceneRegion.class, this.bindings.get("regions")).stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.suites =
ScriptLoader.getSerializer().toList(SceneSuite.class, this.bindings.get("suites"));
this.regions =
ScriptLoader.getSerializer()
.toList(SceneRegion.class, this.bindings.get("regions"))
.stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.regions.values().forEach(m -> m.group = this);
this.init_config = ScriptLoader.getSerializer().toObject(SceneInitConfig.class, this.bindings.get("init_config"));
this.init_config =
ScriptLoader.getSerializer()
.toObject(SceneInitConfig.class, this.bindings.get("init_config"));
// Garbages // TODO: fix properly later
Object garbagesValue = this.bindings.get("garbages");
if (garbagesValue instanceof LuaValue garbagesTable) {
this.garbages = new SceneGarbage();
if (garbagesTable.checktable().get("gadgets") != LuaValue.NIL) {
this.garbages.gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, garbagesTable.checktable().get("gadgets").checktable());
this.garbages.gadgets =
ScriptLoader.getSerializer()
.toList(
SceneGadget.class, garbagesTable.checktable().get("gadgets").checktable());
this.garbages.gadgets.forEach(m -> m.group = this);
}
}
// Add variables to suite
this.variables = ScriptLoader.getSerializer().toList(SceneVar.class, this.bindings.get("variables"));
this.variables =
ScriptLoader.getSerializer().toList(SceneVar.class, this.bindings.get("variables"));
// Add monsters and gadgets to suite
this.suites.forEach(i -> i.init(this));
} catch (ScriptException e) {
Grasscutter.getLogger().error("An error occurred while loading group " + this.id + " in scene " + sceneId + ".", e);
Grasscutter.getLogger()
.error(
"An error occurred while loading group " + this.id + " in scene " + sceneId + ".", e);
}
Grasscutter.getLogger().debug("Successfully loaded group {} in scene {}.", this.id, sceneId);
return this;
}
public int findInitSuiteIndex(int exclude_index) { //TODO: Investigate end index
public int findInitSuiteIndex(int exclude_index) { // TODO: Investigate end index
if (init_config == null) return 1;
if (init_config.io_type == 1) return init_config.suite; //IO TYPE FLOW
if (init_config.io_type == 1) return init_config.suite; // IO TYPE FLOW
if (init_config.rand_suite) {
if (suites.size() == 1) {
return init_config.suite;
@@ -164,7 +188,7 @@ public final class SceneGroup {
if (i == exclude_index) continue;
var suite = suites.get(i);
for(int j = 0; j < suite.rand_weight; j++) randSuiteList.add(i);
for (int j = 0; j < suite.rand_weight; j++) randSuiteList.add(i);
}
return randSuiteList.get(new Random().nextInt(randSuiteList.size()));
@@ -175,9 +199,8 @@ public final class SceneGroup {
public Optional<SceneBossChest> searchBossChestInGroup() {
return this.gadgets.values().stream()
.filter(g -> g.boss_chest != null && g.boss_chest.monster_config_id > 0)
.map(g -> g.boss_chest)
.findFirst();
.filter(g -> g.boss_chest != null && g.boss_chest.monster_config_id > 0)
.map(g -> g.boss_chest)
.findFirst();
}
}

View File

@@ -5,7 +5,7 @@ import lombok.ToString;
@ToString
@Setter
public class SceneMonster extends SceneObject{
public class SceneMonster extends SceneObject {
public int monster_id;
public int pose_id;
public int drop_id;

View File

@@ -2,7 +2,6 @@ package emu.grasscutter.scripts.data;
import java.util.ArrayList;
import java.util.List;
import lombok.Setter;
import lombok.ToString;
@@ -24,40 +23,39 @@ public class SceneSuite {
public transient List<SceneRegion> sceneRegions = List.of();
public void init(SceneGroup sceneGroup) {
if(sceneGroup.monsters != null){
this.sceneMonsters = new ArrayList<>(
this.monsters.stream()
.filter(sceneGroup.monsters::containsKey)
.map(sceneGroup.monsters::get)
.toList()
);
if (sceneGroup.monsters != null) {
this.sceneMonsters =
new ArrayList<>(
this.monsters.stream()
.filter(sceneGroup.monsters::containsKey)
.map(sceneGroup.monsters::get)
.toList());
}
if(sceneGroup.gadgets != null){
this.sceneGadgets = new ArrayList<>(
this.gadgets.stream()
.filter(sceneGroup.gadgets::containsKey)
.map(sceneGroup.gadgets::get)
.toList()
);
if (sceneGroup.gadgets != null) {
this.sceneGadgets =
new ArrayList<>(
this.gadgets.stream()
.filter(sceneGroup.gadgets::containsKey)
.map(sceneGroup.gadgets::get)
.toList());
}
if(sceneGroup.triggers != null) {
this.sceneTriggers = new ArrayList<>(
this.triggers.stream()
.filter(sceneGroup.triggers::containsKey)
.map(sceneGroup.triggers::get)
.toList()
);
if (sceneGroup.triggers != null) {
this.sceneTriggers =
new ArrayList<>(
this.triggers.stream()
.filter(sceneGroup.triggers::containsKey)
.map(sceneGroup.triggers::get)
.toList());
}
if(sceneGroup.regions != null) {
this.sceneRegions = new ArrayList<>(
this.regions.stream()
.filter(sceneGroup.regions::containsKey)
.map(sceneGroup.regions::get)
.toList()
);
if (sceneGroup.regions != null) {
this.sceneRegions =
new ArrayList<>(
this.regions.stream()
.filter(sceneGroup.regions::containsKey)
.map(sceneGroup.regions::get)
.toList());
}
}
}

View File

@@ -20,7 +20,7 @@ public final class SceneTrigger {
@Override
public boolean equals(Object obj) {
if (obj instanceof SceneTrigger sceneTrigger){
if (obj instanceof SceneTrigger sceneTrigger) {
return this.name.equals(sceneTrigger.name);
} else return super.equals(obj);
}
@@ -32,14 +32,26 @@ public final class SceneTrigger {
@Override
public String toString() {
return "SceneTrigger{" +
"name='" + name + '\'' +
", config_id=" + config_id +
", event=" + event +
", source='" + source + '\'' +
", condition='" + condition + '\'' +
", action='" + action + '\'' +
", trigger_count='" + trigger_count + '\'' +
'}';
return "SceneTrigger{"
+ "name='"
+ name
+ '\''
+ ", config_id="
+ config_id
+ ", event="
+ event
+ ", source='"
+ source
+ '\''
+ ", condition='"
+ condition
+ '\''
+ ", action='"
+ action
+ '\''
+ ", trigger_count='"
+ trigger_count
+ '\''
+ '}';
}
}

View File

@@ -11,11 +11,11 @@ public class ScriptArgs {
public int type; // lua event type, used by scripts and the ScriptManager
public ScriptArgs(int groupId, int eventType) {
this(groupId, eventType, 0,0);
this(groupId, eventType, 0, 0);
}
public ScriptArgs(int groupId, int eventType, int param1) {
this(groupId, eventType, param1,0);
this(groupId, eventType, param1, 0);
}
public ScriptArgs(int groupId, int eventType, int param1, int param2) {

View File

@@ -7,8 +7,6 @@ import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.scripts.listener.ScriptMonsterListener;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
@@ -22,11 +20,15 @@ public final class ScriptMonsterTideService {
private final int monsterSceneLimit;
private final ConcurrentLinkedQueue<Integer> monsterConfigOrders;
private final List<Integer> monsterConfigIds;
private final OnMonsterCreated onMonsterCreated= new OnMonsterCreated();
private final OnMonsterDead onMonsterDead= new OnMonsterDead();
private final OnMonsterCreated onMonsterCreated = new OnMonsterCreated();
private final OnMonsterDead onMonsterDead = new OnMonsterDead();
public ScriptMonsterTideService(SceneScriptManager sceneScriptManager,
SceneGroup group, int tideCount, int monsterSceneLimit, Integer[] ordersConfigId){
public ScriptMonsterTideService(
SceneScriptManager sceneScriptManager,
SceneGroup group,
int tideCount,
int monsterSceneLimit,
Integer[] ordersConfigId) {
this.sceneScriptManager = sceneScriptManager;
this.currentGroup = group;
this.monsterSceneLimit = monsterSceneLimit;
@@ -36,27 +38,30 @@ public final class ScriptMonsterTideService {
this.monsterConfigOrders = new ConcurrentLinkedQueue<>(List.of(ordersConfigId));
this.monsterConfigIds = List.of(ordersConfigId);
this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterCreatedListener(onMonsterCreated);
this.sceneScriptManager
.getScriptMonsterSpawnService()
.addMonsterCreatedListener(onMonsterCreated);
this.sceneScriptManager.getScriptMonsterSpawnService().addMonsterDeadListener(onMonsterDead);
// spawn the first turn
for (int i = 0; i < this.monsterSceneLimit; i++) {
sceneScriptManager.addEntity(this.sceneScriptManager.createMonster(group.id, group.block_id, getNextMonster()));
sceneScriptManager.addEntity(
this.sceneScriptManager.createMonster(group.id, group.block_id, getNextMonster()));
}
}
public class OnMonsterCreated implements ScriptMonsterListener{
public class OnMonsterCreated implements ScriptMonsterListener {
@Override
public void onNotify(EntityMonster sceneMonster) {
if(monsterConfigIds.contains(sceneMonster.getConfigId()) && monsterSceneLimit > 0){
if (monsterConfigIds.contains(sceneMonster.getConfigId()) && monsterSceneLimit > 0) {
monsterAlive.incrementAndGet();
monsterTideCount.decrementAndGet();
}
}
}
public SceneMonster getNextMonster(){
public SceneMonster getNextMonster() {
var nextId = this.monsterConfigOrders.poll();
if(currentGroup.monsters.containsKey(nextId)){
if (currentGroup.monsters.containsKey(nextId)) {
return currentGroup.monsters.get(nextId);
}
// TODO some monster config_id do not exist in groups, so temporarily set it to the first
@@ -76,17 +81,22 @@ public final class ScriptMonsterTideService {
monsterKillCount.incrementAndGet();
if (monsterTideCount.get() > 0) {
// add more
sceneScriptManager.addEntity(sceneScriptManager.createMonster(currentGroup.id, currentGroup.block_id, getNextMonster()));
sceneScriptManager.addEntity(
sceneScriptManager.createMonster(
currentGroup.id, currentGroup.block_id, getNextMonster()));
}
// spawn the last turn of monsters
// fix the 5-2
sceneScriptManager.callEvent(new ScriptArgs(currentGroup.id, EventType.EVENT_MONSTER_TIDE_DIE, monsterKillCount.get()));
sceneScriptManager.callEvent(
new ScriptArgs(
currentGroup.id, EventType.EVENT_MONSTER_TIDE_DIE, monsterKillCount.get()));
}
}
public void unload(){
this.sceneScriptManager.getScriptMonsterSpawnService().removeMonsterCreatedListener(onMonsterCreated);
public void unload() {
this.sceneScriptManager
.getScriptMonsterSpawnService()
.removeMonsterCreatedListener(onMonsterCreated);
this.sceneScriptManager.getScriptMonsterSpawnService().removeMonsterDeadListener(onMonsterDead);
}
}

View File

@@ -4,17 +4,20 @@ import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.props.ElementType;
import emu.grasscutter.server.event.Cancellable;
import emu.grasscutter.server.event.types.EntityEvent;
import javax.annotation.Nullable;
import lombok.Getter;
import lombok.Setter;
import javax.annotation.Nullable;
public final class EntityDamageEvent extends EntityEvent implements Cancellable {
@Getter @Setter private float damage;
@Getter @Setter private ElementType attackElementType;
@Getter @Nullable private final GameEntity damager;
public EntityDamageEvent(GameEntity entity, float damage, ElementType attackElementType, @Nullable GameEntity damager) {
public EntityDamageEvent(
GameEntity entity,
float damage,
ElementType attackElementType,
@Nullable GameEntity damager) {
super(entity);
this.damage = damage;

View File

@@ -1,14 +1,14 @@
//package emu.grasscutter.server.packet.recv;
// package emu.grasscutter.server.packet.recv;
//
//import emu.grasscutter.net.packet.Opcodes;
//import emu.grasscutter.net.packet.PacketHandler;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.server.game.GameSession;
// import emu.grasscutter.net.packet.Opcodes;
// import emu.grasscutter.net.packet.PacketHandler;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.server.game.GameSession;
//
//@Opcodes(PacketOpcodes.AddCustomTeamReq)
//public class HandlerAddCustomTeamReq extends PacketHandler {
// @Opcodes(PacketOpcodes.AddCustomTeamReq)
// public class HandlerAddCustomTeamReq extends PacketHandler {
// @Override
// public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
// session.getPlayer().getTeamManager().addNewCustomTeam();
// }
//}
// }

View File

@@ -16,11 +16,10 @@ public class HandlerAddQuestContentProgressReq extends PacketHandler {
// Find all conditions in quest that are the same as the given one
var type = QuestContent.getContentTriggerByValue(req.getContentType());
if(type != null) {
if (type != null) {
session.getPlayer().getQuestManager().queueEvent(type, req.getParam());
}
session.send(new PacketAddQuestContentProgressRsp(req.getContentType()));
}
}

View File

@@ -10,9 +10,7 @@ import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAvatarChangeElementTypeRsp;
import lombok.val;
/**
* Changes the currently active avatars Element if possible
*/
/** Changes the currently active avatars Element if possible */
@Opcodes(PacketOpcodes.AvatarChangeElementTypeReq)
public class HandlerAvatarChangeElementTypeReq extends PacketHandler {
@@ -21,7 +19,9 @@ public class HandlerAvatarChangeElementTypeReq extends PacketHandler {
var req = AvatarChangeElementTypeReq.parseFrom(payload);
var area = GameData.getWorldAreaDataMap().get(req.getAreaId());
if (area == null || area.getElementType() == null || area.getElementType().getDepotIndex() <= 0) {
if (area == null
|| area.getElementType() == null
|| area.getElementType().getDepotIndex() <= 0) {
session.send(new PacketAvatarChangeElementTypeRsp(Retcode.RET_SVR_ERROR_VALUE));
return;
}
@@ -35,5 +35,4 @@ public class HandlerAvatarChangeElementTypeReq extends PacketHandler {
// Success
session.send(new PacketAvatarChangeElementTypeRsp());
}
}

View File

@@ -1,15 +1,15 @@
//package emu.grasscutter.server.packet.recv;
// package emu.grasscutter.server.packet.recv;
//
//import emu.grasscutter.net.packet.Opcodes;
//import emu.grasscutter.net.packet.PacketHandler;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.Unk2700BEDLIGJANCJClientReq;
//import emu.grasscutter.server.game.GameSession;
//import emu.grasscutter.server.packet.send.PacketChangeHomeBgmNotify;
//import emu.grasscutter.server.packet.send.PacketChangeHomeBgmRsp;
// import emu.grasscutter.net.packet.Opcodes;
// import emu.grasscutter.net.packet.PacketHandler;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.Unk2700BEDLIGJANCJClientReq;
// import emu.grasscutter.server.game.GameSession;
// import emu.grasscutter.server.packet.send.PacketChangeHomeBgmNotify;
// import emu.grasscutter.server.packet.send.PacketChangeHomeBgmRsp;
//
//@Opcodes(PacketOpcodes.Unk2700_BEDLIGJANCJ_ClientReq)
//public class HandlerChangeHomeBgmReq extends PacketHandler {
// @Opcodes(PacketOpcodes.Unk2700_BEDLIGJANCJ_ClientReq)
// public class HandlerChangeHomeBgmReq extends PacketHandler {
// @Override
// public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
// var req = Unk2700BEDLIGJANCJClientReq.Unk2700_BEDLIGJANCJ_ClientReq.parseFrom(payload);
@@ -23,4 +23,4 @@
// session.send(new PacketChangeHomeBgmNotify(homeBgmId));
// session.send(new PacketChangeHomeBgmRsp());
// }
//}
// }

View File

@@ -1,13 +1,13 @@
//package emu.grasscutter.server.packet.recv;
// package emu.grasscutter.server.packet.recv;
//
//import emu.grasscutter.net.packet.Opcodes;
//import emu.grasscutter.net.packet.PacketHandler;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.server.game.GameSession;
//import emu.grasscutter.server.packet.send.PacketHomeUnknown2Rsp;
// import emu.grasscutter.net.packet.Opcodes;
// import emu.grasscutter.net.packet.PacketHandler;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.server.game.GameSession;
// import emu.grasscutter.server.packet.send.PacketHomeUnknown2Rsp;
//
//@Opcodes(PacketOpcodes.Unk2700_ACILPONNGGK_ClientReq)
//public class HandlerHomeUnknown2Req extends PacketHandler {
// @Opcodes(PacketOpcodes.Unk2700_ACILPONNGGK_ClientReq)
// public class HandlerHomeUnknown2Req extends PacketHandler {
//
// @Override
// public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
@@ -16,4 +16,4 @@
// */
// session.send(new PacketHomeUnknown2Rsp());
// }
//}
// }

View File

@@ -23,9 +23,12 @@ public class HandlerMusicGameSettleReq extends PacketHandler {
val activityManager = session.getPlayer().getActivityManager();
val playerDataOpt = activityManager.getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_MUSIC_GAME);
val playerDataOpt =
activityManager.getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_MUSIC_GAME);
if (playerDataOpt.isEmpty()) {
session.send(new PacketMusicGameSettleRsp(RetcodeOuterClass.Retcode.RET_MUSIC_GAME_LEVEL_CONFIG_NOT_FOUND, req));
session.send(
new PacketMusicGameSettleRsp(
RetcodeOuterClass.Retcode.RET_MUSIC_GAME_LEVEL_CONFIG_NOT_FOUND, req));
return;
}
@@ -35,32 +38,38 @@ public class HandlerMusicGameSettleReq extends PacketHandler {
// check if custom beatmap
if (req.getUgcGuid() == 0) {
session.getPlayer().getActivityManager().triggerWatcher(
WatcherTriggerType.TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE,
String.valueOf(req.getMusicBasicId()),
String.valueOf(req.getScore())
);
session
.getPlayer()
.getActivityManager()
.triggerWatcher(
WatcherTriggerType.TRIGGER_FLEUR_FAIR_MUSIC_GAME_REACH_SCORE,
String.valueOf(req.getMusicBasicId()),
String.valueOf(req.getScore()));
isNewRecord = handler.setMusicGameRecord(playerData,
MusicGamePlayerData.MusicGameRecord.of()
.musicId(req.getMusicBasicId())
.maxCombo(req.getMaxCombo())
.maxScore(req.getScore())
.build());
isNewRecord =
handler.setMusicGameRecord(
playerData,
MusicGamePlayerData.MusicGameRecord.of()
.musicId(req.getMusicBasicId())
.maxCombo(req.getMaxCombo())
.maxScore(req.getScore())
.build());
// update activity info
session.send(new PacketActivityInfoNotify(handler.toProto(playerData, activityManager.getConditionExecutor())));
session.send(
new PacketActivityInfoNotify(
handler.toProto(playerData, activityManager.getConditionExecutor())));
} else {
handler.setMusicGameCustomBeatmapRecord(playerData,
MusicGamePlayerData.CustomBeatmapRecord.of()
.musicShareId(req.getUgcGuid())
.score(req.getMaxCombo())
.settle(req.getIsSaveScore())
.build());
handler.setMusicGameCustomBeatmapRecord(
playerData,
MusicGamePlayerData.CustomBeatmapRecord.of()
.musicShareId(req.getUgcGuid())
.score(req.getMaxCombo())
.settle(req.getIsSaveScore())
.build());
}
session.send(new PacketMusicGameSettleRsp(req.getMusicBasicId(), req.getUgcGuid(), isNewRecord));
session.send(
new PacketMusicGameSettleRsp(req.getMusicBasicId(), req.getUgcGuid(), isNewRecord));
}
}

View File

@@ -1,16 +1,16 @@
//package emu.grasscutter.server.packet.recv;
// package emu.grasscutter.server.packet.recv;
//
//import emu.grasscutter.net.packet.Opcodes;
//import emu.grasscutter.net.packet.PacketHandler;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq;
//import emu.grasscutter.server.game.GameSession;
// import emu.grasscutter.net.packet.Opcodes;
// import emu.grasscutter.net.packet.PacketHandler;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.RemoveCustomTeamReqOuterClass.RemoveCustomTeamReq;
// import emu.grasscutter.server.game.GameSession;
//
//@Opcodes(PacketOpcodes.RemoveCustomTeamReq)
//public class HandlerRemoveCustomTeamReq extends PacketHandler {
// @Opcodes(PacketOpcodes.RemoveCustomTeamReq)
// public class HandlerRemoveCustomTeamReq extends PacketHandler {
// @Override
// public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
// RemoveCustomTeamReq req = RemoveCustomTeamReq.parseFrom(payload);
// session.getPlayer().getTeamManager().removeCustomTeam(req.getId());
// }
//}
// }

View File

@@ -1,25 +1,25 @@
//package emu.grasscutter.server.packet.recv;
// package emu.grasscutter.server.packet.recv;
//
//import emu.grasscutter.database.DatabaseHelper;
//import emu.grasscutter.game.activity.musicgame.MusicGameActivityHandler;
//import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap;
//import emu.grasscutter.game.activity.musicgame.MusicGamePlayerData;
//import emu.grasscutter.game.props.ActivityType;
//import emu.grasscutter.net.packet.Opcodes;
//import emu.grasscutter.net.packet.PacketHandler;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.RetcodeOuterClass;
//import emu.grasscutter.net.proto.SaveUgcReqOuterClass;
//import emu.grasscutter.net.proto.UgcTypeOuterClass;
//import emu.grasscutter.server.game.GameSession;
//import emu.grasscutter.server.packet.send.PacketActivityInfoNotify;
//import emu.grasscutter.server.packet.send.PacketMusicGameCreateBeatmapRsp;
//import emu.grasscutter.utils.Utils;
//import java.util.Objects;
//import lombok.val;
// import emu.grasscutter.database.DatabaseHelper;
// import emu.grasscutter.game.activity.musicgame.MusicGameActivityHandler;
// import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap;
// import emu.grasscutter.game.activity.musicgame.MusicGamePlayerData;
// import emu.grasscutter.game.props.ActivityType;
// import emu.grasscutter.net.packet.Opcodes;
// import emu.grasscutter.net.packet.PacketHandler;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.RetcodeOuterClass;
// import emu.grasscutter.net.proto.SaveUgcReqOuterClass;
// import emu.grasscutter.net.proto.UgcTypeOuterClass;
// import emu.grasscutter.server.game.GameSession;
// import emu.grasscutter.server.packet.send.PacketActivityInfoNotify;
// import emu.grasscutter.server.packet.send.PacketMusicGameCreateBeatmapRsp;
// import emu.grasscutter.utils.Utils;
// import java.util.Objects;
// import lombok.val;
//
//@Opcodes(PacketOpcodes.SaveUgcReq)
//public class HandlerSaveUgcReq extends PacketHandler {
// @Opcodes(PacketOpcodes.SaveUgcReq)
// public class HandlerSaveUgcReq extends PacketHandler {
//
// @Override
// public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
@@ -48,7 +48,8 @@
// .realTimeEditTime(briefInfo.getRealTimeEditTime())
// .maxScore(briefInfo.getMaxScore())
// .authorUid(session.getPlayer().getUid())
// .beatmap(MusicGameBeatmap.parse(req.getMusicRecord().getMusicTrackListList()))
//
// .beatmap(MusicGameBeatmap.parse(req.getMusicRecord().getMusicTrackListList()))
// .createTime(Utils.getCurrentSeconds())
// .build();
//
@@ -58,7 +59,8 @@
// session
// .getPlayer()
// .getActivityManager()
// .getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_MUSIC_GAME);
//
// .getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_MUSIC_GAME);
// if (playerData.isEmpty()) {
// session.send(
// new PacketMusicGameCreateBeatmapRsp(
@@ -76,7 +78,8 @@
// .filter(Objects::nonNull)
// .filter(item -> item.getAuthorUid() == session.getPlayer().getUid())
// .filter(item -> item.getMusicId() == req.getMusicBriefInfo().getMusicId())
// .filter(item -> item.getSavePosition() == req.getMusicBriefInfo().getSaveIdx())
// .filter(item -> item.getSavePosition() ==
// req.getMusicBriefInfo().getSaveIdx())
// .findFirst();
//
// // delete old beatmap for player
@@ -90,8 +93,10 @@
// new PacketActivityInfoNotify(
// handler.toProto(
// playerData.get(),
// session.getPlayer().getActivityManager().getConditionExecutor())));
//
// session.getPlayer().getActivityManager().getConditionExecutor())));
// session.send(
// new PacketMusicGameCreateBeatmapRsp(musicGameBeatmap.getMusicShareId(), req.getUgcType()));
// new PacketMusicGameCreateBeatmapRsp(musicGameBeatmap.getMusicShareId(),
// req.getUgcType()));
// }
//}
// }

View File

@@ -4,11 +4,11 @@ import emu.grasscutter.game.entity.EntityGadget;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.quest.enums.QuestContent;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.SelectWorktopOptionReqOuterClass.SelectWorktopOptionReq;
import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.ScriptArgs;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketSelectWorktopOptionRsp;
@@ -26,14 +26,24 @@ public class HandlerSelectWorktopOptionReq extends PacketHandler {
return;
}
session.getPlayer().getScene().selectWorktopOptionWith(req);
session.getPlayer().getScene().getScriptManager().callEvent(
new ScriptArgs(entity.getGroupId(), EventType.EVENT_SELECT_OPTION, entity.getConfigId(), req.getOptionId())
);
session.getPlayer().getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_WORKTOP_SELECT, entity.getConfigId(), req.getOptionId());
session
.getPlayer()
.getScene()
.getScriptManager()
.callEvent(
new ScriptArgs(
entity.getGroupId(),
EventType.EVENT_SELECT_OPTION,
entity.getConfigId(),
req.getOptionId()));
session
.getPlayer()
.getQuestManager()
.queueEvent(
QuestContent.QUEST_CONTENT_WORKTOP_SELECT, entity.getConfigId(), req.getOptionId());
} finally {
// Always send packet
session.send(new PacketSelectWorktopOptionRsp(req.getGadgetEntityId(), req.getOptionId()));
}
}
}

View File

@@ -15,7 +15,8 @@ public class HandlerUpdateAbilityCreatedMovingPlatformNotify extends PacketHandl
var notify = UpdateAbilityCreatedMovingPlatformNotify.parseFrom(payload);
var entity = session.getPlayer().getScene().getEntityById(notify.getEntityId());
if (!(entity instanceof EntityGadget entityGadget) || !(entityGadget.getRouteConfig() instanceof AbilityRoute)) {
if (!(entity instanceof EntityGadget entityGadget)
|| !(entityGadget.getRouteConfig() instanceof AbilityRoute)) {
return;
}

View File

@@ -1,15 +1,16 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp;
//import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.AddCustomTeamRspOuterClass.AddCustomTeamRsp;
// import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
//
//public class PacketAddCustomTeamRsp extends BasePacket {
// public class PacketAddCustomTeamRsp extends BasePacket {
// public PacketAddCustomTeamRsp(Retcode retcode) {
// super(PacketOpcodes.AddCustomTeamRsp);
//
// AddCustomTeamRsp proto = AddCustomTeamRsp.newBuilder().setRetcode(retcode.getNumber()).build();
// AddCustomTeamRsp proto =
// AddCustomTeamRsp.newBuilder().setRetcode(retcode.getNumber()).build();
//
// this.setData(proto);
// }
@@ -17,4 +18,4 @@
// public PacketAddCustomTeamRsp() {
// this(Retcode.RET_SUCC);
// }
//}
// }

View File

@@ -1,15 +1,15 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.BeginCameraSceneLookNotifyOuterClass.BeginCameraSceneLookNotify;
//import emu.grasscutter.utils.Position;
//import java.util.ArrayList;
//import java.util.Collection;
//import lombok.Data;
//import lombok.NoArgsConstructor;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.BeginCameraSceneLookNotifyOuterClass.BeginCameraSceneLookNotify;
// import emu.grasscutter.utils.Position;
// import java.util.ArrayList;
// import java.util.Collection;
// import lombok.Data;
// import lombok.NoArgsConstructor;
//
//public class PacketBeginCameraSceneLookNotify extends BasePacket {
// public class PacketBeginCameraSceneLookNotify extends BasePacket {
//
// public PacketBeginCameraSceneLookNotify(CameraSceneLookNotify parameters) {
// super(PacketOpcodes.BeginCameraSceneLookNotify);
@@ -58,4 +58,4 @@
// int entityId = 0;
// Collection<String> otherParams = new ArrayList<>(0);
// }
//}
// }

View File

@@ -1,10 +1,10 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.Unk2700FJEHHCPCBLGServerNotify;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.Unk2700FJEHHCPCBLGServerNotify;
//
//public class PacketChangeHomeBgmNotify extends BasePacket {
// public class PacketChangeHomeBgmNotify extends BasePacket {
// public PacketChangeHomeBgmNotify(int homeBgmId) {
// super(PacketOpcodes.Unk2700_FJEHHCPCBLG_ServerNotify);
//
@@ -15,4 +15,4 @@
//
// this.setData(notify);
// }
//}
// }

View File

@@ -1,10 +1,10 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.Unk2700OGHMHELMBNNServerRsp;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.Unk2700OGHMHELMBNNServerRsp;
//
//public class PacketChangeHomeBgmRsp extends BasePacket {
// public class PacketChangeHomeBgmRsp extends BasePacket {
// public PacketChangeHomeBgmRsp() {
// super(PacketOpcodes.Unk2700_OGHMHELMBNN_ServerRsp);
//
@@ -15,4 +15,4 @@
//
// this.setData(rsp);
// }
//}
// }

View File

@@ -1,11 +1,11 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.game.player.Player;
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify;
// import emu.grasscutter.game.player.Player;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.CustomTeamListNotifyOuterClass.CustomTeamListNotify;
//
//public class PacketCustomTeamListNotify extends BasePacket {
// public class PacketCustomTeamListNotify extends BasePacket {
// public PacketCustomTeamListNotify(Player player) {
// super(PacketOpcodes.CustomTeamListNotify);
//
@@ -26,4 +26,4 @@
//
// this.setData(proto);
// }
//}
// }

View File

@@ -5,7 +5,6 @@ import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.EntityFightPropUpdateNotifyOuterClass.EntityFightPropUpdateNotify;
import java.util.Collection;
public class PacketEntityFightPropUpdateNotify extends BasePacket {
@@ -24,8 +23,7 @@ public class PacketEntityFightPropUpdateNotify extends BasePacket {
public PacketEntityFightPropUpdateNotify(GameEntity entity, Collection<FightProperty> props) {
super(PacketOpcodes.EntityFightPropUpdateNotify);
var protoBuilder = EntityFightPropUpdateNotify.newBuilder()
.setEntityId(entity.getId());
var protoBuilder = EntityFightPropUpdateNotify.newBuilder().setEntityId(entity.getId());
props.forEach(p -> protoBuilder.putFightPropMap(p.getId(), entity.getFightProperty(p)));
this.setData(protoBuilder);

View File

@@ -15,7 +15,7 @@ public class PacketFinishedParentQuestNotify extends BasePacket {
FinishedParentQuestNotify.Builder proto = FinishedParentQuestNotify.newBuilder();
for (GameMainQuest mainQuest : player.getQuestManager().getMainQuests().values()) {
//Canceled Quests do not appear in this packet
// Canceled Quests do not appear in this packet
if (mainQuest.getState() != ParentQuestState.PARENT_QUEST_STATE_CANCELED) {
proto.addParentQuestList(mainQuest.toProto(false));
}

View File

@@ -4,7 +4,6 @@ import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.FinishedParentQuestUpdateNotifyOuterClass.FinishedParentQuestUpdateNotify;
import java.util.List;
public class PacketFinishedParentQuestUpdateNotify extends BasePacket {
@@ -12,9 +11,10 @@ public class PacketFinishedParentQuestUpdateNotify extends BasePacket {
public PacketFinishedParentQuestUpdateNotify(GameMainQuest quest) {
super(PacketOpcodes.FinishedParentQuestUpdateNotify);
FinishedParentQuestUpdateNotify proto = FinishedParentQuestUpdateNotify.newBuilder()
.addParentQuestList(quest.toProto(true))
.build();
FinishedParentQuestUpdateNotify proto =
FinishedParentQuestUpdateNotify.newBuilder()
.addParentQuestList(quest.toProto(true))
.build();
this.setData(proto);
}

View File

@@ -5,7 +5,6 @@ import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetAllMailResultNotifyOuterClass.GetAllMailResultNotify;
import emu.grasscutter.utils.Utils;
import java.time.Instant;
import java.util.List;
@@ -17,18 +16,21 @@ public final class PacketGetAllMailResultNotify extends BasePacket {
public PacketGetAllMailResultNotify(Player player, boolean gifts) {
super(PacketOpcodes.GetAllMailResultNotify);
var packet = GetAllMailResultNotify.newBuilder()
.setTransaction(player.getUid() + "-" + Utils.getCurrentSeconds() + "-" + 0)
.setIsCollected(gifts)
.setPacketBeSentNum(1)
.setPacketNum(1);
var packet =
GetAllMailResultNotify.newBuilder()
.setTransaction(player.getUid() + "-" + Utils.getCurrentSeconds() + "-" + 0)
.setIsCollected(gifts)
.setPacketBeSentNum(1)
.setPacketNum(1);
var inbox = player.getAllMail();
if (!gifts && inbox.size() > 0) {
packet.addAllMailList(inbox.stream()
.filter(mail -> mail.stateValue == 1)
.filter(mail -> mail.expireTime > Instant.now().getEpochSecond())
.map(mail -> mail.toProto(player)).toList());
packet.addAllMailList(
inbox.stream()
.filter(mail -> mail.stateValue == 1)
.filter(mail -> mail.expireTime > Instant.now().getEpochSecond())
.map(mail -> mail.toProto(player))
.toList());
} else {
// Empty mailbox.
// TODO: Implement the gift mailbox.

View File

@@ -1,10 +1,10 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.HomeUnknown1NotifyOuterClass;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.HomeUnknown1NotifyOuterClass;
//
//public class PacketHomeUnknown1Notify extends BasePacket {
// public class PacketHomeUnknown1Notify extends BasePacket {
//
// public PacketHomeUnknown1Notify(boolean isEnterEditMode) {
// super(PacketOpcodes.Unk2700_JDMPECKFGIG_ServerNotify);
@@ -15,4 +15,4 @@
//
// this.setData(proto);
// }
//}
// }

View File

@@ -1,11 +1,11 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
//
//public class PacketHomeUnknown2Rsp extends BasePacket {
// public class PacketHomeUnknown2Rsp extends BasePacket {
//
// public PacketHomeUnknown2Rsp() {
// super(PacketOpcodes.Unk2700_KIIOGMKFNNP_ServerRsp);
// }
//}
// }

View File

@@ -18,14 +18,15 @@ public class PacketMusicGameSettleRsp extends BasePacket {
this.setData(proto);
}
public PacketMusicGameSettleRsp(RetcodeOuterClass.Retcode errorCode, MusicGameSettleReqOuterClass.MusicGameSettleReq req) {
public PacketMusicGameSettleRsp(
RetcodeOuterClass.Retcode errorCode, MusicGameSettleReqOuterClass.MusicGameSettleReq req) {
super(PacketOpcodes.MusicGameSettleRsp);
var proto = MusicGameSettleRspOuterClass.MusicGameSettleRsp.newBuilder()
.setRetcode(errorCode.getNumber())
.setMusicBasicId(req.getMusicBasicId())
.setUgcGuid(req.getUgcGuid());
var proto =
MusicGameSettleRspOuterClass.MusicGameSettleRsp.newBuilder()
.setRetcode(errorCode.getNumber())
.setMusicBasicId(req.getMusicBasicId())
.setUgcGuid(req.getUgcGuid());
this.setData(proto);
}

View File

@@ -10,10 +10,11 @@ public class PacketPlatformStartRouteNotify extends BasePacket {
public PacketPlatformStartRouteNotify(EntityGadget gadgetEntity) {
super(PacketOpcodes.PlatformStartRouteNotify);
val notify = PlatformStartRouteNotify.newBuilder()
.setEntityId(gadgetEntity.getId())
.setSceneTime(gadgetEntity.getScene().getSceneTime())
.setPlatform(gadgetEntity.getPlatformInfo());
val notify =
PlatformStartRouteNotify.newBuilder()
.setEntityId(gadgetEntity.getId())
.setSceneTime(gadgetEntity.getScene().getSceneTime())
.setPlatform(gadgetEntity.getPlatformInfo());
this.setData(notify);
}

View File

@@ -9,11 +9,12 @@ public class PacketPlatformStopRouteNotify extends BasePacket {
public PacketPlatformStopRouteNotify(EntityGadget gadgetEntity) {
super(PacketOpcodes.PlatformStopRouteNotify);
var notify = PlatformStopRouteNotifyOuterClass.PlatformStopRouteNotify.newBuilder()
.setPlatform(gadgetEntity.getPlatformInfo())
.setSceneTime(gadgetEntity.getScene().getSceneTime())
.setEntityId(gadgetEntity.getId())
.build();
var notify =
PlatformStopRouteNotifyOuterClass.PlatformStopRouteNotify.newBuilder()
.setPlatform(gadgetEntity.getPlatformInfo())
.setSceneTime(gadgetEntity.getScene().getSceneTime())
.setEntityId(gadgetEntity.getId())
.build();
this.setData(notify);
}

View File

@@ -1,16 +1,17 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp;
//import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.RemoveCustomTeamRspOuterClass.RemoveCustomTeamRsp;
// import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
//
//public class PacketRemoveCustomTeamRsp extends BasePacket {
// public class PacketRemoveCustomTeamRsp extends BasePacket {
// public PacketRemoveCustomTeamRsp(Retcode retcode, int id) {
// super(PacketOpcodes.RemoveCustomTeamRsp);
//
// RemoveCustomTeamRsp proto =
// RemoveCustomTeamRsp.newBuilder().setRetcode(retcode.getNumber()).setId(id).build();
//
// RemoveCustomTeamRsp.newBuilder().setRetcode(retcode.getNumber()).setId(id).build();
//
// this.setData(proto);
// }
@@ -18,4 +19,4 @@
// public PacketRemoveCustomTeamRsp(int id) {
// this(Retcode.RET_SUCC, id);
// }
//}
// }

View File

@@ -1,10 +1,10 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.Unk2700MEBFPBDNPGOServerNotify;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.Unk2700MEBFPBDNPGOServerNotify;
//
//public class PacketUnlockHomeBgmNotify extends BasePacket {
// public class PacketUnlockHomeBgmNotify extends BasePacket {
// public PacketUnlockHomeBgmNotify(int homeBgmId) {
// super(PacketOpcodes.Unk2700_MEBFPBDNPGO_ServerNotify);
//
@@ -15,4 +15,4 @@
//
// this.setData(notify);
// }
//}
// }

View File

@@ -1,11 +1,11 @@
//package emu.grasscutter.server.packet.send;
// package emu.grasscutter.server.packet.send;
//
//import emu.grasscutter.game.player.Player;
//import emu.grasscutter.net.packet.BasePacket;
//import emu.grasscutter.net.packet.PacketOpcodes;
//import emu.grasscutter.net.proto.Unk2700LOHBMOKOPLHServerNotify;
// import emu.grasscutter.game.player.Player;
// import emu.grasscutter.net.packet.BasePacket;
// import emu.grasscutter.net.packet.PacketOpcodes;
// import emu.grasscutter.net.proto.Unk2700LOHBMOKOPLHServerNotify;
//
//public class PacketUnlockedHomeBgmNotify extends BasePacket {
// public class PacketUnlockedHomeBgmNotify extends BasePacket {
// public PacketUnlockedHomeBgmNotify(Player player) {
// super(PacketOpcodes.Unk2700_LOHBMOKOPLH_ServerNotify);
//
@@ -22,4 +22,4 @@
//
// this.setData(notify);
// }
//}
// }