feat: implement teapot suite (#2344)

* feat: implement teapot suite

* fix: home animals, check respawn, etc

* fix: NPE and cancel summon events

* fix: forgot to send eventId also
This commit is contained in:
hamusuke
2023-09-08 12:34:03 +09:00
committed by GitHub
parent 83602f78ae
commit fc42f665a7
36 changed files with 1125 additions and 210 deletions

View File

@@ -12,15 +12,17 @@ import emu.grasscutter.game.props.SceneType;
import emu.grasscutter.net.proto.HomeAvatarTalkFinishInfoOuterClass;
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;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import java.util.stream.Stream;
@Entity(value = "homes", useDiscriminator = false)
@Data
@@ -55,6 +57,7 @@ public class GameHome {
Set<Integer> unlockedHomeBgmList;
int enterHomeOption;
Map<Integer, Set<Integer>> finishedTalkIdMap;
Set<Integer> finishedRewardEventIdSet;
public static GameHome getByUid(Integer uid) {
var home = DatabaseHelper.getHomeByUid(uid);
@@ -62,7 +65,9 @@ public class GameHome {
home = GameHome.create(uid);
}
home.reassignIfNull();
home.fixMainHouseIfOld();
home.syncHomeAvatarCostume();
return home;
}
@@ -79,9 +84,19 @@ public class GameHome {
.mainHouseMap(new ConcurrentHashMap<>())
.unlockedHomeBgmList(new HashSet<>())
.finishedTalkIdMap(new HashMap<>())
.finishedRewardEventIdSet(new HashSet<>())
.build();
}
// avoid NPE caused by database remover.
private void reassignIfNull() {
this.getSceneMap().values().stream()
.map(HomeSceneItem::getBlockItems)
.map(Map::values)
.flatMap(Collection::stream)
.forEach(HomeBlockItem::reassignIfNull);
}
// Data fixer.
private void fixMainHouseIfOld() {
if (this.getMainHouseMap() == null) {
@@ -97,6 +112,18 @@ public class GameHome {
this.save();
}
private void syncHomeAvatarCostume() {
Stream.of(this.sceneMap, this.mainHouseMap)
.map(ConcurrentHashMap::values)
.flatMap(Collection::stream)
.map(HomeSceneItem::getBlockItems)
.map(Map::values)
.flatMap(Collection::stream)
.map(HomeBlockItem::getDeployNPCList)
.flatMap(Collection::stream)
.forEach(npc -> npc.setCostumeId(this.getPlayer().getCostumeFrom(npc.getAvatarId())));
}
public void save() {
DatabaseHelper.saveHome(this);
}
@@ -113,12 +140,12 @@ public class GameHome {
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);
}
return HomeSceneItem.parseFrom(defaultItem, sceneId);
});
}
@@ -149,6 +176,8 @@ public class GameHome {
this.getMainHouseMap().remove(outdoor); // delete main house in current scene.
this.getMainHouseItem(outdoor); // put new main house with default arrangement.
this.save();
this.getPlayer().getCurHomeWorld().getModuleManager().refreshMainHouse();
}
public void onOwnerLogin(Player player) {
@@ -160,6 +189,8 @@ public class GameHome {
player.getSession().send(new PacketHomeMarkPointNotify(player));
player.getSession().send(new PacketHomeAvatarTalkFinishInfoNotify(player));
player.getSession().send(new PacketHomeAllUnlockedBgmIdListNotify(player));
player.getSession().send(new PacketHomeAvatarRewardEventNotify(player));
player.getSession().send(new PacketHomeAvatarAllFinishRewardNotify(player));
checkAccumulatedResources(player);
player.getSession().send(new PacketHomeResourceNotify(player));
}
@@ -226,6 +257,20 @@ public class GameHome {
.toList();
}
public boolean onClaimAvatarRewards(int eventId) {
if (this.finishedRewardEventIdSet == null) {
this.finishedRewardEventIdSet = new HashSet<>();
}
var success = this.finishedRewardEventIdSet.add(eventId);
this.save();
return success;
}
public boolean isRewardEventFinished(int eventId) {
return this.finishedRewardEventIdSet != null && this.finishedRewardEventIdSet.contains(eventId);
}
public boolean addUnlockedHomeBgm(int homeBgmId) {
if (!getUnlockedHomeBgmList().add(homeBgmId)) return false;
@@ -404,7 +449,7 @@ public class GameHome {
newCoin = storedCoin + owedCoin;
}
// Ensure max is not exceeded
storedCoin = (maxCoin >= newCoin) ? newCoin : maxCoin;
storedCoin = Math.min(maxCoin, newCoin);
}
// Update fetter exp
@@ -416,7 +461,7 @@ public class GameHome {
newFetter = storedFetterExp + owedFetter;
}
// Ensure max is not exceeded
storedFetterExp = (maxFetter >= newFetter) ? newFetter : maxFetter;
storedFetterExp = Math.min(maxFetter, newFetter);
}
save();