Run Spotless on src/main

This commit is contained in:
KingRainbow44
2023-03-31 22:30:45 -04:00
parent 99822b0e22
commit fc05602128
1003 changed files with 60650 additions and 58050 deletions

View File

@@ -1,32 +1,31 @@
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import emu.grasscutter.net.proto.FurnitureMakeDataOuterClass;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class FurnitureMakeSlotItem {
@Id
int index;
int makeId;
int avatarId;
int beginTime;
int durTime;
public FurnitureMakeDataOuterClass.FurnitureMakeData toProto() {
return FurnitureMakeDataOuterClass.FurnitureMakeData.newBuilder()
.setIndex(index)
.setAvatarId(avatarId)
.setMakeId(makeId)
.setBeginTime(beginTime)
.setDurTime(durTime)
.build();
}
}
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import emu.grasscutter.net.proto.FurnitureMakeDataOuterClass;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class FurnitureMakeSlotItem {
@Id int index;
int makeId;
int avatarId;
int beginTime;
int durTime;
public FurnitureMakeDataOuterClass.FurnitureMakeData toProto() {
return FurnitureMakeDataOuterClass.FurnitureMakeData.newBuilder()
.setIndex(index)
.setAvatarId(avatarId)
.setMakeId(makeId)
.setBeginTime(beginTime)
.setDurTime(durTime)
.build();
}
}

View File

