mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-23 17:17:43 +00:00
Merge branch 'dev-world-scripts' of https://github.com/Grasscutters/Grasscutter into dev-world-scripts
This commit is contained in:
commit
73a88b2da2
135
data/ChestReward.json
Normal file
135
data/ChestReward.json
Normal file
@ -0,0 +1,135 @@
|
||||
[
|
||||
{
|
||||
"objNames" : [
|
||||
"SceneObj_Chest_Default_Lv1",
|
||||
"SceneObj_Chest_Locked_Lv1",
|
||||
"SceneObj_Chest_Bramble_Lv1",
|
||||
"SceneObj_Chest_Frozen_Lv1",
|
||||
"SceneObj_Chest_Rock_Lv1",
|
||||
"SceneObj_EssenceChest_Default_Lv1",
|
||||
"SceneObj_EssenceChest_Locked_Lv1"
|
||||
],
|
||||
"advExp" : 10,
|
||||
"resin" : 0,
|
||||
"mora" : 257,
|
||||
"sigil" : 1,
|
||||
"content" : [
|
||||
{
|
||||
"itemId" : 104011,
|
||||
"count": 3
|
||||
},
|
||||
{
|
||||
"itemId" : 104001,
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"randomCount": 4,
|
||||
"randomContent": [
|
||||
{
|
||||
"itemId" : 11101,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 11201,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 12101,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 12201,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 13101,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 13201,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 14101,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 14201,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 15101,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 15201,
|
||||
"count": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"objNames" : [
|
||||
"SceneObj_Chest_Default_Lv2",
|
||||
"SceneObj_Chest_Locked_Lv2",
|
||||
"SceneObj_Chest_Bramble_Lv2",
|
||||
"SceneObj_Chest_Frozen_Lv2"
|
||||
],
|
||||
"advExp" : 20,
|
||||
"resin" : 2,
|
||||
"mora" : 756,
|
||||
"sigil" : 2,
|
||||
"content" : [
|
||||
{
|
||||
"itemId" : 104012,
|
||||
"count": 3
|
||||
},
|
||||
{
|
||||
"itemId" : 104002,
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"randomCount": 4,
|
||||
"randomContent": [
|
||||
{
|
||||
"itemId" : 11201,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 11301,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 12201,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 12301,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 13201,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 13301,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 14201,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 14301,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 15201,
|
||||
"count": 1
|
||||
},
|
||||
{
|
||||
"itemId" : 15301,
|
||||
"count": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -1,23 +1,21 @@
|
||||
package emu.grasscutter.game.entity;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.def.GadgetData;
|
||||
import emu.grasscutter.game.entity.gadget.GadgetContent;
|
||||
import emu.grasscutter.game.entity.gadget.GadgetGatherPoint;
|
||||
import emu.grasscutter.game.entity.gadget.GadgetRewardStatue;
|
||||
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.EntityIdType;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.game.world.World;
|
||||
import emu.grasscutter.net.proto.ClientGadgetInfoOuterClass;
|
||||
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
||||
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
||||
import emu.grasscutter.net.proto.BossChestInfoOuterClass;
|
||||
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
||||
import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData;
|
||||
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
||||
@ -32,11 +30,14 @@ import emu.grasscutter.net.proto.WorktopInfoOuterClass.WorktopInfo;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.utils.ProtoHelper;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
@ToString(callSuper = true)
|
||||
public class EntityGadget extends EntityBaseGadget {
|
||||
private final GadgetData data;
|
||||
private final Position pos;
|
||||
@ -175,4 +176,30 @@ public class EntityGadget extends EntityBaseGadget {
|
||||
|
||||
return entityInfo.build();
|
||||
}
|
||||
|
||||
public void openChest(Player player) {
|
||||
var chestRewardMap = getScene().getWorld().getServer().getWorldDataManager().getChestRewardMap();
|
||||
var chestReward = chestRewardMap.get(this.getGadgetData().getJsonName());
|
||||
if(chestReward == null){
|
||||
Grasscutter.getLogger().warn("Could not found the config of this type of Chests {}", this.getGadgetData().getJsonName());
|
||||
return;
|
||||
}
|
||||
|
||||
player.earnExp(chestReward.getAdvExp());
|
||||
player.getInventory().addItem(201, chestReward.getResin());
|
||||
|
||||
var mora = chestReward.getMora() * (1 + (player.getWorldLevel() - 1) * 0.5);
|
||||
player.getInventory().addItem(202, (int)mora);
|
||||
|
||||
for(int i=0;i<chestReward.getContent().size();i++){
|
||||
getScene().addItemEntity(chestReward.getContent().get(i).getItemId(), chestReward.getContent().get(i).getCount(), this);
|
||||
}
|
||||
|
||||
var random = new Random(System.currentTimeMillis());
|
||||
for(int i=0;i<chestReward.getRandomCount();i++){
|
||||
var index = random.nextInt(chestReward.getRandomContent().size());
|
||||
var item = chestReward.getRandomContent().get(index);
|
||||
getScene().addItemEntity(item.getItemId(), item.getCount(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,10 @@ import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.PropGrowCurve;
|
||||
import emu.grasscutter.data.def.MonsterCurveData;
|
||||
import emu.grasscutter.data.def.MonsterData;
|
||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
||||
import emu.grasscutter.game.props.EntityIdType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.game.world.World;
|
||||
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
||||
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
||||
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
||||
@ -24,6 +22,7 @@ import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
||||
import emu.grasscutter.net.proto.SceneMonsterInfoOuterClass.SceneMonsterInfo;
|
||||
import emu.grasscutter.net.proto.SceneWeaponInfoOuterClass.SceneWeaponInfo;
|
||||
import emu.grasscutter.scripts.constants.EventType;
|
||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.utils.ProtoHelper;
|
||||
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
||||
@ -126,7 +125,9 @@ public class EntityMonster extends GameEntity {
|
||||
}
|
||||
// prevent spawn monster after success
|
||||
if(getScene().getChallenge() != null && getScene().getChallenge().inProgress()){
|
||||
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, null);
|
||||
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, new ScriptArgs().setParam1(this.getConfigId()));
|
||||
}else if(getScene().getChallenge() == null){
|
||||
getScene().getScriptManager().callEvent(EventType.EVENT_ANY_MONSTER_DIE, new ScriptArgs().setParam1(this.getConfigId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo;
|
||||
import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo;
|
||||
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
|
||||
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
||||
import emu.grasscutter.scripts.constants.ScriptGadgetState;
|
||||
import emu.grasscutter.server.event.player.PlayerJoinEvent;
|
||||
import emu.grasscutter.server.event.player.PlayerQuitEvent;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
@ -927,6 +928,13 @@ public class Player {
|
||||
if (shouldDelete) {
|
||||
entity.getScene().removeEntity(entity);
|
||||
}
|
||||
else if (gadget.getGadgetData().getType() == EntityType.Chest) {
|
||||
getScene().updateGadgetState(gadget, ScriptGadgetState.ChestOpened);
|
||||
gadget.openChest(this);
|
||||
|
||||
this.sendPacket(new PacketGadgetInteractRsp(gadget, InteractType.INTERACT_OPEN_CHEST));
|
||||
getScene().killEntity(gadget, 0);
|
||||
}
|
||||
} else {
|
||||
// Delete directly
|
||||
entity.getScene().removeEntity(entity);
|
||||
|
22
src/main/java/emu/grasscutter/game/world/ChestReward.java
Normal file
22
src/main/java/emu/grasscutter/game/world/ChestReward.java
Normal file
@ -0,0 +1,22 @@
|
||||
package emu.grasscutter.game.world;
|
||||
|
||||
import emu.grasscutter.game.inventory.ItemDef;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ChestReward {
|
||||
List<String> objNames;
|
||||
int advExp;
|
||||
int resin;
|
||||
int mora;
|
||||
int sigil;
|
||||
List<ItemDef> content;
|
||||
int randomCount;
|
||||
List<ItemDef> randomContent;
|
||||
|
||||
}
|
@ -3,10 +3,7 @@ package emu.grasscutter.game.world;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameDepot;
|
||||
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.data.def.*;
|
||||
import emu.grasscutter.game.dungeons.DungeonChallenge;
|
||||
import emu.grasscutter.game.dungeons.DungeonSettleListener;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
@ -25,11 +22,8 @@ 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.PacketAvatarSkillInfoNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneEntityDisappearNotify;
|
||||
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;
|
||||
@ -38,6 +32,8 @@ import org.danilopianini.util.SpatialIndex;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public class Scene {
|
||||
private final World world;
|
||||
private final SceneData sceneData;
|
||||
@ -595,8 +591,10 @@ public class Scene {
|
||||
|
||||
do {
|
||||
var suiteData = group.getSuiteByIndex(suite);
|
||||
suiteData.sceneTriggers.forEach(getScriptManager()::registerTrigger);
|
||||
|
||||
entities.addAll(suiteData.sceneGadgets.stream()
|
||||
.map(g -> scriptManager.createGadgets(group.id, group.block_id, g)).toList());
|
||||
.map(g -> scriptManager.createGadget(group.id, group.block_id, g)).toList());
|
||||
entities.addAll(suiteData.sceneMonsters.stream()
|
||||
.map(mob -> scriptManager.createMonster(group.id, group.block_id, mob)).toList());
|
||||
suite++;
|
||||
@ -618,7 +616,7 @@ public class Scene {
|
||||
|
||||
for (SceneGroup group : block.groups) {
|
||||
if(group.triggers != null){
|
||||
group.triggers.forEach(getScriptManager()::deregisterTrigger);
|
||||
group.triggers.values().forEach(getScriptManager()::deregisterTrigger);
|
||||
}
|
||||
if(group.regions != null){
|
||||
group.regions.forEach(getScriptManager()::deregisterRegion);
|
||||
@ -690,4 +688,27 @@ public class Scene {
|
||||
player.getSession().send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void addItemEntity(int itemId, int amount, GameEntity bornForm){
|
||||
ItemData itemData = GameData.getItemDataMap().get(itemId);
|
||||
if (itemData == null) {
|
||||
return;
|
||||
}
|
||||
if (itemData.isEquip()) {
|
||||
float range = (3f + (.1f * amount));
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Position pos = bornForm.getPosition().clone().addX((float) (Math.random() * range) - (range / 2)).addZ((float) (Math.random() * range) - (range / 2)).addZ(.9f);
|
||||
EntityItem entity = new EntityItem(this, null, itemData, pos, 1);
|
||||
addEntity(entity);
|
||||
}
|
||||
} else {
|
||||
EntityItem entity = new EntityItem(this, null, itemData, bornForm.getPosition().clone().addZ(.9f), amount);
|
||||
addEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateGadgetState(EntityGadget gadget, int state){
|
||||
gadget.setState(state);
|
||||
broadcastPacket(new PacketGadgetStateNotify(gadget, state));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
package emu.grasscutter.game.world;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static emu.grasscutter.Configuration.DATA;
|
||||
|
||||
public class WorldDataManager {
|
||||
private final GameServer gameServer;
|
||||
private final Map<String, ChestReward> chestRewardMap;
|
||||
|
||||
public WorldDataManager(GameServer gameServer){
|
||||
this.gameServer = gameServer;
|
||||
this.chestRewardMap = new HashMap<>();
|
||||
load();
|
||||
}
|
||||
|
||||
public synchronized void load(){
|
||||
try {
|
||||
List<ChestReward> chestReward = Grasscutter.getGsonFactory().fromJson(
|
||||
Files.readString(Path.of(DATA("ChestReward.json"))),
|
||||
TypeToken.getParameterized(List.class, ChestReward.class).getType());
|
||||
chestReward.forEach(reward ->
|
||||
reward.getObjNames().forEach(name -> chestRewardMap.put(name, reward)));
|
||||
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("Unable to load chest reward config.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, ChestReward> getChestRewardMap() {
|
||||
return chestRewardMap;
|
||||
}
|
||||
}
|
@ -42,7 +42,6 @@ public class SceneScriptManager {
|
||||
private final Int2ObjectOpenHashMap<Set<SceneTrigger>> currentTriggers;
|
||||
private final Int2ObjectOpenHashMap<SceneRegion> regions;
|
||||
private Map<Integer,SceneGroup> sceneGroups;
|
||||
private SceneGroup currentGroup;
|
||||
private ScriptMonsterTideService scriptMonsterTideService;
|
||||
private ScriptMonsterSpawnService scriptMonsterSpawnService;
|
||||
/**
|
||||
@ -94,10 +93,6 @@ public class SceneScriptManager {
|
||||
return meta.config;
|
||||
}
|
||||
|
||||
public SceneGroup getCurrentGroup() {
|
||||
return currentGroup;
|
||||
}
|
||||
|
||||
public Map<Integer, SceneBlock> getBlocks() {
|
||||
return meta.blocks;
|
||||
}
|
||||
@ -118,20 +113,19 @@ public class SceneScriptManager {
|
||||
this.triggers.remove(trigger.name);
|
||||
getTriggersByEvent(trigger.event).remove(trigger);
|
||||
}
|
||||
public void resetTriggers(List<String> triggerNames) {
|
||||
for(var name : triggerNames){
|
||||
var instance = triggers.get(name);
|
||||
this.currentTriggers.get(instance.event).clear();
|
||||
this.currentTriggers.get(instance.event).add(instance);
|
||||
}
|
||||
public void resetTriggers(int eventId) {
|
||||
currentTriggers.put(eventId, new HashSet<>());
|
||||
}
|
||||
public void refreshGroup(SceneGroup group, int suiteIndex){
|
||||
var suite = group.getSuiteByIndex(suiteIndex);
|
||||
if(suite == null){
|
||||
return;
|
||||
}
|
||||
if(suite.triggers.size() > 0){
|
||||
resetTriggers(suite.triggers);
|
||||
if(suite.sceneTriggers.size() > 0){
|
||||
for(var trigger : suite.sceneTriggers){
|
||||
resetTriggers(trigger.event);
|
||||
this.currentTriggers.get(trigger.event).add(trigger);
|
||||
}
|
||||
}
|
||||
spawnMonstersInGroup(group, suite);
|
||||
spawnGadgetsInGroup(group, suite);
|
||||
@ -158,7 +152,7 @@ public class SceneScriptManager {
|
||||
for (SceneGroup group : block.groups) {
|
||||
if (group.id == groupId) {
|
||||
if(!group.isLoaded()){
|
||||
loadGroupFromScript(group);
|
||||
getScene().onLoadGroup(List.of(group));
|
||||
}
|
||||
return group;
|
||||
}
|
||||
@ -204,9 +198,6 @@ public class SceneScriptManager {
|
||||
group.variables.forEach(var -> this.getVariables().put(var.name, var.value));
|
||||
this.sceneGroups.put(group.id, group);
|
||||
|
||||
if(group.triggers != null){
|
||||
group.triggers.forEach(this::registerTrigger);
|
||||
}
|
||||
if(group.regions != null){
|
||||
group.regions.forEach(this::registerRegion);
|
||||
}
|
||||
@ -248,7 +239,7 @@ public class SceneScriptManager {
|
||||
}
|
||||
|
||||
var toCreate = gadgets.stream()
|
||||
.map(g -> createGadgets(g.groupId, group.block_id, g))
|
||||
.map(g -> createGadget(g.groupId, group.block_id, g))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
this.addEntities(toCreate);
|
||||
@ -265,20 +256,17 @@ public class SceneScriptManager {
|
||||
if(suite == null || suite.sceneMonsters.size() <= 0){
|
||||
return;
|
||||
}
|
||||
this.currentGroup = group;
|
||||
this.addEntities(suite.sceneMonsters.stream()
|
||||
.map(mob -> createMonster(group.id, group.block_id, mob)).toList());
|
||||
|
||||
}
|
||||
|
||||
public void spawnMonstersInGroup(SceneGroup group) {
|
||||
this.currentGroup = group;
|
||||
this.addEntities(group.monsters.values().stream()
|
||||
.map(mob -> createMonster(group.id, group.block_id, mob)).toList());
|
||||
}
|
||||
|
||||
public void startMonsterTideInGroup(SceneGroup group, Integer[] ordersConfigId, int tideCount, int sceneLimit) {
|
||||
this.currentGroup = group;
|
||||
this.scriptMonsterTideService =
|
||||
new ScriptMonsterTideService(this, group, tideCount, sceneLimit, ordersConfigId);
|
||||
|
||||
@ -289,15 +277,15 @@ public class SceneScriptManager {
|
||||
}
|
||||
this.getScriptMonsterTideService().unload();
|
||||
}
|
||||
public void spawnMonstersByConfigId(int configId, int delayTime) {
|
||||
public void spawnMonstersByConfigId(SceneGroup group, int configId, int delayTime) {
|
||||
// TODO delay
|
||||
getScene().addEntity(
|
||||
createMonster(this.currentGroup.id, this.currentGroup.block_id, this.currentGroup.monsters.get(configId)));
|
||||
getScene().addEntity(createMonster(group.id, group.block_id, group.monsters.get(configId)));
|
||||
}
|
||||
// Events
|
||||
|
||||
public void callEvent(int eventType, ScriptArgs params) {
|
||||
for (SceneTrigger trigger : this.getTriggersByEvent(eventType)) {
|
||||
scriptLib.setCurrentGroup(trigger.currentGroup);
|
||||
LuaValue condition = null;
|
||||
|
||||
if (trigger.condition != null && !trigger.condition.isEmpty()) {
|
||||
@ -330,6 +318,7 @@ public class SceneScriptManager {
|
||||
safetyCall(trigger.action, action, args);
|
||||
}
|
||||
//TODO some ret may not bool
|
||||
scriptLib.removeCurrentGroup();
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,7 +326,7 @@ public class SceneScriptManager {
|
||||
try{
|
||||
return func.call(this.getScriptLibLua(), args);
|
||||
}catch (LuaError error){
|
||||
ScriptLib.logger.error("[LUA] call trigger failed {},{}",name,args,error);
|
||||
ScriptLib.logger.error("[LUA] call trigger failed {},{},{}",name,args,error.getMessage());
|
||||
return LuaValue.valueOf(-1);
|
||||
}
|
||||
}
|
||||
@ -350,7 +339,7 @@ public class SceneScriptManager {
|
||||
return scriptMonsterSpawnService;
|
||||
}
|
||||
|
||||
public EntityGadget createGadgets(int groupId, int blockId, SceneGadget g) {
|
||||
public EntityGadget createGadget(int groupId, int blockId, SceneGadget g) {
|
||||
EntityGadget entity = new EntityGadget(getScene(), g.gadget_id, g.pos);
|
||||
|
||||
if (entity.getGadgetData() == null){
|
||||
|
@ -24,6 +24,7 @@ public class ScriptLib {
|
||||
|
||||
public ScriptLib(SceneScriptManager sceneScriptManager) {
|
||||
this.sceneScriptManager = sceneScriptManager;
|
||||
this.currentGroup = new ThreadLocal<>();
|
||||
}
|
||||
|
||||
public SceneScriptManager getSceneScriptManager() {
|
||||
@ -39,7 +40,17 @@ public class ScriptLib {
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private final ThreadLocal<SceneGroup> currentGroup;
|
||||
public void setCurrentGroup(SceneGroup currentGroup){
|
||||
logger.debug("current {}", currentGroup);
|
||||
this.currentGroup.set(currentGroup);
|
||||
}
|
||||
public Optional<SceneGroup> getCurrentGroup(){
|
||||
return Optional.ofNullable(this.currentGroup.get());
|
||||
}
|
||||
public void removeCurrentGroup(){
|
||||
this.currentGroup.remove();
|
||||
}
|
||||
public int SetGadgetStateByConfigId(int configId, int gadgetState) {
|
||||
logger.debug("[LUA] Call SetGadgetStateByConfigId with {},{}",
|
||||
configId,gadgetState);
|
||||
@ -102,7 +113,12 @@ public class ScriptLib {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public int SetWorktopOptions(LuaTable table){
|
||||
logger.debug("[LUA] Call SetWorktopOptions with {}", printTable(table));
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
public int DelWorktopOptionByGroupId(int groupId, int configId, int option) {
|
||||
logger.debug("[LUA] Call DelWorktopOptionByGroupId with {},{},{}",groupId,configId,option);
|
||||
|
||||
@ -273,7 +289,8 @@ public class ScriptLib {
|
||||
var1);
|
||||
|
||||
return (int) getSceneScriptManager().getScene().getEntities().values().stream()
|
||||
.filter(e -> e instanceof EntityMonster && e.getGroupId() == getSceneScriptManager().getCurrentGroup().id)
|
||||
.filter(e -> e instanceof EntityMonster &&
|
||||
e.getGroupId() == getCurrentGroup().map(sceneGroup -> sceneGroup.id).orElse(-1))
|
||||
.count();
|
||||
}
|
||||
public int SetMonsterBattleByGroup(int var1, int var2, int var3){
|
||||
@ -335,7 +352,11 @@ public class ScriptLib {
|
||||
var configId = table.get("config_id").toint();
|
||||
var delayTime = table.get("delay_time").toint();
|
||||
|
||||
getSceneScriptManager().spawnMonstersByConfigId(configId, delayTime);
|
||||
if(getCurrentGroup().isEmpty()){
|
||||
return 1;
|
||||
}
|
||||
|
||||
getSceneScriptManager().spawnMonstersByConfigId(getCurrentGroup().get(), configId, delayTime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -354,7 +375,13 @@ public class ScriptLib {
|
||||
printTable(table));
|
||||
var configId = table.get("config_id").toint();
|
||||
|
||||
//TODO
|
||||
var group = getCurrentGroup();
|
||||
if(group.isEmpty()){
|
||||
return 1;
|
||||
}
|
||||
var gadget = group.get().gadgets.get(configId);
|
||||
var entity = getSceneScriptManager().createGadget(group.get().id, group.get().block_id, gadget);
|
||||
getSceneScriptManager().addEntity(entity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -377,14 +404,42 @@ public class ScriptLib {
|
||||
.filter(g -> g.getConfigId() == configId)
|
||||
.findFirst();
|
||||
if(gadget.isEmpty()){
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
var stat = ((EntityGadget)gadget.get()).getState();
|
||||
return stat;
|
||||
return ((EntityGadget)gadget.get()).getState();
|
||||
}
|
||||
public int SetGadgetStateByConfigId(int configId, LuaTable gadgetState){
|
||||
logger.debug("[LUA] Call SetGadgetStateByConfigId with {},{}",
|
||||
configId, printTable(gadgetState));
|
||||
|
||||
public int MarkPlayerAction(int var1, int var2, int var3, int var4){
|
||||
logger.debug("[LUA] Call MarkPlayerAction with {},{}",
|
||||
var1, var2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int AddQuestProgress(String var1){
|
||||
logger.debug("[LUA] Call AddQuestProgress with {}",
|
||||
var1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* change the state of gadget
|
||||
*/
|
||||
public int ChangeGroupGadget(LuaTable table){
|
||||
logger.debug("[LUA] Call ChangeGroupGadget with {}",
|
||||
printTable(table));
|
||||
var configId = table.get("config_id").toint();
|
||||
var state = table.get("state").toint();
|
||||
|
||||
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId);
|
||||
if(entity == null){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(entity instanceof EntityGadget entityGadget){
|
||||
getSceneScriptManager().getScene().updateGadgetState(entityGadget, state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package emu.grasscutter.scripts.constants;
|
||||
|
||||
public class EventType {
|
||||
public static final int EVENT_NONE = 0;
|
||||
/**
|
||||
* param1: monster.configId
|
||||
*/
|
||||
public static final int EVENT_ANY_MONSTER_DIE = 1;
|
||||
public static final int EVENT_ANY_GADGET_DIE = 2;
|
||||
public static final int EVENT_VARIABLE_CHANGE = 3;
|
||||
|
@ -28,8 +28,8 @@ public class SceneGroup {
|
||||
|
||||
public Map<Integer,SceneMonster> monsters; // <ConfigId, Monster>
|
||||
public Map<Integer, SceneGadget> gadgets; // <ConfigId, Gadgets>
|
||||
|
||||
public List<SceneTrigger> triggers;
|
||||
public Map<String, SceneTrigger> triggers;
|
||||
|
||||
public List<SceneRegion> regions;
|
||||
public List<SceneSuite> suites;
|
||||
public List<SceneVar> variables;
|
||||
@ -94,9 +94,10 @@ public class SceneGroup {
|
||||
.collect(Collectors.toMap(x -> x.config_id, y -> y));
|
||||
gadgets.values().forEach(m -> m.groupId = id);
|
||||
|
||||
triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, bindings.get("triggers"));
|
||||
triggers.forEach(t -> t.currentGroup = this);
|
||||
|
||||
triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, bindings.get("triggers")).stream()
|
||||
.collect(Collectors.toMap(x -> x.name, y -> y));
|
||||
triggers.values().forEach(t -> t.currentGroup = this);
|
||||
|
||||
suites = ScriptLoader.getSerializer().toList(SceneSuite.class, bindings.get("suites"));
|
||||
regions = ScriptLoader.getSerializer().toList(SceneRegion.class, bindings.get("regions"));
|
||||
garbages = ScriptLoader.getSerializer().toObject(SceneGarbage.class, bindings.get("garbages"));
|
||||
@ -120,6 +121,13 @@ public class SceneGroup {
|
||||
.map(gadgets::get)
|
||||
.toList()
|
||||
);
|
||||
|
||||
suite.sceneTriggers = new ArrayList<>(
|
||||
suite.triggers.stream()
|
||||
.filter(triggers::containsKey)
|
||||
.map(triggers::get)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
} catch (ScriptException e) {
|
||||
|
@ -15,4 +15,5 @@ public class SceneSuite {
|
||||
|
||||
public transient List<SceneMonster> sceneMonsters;
|
||||
public transient List<SceneGadget> sceneGadgets;
|
||||
public transient List<SceneTrigger> sceneTriggers;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ public class SceneTrigger {
|
||||
public String condition;
|
||||
public String action;
|
||||
|
||||
public SceneGroup currentGroup;
|
||||
public transient SceneGroup currentGroup;
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof SceneTrigger sceneTrigger){
|
||||
|
@ -19,6 +19,7 @@ import emu.grasscutter.game.quest.ServerQuestHandler;
|
||||
import emu.grasscutter.game.shop.ShopManager;
|
||||
import emu.grasscutter.game.tower.TowerScheduleManager;
|
||||
import emu.grasscutter.game.world.World;
|
||||
import emu.grasscutter.game.world.WorldDataManager;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
|
||||
import emu.grasscutter.netty.KcpServer;
|
||||
@ -57,6 +58,7 @@ public final class GameServer extends KcpServer {
|
||||
|
||||
private final CombineManger combineManger;
|
||||
private final TowerScheduleManager towerScheduleManager;
|
||||
private final WorldDataManager worldDataManager;
|
||||
public GameServer() {
|
||||
this(new InetSocketAddress(
|
||||
GAME_INFO.bindAddress,
|
||||
@ -86,6 +88,7 @@ public final class GameServer extends KcpServer {
|
||||
this.expeditionManager = new ExpeditionManager(this);
|
||||
this.combineManger = new CombineManger(this);
|
||||
this.towerScheduleManager = new TowerScheduleManager(this);
|
||||
this.worldDataManager = new WorldDataManager(this);
|
||||
// Hook into shutdown event.
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown));
|
||||
}
|
||||
@ -153,6 +156,10 @@ public final class GameServer extends KcpServer {
|
||||
return towerScheduleManager;
|
||||
}
|
||||
|
||||
public WorldDataManager getWorldDataManager() {
|
||||
return worldDataManager;
|
||||
}
|
||||
|
||||
public TaskMap getTaskMap() {
|
||||
return this.taskMap;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user