Apply changes from #63 (Anime-Game-Servers/Grasscutter-Quests)

This commit is contained in:
KingRainbow44
2023-04-23 22:51:08 -04:00
parent d608831594
commit c9d6225194
20 changed files with 893 additions and 460 deletions

View File

@@ -28,12 +28,16 @@ import emu.grasscutter.utils.Position;
import io.netty.util.concurrent.FastThreadLocalThread;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import kotlin.Pair;
import lombok.val;
import org.luaj.vm2.LuaError;
@@ -45,6 +49,7 @@ public class SceneScriptManager {
private final Map<String, Integer> variables;
private SceneMeta meta;
private boolean isInit;
/** current triggers controlled by RefreshGroup */
private final Map<Integer, Set<SceneTrigger>> currentTriggers;
@@ -59,8 +64,8 @@ public class SceneScriptManager {
private ScriptMonsterSpawnService scriptMonsterSpawnService;
/** blockid - loaded groupSet */
private final Map<Integer, Set<SceneGroup>> loadedGroupSetPerBlock;
private List<Grid> groupGrids;
private static final Int2ObjectMap<List<Grid>> groupGridsCache
= new Int2ObjectOpenHashMap<>();
public static final ExecutorService eventExecutor;
static {
@@ -89,7 +94,6 @@ public class SceneScriptManager {
this.cachedSceneGroupsInstances = new ConcurrentHashMap<>();
this.scriptMonsterSpawnService = new ScriptMonsterSpawnService(this);
this.loadedGroupSetPerBlock = new ConcurrentHashMap<>();
this.groupGrids = null; // This is changed on init
// TEMPORARY
if (this.getScene().getId() < 10
@@ -105,10 +109,6 @@ public class SceneScriptManager {
return scene;
}
public List<Grid> getGroupGrids() {
return groupGrids;
}
public SceneConfig getConfig() {
return this.isInit ? this.meta.config : null;
}
@@ -118,7 +118,8 @@ public class SceneScriptManager {
}
@Nullable public Map<String, Integer> getVariables(int group_id) {
if (getCachedGroupInstanceById(group_id) == null) return null;
if (this.getCachedGroupInstanceById(group_id) == null)
return Collections.emptyMap();
return getCachedGroupInstanceById(group_id).getCachedVariables();
}
@@ -199,8 +200,11 @@ public class SceneScriptManager {
// }
}
public int refreshGroup(
SceneGroupInstance groupInstance, int suiteIndex, boolean excludePrevSuite) {
public int refreshGroup(SceneGroupInstance groupInstance, int suiteIndex, boolean excludePrevSuite) {
return this.refreshGroup(groupInstance, suiteIndex, excludePrevSuite, null);
}
public int refreshGroup(SceneGroupInstance groupInstance, int suiteIndex, boolean excludePrevSuite, List<GameEntity> entitiesAdded) {
SceneGroup group = groupInstance.getLuaGroup();
if (suiteIndex == 0) {
if (excludePrevSuite) {
@@ -242,7 +246,7 @@ public class SceneScriptManager {
removeGroupSuite(group, prevSuiteData);
} // Remove old group suite
addGroupSuite(groupInstance, suiteData);
this.addGroupSuite(groupInstance, suiteData, entitiesAdded);
// Refesh variables here
group.variables.forEach(
@@ -423,152 +427,104 @@ public class SceneScriptManager {
}
this.meta = meta;
var path = FileUtils.getScriptPath("Scene/" + getScene().getId() + "/scene_grid.json");
// TEMP
this.isInit = true;
}
try {
this.groupGrids = JsonUtils.loadToList(path, Grid.class);
this.groupGrids.forEach(Grid::load);
} catch (IOException ignored) {
Grasscutter.getLogger().error("Scene {} unable to load grid file.", getScene().getId());
} catch (Exception e) {
Grasscutter.getLogger().error("Scene {} unable to load grid file.", getScene().getId(), e);
}
public List<Grid> getGroupGrids() {
int sceneId = scene.getId();
if (groupGridsCache.containsKey(sceneId) && groupGridsCache.get(sceneId) != null) {
Grasscutter.getLogger().debug("Hit cache for scene {}",sceneId);
return groupGridsCache.get(sceneId);
} else {
var path = FileUtils.getCachePath("scene" + sceneId + "_grid.json");
if (path.toFile().isFile() && !Grasscutter.config.server.game.cacheSceneEntitiesEveryRun) {
try {
var groupGrids = JsonUtils.loadToList(path, Grid.class);
groupGridsCache.put(sceneId, groupGrids);
if(groupGrids != null) return groupGrids;
} catch (IOException e) {
e.printStackTrace();
}
}
boolean runForFirstTime = this.groupGrids == null;
// Find if the scene entities are already generated, if not generate it
if (Grasscutter.getConfig().server.game.cacheSceneEntitiesEveryRun || runForFirstTime) {
//otherwise generate the grids
List<Map<GridPosition, Set<Integer>>> groupPositions = new ArrayList<>();
for (int i = 0; i < 6; i++) groupPositions.add(new HashMap<>());
var visionOptions = Grasscutter.getConfig().server.game.visionOptions;
meta.blocks
.values()
.forEach(
block -> {
block.load(scene.getId(), meta.context);
block.groups.values().stream()
.filter(g -> !g.dynamic_load)
.forEach(
group -> {
group.load(this.scene.getId());
var visionOptions = Grasscutter.config.server.game.visionOptions;
meta.blocks.values().forEach(block -> {
block.load(sceneId, meta.context);
block.groups.values().stream().filter(g -> !g.dynamic_load).forEach(group -> {
group.load(this.scene.getId());
// Add all entitites here
Set<Integer> vision_levels = new HashSet<>();
//Add all entities here
Set<Integer> vision_levels = new HashSet<>();
if (group.monsters != null) {
group
.monsters
.values()
.forEach(
m -> {
addGridPositionToMap(
groupPositions.get(m.vision_level),
group.id,
m.vision_level,
m.pos);
vision_levels.add(m.vision_level);
});
} else {
Grasscutter.getLogger()
.error("group.monsters null for group {}", group.id);
}
if (group.gadgets != null) {
group
.gadgets
.values()
.forEach(
g -> {
int vision_level =
Math.max(
getGadgetVisionLevel(g.gadget_id), g.vision_level);
addGridPositionToMap(
groupPositions.get(vision_level),
group.id,
vision_level,
g.pos);
vision_levels.add(vision_level);
});
} else {
Grasscutter.getLogger()
.error("group.gadgets null for group {}", group.id);
}
if (group.monsters != null) {
group.monsters.values().forEach(m -> {
addGridPositionToMap(groupPositions.get(m.vision_level), group.id, m.vision_level, m.pos);
vision_levels.add(m.vision_level);
});
} else {
Grasscutter.getLogger().error("group.monsters null for group {}", group.id);
}
if (group.gadgets != null) {
group.gadgets.values().forEach(g -> {
int vision_level = Math.max(getGadgetVisionLevel(g.gadget_id), g.vision_level);
addGridPositionToMap(groupPositions.get(vision_level), group.id, vision_level, g.pos);
vision_levels.add(vision_level);
});
} else {
Grasscutter.getLogger().error("group.gadgets null for group {}", group.id);
}
if (group.npcs != null) {
group
.npcs
.values()
.forEach(
n ->
addGridPositionToMap(
groupPositions.get(n.vision_level),
group.id,
n.vision_level,
n.pos));
} else {
Grasscutter.getLogger().error("group.npcs null for group {}", group.id);
}
if (group.npcs != null) {
group.npcs.values().forEach(n -> addGridPositionToMap(groupPositions.get(n.vision_level), group.id, n.vision_level, n.pos));
} else {
Grasscutter.getLogger().error("group.npcs null for group {}", group.id);
}
if (group.regions != null) {
group
.regions
.values()
.forEach(
r ->
addGridPositionToMap(
groupPositions.get(0), group.id, 0, r.pos));
} else {
Grasscutter.getLogger()
.error("group.regions null for group {}", group.id);
}
if (group.regions != null) {
group.regions.values().forEach(r -> addGridPositionToMap(groupPositions.get(0), group.id, 0, r.pos));
} else {
Grasscutter.getLogger().error("group.regions null for group {}", group.id);
}
if (group.garbages != null && group.garbages.gadgets != null)
group.garbages.gadgets.forEach(
g ->
addGridPositionToMap(
groupPositions.get(g.vision_level),
group.id,
g.vision_level,
g.pos));
if (group.garbages != null && group.garbages.gadgets != null)
group.garbages.gadgets.forEach(g -> addGridPositionToMap(groupPositions.get(g.vision_level), group.id, g.vision_level, g.pos));
int max_vision_level = -1;
if (!vision_levels.isEmpty()) {
for (int vision_level : vision_levels) {
if (max_vision_level == -1
|| visionOptions[max_vision_level].visionRange
< visionOptions[vision_level].visionRange)
max_vision_level = vision_level;
}
}
if (max_vision_level == -1) max_vision_level = 0;
int max_vision_level = -1;
if (!vision_levels.isEmpty()) {
for (int vision_level : vision_levels) {
if (max_vision_level == -1 || visionOptions[max_vision_level].visionRange < visionOptions[vision_level].visionRange)
max_vision_level = vision_level;
}
}
if (max_vision_level == -1) max_vision_level = 0;
addGridPositionToMap(
groupPositions.get(max_vision_level),
group.id,
max_vision_level,
group.pos);
});
});
addGridPositionToMap(groupPositions.get(max_vision_level), group.id, max_vision_level, group.pos);
});
});
this.groupGrids = new ArrayList<>();
var groupGrids = new ArrayList<Grid>();
for (int i = 0; i < 6; i++) {
this.groupGrids.add(new Grid());
this.groupGrids.get(i).gridMap = groupPositions.get(i);
groupGrids.add(new Grid());
groupGrids.get(i).grid = groupPositions.get(i);
}
groupGridsCache.put(scene.getId(), groupGrids);
try (FileWriter file = new FileWriter(path.toFile())) {
try {
Files.createDirectories(path.getParent());
} catch (IOException ignored) {}
try (var file = new FileWriter(path.toFile())) {
file.write(JsonUtils.encode(groupGrids));
} catch (IOException ignored) {
Grasscutter.getLogger().error("Scene {} unable to write to grid file.", getScene().getId());
Grasscutter.getLogger().info("Scene {} saved grid file.", getScene().getId());
} catch (Exception e) {
Grasscutter.getLogger().error("Scene {} unable to save grid file.", e, getScene().getId());
Grasscutter.getLogger().error("Scene {} unable to save grid file.", getScene().getId(), e);
}
Grasscutter.getLogger().info("Scene {} saved grid file.", getScene().getId());
return groupGrids;
}
// TEMP
this.isInit = true;
}
public boolean isInit() {
@@ -699,6 +655,10 @@ public class SceneScriptManager {
}
public void addGroupSuite(SceneGroupInstance groupInstance, SceneSuite suite) {
this.addGroupSuite(groupInstance, suite, null);
}
public void addGroupSuite(SceneGroupInstance groupInstance, SceneSuite suite, List<GameEntity> entities) {
// we added trigger first
registerTrigger(suite.sceneTriggers);
@@ -706,7 +666,9 @@ public class SceneScriptManager {
var toCreate = new ArrayList<GameEntity>();
toCreate.addAll(getGadgetsInGroupSuite(groupInstance, suite));
toCreate.addAll(getMonstersInGroupSuite(groupInstance, suite));
addEntities(toCreate);
if (entities != null)
entities.addAll(toCreate);
else this.addEntities(toCreate);
registerRegionInGroupSuite(group, suite);
}