@@ -1,341 +1,358 @@
package emu.grasscutter.game.home;
import dev.morphia.annotations.*;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.HomeWorldLevelData;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@Entity(value = "homes", useDiscriminator = false)
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class GameHome {
@Id
String id;
@Indexed(options = @IndexOptions(unique = true))
long ownerUid;
@Transient
Player player;
int level;
int exp;
int lastUpdatedTime;
int nextUpdateTime;
int storedCoin;
int storedFetterExp;
List<FurnitureMakeSlotItem> furnitureMakeSlotItemList;
ConcurrentHashMap<Integer, HomeSceneItem> sceneMap;
Set<Integer> unlockedHomeBgmList;
int enterHomeOption;
public static GameHome getByUid(Integer uid) {
var home = DatabaseHelper.getHomeByUid(uid);
if (home == null) {
home = GameHome.create(uid);
}
return home;
}
public static GameHome create(Integer uid) {
return GameHome.of()
.ownerUid(uid)
.level(1)
.sceneMap(new ConcurrentHashMap<>())
.unlockedHomeBgmList(new HashSet<>())
.build();
}
public void save() {
DatabaseHelper.saveHome(this);
}
public HomeSceneItem getHomeSceneItem(int sceneId) {
return sceneMap.computeIfAbsent(sceneId, e -> {
var defaultItem = GameData.getHomeworldDefaultSaveData().get(sceneId);
if (defaultItem != null) {
Grasscutter.getLogger().info("Set player {} home {} to initial setting", ownerUid, sceneId);
return HomeSceneItem.parseFrom(defaultItem, sceneId);
} else {
// Realm res missing bricks account, use default realm data to allow main house
defaultItem = GameData.getHomeworldDefaultSaveData().get(2001);
return HomeSceneItem.parseFrom(defaultItem, sceneId);
}
});
}
public void onOwnerLogin(Player player) {
if (this.player == null)
this.player = player;
player.getSession().send(new PacketHomeBasicInfoNotify(player, false));
player.getSession().send(new PacketPlayerHomeCompInfoNotify(player));
player.getSession().send(new PacketHomeComfortInfoNotify(player));
player.getSession().send(new PacketFurnitureCurModuleArrangeCountNotify());
player.getSession().send(new PacketHomeMarkPointNotify(player));
player.getSession().send(new PacketHomeAllUnlockedBgmIdListNotify(player));
checkAccumulatedResources(player);
player.getSession().send(new PacketHomeResourceNotify(player));
}
// Tell the client the reward is claimed or realm unlocked
public void onClaimReward(Player player) {
player.getSession().send(new PacketPlayerHomeCompInfoNotify(player));
}
public Player getPlayer() {
if (this.player == null)
this.player = Grasscutter.getGameServer().getPlayerByUid((int) this.ownerUid, true);
return this.player;
}
public HomeWorldLevelData getLevelData() {
return GameData.getHomeWorldLevelDataMap().get(level);
}
public boolean addUnlockedHomeBgm(int homeBgmId) {
if (!getUnlockedHomeBgmList().add(homeBgmId)) return false;
var player = this.getPlayer();
player.sendPacket(new PacketHomeNewUnlockedBgmIdListNotify(homeBgmId));
player.sendPacket(new PacketHomeAllUnlockedBgmIdListNotify(player));
save();
return true;
}
public Set<Integer> getUnlockedHomeBgmList() {
if (this.unlockedHomeBgmList == null) {
this.unlockedHomeBgmList = new HashSet<>();
}
if (this.unlockedHomeBgmList.addAll(getDefaultUnlockedHomeBgmIds())) {
save();
}
return this.unlockedHomeBgmList;
}
private Set<Integer> getDefaultUnlockedHomeBgmIds() {
return GameData.getHomeWorldBgmDataMap().int2ObjectEntrySet().stream()
.filter(e -> e.getValue().isDefaultUnlock())
.map(Int2ObjectMap.Entry::getIntKey)
.collect(Collectors.toUnmodifiableSet());
}
// Same as Player.java addExpDirectly
public void addExp(Player player, int count) {
exp += count;
int reqExp = getExpRequired(level);
while (exp >= reqExp && reqExp > 0) {
exp -= reqExp;
level += 1;
reqExp = getExpRequired(level);
// Update client level and exp
player.getSession().send(new PacketHomeBasicInfoNotify(player, false));
}
// Update client home
onOwnerLogin(player);
}
private void checkAccumulatedResources(Player player) {
int clientTime = (int) ZonedDateTime.now().toEpochSecond();
int owedRewards = 0;
// Don't owe if previous update hasn't passed
if (nextUpdateTime > clientTime) {
return;
}
if (lastUpdatedTime == 0) {
lastUpdatedTime = clientTime;
}
// Calculate number of owed rewards
owedRewards = 1 + ((clientTime - nextUpdateTime) / 3600);
// Ensure next update is at top of the hour
nextUpdateTime = (int) ZonedDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS).toEpochSecond();
// Get resources
var hourlyResources = getComfortResources(player);
var owedCoin = hourlyResources.get(0) * owedRewards;
var owedFetter = hourlyResources.get(1) * owedRewards;
// Update stored amounts
storeResources(player, owedCoin, owedFetter);
}
public void takeHomeCoin(Player player) {
player.getInventory().addItem(204, storedCoin);
storedCoin = 0;
save();
player.getSession().send(new PacketHomeResourceNotify(player));
}
public void takeHomeFetter(Player player) {
List<Integer> invitedAvatars = new ArrayList<>();
// Outdoors avatars
sceneMap.get(player.getCurrentRealmId() + 2000).getBlockItems().forEach((i, e) -> {
e.getDeployNPCList().forEach(id -> {
invitedAvatars.add(id.getAvatarId());
});
});
// Check as realm 5 inside is not in defaults and will be null
if (Objects.nonNull(sceneMap.get(player.getCurrentRealmId() + 2200))) {
// Indoors avatars
sceneMap.get(player.getCurrentRealmId() + 2200).getBlockItems().forEach((i, e) -> {
e.getDeployNPCList().forEach(id -> {
invitedAvatars.add(id.getAvatarId());
});
});
}
// Add exp to all avatars
invitedAvatars.forEach(id -> {
var avatar = player.getAvatars().getAvatarById(id);
player.getServer().getInventorySystem().upgradeAvatarFetterLevel(player, avatar, storedFetterExp);
});
storedFetterExp = 0;
save();
player.getSession().send(new PacketHomeResourceNotify(player));
}
public void updateHourlyResources(Player player) {
int clientTime = (int) ZonedDateTime.now().toEpochSecond();
// Check if resources can update
if (nextUpdateTime > clientTime) {
return;
}
// If no update has occurred before
if (lastUpdatedTime == 0) {
lastUpdatedTime = clientTime;
}
// Update stored resources
storeResources(player, 0, 0);
lastUpdatedTime = clientTime;
nextUpdateTime = (int) ZonedDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS).toEpochSecond();
save();
// Send packet
player.getSession().send(new PacketHomeResourceNotify(player));
}
public void storeResources(Player player, int owedCoin, int owedFetter) {
// Get max values
var maxCoin = getMaxCoin(level);
var maxFetter = getMaxFetter(level);
int newCoin = 0;
int newFetter = 0;
// Check if resources are already max
if (storedCoin >= maxCoin && storedFetterExp >= maxFetter) {
return;
}
// Get resources
var hourlyResources = getComfortResources(player);
// Update home coin
if (storedCoin < maxCoin) {
// Check if owed or hourly
if (owedCoin == 0) {
newCoin = storedCoin + hourlyResources.get(0);
} else {
newCoin = storedCoin + owedCoin;
}
// Ensure max is not exceeded
storedCoin = (maxCoin >= newCoin) ? newCoin : maxCoin;
}
// Update fetter exp
if (storedFetterExp < maxFetter) {
// Check if owed or hourly
if (owedFetter == 0) {
newFetter = storedFetterExp + hourlyResources.get(1);
} else {
newFetter = storedFetterExp + owedFetter;
}
// Ensure max is not exceeded
storedFetterExp = (maxFetter >= newFetter) ? newFetter : maxFetter;
}
save();
}
public List<Integer> getComfortResources(Player player) {
List<Integer> allHomesComfort = new ArrayList<>();
int highestComfort = 0;
// Use HomeComfortInfoNotify data since comfort value isn't stored
if (player.getRealmList() == null) {
return List.of(0, 0);
}
// Calculate comfort value for each home
for (int moduleId : player.getRealmList()) {
var homeScene = player.getHome().getHomeSceneItem(moduleId + 2000);
allHomesComfort.add(homeScene.calComfort());
}
// Get highest comfort value
highestComfort = Collections.max(allHomesComfort);
// Determine hourly resources
if (highestComfort >= 20000) {
return List.of(30, 5);
} else if (highestComfort >= 15000) {
return List.of(28, 5);
} else if (highestComfort >= 12000) {
return List.of(26, 5);
} else if (highestComfort >= 10000) {
return List.of(24, 4);
} else if (highestComfort >= 8000) {
return List.of(22, 4);
} else if (highestComfort >= 6000) {
return List.of(20, 4);
} else if (highestComfort >= 4500) {
return List.of(16, 3);
} else if (highestComfort >= 3000) {
return List.of(12, 3);
} else if (highestComfort >= 2000) {
return List.of(8, 2);
} else
return List.of(4, 2);
}
private int getExpRequired(int level) {
HomeWorldLevelData levelData = GameData.getHomeWorldLevelDataMap().get(level);
return levelData != null ? levelData.getExp() : 0;
}
public int getMaxCoin(int level) {
var levelData = GameData.getHomeWorldLevelDataMap().get(level);
return levelData != null ? levelData.getHomeCoinStoreLimit() : 0;
}
public int getMaxFetter(int level) {
var levelData = GameData.getHomeWorldLevelDataMap().get(level);
return levelData != null ? levelData.getHomeFetterExpStoreLimit() : 0;
}
}
package emu.grasscutter.game.home;
import dev.morphia.annotations.*;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.HomeWorldLevelData;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity(value = "homes", useDiscriminator = false)
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class GameHome {
@Id String id;
@Indexed(options = @IndexOptions(unique = true))
long ownerUid;
@Transient Player player;
int level;
int exp;
int lastUpdatedTime;
int nextUpdateTime;
int storedCoin;
int storedFetterExp;
List<FurnitureMakeSlotItem> furnitureMakeSlotItemList;
ConcurrentHashMap<Integer, HomeSceneItem> sceneMap;
Set<Integer> unlockedHomeBgmList;
int enterHomeOption;
public static GameHome getByUid(Integer uid) {
var home = DatabaseHelper.getHomeByUid(uid);
if (home == null) {
home = GameHome.create(uid);
}
return home;
}
public static GameHome create(Integer uid) {
return GameHome.of()
.ownerUid(uid)
.level(1)
.sceneMap(new ConcurrentHashMap<>())
.unlockedHomeBgmList(new HashSet<>())
.build();
}
public void save() {
DatabaseHelper.saveHome(this);
}
public HomeSceneItem getHomeSceneItem(int sceneId) {
return sceneMap.computeIfAbsent(
sceneId,
e -> {
var defaultItem = GameData.getHomeworldDefaultSaveData().get(sceneId);
if (defaultItem != null) {
Grasscutter.getLogger()
.info("Set player {} home {} to initial setting", ownerUid, sceneId);
return HomeSceneItem.parseFrom(defaultItem, sceneId);
} else {
// Realm res missing bricks account, use default realm data to allow main house
defaultItem = GameData.getHomeworldDefaultSaveData().get(2001);
return HomeSceneItem.parseFrom(defaultItem, sceneId);
}
});
}
public void onOwnerLogin(Player player) {
if (this.player == null) this.player = player;
player.getSession().send(new PacketHomeBasicInfoNotify(player, false));
player.getSession().send(new PacketPlayerHomeCompInfoNotify(player));
player.getSession().send(new PacketHomeComfortInfoNotify(player));
player.getSession().send(new PacketFurnitureCurModuleArrangeCountNotify());
player.getSession().send(new PacketHomeMarkPointNotify(player));
player.getSession().send(new PacketHomeAllUnlockedBgmIdListNotify(player));
checkAccumulatedResources(player);
player.getSession().send(new PacketHomeResourceNotify(player));
}
// Tell the client the reward is claimed or realm unlocked
public void onClaimReward(Player player) {
player.getSession().send(new PacketPlayerHomeCompInfoNotify(player));
}
public Player getPlayer() {
if (this.player == null)
this.player = Grasscutter.getGameServer().getPlayerByUid((int) this.ownerUid, true);
return this.player;
}
public HomeWorldLevelData getLevelData() {
return GameData.getHomeWorldLevelDataMap().get(level);
}
public boolean addUnlockedHomeBgm(int homeBgmId) {
if (!getUnlockedHomeBgmList().add(homeBgmId)) return false;
var player = this.getPlayer();
player.sendPacket(new PacketHomeNewUnlockedBgmIdListNotify(homeBgmId));
player.sendPacket(new PacketHomeAllUnlockedBgmIdListNotify(player));
save();
return true;
}
public Set<Integer> getUnlockedHomeBgmList() {
if (this.unlockedHomeBgmList == null) {
this.unlockedHomeBgmList = new HashSet<>();
}
if (this.unlockedHomeBgmList.addAll(getDefaultUnlockedHomeBgmIds())) {
save();
}
return this.unlockedHomeBgmList;
}
private Set<Integer> getDefaultUnlockedHomeBgmIds() {
return GameData.getHomeWorldBgmDataMap().int2ObjectEntrySet().stream()
.filter(e -> e.getValue().isDefaultUnlock())
.map(Int2ObjectMap.Entry::getIntKey)
.collect(Collectors.toUnmodifiableSet());
}
// Same as Player.java addExpDirectly
public void addExp(Player player, int count) {
exp += count;
int reqExp = getExpRequired(level);
while (exp >= reqExp && reqExp > 0) {
exp -= reqExp;
level += 1;
reqExp = getExpRequired(level);
// Update client level and exp
player.getSession().send(new PacketHomeBasicInfoNotify(player, false));
}
// Update client home
onOwnerLogin(player);
}
private void checkAccumulatedResources(Player player) {
int clientTime = (int) ZonedDateTime.now().toEpochSecond();
int owedRewards = 0;
// Don't owe if previous update hasn't passed
if (nextUpdateTime > clientTime) {
return;
}
if (lastUpdatedTime == 0) {
lastUpdatedTime = clientTime;
}
// Calculate number of owed rewards
owedRewards = 1 + ((clientTime - nextUpdateTime) / 3600);
// Ensure next update is at top of the hour
nextUpdateTime =
(int) ZonedDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS).toEpochSecond();
// Get resources
var hourlyResources = getComfortResources(player);
var owedCoin = hourlyResources.get(0) * owedRewards;
var owedFetter = hourlyResources.get(1) * owedRewards;
// Update stored amounts
storeResources(player, owedCoin, owedFetter);
}
public void takeHomeCoin(Player player) {
player.getInventory().addItem(204, storedCoin);
storedCoin = 0;
save();
player.getSession().send(new PacketHomeResourceNotify(player));
}
public void takeHomeFetter(Player player) {
List<Integer> invitedAvatars = new ArrayList<>();
// Outdoors avatars
sceneMap
.get(player.getCurrentRealmId() + 2000)
.getBlockItems()
.forEach(
(i, e) -> {
e.getDeployNPCList()
.forEach(
id -> {
invitedAvatars.add(id.getAvatarId());
});
});
// Check as realm 5 inside is not in defaults and will be null
if (Objects.nonNull(sceneMap.get(player.getCurrentRealmId() + 2200))) {
// Indoors avatars
sceneMap
.get(player.getCurrentRealmId() + 2200)
.getBlockItems()
.forEach(
(i, e) -> {
e.getDeployNPCList()
.forEach(
id -> {
invitedAvatars.add(id.getAvatarId());
});
});
}
// Add exp to all avatars
invitedAvatars.forEach(
id -> {
var avatar = player.getAvatars().getAvatarById(id);
player
.getServer()
.getInventorySystem()
.upgradeAvatarFetterLevel(player, avatar, storedFetterExp);
});
storedFetterExp = 0;
save();
player.getSession().send(new PacketHomeResourceNotify(player));
}
public void updateHourlyResources(Player player) {
int clientTime = (int) ZonedDateTime.now().toEpochSecond();
// Check if resources can update
if (nextUpdateTime > clientTime) {
return;
}
// If no update has occurred before
if (lastUpdatedTime == 0) {
lastUpdatedTime = clientTime;
}
// Update stored resources
storeResources(player, 0, 0);
lastUpdatedTime = clientTime;
nextUpdateTime =
(int) ZonedDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS).toEpochSecond();
save();
// Send packet
player.getSession().send(new PacketHomeResourceNotify(player));
}
public void storeResources(Player player, int owedCoin, int owedFetter) {
// Get max values
var maxCoin = getMaxCoin(level);
var maxFetter = getMaxFetter(level);
int newCoin = 0;
int newFetter = 0;
// Check if resources are already max
if (storedCoin >= maxCoin && storedFetterExp >= maxFetter) {
return;
}
// Get resources
var hourlyResources = getComfortResources(player);
// Update home coin
if (storedCoin < maxCoin) {
// Check if owed or hourly
if (owedCoin == 0) {
newCoin = storedCoin + hourlyResources.get(0);
} else {
newCoin = storedCoin + owedCoin;
}
// Ensure max is not exceeded
storedCoin = (maxCoin >= newCoin) ? newCoin : maxCoin;
}
// Update fetter exp
if (storedFetterExp < maxFetter) {
// Check if owed or hourly
if (owedFetter == 0) {
newFetter = storedFetterExp + hourlyResources.get(1);
} else {
newFetter = storedFetterExp + owedFetter;
}
// Ensure max is not exceeded
storedFetterExp = (maxFetter >= newFetter) ? newFetter : maxFetter;
}
save();
}
public List<Integer> getComfortResources(Player player) {
List<Integer> allHomesComfort = new ArrayList<>();
int highestComfort = 0;
// Use HomeComfortInfoNotify data since comfort value isn't stored
if (player.getRealmList() == null) {
return List.of(0, 0);
}
// Calculate comfort value for each home
for (int moduleId : player.getRealmList()) {
var homeScene = player.getHome().getHomeSceneItem(moduleId + 2000);
allHomesComfort.add(homeScene.calComfort());
}
// Get highest comfort value
highestComfort = Collections.max(allHomesComfort);
// Determine hourly resources
if (highestComfort >= 20000) {
return List.of(30, 5);
} else if (highestComfort >= 15000) {
return List.of(28, 5);
} else if (highestComfort >= 12000) {
return List.of(26, 5);
} else if (highestComfort >= 10000) {
return List.of(24, 4);
} else if (highestComfort >= 8000) {
return List.of(22, 4);
} else if (highestComfort >= 6000) {
return List.of(20, 4);
} else if (highestComfort >= 4500) {
return List.of(16, 3);
} else if (highestComfort >= 3000) {
return List.of(12, 3);
} else if (highestComfort >= 2000) {
return List.of(8, 2);
} else return List.of(4, 2);
}
private int getExpRequired(int level) {
HomeWorldLevelData levelData = GameData.getHomeWorldLevelDataMap().get(level);
return levelData != null ? levelData.getExp() : 0;
}
public int getMaxCoin(int level) {
var levelData = GameData.getHomeWorldLevelDataMap().get(level);
return levelData != null ? levelData.getHomeCoinStoreLimit() : 0;
}
public int getMaxFetter(int level) {
var levelData = GameData.getHomeWorldLevelDataMap().get(level);
return levelData != null ? levelData.getHomeFetterExpStoreLimit() : 0;
}
}

