mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-22 03:45:10 +01:00
Implement script support needed for dungeons
Only a few are supported right now You will need certain script files in ./resources/Scripts
This commit is contained in:
@@ -7,6 +7,7 @@ import emu.grasscutter.data.def.DungeonData;
|
||||
import emu.grasscutter.data.def.MonsterData;
|
||||
import emu.grasscutter.data.def.SceneData;
|
||||
import emu.grasscutter.data.def.WorldLevelData;
|
||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.player.TeamInfo;
|
||||
@@ -18,6 +19,10 @@ import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
|
||||
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
||||
import emu.grasscutter.scripts.SceneScriptManager;
|
||||
import emu.grasscutter.scripts.data.SceneBlock;
|
||||
import emu.grasscutter.scripts.data.SceneGadget;
|
||||
import emu.grasscutter.scripts.data.SceneGroup;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
|
||||
@@ -37,15 +42,19 @@ public class Scene {
|
||||
|
||||
private final Set<SpawnDataEntry> spawnedEntities;
|
||||
private final Set<SpawnDataEntry> deadSpawnedEntities;
|
||||
private final Set<SceneBlock> loadedBlocks;
|
||||
private boolean dontDestroyWhenEmpty;
|
||||
|
||||
private int time;
|
||||
private ClimateType climate;
|
||||
private int weather;
|
||||
|
||||
private SceneScriptManager scriptManager;
|
||||
private DungeonChallenge challenge;
|
||||
private DungeonData dungeonData;
|
||||
private int prevScene; // Id of the previous scene
|
||||
|
||||
private int prevScenePoint;
|
||||
|
||||
public Scene(World world, SceneData sceneData) {
|
||||
this.world = world;
|
||||
this.sceneData = sceneData;
|
||||
@@ -58,6 +67,8 @@ public class Scene {
|
||||
|
||||
this.spawnedEntities = new HashSet<>();
|
||||
this.deadSpawnedEntities = new HashSet<>();
|
||||
this.loadedBlocks = new HashSet<>();
|
||||
this.scriptManager = new SceneScriptManager(this);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
@@ -124,6 +135,14 @@ public class Scene {
|
||||
this.prevScene = prevScene;
|
||||
}
|
||||
|
||||
public int getPrevScenePoint() {
|
||||
return prevScenePoint;
|
||||
}
|
||||
|
||||
public void setPrevScenePoint(int prevPoint) {
|
||||
this.prevScenePoint = prevPoint;
|
||||
}
|
||||
|
||||
public boolean dontDestroyWhenEmpty() {
|
||||
return dontDestroyWhenEmpty;
|
||||
}
|
||||
@@ -132,6 +151,10 @@ public class Scene {
|
||||
this.dontDestroyWhenEmpty = dontDestroyWhenEmpty;
|
||||
}
|
||||
|
||||
public Set<SceneBlock> getLoadedBlocks() {
|
||||
return loadedBlocks;
|
||||
}
|
||||
|
||||
public Set<SpawnDataEntry> getSpawnedEntities() {
|
||||
return spawnedEntities;
|
||||
}
|
||||
@@ -140,6 +163,10 @@ public class Scene {
|
||||
return deadSpawnedEntities;
|
||||
}
|
||||
|
||||
public SceneScriptManager getScriptManager() {
|
||||
return scriptManager;
|
||||
}
|
||||
|
||||
public DungeonData getDungeonData() {
|
||||
return dungeonData;
|
||||
}
|
||||
@@ -151,6 +178,14 @@ public class Scene {
|
||||
this.dungeonData = dungeonData;
|
||||
}
|
||||
|
||||
public DungeonChallenge getChallenge() {
|
||||
return challenge;
|
||||
}
|
||||
|
||||
public void setChallenge(DungeonChallenge challenge) {
|
||||
this.challenge = challenge;
|
||||
}
|
||||
|
||||
public boolean isInScene(GameEntity entity) {
|
||||
return this.entities.containsKey(entity.getId());
|
||||
}
|
||||
@@ -183,7 +218,7 @@ public class Scene {
|
||||
this.removePlayerAvatars(player);
|
||||
|
||||
// Remove player gadgets
|
||||
for (EntityGadget gadget : player.getTeamManager().getGadgets()) {
|
||||
for (EntityBaseGadget gadget : player.getTeamManager().getGadgets()) {
|
||||
this.removeEntity(gadget);
|
||||
}
|
||||
|
||||
@@ -338,7 +373,15 @@ public class Scene {
|
||||
}
|
||||
|
||||
public void onTick() {
|
||||
this.checkSpawns();
|
||||
if (this.getScriptManager().isInit()) {
|
||||
this.checkBlocks();
|
||||
} else {
|
||||
// TEMPORARY
|
||||
this.checkSpawns();
|
||||
}
|
||||
|
||||
// Triggers
|
||||
this.getScriptManager().onTick();
|
||||
}
|
||||
|
||||
// TODO - Test
|
||||
@@ -411,6 +454,75 @@ public class Scene {
|
||||
}
|
||||
}
|
||||
|
||||
public void checkBlocks() {
|
||||
Set<SceneBlock> visible = new HashSet<>();
|
||||
|
||||
for (Player player : this.getPlayers()) {
|
||||
for (SceneBlock block : getScriptManager().getBlocks()) {
|
||||
if (!block.contains(player.getPos())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
visible.add(block);
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<SceneBlock> it = this.getLoadedBlocks().iterator();
|
||||
while (it.hasNext()) {
|
||||
SceneBlock block = it.next();
|
||||
|
||||
if (!visible.contains(block)) {
|
||||
it.remove();
|
||||
|
||||
onUnloadBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
for (SceneBlock block : visible) {
|
||||
if (!this.getLoadedBlocks().contains(block)) {
|
||||
this.getLoadedBlocks().add(block);
|
||||
this.onLoadBlock(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO optimize
|
||||
public void onLoadBlock(SceneBlock block) {
|
||||
for (SceneGroup group : block.groups) {
|
||||
group.triggers.forEach(getScriptManager()::registerTrigger);
|
||||
}
|
||||
|
||||
for (SceneGroup group : block.groups) {
|
||||
for (SceneGadget g : group.gadgets) {
|
||||
EntityGadget entity = new EntityGadget(this, g.gadget_id, g.pos);
|
||||
|
||||
if (entity.getGadgetData() == null) continue;
|
||||
|
||||
entity.setBlockId(block.id);
|
||||
entity.setConfigId(g.config_id);
|
||||
entity.setGroupId(group.id);
|
||||
entity.getRotation().set(g.rot);
|
||||
entity.setState(g.state);
|
||||
|
||||
this.addEntity(entity);
|
||||
this.getScriptManager().onGadgetCreate(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onUnloadBlock(SceneBlock block) {
|
||||
List<GameEntity> toRemove = this.getEntities().values().stream().filter(e -> e.getBlockId() == block.id).toList();
|
||||
|
||||
if (toRemove.size() > 0) {
|
||||
toRemove.stream().forEach(this::removeEntityDirectly);
|
||||
this.broadcastPacket(new PacketSceneEntityDisappearNotify(toRemove, VisionType.VISION_REMOVE));
|
||||
}
|
||||
|
||||
for (SceneGroup group : block.groups) {
|
||||
group.triggers.forEach(getScriptManager()::deregisterTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
// Gadgets
|
||||
|
||||
public void onPlayerCreateGadget(EntityClientGadget gadget) {
|
||||
|
||||
@@ -21,11 +21,12 @@ import emu.grasscutter.data.def.DungeonData;
|
||||
import emu.grasscutter.data.def.SceneData;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.game.entity.EntityClientGadget;
|
||||
import emu.grasscutter.game.entity.EntityGadget;
|
||||
import emu.grasscutter.game.entity.EntityBaseGadget;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
|
||||
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
|
||||
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
||||
import emu.grasscutter.scripts.data.SceneConfig;
|
||||
import emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
|
||||
@@ -243,16 +244,22 @@ public class World implements Iterable<Player> {
|
||||
newScene.addPlayer(player);
|
||||
|
||||
// Dungeon
|
||||
if (dungeonData != null) {
|
||||
// TODO set position
|
||||
SceneConfig config = newScene.getScriptManager().getConfig();
|
||||
if (pos == null && config != null) {
|
||||
if (config.born_pos != null) {
|
||||
pos = newScene.getScriptManager().getConfig().born_pos;
|
||||
}
|
||||
if (config.born_rot != null) {
|
||||
player.getRotation().set(config.born_rot);
|
||||
}
|
||||
}
|
||||
|
||||
// Set player position
|
||||
if (pos != null) {
|
||||
player.getPos().set(pos);
|
||||
} else {
|
||||
if (pos == null) {
|
||||
pos = player.getPos();
|
||||
}
|
||||
|
||||
player.getPos().set(pos);
|
||||
|
||||
if (oldScene != null) {
|
||||
newScene.setPrevScene(oldScene.getId());
|
||||
|
||||
Reference in New Issue
Block a user