mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-16 08:56:04 +01:00
Merge branch 'development' into Weather
This commit is contained in:
74
src/main/java/emu/grasscutter/game/entity/EntityRegion.java
Normal file
74
src/main/java/emu/grasscutter/game/entity/EntityRegion.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package emu.grasscutter.game.entity;
|
||||
|
||||
import emu.grasscutter.game.props.EntityIdType;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass;
|
||||
import emu.grasscutter.scripts.data.SceneRegion;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Getter
|
||||
public class EntityRegion extends GameEntity{
|
||||
private final Position position;
|
||||
private boolean hasNewEntities;
|
||||
private final Set<Integer> entities; // Ids of entities inside this region
|
||||
private final SceneRegion metaRegion;
|
||||
|
||||
public EntityRegion(Scene scene, SceneRegion region) {
|
||||
super(scene);
|
||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.REGION);
|
||||
setGroupId(region.group.id);
|
||||
setBlockId(region.group.block_id);
|
||||
setConfigId(region.config_id);
|
||||
this.position = region.pos.clone();
|
||||
this.entities = ConcurrentHashMap.newKeySet();
|
||||
this.metaRegion = region;
|
||||
}
|
||||
|
||||
public void addEntity(GameEntity entity) {
|
||||
if (this.getEntities().contains(entity.getId())) {
|
||||
return;
|
||||
}
|
||||
this.getEntities().add(entity.getId());
|
||||
this.hasNewEntities = true;
|
||||
}
|
||||
|
||||
public boolean hasNewEntities() {
|
||||
return hasNewEntities;
|
||||
}
|
||||
|
||||
public void resetNewEntities() {
|
||||
hasNewEntities = false;
|
||||
}
|
||||
|
||||
public void removeEntity(GameEntity entity) {
|
||||
this.getEntities().remove(entity.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Int2FloatOpenHashMap getFightProperties() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getRotation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SceneEntityInfoOuterClass.SceneEntityInfo toProto() {
|
||||
/**
|
||||
* The Region Entity would not be sent to client.
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -125,7 +125,7 @@ public class Player {
|
||||
@Transient private MessageHandler messageHandler;
|
||||
@Transient private AbilityManager abilityManager;
|
||||
@Transient private QuestManager questManager;
|
||||
|
||||
|
||||
@Transient private SotSManager sotsManager;
|
||||
@Transient private InsectCaptureManager insectCaptureManager;
|
||||
|
||||
@@ -436,7 +436,7 @@ public class Player {
|
||||
public int getWorldLevel() {
|
||||
return this.getProperty(PlayerProperty.PROP_PLAYER_WORLD_LEVEL);
|
||||
}
|
||||
|
||||
|
||||
public void setWorldLevel(int level) {
|
||||
this.setProperty(PlayerProperty.PROP_PLAYER_WORLD_LEVEL, level);
|
||||
this.sendPacket(new PacketPlayerPropNotify(this, PlayerProperty.PROP_PLAYER_WORLD_LEVEL));
|
||||
@@ -459,7 +459,7 @@ public class Player {
|
||||
this.setProperty(PlayerProperty.PROP_PLAYER_SCOIN, mora);
|
||||
this.sendPacket(new PacketPlayerPropNotify(this, PlayerProperty.PROP_PLAYER_SCOIN));
|
||||
}
|
||||
|
||||
|
||||
public int getCrystals() {
|
||||
return this.getProperty(PlayerProperty.PROP_PLAYER_MCOIN);
|
||||
}
|
||||
@@ -534,11 +534,11 @@ public class Player {
|
||||
public TeamManager getTeamManager() {
|
||||
return this.teamManager;
|
||||
}
|
||||
|
||||
|
||||
public TowerManager getTowerManager() {
|
||||
return towerManager;
|
||||
}
|
||||
|
||||
|
||||
public TowerData getTowerData() {
|
||||
if(towerData==null){
|
||||
// because of mistake, null may be saved as storage at some machine, this if can be removed in future
|
||||
@@ -546,7 +546,7 @@ public class Player {
|
||||
}
|
||||
return towerData;
|
||||
}
|
||||
|
||||
|
||||
public QuestManager getQuestManager() {
|
||||
return questManager;
|
||||
}
|
||||
@@ -615,7 +615,7 @@ public class Player {
|
||||
public MpSettingType getMpSetting() {
|
||||
return MpSettingType.MP_SETTING_TYPE_ENTER_AFTER_APPLY; // TEMP
|
||||
}
|
||||
|
||||
|
||||
public Queue<AttackResult> getAttackResults() {
|
||||
return this.attackResults;
|
||||
}
|
||||
@@ -810,7 +810,7 @@ public class Player {
|
||||
remainCalendar.add(Calendar.DATE, moonCardDuration);
|
||||
Date theLastDay = remainCalendar.getTime();
|
||||
Date now = DateHelper.onlyYearMonthDay(new Date());
|
||||
return (int) ((theLastDay.getTime() - now.getTime()) / (24 * 60 * 60 * 1000)); // By copilot
|
||||
return (int) ((theLastDay.getTime() - now.getTime()) / (24 * 60 * 60 * 1000)); // By copilot
|
||||
}
|
||||
|
||||
public void rechargeMoonCard() {
|
||||
@@ -1007,7 +1007,7 @@ public class Player {
|
||||
}
|
||||
|
||||
public Mail getMail(int index) { return this.getMailHandler().getMailById(index); }
|
||||
|
||||
|
||||
public int getMailId(Mail message) {
|
||||
return this.getMailHandler().getMailIndex(message);
|
||||
}
|
||||
@@ -1015,9 +1015,9 @@ public class Player {
|
||||
public boolean replaceMailByIndex(int index, Mail message) {
|
||||
return this.getMailHandler().replaceMailByIndex(index, message);
|
||||
}
|
||||
|
||||
|
||||
public void interactWith(int gadgetEntityId, GadgetInteractReq req) {
|
||||
|
||||
public void interactWith(int gadgetEntityId, GadgetInteractReq opType) {
|
||||
GameEntity entity = getScene().getEntityById(gadgetEntityId);
|
||||
if (entity == null) {
|
||||
return;
|
||||
@@ -1045,13 +1045,13 @@ public class Player {
|
||||
}
|
||||
}
|
||||
} else if (entity instanceof EntityGadget gadget) {
|
||||
|
||||
|
||||
if (gadget.getContent() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean shouldDelete = gadget.getContent().onInteract(this, req);
|
||||
|
||||
|
||||
boolean shouldDelete = gadget.getContent().onInteract(this, opType);
|
||||
|
||||
if (shouldDelete) {
|
||||
entity.getScene().removeEntity(entity);
|
||||
}
|
||||
@@ -1195,7 +1195,7 @@ public class Player {
|
||||
}
|
||||
return showAvatarInfoList;
|
||||
}
|
||||
|
||||
|
||||
public PlayerWorldLocationInfoOuterClass.PlayerWorldLocationInfo getWorldPlayerLocationInfo() {
|
||||
return PlayerWorldLocationInfoOuterClass.PlayerWorldLocationInfo.newBuilder()
|
||||
.setSceneId(this.getSceneId())
|
||||
@@ -1238,7 +1238,7 @@ public class Player {
|
||||
public BattlePassManager getBattlePassManager(){
|
||||
return battlePassManager;
|
||||
}
|
||||
|
||||
|
||||
public void loadBattlePassManager() {
|
||||
if (this.battlePassManager != null) return;
|
||||
this.battlePassManager = DatabaseHelper.loadBattlePass(this);
|
||||
@@ -1328,7 +1328,7 @@ public class Player {
|
||||
public void save() {
|
||||
DatabaseHelper.savePlayer(this);
|
||||
}
|
||||
|
||||
|
||||
// Called from tokenrsp
|
||||
public void loadFromDatabase() {
|
||||
// Make sure these exist
|
||||
@@ -1346,7 +1346,7 @@ public class Player {
|
||||
}
|
||||
//Make sure towerManager's player is online player
|
||||
this.getTowerManager().setPlayer(this);
|
||||
|
||||
|
||||
// Load from db
|
||||
this.getAvatars().loadFromDatabase();
|
||||
this.getInventory().loadFromDatabase();
|
||||
@@ -1355,7 +1355,7 @@ public class Player {
|
||||
this.getFriendsList().loadFromDatabase();
|
||||
this.getMailHandler().loadFromDatabase();
|
||||
this.getQuestManager().loadFromDatabase();
|
||||
|
||||
|
||||
this.loadBattlePassManager();
|
||||
}
|
||||
|
||||
@@ -1368,12 +1368,12 @@ public class Player {
|
||||
quest.finish();
|
||||
}
|
||||
getQuestManager().addQuest(35101);
|
||||
|
||||
|
||||
this.setSceneId(3);
|
||||
this.getPos().set(GameConstants.START_POSITION);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Create world
|
||||
World world = new World(this);
|
||||
world.addPlayer(this);
|
||||
@@ -1410,7 +1410,7 @@ public class Player {
|
||||
|
||||
// First notify packets sent
|
||||
this.setHasSentAvatarDataNotify(true);
|
||||
|
||||
|
||||
// Set session state
|
||||
session.setState(SessionState.ACTIVE);
|
||||
|
||||
@@ -1420,7 +1420,7 @@ public class Player {
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// register
|
||||
getServer().registerPlayer(this);
|
||||
getProfile().setPlayer(this); // Set online
|
||||
|
||||
@@ -5,10 +5,11 @@ public enum EntityIdType {
|
||||
MONSTER (0x02),
|
||||
NPC (0x03),
|
||||
GADGET (0x04),
|
||||
WEAPON (0x06),
|
||||
REGION (0x05),
|
||||
WEAPON (0x06),
|
||||
TEAM (0x09),
|
||||
MPLEVEL (0x0b);
|
||||
|
||||
|
||||
private final int id;
|
||||
|
||||
private EntityIdType(int id) {
|
||||
|
||||
@@ -30,22 +30,23 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import org.danilopianini.util.SpatialIndex;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Scene {
|
||||
private final World world;
|
||||
private final SceneData sceneData;
|
||||
private final List<Player> players;
|
||||
private final Int2ObjectMap<GameEntity> entities;
|
||||
|
||||
private final Map<Integer, GameEntity> entities;
|
||||
private final Set<SpawnDataEntry> spawnedEntities;
|
||||
private final Set<SpawnDataEntry> deadSpawnedEntities;
|
||||
private final Set<SceneBlock> loadedBlocks;
|
||||
private boolean dontDestroyWhenEmpty;
|
||||
|
||||
|
||||
private int autoCloseTime;
|
||||
private int time;
|
||||
|
||||
|
||||
private SceneScriptManager scriptManager;
|
||||
private WorldChallenge challenge;
|
||||
private List<DungeonSettleListener> dungeonSettleListeners;
|
||||
@@ -55,18 +56,18 @@ public class Scene {
|
||||
public Scene(World world, SceneData sceneData) {
|
||||
this.world = world;
|
||||
this.sceneData = sceneData;
|
||||
this.players = Collections.synchronizedList(new ArrayList<>());
|
||||
this.entities = Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap<>());
|
||||
this.players = new CopyOnWriteArrayList<>();
|
||||
this.entities = new ConcurrentHashMap<>();
|
||||
|
||||
this.time = 8 * 60;
|
||||
this.prevScene = 3;
|
||||
|
||||
this.spawnedEntities = new HashSet<>();
|
||||
this.deadSpawnedEntities = new HashSet<>();
|
||||
this.loadedBlocks = new HashSet<>();
|
||||
|
||||
this.spawnedEntities = ConcurrentHashMap.newKeySet();
|
||||
this.deadSpawnedEntities = ConcurrentHashMap.newKeySet();
|
||||
this.loadedBlocks = ConcurrentHashMap.newKeySet();
|
||||
this.scriptManager = new SceneScriptManager(this);
|
||||
}
|
||||
|
||||
|
||||
public int getId() {
|
||||
return sceneData.getId();
|
||||
}
|
||||
@@ -86,15 +87,15 @@ public class Scene {
|
||||
public List<Player> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
|
||||
|
||||
public int getPlayerCount() {
|
||||
return this.getPlayers().size();
|
||||
}
|
||||
|
||||
public Int2ObjectMap<GameEntity> getEntities() {
|
||||
public Map<Integer, GameEntity> getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
||||
|
||||
public GameEntity getEntityById(int id) {
|
||||
return this.entities.get(id);
|
||||
}
|
||||
@@ -610,15 +611,10 @@ public class Scene {
|
||||
var suiteData = group.getSuiteByIndex(suite);
|
||||
suiteData.sceneTriggers.forEach(getScriptManager()::registerTrigger);
|
||||
|
||||
entities.addAll(suiteData.sceneGadgets.stream()
|
||||
.map(g -> scriptManager.createGadget(group.id, group.block_id, g))
|
||||
.filter(Objects::nonNull)
|
||||
.toList());
|
||||
entities.addAll(suiteData.sceneMonsters.stream()
|
||||
.map(mob -> scriptManager.createMonster(group.id, group.block_id, mob))
|
||||
.filter(Objects::nonNull)
|
||||
.toList());
|
||||
entities.addAll(scriptManager.getGadgetsInGroupSuite(group, suiteData));
|
||||
entities.addAll(scriptManager.getMonstersInGroupSuite(group, suiteData));
|
||||
|
||||
scriptManager.registerRegionInGroupSuite(group, suiteData);
|
||||
}
|
||||
|
||||
scriptManager.meetEntities(entities);
|
||||
@@ -635,19 +631,18 @@ public class Scene {
|
||||
toRemove.forEach(this::removeEntityDirectly);
|
||||
this.broadcastPacket(new PacketSceneEntityDisappearNotify(toRemove, VisionType.VISION_TYPE_REMOVE));
|
||||
}
|
||||
|
||||
|
||||
for (SceneGroup group : block.groups.values()) {
|
||||
if(group.triggers != null){
|
||||
group.triggers.values().forEach(getScriptManager()::deregisterTrigger);
|
||||
}
|
||||
if(group.regions != null){
|
||||
group.regions.forEach(getScriptManager()::deregisterRegion);
|
||||
group.regions.values().forEach(getScriptManager()::deregisterRegion);
|
||||
}
|
||||
}
|
||||
scriptManager.getLoadedGroupSetPerBlock().remove(block.id);
|
||||
Grasscutter.getLogger().info("Scene {} Block {} is unloaded.", this.getId(), block.id);
|
||||
}
|
||||
|
||||
// Gadgets
|
||||
|
||||
public void onPlayerCreateGadget(EntityClientGadget gadget) {
|
||||
|
||||
Reference in New Issue
Block a user