View File

@@ -1,36 +1,35 @@
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import emu.grasscutter.net.proto.HomeAnimalDataOuterClass;
import emu.grasscutter.utils.Position;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class HomeAnimalItem {
int furnitureId;
Position spawnPos;
Position spawnRot;
public static HomeAnimalItem parseFrom(HomeAnimalDataOuterClass.HomeAnimalData homeAnimalData) {
return HomeAnimalItem.of()
.furnitureId(homeAnimalData.getFurnitureId())
.spawnPos(new Position(homeAnimalData.getSpawnPos()))
.spawnRot(new Position(homeAnimalData.getSpawnRot()))
.build();
}
public HomeAnimalDataOuterClass.HomeAnimalData toProto() {
return HomeAnimalDataOuterClass.HomeAnimalData.newBuilder()
.setFurnitureId(furnitureId)
.setSpawnPos(spawnPos.toProto())
.setSpawnRot(spawnRot.toProto())
.build();
}
}
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import emu.grasscutter.net.proto.HomeAnimalDataOuterClass;
import emu.grasscutter.utils.Position;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class HomeAnimalItem {
int furnitureId;
Position spawnPos;
Position spawnRot;
public static HomeAnimalItem parseFrom(HomeAnimalDataOuterClass.HomeAnimalData homeAnimalData) {
return HomeAnimalItem.of()
.furnitureId(homeAnimalData.getFurnitureId())
.spawnPos(new Position(homeAnimalData.getSpawnPos()))
.spawnRot(new Position(homeAnimalData.getSpawnRot()))
.build();
}
public HomeAnimalDataOuterClass.HomeAnimalData toProto() {
return HomeAnimalDataOuterClass.HomeAnimalData.newBuilder()
.setFurnitureId(furnitureId)
.setSpawnPos(spawnPos.toProto())
.setSpawnRot(spawnRot.toProto())
.build();
}
}

