mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-16 17:05:20 +01:00
Block loader (sort and merge gadgets into different blocks) (#1517)
Original commits: * block loader * fix * fix * fix foolish bug * add scales * rename * set to 600 * nitpick Co-authored-by: AnimeGitB <AnimeGitB@bigblueball.in>
This commit is contained in:
@@ -9,12 +9,10 @@ import emu.grasscutter.game.dungeons.DungeonSettleListener;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.player.TeamInfo;
|
||||
import emu.grasscutter.game.props.ClimateType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.LifeState;
|
||||
import emu.grasscutter.game.props.SceneType;
|
||||
import emu.grasscutter.game.quest.QuestGroupSuite;
|
||||
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
||||
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
|
||||
@@ -26,15 +24,10 @@ import emu.grasscutter.scripts.data.SceneGadget;
|
||||
import emu.grasscutter.scripts.data.SceneGroup;
|
||||
import emu.grasscutter.server.packet.send.*;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
||||
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;
|
||||
@@ -44,6 +37,7 @@ public class Scene {
|
||||
private final Set<SpawnDataEntry> spawnedEntities;
|
||||
private final Set<SpawnDataEntry> deadSpawnedEntities;
|
||||
private final Set<SceneBlock> loadedBlocks;
|
||||
private Set<SpawnDataEntry.GridBlockId> loadedGridBlocks;
|
||||
private boolean dontDestroyWhenEmpty;
|
||||
|
||||
private int autoCloseTime;
|
||||
@@ -68,6 +62,7 @@ public class Scene {
|
||||
this.spawnedEntities = ConcurrentHashMap.newKeySet();
|
||||
this.deadSpawnedEntities = ConcurrentHashMap.newKeySet();
|
||||
this.loadedBlocks = ConcurrentHashMap.newKeySet();
|
||||
this.loadedGridBlocks = new HashSet<>();
|
||||
this.npcBornEntrySet = ConcurrentHashMap.newKeySet();
|
||||
this.scriptManager = new SceneScriptManager(this);
|
||||
}
|
||||
@@ -461,25 +456,24 @@ public class Scene {
|
||||
this.npcBornEntrySet = npcBornEntries;
|
||||
}
|
||||
|
||||
// TODO - Test
|
||||
public synchronized void checkSpawns() {
|
||||
int RANGE = 100;
|
||||
|
||||
SpatialIndex<SpawnGroupEntry> list = GameDepot.getSpawnListById(this.getId());
|
||||
Set<SpawnDataEntry> visible = new HashSet<>();
|
||||
|
||||
for (Player player : this.getPlayers()) {
|
||||
Position position = player.getPos();
|
||||
Collection<SpawnGroupEntry> entries = list.query(
|
||||
new double[] {position.getX() - RANGE, position.getZ() - RANGE},
|
||||
new double[] {position.getX() + RANGE, position.getZ() + RANGE}
|
||||
);
|
||||
for (SpawnGroupEntry entry : entries) {
|
||||
for (SpawnDataEntry spawnData : entry.getSpawns()) {
|
||||
visible.add(spawnData);
|
||||
}
|
||||
}
|
||||
}
|
||||
public synchronized void checkSpawns() {
|
||||
Set<SpawnDataEntry.GridBlockId> loadedGridBlocks = new HashSet<>();
|
||||
for (Player player : this.getPlayers()) {
|
||||
for (SpawnDataEntry.GridBlockId block : SpawnDataEntry.GridBlockId.getAdjacentGridBlockIds(player.getSceneId(), player.getPos()))
|
||||
loadedGridBlocks.add(block);
|
||||
}
|
||||
if (this.loadedGridBlocks.containsAll(loadedGridBlocks)) { // Don't recalculate static spawns if nothing has changed
|
||||
return;
|
||||
}
|
||||
this.loadedGridBlocks = loadedGridBlocks;
|
||||
var spawnLists = GameDepot.getSpawnLists();
|
||||
Set<SpawnDataEntry> visible = new HashSet<>();
|
||||
for (var block : loadedGridBlocks) {
|
||||
var spawns = spawnLists.get(block);
|
||||
if(spawns!=null) {
|
||||
visible.addAll(spawns);
|
||||
}
|
||||
}
|
||||
|
||||
// World level
|
||||
WorldLevelData worldLevelData = GameData.getWorldLevelDataMap().get(getWorld().getWorldLevel());
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package emu.grasscutter.game.world;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import emu.grasscutter.data.GameDepot;
|
||||
import emu.grasscutter.utils.Position;
|
||||
|
||||
public class SpawnDataEntry {
|
||||
@@ -60,11 +62,18 @@ public class SpawnDataEntry {
|
||||
return rot;
|
||||
}
|
||||
|
||||
public GridBlockId getBlockId(){
|
||||
int scale = GridBlockId.getScale(gadgetId);
|
||||
return new GridBlockId(group.sceneId,scale,
|
||||
(int)(pos.getX() / GameDepot.BLOCK_SIZE[scale]),
|
||||
(int)(pos.getZ() / GameDepot.BLOCK_SIZE[scale])
|
||||
);
|
||||
}
|
||||
|
||||
public static class SpawnGroupEntry {
|
||||
private int sceneId;
|
||||
private int groupId;
|
||||
private int blockId;
|
||||
private Position pos;
|
||||
private List<SpawnDataEntry> spawns;
|
||||
|
||||
public int getSceneId() {
|
||||
@@ -83,12 +92,64 @@ public class SpawnDataEntry {
|
||||
this.blockId = blockId;
|
||||
}
|
||||
|
||||
public Position getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public List<SpawnDataEntry> getSpawns() {
|
||||
return spawns;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GridBlockId {
|
||||
int sceneId;
|
||||
int scale;
|
||||
int x;
|
||||
int z;
|
||||
|
||||
public GridBlockId(int sceneId, int scale, int x, int z) {
|
||||
this.sceneId = sceneId;
|
||||
this.scale = scale;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SpawnDataEntryScaledPoint{" +
|
||||
"sceneId=" + sceneId +
|
||||
", scale=" + scale +
|
||||
", x=" + x +
|
||||
", z=" + z +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GridBlockId that = (GridBlockId) o;
|
||||
return sceneId == that.sceneId && scale == that.scale && x == that.x && z == that.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(sceneId, scale, x, z);
|
||||
}
|
||||
|
||||
public static GridBlockId[] getAdjacentGridBlockIds(int sceneId, Position pos){
|
||||
GridBlockId[] results = new GridBlockId[5*5*GameDepot.BLOCK_SIZE.length];
|
||||
int t=0;
|
||||
for (int scale = 0; scale < GameDepot.BLOCK_SIZE.length; scale++) {
|
||||
int x = ((int)(pos.getX()/GameDepot.BLOCK_SIZE[scale]));
|
||||
int z = ((int)(pos.getZ()/GameDepot.BLOCK_SIZE[scale]));
|
||||
for (int i=x-2; i<x+3; i++) {
|
||||
for (int j=z-2; j<z+3; j++) {
|
||||
results[t++] = new GridBlockId(sceneId, scale, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static int getScale(int gadgetId){
|
||||
return 0;//you should implement here,this is index of GameDepot.BLOCK_SIZE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user