View File

@@ -1,86 +1,87 @@
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
import emu.grasscutter.net.proto.HomeBlockArrangementInfoOuterClass.HomeBlockArrangementInfo;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import java.util.List;
@Entity
@Data
@Builder(builderMethodName = "of")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class HomeBlockItem {
@Id
int blockId;
boolean unlocked;
List<HomeFurnitureItem> deployFurnitureList;
List<HomeFurnitureItem> persistentFurnitureList;
List<HomeAnimalItem> deployAnimalList;
List<HomeNPCItem> deployNPCList;
public static HomeBlockItem parseFrom(HomeworldDefaultSaveData.HomeBlock homeBlock) {
// create from default setting
return HomeBlockItem.of()
.blockId(homeBlock.getBlockId())
.unlocked(homeBlock.getFurnitures() != null)
.deployFurnitureList(
homeBlock.getFurnitures() == null ? List.of() :
homeBlock.getFurnitures().stream()
.map(HomeFurnitureItem::parseFrom)
.toList())
.persistentFurnitureList(
homeBlock.getPersistentFurnitures() == null ? List.of() :
homeBlock.getPersistentFurnitures().stream()
.map(HomeFurnitureItem::parseFrom)
.toList())
.deployAnimalList(List.of())
.deployNPCList(List.of())
.build();
}
public void update(HomeBlockArrangementInfo homeBlockArrangementInfo) {
this.blockId = homeBlockArrangementInfo.getBlockId();
this.deployFurnitureList = homeBlockArrangementInfo.getDeployFurniureListList().stream()
.map(HomeFurnitureItem::parseFrom)
.toList();
this.persistentFurnitureList = homeBlockArrangementInfo.getPersistentFurnitureListList().stream()
.map(HomeFurnitureItem::parseFrom)
.toList();
this.deployAnimalList = homeBlockArrangementInfo.getDeployAnimalListList().stream()
.map(HomeAnimalItem::parseFrom)
.toList();
this.deployNPCList = homeBlockArrangementInfo.getDeployNpcListList().stream()
.map(HomeNPCItem::parseFrom)
.toList();
}
public int calComfort() {
return this.deployFurnitureList.stream()
.mapToInt(HomeFurnitureItem::getComfort)
.sum();
}
public HomeBlockArrangementInfo toProto() {
var proto = HomeBlockArrangementInfo.newBuilder()
.setBlockId(blockId)
.setIsUnlocked(unlocked)
.setComfortValue(calComfort());
this.deployFurnitureList.forEach(f -> proto.addDeployFurniureList(f.toProto()));
this.persistentFurnitureList.forEach(f -> proto.addPersistentFurnitureList(f.toProto()));
this.deployAnimalList.forEach(f -> proto.addDeployAnimalList(f.toProto()));
this.deployNPCList.forEach(f -> proto.addDeployNpcList(f.toProto()));
return proto.build();
}
}
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
import emu.grasscutter.net.proto.HomeBlockArrangementInfoOuterClass.HomeBlockArrangementInfo;
import java.util.List;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@Builder(builderMethodName = "of")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class HomeBlockItem {
@Id int blockId;
boolean unlocked;
List<HomeFurnitureItem> deployFurnitureList;
List<HomeFurnitureItem> persistentFurnitureList;
List<HomeAnimalItem> deployAnimalList;
List<HomeNPCItem> deployNPCList;
public static HomeBlockItem parseFrom(HomeworldDefaultSaveData.HomeBlock homeBlock) {
// create from default setting
return HomeBlockItem.of()
.blockId(homeBlock.getBlockId())
.unlocked(homeBlock.getFurnitures() != null)
.deployFurnitureList(
homeBlock.getFurnitures() == null
? List.of()
: homeBlock.getFurnitures().stream().map(HomeFurnitureItem::parseFrom).toList())
.persistentFurnitureList(
homeBlock.getPersistentFurnitures() == null
? List.of()
: homeBlock.getPersistentFurnitures().stream()
.map(HomeFurnitureItem::parseFrom)
.toList())
.deployAnimalList(List.of())
.deployNPCList(List.of())
.build();
}
public void update(HomeBlockArrangementInfo homeBlockArrangementInfo) {
this.blockId = homeBlockArrangementInfo.getBlockId();
this.deployFurnitureList =
homeBlockArrangementInfo.getDeployFurniureListList().stream()
.map(HomeFurnitureItem::parseFrom)
.toList();
this.persistentFurnitureList =
homeBlockArrangementInfo.getPersistentFurnitureListList().stream()
.map(HomeFurnitureItem::parseFrom)
.toList();
this.deployAnimalList =
homeBlockArrangementInfo.getDeployAnimalListList().stream()
.map(HomeAnimalItem::parseFrom)
.toList();
this.deployNPCList =
homeBlockArrangementInfo.getDeployNpcListList().stream()
.map(HomeNPCItem::parseFrom)
.toList();
}
public int calComfort() {
return this.deployFurnitureList.stream().mapToInt(HomeFurnitureItem::getComfort).sum();
}
public HomeBlockArrangementInfo toProto() {
var proto =
HomeBlockArrangementInfo.newBuilder()
.setBlockId(blockId)
.setIsUnlocked(unlocked)
.setComfortValue(calComfort());
this.deployFurnitureList.forEach(f -> proto.addDeployFurniureList(f.toProto()));
this.persistentFurnitureList.forEach(f -> proto.addPersistentFurnitureList(f.toProto()));
this.deployAnimalList.forEach(f -> proto.addDeployAnimalList(f.toProto()));
this.deployNPCList.forEach(f -> proto.addDeployNpcList(f.toProto()));
return proto.build();
}
}

View File

@@ -1,80 +1,82 @@
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.net.proto.HomeFurnitureDataOuterClass;
import emu.grasscutter.net.proto.HomeMarkPointFurnitureDataOuterClass;
import emu.grasscutter.utils.Position;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class HomeFurnitureItem {
int furnitureId;
int guid;
int parentFurnitureIndex;
Position spawnPos;
Position spawnRot;
int version;
public static HomeFurnitureItem parseFrom(HomeFurnitureDataOuterClass.HomeFurnitureData homeFurnitureData) {
return HomeFurnitureItem.of()
.furnitureId(homeFurnitureData.getFurnitureId())
.guid(homeFurnitureData.getGuid())
.parentFurnitureIndex(homeFurnitureData.getParentFurnitureIndex())
.spawnPos(new Position(homeFurnitureData.getSpawnPos()))
.spawnRot(new Position(homeFurnitureData.getSpawnRot()))
.version(homeFurnitureData.getVersion())
.build();
}
public static HomeFurnitureItem parseFrom(HomeworldDefaultSaveData.HomeFurniture homeFurniture) {
return HomeFurnitureItem.of()
.furnitureId(homeFurniture.getId())
.parentFurnitureIndex(1)
.spawnPos(homeFurniture.getPos() == null ? new Position() : homeFurniture.getPos())
.spawnRot(homeFurniture.getRot() == null ? new Position() : homeFurniture.getRot())
.build();
}
public HomeFurnitureDataOuterClass.HomeFurnitureData toProto() {
return HomeFurnitureDataOuterClass.HomeFurnitureData.newBuilder()
.setFurnitureId(furnitureId)
.setGuid(guid)
.setParentFurnitureIndex(parentFurnitureIndex)
.setSpawnPos(spawnPos.toProto())
.setSpawnRot(spawnRot.toProto())
.setVersion(version)
.build();
}
public HomeMarkPointFurnitureDataOuterClass.HomeMarkPointFurnitureData toMarkPointProto(int type) {
return HomeMarkPointFurnitureDataOuterClass.HomeMarkPointFurnitureData.newBuilder()
.setFurnitureId(furnitureId)
.setGuid(guid)
.setFurnitureType(type)
.setPos(spawnPos.toProto())
// TODO NPC and farm
.build();
}
public ItemData getAsItem() {
return GameData.getItemDataMap().get(this.furnitureId);
}
public int getComfort() {
var item = getAsItem();
if (item == null) {
return 0;
}
return item.getComfort();
}
}
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.net.proto.HomeFurnitureDataOuterClass;
import emu.grasscutter.net.proto.HomeMarkPointFurnitureDataOuterClass;
import emu.grasscutter.utils.Position;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class HomeFurnitureItem {
int furnitureId;
int guid;
int parentFurnitureIndex;
Position spawnPos;
Position spawnRot;
int version;
public static HomeFurnitureItem parseFrom(
HomeFurnitureDataOuterClass.HomeFurnitureData homeFurnitureData) {
return HomeFurnitureItem.of()
.furnitureId(homeFurnitureData.getFurnitureId())
.guid(homeFurnitureData.getGuid())
.parentFurnitureIndex(homeFurnitureData.getParentFurnitureIndex())
.spawnPos(new Position(homeFurnitureData.getSpawnPos()))
.spawnRot(new Position(homeFurnitureData.getSpawnRot()))
.version(homeFurnitureData.getVersion())
.build();
}
public static HomeFurnitureItem parseFrom(HomeworldDefaultSaveData.HomeFurniture homeFurniture) {
return HomeFurnitureItem.of()
.furnitureId(homeFurniture.getId())
.parentFurnitureIndex(1)
.spawnPos(homeFurniture.getPos() == null ? new Position() : homeFurniture.getPos())
.spawnRot(homeFurniture.getRot() == null ? new Position() : homeFurniture.getRot())
.build();
}
public HomeFurnitureDataOuterClass.HomeFurnitureData toProto() {
return HomeFurnitureDataOuterClass.HomeFurnitureData.newBuilder()
.setFurnitureId(furnitureId)
.setGuid(guid)
.setParentFurnitureIndex(parentFurnitureIndex)
.setSpawnPos(spawnPos.toProto())
.setSpawnRot(spawnRot.toProto())
.setVersion(version)
.build();
}
public HomeMarkPointFurnitureDataOuterClass.HomeMarkPointFurnitureData toMarkPointProto(
int type) {
return HomeMarkPointFurnitureDataOuterClass.HomeMarkPointFurnitureData.newBuilder()
.setFurnitureId(furnitureId)
.setGuid(guid)
.setFurnitureType(type)
.setPos(spawnPos.toProto())
// TODO NPC and farm
.build();
}
public ItemData getAsItem() {
return GameData.getItemDataMap().get(this.furnitureId);
}
public int getComfort() {
var item = getAsItem();
if (item == null) {
return 0;
}
return item.getComfort();
}
}

View File

@@ -1,38 +1,38 @@
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import emu.grasscutter.net.proto.HomeNpcDataOuterClass;
import emu.grasscutter.utils.Position;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class HomeNPCItem {
int avatarId;
Position spawnPos;
Position spawnRot;
int costumeId;
public static HomeNPCItem parseFrom(HomeNpcDataOuterClass.HomeNpcData homeNpcData) {
return HomeNPCItem.of()
.avatarId(homeNpcData.getAvatarId())
.spawnPos(new Position(homeNpcData.getSpawnPos()))
.spawnRot(new Position(homeNpcData.getSpawnRot()))
.costumeId(homeNpcData.getCostumeId())
.build();
}
public HomeNpcDataOuterClass.HomeNpcData toProto() {
return HomeNpcDataOuterClass.HomeNpcData.newBuilder()
.setAvatarId(avatarId)
.setSpawnPos(spawnPos.toProto())
.setSpawnRot(spawnRot.toProto())
.setCostumeId(costumeId)
.build();
}
}
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import emu.grasscutter.net.proto.HomeNpcDataOuterClass;
import emu.grasscutter.utils.Position;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class HomeNPCItem {
int avatarId;
Position spawnPos;
Position spawnRot;
int costumeId;
public static HomeNPCItem parseFrom(HomeNpcDataOuterClass.HomeNpcData homeNpcData) {
return HomeNPCItem.of()
.avatarId(homeNpcData.getAvatarId())
.spawnPos(new Position(homeNpcData.getSpawnPos()))
.spawnRot(new Position(homeNpcData.getSpawnRot()))
.costumeId(homeNpcData.getCostumeId())
.build();
}
public HomeNpcDataOuterClass.HomeNpcData toProto() {
return HomeNpcDataOuterClass.HomeNpcData.newBuilder()
.setAvatarId(avatarId)
.setSpawnPos(spawnPos.toProto())
.setSpawnRot(spawnRot.toProto())
.setCostumeId(costumeId)
.build();
}
}

View File

@@ -1,97 +1,96 @@
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
import emu.grasscutter.net.proto.HomeSceneArrangementInfoOuterClass.HomeSceneArrangementInfo;
import emu.grasscutter.utils.Position;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import java.util.Map;
import java.util.stream.Collectors;
@Entity
@Data
@Builder(builderMethodName = "of")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class HomeSceneItem {
@Id
int sceneId;
Map<Integer, HomeBlockItem> blockItems;
Position bornPos;
Position bornRot;
Position djinnPos;
int homeBgmId;
HomeFurnitureItem mainHouse;
int tmpVersion;
public static HomeSceneItem parseFrom(HomeworldDefaultSaveData defaultItem, int sceneId) {
return HomeSceneItem.of()
.sceneId(sceneId)
.blockItems(defaultItem.getHomeBlockLists().stream()
.map(HomeBlockItem::parseFrom)
.collect(Collectors.toMap(HomeBlockItem::getBlockId, y -> y)))
.bornPos(defaultItem.getBornPos())
.bornRot(defaultItem.getBornRot() == null ? new Position() : defaultItem.getBornRot())
.djinnPos(defaultItem.getDjinPos() == null ? new Position() : defaultItem.getDjinPos())
.mainHouse(defaultItem.getMainhouse() == null ? null :
HomeFurnitureItem.parseFrom(defaultItem.getMainhouse()))
.build();
}
public void update(HomeSceneArrangementInfo arrangementInfo) {
for (var blockItem : arrangementInfo.getBlockArrangementInfoListList()) {
var block = this.blockItems.get(blockItem.getBlockId());
if (block == null) {
Grasscutter.getLogger().warn("Could not found the Home Block {}", blockItem.getBlockId());
continue;
}
block.update(blockItem);
this.blockItems.put(blockItem.getBlockId(), block);
}
this.bornPos = new Position(arrangementInfo.getBornPos());
this.bornRot = new Position(arrangementInfo.getBornRot());
this.djinnPos = new Position(arrangementInfo.getDjinnPos());
this.homeBgmId = arrangementInfo.getBgmId();
this.mainHouse = HomeFurnitureItem.parseFrom(arrangementInfo.getMainHouse());
this.tmpVersion = arrangementInfo.getTmpVersion();
}
public int getRoomSceneId() {
if (mainHouse == null || mainHouse.getAsItem() == null) {
return 0;
}
return mainHouse.getAsItem().getRoomSceneId();
}
public int calComfort() {
return this.blockItems.values().stream()
.mapToInt(HomeBlockItem::calComfort)
.sum();
}
public HomeSceneArrangementInfo toProto() {
var proto = HomeSceneArrangementInfo.newBuilder();
blockItems.values().forEach(b -> proto.addBlockArrangementInfoList(b.toProto()));
proto.setComfortValue(calComfort())
.setBornPos(bornPos.toProto())
.setBornRot(bornRot.toProto())
.setDjinnPos(djinnPos.toProto())
.setIsSetBornPos(true)
.setSceneId(sceneId)
.setBgmId(homeBgmId)
.setTmpVersion(tmpVersion);
if (mainHouse != null) {
proto.setMainHouse(mainHouse.toProto());
}
return proto.build();
}
}
package emu.grasscutter.game.home;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.HomeworldDefaultSaveData;
import emu.grasscutter.net.proto.HomeSceneArrangementInfoOuterClass.HomeSceneArrangementInfo;
import emu.grasscutter.utils.Position;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
@Entity
@Data
@Builder(builderMethodName = "of")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class HomeSceneItem {
@Id int sceneId;
Map<Integer, HomeBlockItem> blockItems;
Position bornPos;
Position bornRot;
Position djinnPos;
int homeBgmId;
HomeFurnitureItem mainHouse;
int tmpVersion;
public static HomeSceneItem parseFrom(HomeworldDefaultSaveData defaultItem, int sceneId) {
return HomeSceneItem.of()
.sceneId(sceneId)
.blockItems(
defaultItem.getHomeBlockLists().stream()
.map(HomeBlockItem::parseFrom)
.collect(Collectors.toMap(HomeBlockItem::getBlockId, y -> y)))
.bornPos(defaultItem.getBornPos())
.bornRot(defaultItem.getBornRot() == null ? new Position() : defaultItem.getBornRot())
.djinnPos(defaultItem.getDjinPos() == null ? new Position() : defaultItem.getDjinPos())
.mainHouse(
defaultItem.getMainhouse() == null
? null
: HomeFurnitureItem.parseFrom(defaultItem.getMainhouse()))
.build();
}
public void update(HomeSceneArrangementInfo arrangementInfo) {
for (var blockItem : arrangementInfo.getBlockArrangementInfoListList()) {
var block = this.blockItems.get(blockItem.getBlockId());
if (block == null) {
Grasscutter.getLogger().warn("Could not found the Home Block {}", blockItem.getBlockId());
continue;
}
block.update(blockItem);
this.blockItems.put(blockItem.getBlockId(), block);
}
this.bornPos = new Position(arrangementInfo.getBornPos());
this.bornRot = new Position(arrangementInfo.getBornRot());
this.djinnPos = new Position(arrangementInfo.getDjinnPos());
this.homeBgmId = arrangementInfo.getBgmId();
this.mainHouse = HomeFurnitureItem.parseFrom(arrangementInfo.getMainHouse());
this.tmpVersion = arrangementInfo.getTmpVersion();
}
public int getRoomSceneId() {
if (mainHouse == null || mainHouse.getAsItem() == null) {
return 0;
}
return mainHouse.getAsItem().getRoomSceneId();
}
public int calComfort() {
return this.blockItems.values().stream().mapToInt(HomeBlockItem::calComfort).sum();
}
public HomeSceneArrangementInfo toProto() {
var proto = HomeSceneArrangementInfo.newBuilder();
blockItems.values().forEach(b -> proto.addBlockArrangementInfoList(b.toProto()));
proto
.setComfortValue(calComfort())
.setBornPos(bornPos.toProto())
.setBornRot(bornRot.toProto())
.setDjinnPos(djinnPos.toProto())
.setIsSetBornPos(true)
.setSceneId(sceneId)
.setBgmId(homeBgmId)
.setTmpVersion(tmpVersion);
if (mainHouse != null) {
proto.setMainHouse(mainHouse.toProto());
}
return proto.build();
}
}