Commit 86b8f454 authored by KingRainbow44's avatar KingRainbow44
Browse files

Merge remote-tracking branch 'origin/api' into api

parents b5c27723 63d41fd7
...@@ -115,7 +115,7 @@ There is a dummy user named "Server" in every player's friends list that you can ...@@ -115,7 +115,7 @@ There is a dummy user named "Server" in every player's friends list that you can
| drop | drop <itemID\|itemName> [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` | | drop | drop <itemID\|itemName> [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` |
| give | give [player] <itemId\|itemName> [amount] [level] [finement] | player.give | Both side | Gives item(s) to you or the specified player. (finement option only weapon.) | `g` `item` `giveitem` | | give | give [player] <itemId\|itemName> [amount] [level] [finement] | player.give | Both side | Gives item(s) to you or the specified player. (finement option only weapon.) | `g` `item` `giveitem` |
| givechar | givechar \<uid> \<avatarId> | player.givechar | Both side | Gives the player a specified character. | givec | | givechar | givechar \<uid> \<avatarId> | player.givechar | Both side | Gives the player a specified character. | givec |
| giveart | giveart [player] \<artifactId> \<mainPropId> [\<appendPropId>[,\<times>]]... [level] | player.giveart | Both side | Gives the player a specified reliquary. | givea | | giveart | giveart [player] \<artifactId> \<mainPropId> [\<appendPropId>[,\<times>]]... [level] | player.giveart | Both side | Gives the player a specified artifact. | gart |
| giveall | giveall [uid] [amount] | player.giveall | Both side | Gives all items. | givea | | giveall | giveall [uid] [amount] | player.giveall | Both side | Gives all items. | givea |
| godmode | godmode [uid] | player.godmode | Client only | Prevents you from taking damage. | | | godmode | godmode [uid] | player.godmode | Client only | Prevents you from taking damage. | |
| heal | heal | player.heal | Client only | Heals all characters in your current team. | h | | heal | heal | player.heal | Client only | Heals all characters in your current team. | h |
...@@ -135,7 +135,7 @@ There is a dummy user named "Server" in every player's friends list that you can ...@@ -135,7 +135,7 @@ There is a dummy user named "Server" in every player's friends list that you can
| spawn | spanw <entityID\|entityName> [level] [amount] | server.spawn | Client only | Spawns an entity near you | | | spawn | spanw <entityID\|entityName> [level] [amount] | server.spawn | Client only | Spawns an entity near you | |
| stop | stop | server.stop | Both side | Stops the server | | | stop | stop | server.stop | Both side | Stops the server | |
| talent | talent \<talentID> \<value> | player.settalent | Client only | Sets talent level for your currently selected character | | | talent | talent \<talentID> \<value> | player.settalent | Client only | Sets talent level for your currently selected character | |
| teleport | teleport \<x> \<y> \<z> | player.teleport | Client only | Change the player's position. | tp | | teleport | teleport [@playerUid] \<x> \<y> \<z> [sceneId] | player.teleport | Both side | Change the player's position. | tp |
| tpall | | player.tpall | Client only | Teleports all players in your world to your position | | | tpall | | player.tpall | Client only | Teleports all players in your world to your position | |
| weather | weather \<weatherID> \<climateID> | player.weather | Client only | Changes the weather | w | | weather | weather \<weatherID> \<climateID> | player.weather | Client only | Changes the weather | w |
...@@ -144,9 +144,12 @@ There is a dummy user named "Server" in every player's friends list that you can ...@@ -144,9 +144,12 @@ There is a dummy user named "Server" in every player's friends list that you can
When you want to teleport to somewhere, use the ingame marking function on Map, click Confirm. You will see your When you want to teleport to somewhere, use the ingame marking function on Map, click Confirm. You will see your
character falling from a very high destination, exact location that you marked. character falling from a very high destination, exact location that you marked.
You can also specify a set Y coordinate by renaming the map marker.
# Quick Troubleshooting # Quick Troubleshooting
* If compiling wasn't successful, please check your JDK installation (JDK 17 and validated JDK's bin PATH variable) * If compiling wasn't successful, please check your JDK installation (JDK 17 and validated JDK's bin PATH variable)
* My client doesn't connect, doesn't login, 4206, etc... - Mostly your proxy daemon setup is *the issue*, if using * My client doesn't connect, doesn't login, 4206, etc... - Mostly your proxy daemon setup is *the issue*, if using
Fiddler make sure it running on another port except 8888 Fiddler make sure it running on another port except 8888
* Startup sequence: Mongodb -> Grasscutter -> Proxy daemon (mitmdump, fiddler, etc.) -> Client
* Startup sequence: Mongodb > Grasscutter > Proxy daemon (mitmdump, fiddler, etc.) > Game
...@@ -116,7 +116,7 @@ chmod +x gradlew ...@@ -116,7 +116,7 @@ chmod +x gradlew
| drop | drop <物品ID\|物品名称> [数量] | server.drop | 仅客户端 | 在指定玩家周围掉落指定物品 | `d` `dropitem` | | drop | drop <物品ID\|物品名称> [数量] | server.drop | 仅客户端 | 在指定玩家周围掉落指定物品 | `d` `dropitem` |
| give | give [uid] <物品ID\|物品名称> [数量] [等级] [精炼等级] | | | 给予指定玩家一定数量及等级的物品 (精炼等级仅适用于武器) | `g` `item` `giveitem` | | give | give [uid] <物品ID\|物品名称> [数量] [等级] [精炼等级] | | | 给予指定玩家一定数量及等级的物品 (精炼等级仅适用于武器) | `g` `item` `giveitem` |
| givechar | givechar \<uid> <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec | | givechar | givechar \<uid> <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec |
| giveart | giveart [uid] \<圣遗物ID> \<主属性ID> [\<副属性ID>[,<次数>]]... [等级] | player.giveart | 均可使用 | 给予玩家指定属性的圣遗物 | givea | | giveart | giveart [uid] \<圣遗物ID> \<主属性ID> [\<副属性ID>[,<次数>]]... [等级] | player.giveart | 均可使用 | 给予玩家指定属性的圣遗物 | gart |
| giveall | giveall [uid] [数量] | player.giveall | 均可使用 | 给予指定玩家全部物品 | givea | | giveall | giveall [uid] [数量] | player.giveall | 均可使用 | 给予指定玩家全部物品 | givea |
| godmode | godmode [uid] | player.godmode | 仅客户端 | 保护你不受到任何伤害(依然会被击退) | | | godmode | godmode [uid] | player.godmode | 仅客户端 | 保护你不受到任何伤害(依然会被击退) | |
| heal | heal | player.heal | 仅客户端 | 治疗队伍中所有角色 | h | | heal | heal | player.heal | 仅客户端 | 治疗队伍中所有角色 | h |
...@@ -136,7 +136,7 @@ chmod +x gradlew ...@@ -136,7 +136,7 @@ chmod +x gradlew
| spawn | spanw <实体ID\|实体名称> [等级] [数量] | server.spawn | 仅客户端 | 在你周围生成实体 | | | spawn | spanw <实体ID\|实体名称> [等级] [数量] | server.spawn | 仅客户端 | 在你周围生成实体 | |
| stop | stop | server.stop | 均可使用 | 停止服务器 | | | stop | stop | server.stop | 均可使用 | 停止服务器 | |
| talent | talent <天赋ID> <等级> | player.settalent | 仅客户端 | 设置当前角色的天赋等级 | | | talent | talent <天赋ID> <等级> | player.settalent | 仅客户端 | 设置当前角色的天赋等级 | |
| teleport | teleport \<x> \<y> \<z> | player.teleport | 仅客户端 | 传送玩家到指定坐标 | tp | | teleport | teleport [@playerUid] \<x> \<y> \<z> [sceneId] | player.teleport | 均可使用 | 传送玩家到指定坐标 | tp |
| tpall | | player.tpall | 仅客户端 | 传送多人世界中所有的玩家到自身地点 | | | tpall | | player.tpall | 仅客户端 | 传送多人世界中所有的玩家到自身地点 | |
| weather | weather <天气ID> <气候ID> | player.weather | 仅客户端 | 改变天气 | w | | weather | weather <天气ID> <气候ID> | player.weather | 仅客户端 | 改变天气 | w |
......
package emu.grasscutter; package emu.grasscutter;
import emu.grasscutter.game.mail.Mail;
public final class Config { public final class Config {
public String DatabaseUrl = "mongodb://localhost:27017"; public String DatabaseUrl = "mongodb://localhost:27017";
...@@ -71,10 +73,15 @@ public final class Config { ...@@ -71,10 +73,15 @@ public final class Config {
public int MaxAvatarsInTeamMultiplayer = 4; public int MaxAvatarsInTeamMultiplayer = 4;
public int MaxEntityLimit = 1000; // Max entity limit per world. // TODO: Enforce later. public int MaxEntityLimit = 1000; // Max entity limit per world. // TODO: Enforce later.
public boolean WatchGacha = false; public boolean WatchGacha = false;
public String ServerNickname = "Server";
public int ServerAvatarId = 10000007;
public int[] WelcomeEmotes = {2007, 1002, 4010}; public int[] WelcomeEmotes = {2007, 1002, 4010};
public String WelcomeMotd = "Welcome to Grasscutter emu"; public String WelcomeMotd = "Welcome to Grasscutter emu";
public String WelcomeMailContent = "Hi there!\r\nFirst of all, welcome to Grasscutter. If you have any issues, please let us know so that Lawnmower can help you! \r\n\r\nCheck out our:\r\n<type=\"browser\" text=\"Discord\" href=\"https://discord.gg/T5vZU6UyeG\"/> <type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>"; public String WelcomeMailContent = "Hi there!\r\nFirst of all, welcome to Grasscutter. If you have any issues, please let us know so that Lawnmower can help you! \r\n\r\nCheck out our:\r\n<type=\"browser\" text=\"Discord\" href=\"https://discord.gg/T5vZU6UyeG\"/> <type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>";
public int[] WelcomeMailItems = {13509}; public Mail.MailItem[] WelcomeMailItems = {
new Mail.MailItem(13509, 1, 1),
new Mail.MailItem(201, 10000, 1),
};
public boolean EnableOfficialShop = true; public boolean EnableOfficialShop = true;
......
...@@ -11,6 +11,8 @@ public final class GameConstants { ...@@ -11,6 +11,8 @@ public final class GameConstants {
public static final int MAX_TEAMS = 4; public static final int MAX_TEAMS = 4;
public static final int MAIN_CHARACTER_MALE = 10000005; public static final int MAIN_CHARACTER_MALE = 10000005;
public static final int MAIN_CHARACTER_FEMALE = 10000007; public static final int MAIN_CHARACTER_FEMALE = 10000007;
public static final String SERVER_AVATAR_NAME = Grasscutter.getConfig().getGameServerOptions().ServerNickname;
public static final int SERVER_AVATAR_ID = Grasscutter.getConfig().getGameServerOptions().ServerAvatarId;
public static final Position START_POSITION = new Position(2747, 194, -1719); public static final Position START_POSITION = new Position(2747, 194, -1719);
public static final int MAX_FRIENDS = 45; public static final int MAX_FRIENDS = 45;
......
...@@ -6,6 +6,7 @@ import java.io.FileReader; ...@@ -6,6 +6,7 @@ import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Calendar;
import emu.grasscutter.command.CommandMap; import emu.grasscutter.command.CommandMap;
import emu.grasscutter.plugin.PluginManager; import emu.grasscutter.plugin.PluginManager;
...@@ -32,6 +33,8 @@ public final class Grasscutter { ...@@ -32,6 +33,8 @@ public final class Grasscutter {
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static final File configFile = new File("./config.json"); private static final File configFile = new File("./config.json");
private static int day; // Current day of week
public static RunMode MODE = RunMode.BOTH; public static RunMode MODE = RunMode.BOTH;
private static DispatchServer dispatchServer; private static DispatchServer dispatchServer;
private static GameServer gameServer; private static GameServer gameServer;
...@@ -67,8 +70,10 @@ public final class Grasscutter { ...@@ -67,8 +70,10 @@ public final class Grasscutter {
Grasscutter.getLogger().info("Starting Grasscutter..."); Grasscutter.getLogger().info("Starting Grasscutter...");
// Load all resources. // Load all resources.
Grasscutter.updateDayOfWeek();
ResourceLoader.loadAll(); ResourceLoader.loadAll();
ScriptLoader.init(); ScriptLoader.init();
// Database // Database
DatabaseManager.initialize(); DatabaseManager.initialize();
...@@ -179,4 +184,13 @@ public final class Grasscutter { ...@@ -179,4 +184,13 @@ public final class Grasscutter {
public static PluginManager getPluginManager() { public static PluginManager getPluginManager() {
return pluginManager; return pluginManager;
} }
public static void updateDayOfWeek() {
Calendar calendar = Calendar.getInstance();
day = calendar.get(Calendar.DAY_OF_WEEK);
}
public static int getCurrentDayOfWeek() {
return day;
}
} }
...@@ -98,16 +98,16 @@ public final class GiveAllCommand implements CommandHandler { ...@@ -98,16 +98,16 @@ public final class GiveAllCommand implements CommandHandler {
if (isTestItem(itemdata.getId())) continue; if (isTestItem(itemdata.getId())) continue;
if (itemdata.isEquip()) { if (itemdata.isEquip()) {
if (itemdata.getItemType() == ItemType.ITEM_WEAPON) {
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
GameItem item = new GameItem(itemdata); GameItem item = new GameItem(itemdata);
if (itemdata.getItemType() == ItemType.ITEM_WEAPON) {
item.setLevel(90); item.setLevel(90);
item.setPromoteLevel(6); item.setPromoteLevel(6);
item.setRefinement(4); item.setRefinement(4);
}
itemList.add(item); itemList.add(item);
} }
} }
}
else { else {
GameItem item = new GameItem(itemdata); GameItem item = new GameItem(itemdata);
item.setCount(amount); item.setCount(amount);
......
...@@ -14,13 +14,13 @@ import java.util.ArrayList; ...@@ -14,13 +14,13 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@Command(label = "giveart", usage = "giveart [player] <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [level]", description = "Gives the player a specified reliquary", aliases = {"givea"}, permission = "player.giveart") @Command(label = "giveart", usage = "giveart [player] <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [level]", description = "Gives the player a specified artifact", aliases = {"gart"}, permission = "player.giveart")
public final class GiveArtifactCommand implements CommandHandler { public final class GiveArtifactCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, List<String> args) { public void execute(Player sender, List<String> args) {
int size = args.size(), target, itemId, mainPropId, level; int size = args.size(), target, itemId, mainPropId, level = 1;
ArrayList<Integer> appendPropIdList = new ArrayList<>(); ArrayList<Integer> appendPropIdList = new ArrayList<>();
String msg = "Usage: giveart|givea [player] <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [level]"; String msg = "Usage: giveart|gart [player] <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [level]";
if (sender == null && size < 2) { if (sender == null && size < 2) {
CommandHandler.sendMessage(null, msg); CommandHandler.sendMessage(null, msg);
...@@ -29,9 +29,14 @@ public final class GiveArtifactCommand implements CommandHandler { ...@@ -29,9 +29,14 @@ public final class GiveArtifactCommand implements CommandHandler {
if (size >= 2) { if (size >= 2) {
try { try {
level = Integer.parseInt(args.get(size - 1)); try {
if (level <= 21) size--; int last = Integer.parseInt(args.get(size - 1));
else level = 1; if (last >= 1 && last <= 21) {
level = last;
size--;
}
} catch (NumberFormatException ignored) {
}
target = Integer.parseInt(args.get(0)); target = Integer.parseInt(args.get(0));
int fromIdx; int fromIdx;
if (Grasscutter.getGameServer().getPlayerByUid(target) == null && sender != null) { if (Grasscutter.getGameServer().getPlayerByUid(target) == null && sender != null) {
...@@ -79,6 +84,7 @@ public final class GiveArtifactCommand implements CommandHandler { ...@@ -79,6 +84,7 @@ public final class GiveArtifactCommand implements CommandHandler {
GameItem item = new GameItem(itemData); GameItem item = new GameItem(itemData);
item.setLevel(level); item.setLevel(level);
item.setMainPropId(mainPropId); item.setMainPropId(mainPropId);
item.getAppendPropIdList().clear();
item.getAppendPropIdList().addAll(appendPropIdList); item.getAppendPropIdList().addAll(appendPropIdList);
targetPlayer.getInventory().addItem(item, ActionReason.SubfieldDrop); targetPlayer.getInventory().addItem(item, ActionReason.SubfieldDrop);
......
...@@ -163,20 +163,28 @@ public final class GiveCommand implements CommandHandler { ...@@ -163,20 +163,28 @@ public final class GiveCommand implements CommandHandler {
List<GameItem> items = new LinkedList<>(); List<GameItem> items = new LinkedList<>();
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
GameItem item = new GameItem(itemData); GameItem item = new GameItem(itemData);
if (item.isEquipped()) {
// check item max level
if (item.getItemType() == ItemType.ITEM_WEAPON) {
if (lvl > 90) lvl = 90;
} else {
if (lvl > 21) lvl = 21;
}
}
item.setCount(amount); item.setCount(amount);
item.setLevel(lvl); item.setLevel(lvl);
if (lvl > 20 && lvl < 40) { if (lvl > 80) {
item.setPromoteLevel(1);
} else if (lvl > 40 && lvl <= 50) {
item.setPromoteLevel(2);
} else if (lvl > 50 && lvl <= 60) {
item.setPromoteLevel(3);
} else if (lvl > 60 && lvl <= 70) {
item.setPromoteLevel(4);
} else if (lvl > 70 && lvl <= 80) {
item.setPromoteLevel(5);
} else if (lvl > 80 && lvl <= 90) {
item.setPromoteLevel(6); item.setPromoteLevel(6);
} else if (lvl > 70) {
item.setPromoteLevel(5);
} else if (lvl > 60) {
item.setPromoteLevel(4);
} else if (lvl > 50) {
item.setPromoteLevel(3);
} else if (lvl > 40) {
item.setPromoteLevel(2);
} else if (lvl > 20) {
item.setPromoteLevel(1);
} }
if (item.getItemType() == ItemType.ITEM_WEAPON) { if (item.getItemType() == ItemType.ITEM_WEAPON) {
if (refinement > 0) { if (refinement > 0) {
......
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
...@@ -7,21 +8,39 @@ import emu.grasscutter.utils.Position; ...@@ -7,21 +8,39 @@ import emu.grasscutter.utils.Position;
import java.util.List; import java.util.List;
@Command(label = "teleport", usage = "teleport <x> <y> <z>", aliases = {"tp"}, @Command(label = "teleport", usage = "teleport [@player id] <x> <y> <z> [scene id]", aliases = {"tp"},
description = "Change the player's position.", permission = "player.teleport") description = "Change the player's position.", permission = "player.teleport")
public final class TeleportCommand implements CommandHandler { public final class TeleportCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, List<String> args) { public void execute(Player sender, List<String> args) {
int target;
if (args.size() < (sender == null ? 4 : 3)) {
CommandHandler.sendMessage(sender, sender == null ? "Usage: /tp @<player id> <x> <y> <z> [scene id]" :
"Usage: /tp [@<player id>] <x> <y> <z> [scene id]");
return;
}
if (args.get(0).startsWith("@")) {
try {
target = Integer.parseInt(args.get(0).substring(1));
} catch (NumberFormatException e) {
CommandHandler.sendMessage(sender, "Invalid player id.");
return;
}
} else {
if (sender == null) { if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game."); CommandHandler.sendMessage(null, "You must specify a player id.");
return; return;
} }
target = sender.getUid();
}
if (args.size() < 3){ Player targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
CommandHandler.sendMessage(sender, "Usage: /tp <x> <y> <z> [scene id]"); if (targetPlayer == null) {
CommandHandler.sendMessage(sender, "Player not found or offline.");
return; return;
} }
args = args.subList(args.get(0).startsWith("@") ? 1 : 0, args.size());
try { try {
float x = 0f; float x = 0f;
...@@ -29,39 +48,41 @@ public final class TeleportCommand implements CommandHandler { ...@@ -29,39 +48,41 @@ public final class TeleportCommand implements CommandHandler {
float z = 0f; float z = 0f;
if (args.get(0).contains("~")) { if (args.get(0).contains("~")) {
if (args.get(0).equals("~")) { if (args.get(0).equals("~")) {
x = sender.getPos().getX(); x = targetPlayer.getPos().getX();
} else { } else {
x = Float.parseFloat(args.get(0).replace("~", "")) + sender.getPos().getX(); x = Float.parseFloat(args.get(0).replace("~", "")) + targetPlayer.getPos().getX();
} }
} else { } else {
x = Float.parseFloat(args.get(0)); x = Float.parseFloat(args.get(0));
} }
if (args.get(1).contains("~")) { if (args.get(1).contains("~")) {
if (args.get(1).equals("~")) { if (args.get(1).equals("~")) {
y = sender.getPos().getY(); y = targetPlayer.getPos().getY();
} else { } else {
y = Float.parseFloat(args.get(1).replace("~", "")) + sender.getPos().getY(); y = Float.parseFloat(args.get(1).replace("~", "")) + targetPlayer.getPos().getY();
} }
} else { } else {
y = Float.parseFloat(args.get(1)); y = Float.parseFloat(args.get(1));
} }
if (args.get(2).contains("~")) { if (args.get(2).contains("~")) {
if (args.get(2).equals("~")) { if (args.get(2).equals("~")) {
z = sender.getPos().getZ(); z = targetPlayer.getPos().getZ();
} else { } else {
z = Float.parseFloat(args.get(2).replace("~", "")) + sender.getPos().getZ(); z = Float.parseFloat(args.get(2).replace("~", "")) + targetPlayer.getPos().getZ();
} }
} else { } else {
z = Float.parseFloat(args.get(2)); z = Float.parseFloat(args.get(2));
} }
int sceneId = sender.getSceneId(); int sceneId = targetPlayer.getSceneId();
if (args.size() == 4){ if (args.size() == 4){
sceneId = Integer.parseInt(args.get(3)); sceneId = Integer.parseInt(args.get(3));
} }
Position target = new Position(x, y, z); Position target_pos = new Position(x, y, z);
boolean result = sender.getWorld().transferPlayerToScene(sender, sceneId, target); boolean result = targetPlayer.getWorld().transferPlayerToScene(targetPlayer, sceneId, target_pos);
if (!result) { if (!result) {
CommandHandler.sendMessage(sender, "Invalid position."); CommandHandler.sendMessage(sender, "Invalid position.");
} else {
CommandHandler.sendMessage(sender, "Teleported " + targetPlayer.getNickname() + " to " + x + "," + y + "," + z + " in scene " + sceneId);
} }
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, "Invalid position."); CommandHandler.sendMessage(sender, "Invalid position.");
......
...@@ -15,6 +15,8 @@ import emu.grasscutter.data.def.*; ...@@ -15,6 +15,8 @@ import emu.grasscutter.data.def.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
public class GameData { public class GameData {
// BinOutputs // BinOutputs
...@@ -61,12 +63,14 @@ public class GameData { ...@@ -61,12 +63,14 @@ public class GameData {
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
// Cache // Cache
private static Map<Integer, List<Integer>> fetters = new HashMap<>(); private static Map<Integer, List<Integer>> fetters = new HashMap<>();
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>(); private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
private static final IntList scenePointIdList = new IntArrayList();
public static char EJWOA = 's'; public static char EJWOA = 's';
...@@ -280,6 +284,10 @@ public class GameData { ...@@ -280,6 +284,10 @@ public class GameData {
return dungeonDataMap; return dungeonDataMap;
} }
public static Int2ObjectMap<DailyDungeonData> getDailyDungeonDataMap() {
return dailyDungeonDataMap;
}
public static Map<Integer, List<ShopGoodsData>> getShopGoodsDataEntries() { public static Map<Integer, List<ShopGoodsData>> getShopGoodsDataEntries() {
if (shopGoods.isEmpty()) { if (shopGoods.isEmpty()) {
shopGoodsDataMap.forEach((k, v) -> { shopGoodsDataMap.forEach((k, v) -> {
...@@ -291,4 +299,8 @@ public class GameData { ...@@ -291,4 +299,8 @@ public class GameData {
return shopGoods; return shopGoods;
} }
public static IntList getScenePointIdList() {
return scenePointIdList;
}
} }
...@@ -48,11 +48,12 @@ public class ResourceLoader { ...@@ -48,11 +48,12 @@ public class ResourceLoader {
loadOpenConfig(); loadOpenConfig();
// Load resources // Load resources
loadResources(); loadResources();
loadScenePoints();
// Process into depots // Process into depots
GameDepot.load(); GameDepot.load();
// Load spawn data // Load spawn data
loadSpawnData(); loadSpawnData();
// Load scene points - must be done AFTER resources are loaded
loadScenePoints();
// Custom - TODO move this somewhere else // Custom - TODO move this somewhere else
try { try {
GameData.getAvatarSkillDepotDataMap().get(504).setAbilities( GameData.getAvatarSkillDepotDataMap().get(504).setAbilities(
...@@ -168,6 +169,9 @@ public class ResourceLoader { ...@@ -168,6 +169,9 @@ public class ResourceLoader {
ScenePointEntry sl = new ScenePointEntry(sceneId + "_" + entry.getKey(), pointData); ScenePointEntry sl = new ScenePointEntry(sceneId + "_" + entry.getKey(), pointData);
scenePointList.add(sl); scenePointList.add(sl);
GameData.getScenePointIdList().add(pointData.getId());
pointData.updateDailyDungeon();
} }
for (ScenePointEntry entry : scenePointList) { for (ScenePointEntry entry : scenePointList) {
......
package emu.grasscutter.data.common; package emu.grasscutter.data.common;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.DailyDungeonData;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
public class PointData { public class PointData {
private int id; private int id;
private String $type; private String $type;
private Position tranPos; private Position tranPos;
private int[] dungeonIds; private int[] dungeonIds;
private int[] dungeonRandomList;
public int getId() { public int getId() {
return id; return id;
...@@ -27,4 +33,31 @@ public class PointData { ...@@ -27,4 +33,31 @@ public class PointData {
public int[] getDungeonIds() { public int[] getDungeonIds() {
return dungeonIds; return dungeonIds;
} }
public int[] getDungeonRandomList() {
return dungeonRandomList;
}
public void updateDailyDungeon() {
if (getDungeonRandomList() == null) {
return;
}
IntList newDungeons = new IntArrayList();
int day = Grasscutter.getCurrentDayOfWeek();
for (int randomId : getDungeonRandomList()) {
DailyDungeonData data = GameData.getDailyDungeonDataMap().get(randomId);
if (data != null) {
int[] addDungeons = data.getDungeonsByDay(day);
for (int d : addDungeons) {
newDungeons.add(d);
}
}
}
this.dungeonIds = newDungeons.toIntArray();
}
} }
package emu.grasscutter.data.def;
import java.util.Calendar;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.SceneType;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
@ResourceType(name = "DailyDungeonConfigData.json")
public class DailyDungeonData extends GameResource {
private int Id;
private int[] Monday;
private int[] Tuesday;
private int[] Wednesday;
private int[] Thursday;
private int[] Friday;
private int[] Saturday;
private int[] Sunday;
private static final int[] empty = new int[0];
private final Int2ObjectMap<int[]> map;
public DailyDungeonData() {
this.map = new Int2ObjectOpenHashMap<>();
}
@Override
public int getId() {
return this.Id;
}
public int[] getDungeonsByDay(int day) {
return map.getOrDefault(day, empty);
}
@Override
public void onLoad() {
map.put(Calendar.MONDAY, Monday);
map.put(Calendar.TUESDAY, Tuesday);
map.put(Calendar.WEDNESDAY, Wednesday);
map.put(Calendar.THURSDAY, Thursday);
map.put(Calendar.FRIDAY, Friday);
map.put(Calendar.SATURDAY, Saturday);
map.put(Calendar.SUNDAY, Sunday);
}
}
...@@ -104,7 +104,10 @@ public class Account { ...@@ -104,7 +104,10 @@ public class Account {
} }
public boolean hasPermission(String permission) { public boolean hasPermission(String permission) {
return this.permissions.contains(permission) || this.permissions.contains("*"); return this.permissions.contains(permission) ||
this.permissions.contains("*") ||
(this.permissions.contains("player") || this.permissions.contains("player.*")) && permission.startsWith("player.") ||
(this.permissions.contains("server") || this.permissions.contains("server.*")) && permission.startsWith("server.");
} }
public boolean removePermission(String permission) { public boolean removePermission(String permission) {
......
...@@ -15,7 +15,6 @@ import dev.morphia.annotations.Indexed; ...@@ -15,7 +15,6 @@ import dev.morphia.annotations.Indexed;
import dev.morphia.annotations.PostLoad; import dev.morphia.annotations.PostLoad;
import dev.morphia.annotations.PrePersist; import dev.morphia.annotations.PrePersist;
import dev.morphia.annotations.Transient; import dev.morphia.annotations.Transient;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.FightPropData; import emu.grasscutter.data.common.FightPropData;
import emu.grasscutter.data.custom.OpenConfigEntry; import emu.grasscutter.data.custom.OpenConfigEntry;
...@@ -26,18 +25,19 @@ import emu.grasscutter.data.def.AvatarSkillDepotData; ...@@ -26,18 +25,19 @@ import emu.grasscutter.data.def.AvatarSkillDepotData;
import emu.grasscutter.data.def.AvatarSkillDepotData.InherentProudSkillOpens; import emu.grasscutter.data.def.AvatarSkillDepotData.InherentProudSkillOpens;
import emu.grasscutter.data.def.AvatarTalentData; import emu.grasscutter.data.def.AvatarTalentData;
import emu.grasscutter.data.def.EquipAffixData; import emu.grasscutter.data.def.EquipAffixData;
import emu.grasscutter.data.def.ItemData.WeaponProperty;
import emu.grasscutter.data.def.ProudSkillData;
import emu.grasscutter.data.def.ReliquaryAffixData; import emu.grasscutter.data.def.ReliquaryAffixData;
import emu.grasscutter.data.def.ReliquaryLevelData; import emu.grasscutter.data.def.ReliquaryLevelData;
import emu.grasscutter.data.def.ReliquaryMainPropData; import emu.grasscutter.data.def.ReliquaryMainPropData;
import emu.grasscutter.data.def.ReliquarySetData; import emu.grasscutter.data.def.ReliquarySetData;
import emu.grasscutter.data.def.WeaponCurveData; import emu.grasscutter.data.def.WeaponCurveData;
import emu.grasscutter.data.def.WeaponPromoteData; import emu.grasscutter.data.def.WeaponPromoteData;
import emu.grasscutter.data.def.ItemData.WeaponProperty;
import emu.grasscutter.data.def.ProudSkillData;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.entity.EntityAvatar; import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.inventory.EquipType; import emu.grasscutter.game.inventory.EquipType;
import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ElementType; import emu.grasscutter.game.props.ElementType;
import emu.grasscutter.game.props.EntityIdType; import emu.grasscutter.game.props.EntityIdType;
...@@ -45,8 +45,11 @@ import emu.grasscutter.game.props.FetterState; ...@@ -45,8 +45,11 @@ import emu.grasscutter.game.props.FetterState;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo; import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo;
import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData;
import emu.grasscutter.net.proto.AvatarInfoOuterClass.AvatarInfo; import emu.grasscutter.net.proto.AvatarInfoOuterClass.AvatarInfo;
import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData;
import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass;
import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass.ShowAvatarInfo;
import emu.grasscutter.net.proto.ShowEquipOuterClass.ShowEquip;
import emu.grasscutter.server.packet.send.PacketAbilityChangeNotify; import emu.grasscutter.server.packet.send.PacketAbilityChangeNotify;
import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify; import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify;
import emu.grasscutter.server.packet.send.PacketAvatarFightPropNotify; import emu.grasscutter.server.packet.send.PacketAvatarFightPropNotify;
...@@ -798,6 +801,46 @@ public class Avatar { ...@@ -798,6 +801,46 @@ public class Avatar {
return avatarInfo.build(); return avatarInfo.build();
} }
// used only in character showcase
public ShowAvatarInfo toShowAvatarInfoProto() {
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder()
.setExpLevel(this.getFetterLevel());
ShowAvatarInfo.Builder showAvatarInfo = ShowAvatarInfoOuterClass.ShowAvatarInfo.newBuilder()
.setAvatarId(avatarId)
.addAllTalentIdList(this.getTalentIdList())
.putAllFightPropMap(this.getFightProperties())
.setSkillDepotId(this.getSkillDepotId())
.setCoreProudSkillLevel(this.getCoreProudSkillLevel())
.addAllInherentProudSkillList(this.getProudSkillList())
.putAllSkillLevelMap(this.getSkillLevelMap())
.putAllProudSkillExtraLevelMap(this.getProudSkillBonusMap())
.setFetterInfo(avatarFetter)
.setCostumeId(this.getCostume());
showAvatarInfo.putPropMap(PlayerProperty.PROP_LEVEL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, this.getLevel()));
showAvatarInfo.putPropMap(PlayerProperty.PROP_EXP.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_EXP, this.getExp()));
showAvatarInfo.putPropMap(PlayerProperty.PROP_BREAK_LEVEL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_BREAK_LEVEL, this.getPromoteLevel()));
showAvatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_VAL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_VAL, this.getSatiation()));
showAvatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_PENALTY_TIME.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_VAL, this.getSatiationPenalty()));
int maxStamina = this.getPlayer().getProperty(PlayerProperty.PROP_MAX_STAMINA);
showAvatarInfo.putPropMap(PlayerProperty.PROP_MAX_STAMINA.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_MAX_STAMINA, maxStamina));
for (GameItem item : this.getEquips().values()) {
if (item.getItemType() == ItemType.ITEM_RELIQUARY) {
showAvatarInfo.addEquipList(ShowEquip.newBuilder()
.setItemId(item.getItemId())
.setReliquary(item.toReliquaryProto()));
} else if (item.getItemType() == ItemType.ITEM_WEAPON) {
showAvatarInfo.addEquipList(ShowEquip.newBuilder()
.setItemId(item.getItemId())
.setWeapon(item.toWeaponProto()));
}
}
return showAvatarInfo.build();
}
@PostLoad @PostLoad
private void onLoad() { private void onLoad() {
......
...@@ -28,7 +28,7 @@ public class DungeonManager { ...@@ -28,7 +28,7 @@ public class DungeonManager {
public void getEntryInfo(Player player, int pointId) { public void getEntryInfo(Player player, int pointId) {
ScenePointEntry entry = GameData.getScenePointEntryById(player.getScene().getId(), pointId); ScenePointEntry entry = GameData.getScenePointEntryById(player.getScene().getId(), pointId);
if (entry == null || entry.getPointData().getDungeonIds() == null) { if (entry == null) {
// Error // Error
player.sendPacket(new PacketDungeonEntryInfoRsp()); player.sendPacket(new PacketDungeonEntryInfoRsp());
return; return;
...@@ -79,4 +79,10 @@ public class DungeonManager { ...@@ -79,4 +79,10 @@ public class DungeonManager {
player.getWorld().transferPlayerToScene(player, prevScene, prevPos); player.getWorld().transferPlayerToScene(player, prevScene, prevPos);
player.sendPacket(new BasePacket(PacketOpcodes.PlayerQuitDungeonRsp)); player.sendPacket(new BasePacket(PacketOpcodes.PlayerQuitDungeonRsp));
} }
public void updateDailyDungeons() {
for (ScenePointEntry entry : GameData.getScenePointEntries().values()) {
entry.getPointData().updateDailyDungeon();
}
}
} }
...@@ -34,6 +34,10 @@ public abstract class GameEntity { ...@@ -34,6 +34,10 @@ public abstract class GameEntity {
return this.id; return this.id;
} }
public int getEntityType() {
return getId() >> 24;
}
public World getWorld() { public World getWorld() {
return this.getScene().getWorld(); return this.getScene().getWorld();
} }
......
...@@ -375,13 +375,7 @@ public class GameItem { ...@@ -375,13 +375,7 @@ public class GameItem {
return relicInfo; return relicInfo;
} }
public Item toProto() { public Weapon toWeaponProto() {
Item.Builder proto = Item.newBuilder()
.setGuid(this.getGuid())
.setItemId(this.getItemId());
switch (getItemType()) {
case ITEM_WEAPON:
Weapon.Builder weapon = Weapon.newBuilder() Weapon.Builder weapon = Weapon.newBuilder()
.setLevel(this.getLevel()) .setLevel(this.getLevel())
.setExp(this.getExp()) .setExp(this.getExp())
...@@ -393,16 +387,32 @@ public class GameItem { ...@@ -393,16 +387,32 @@ public class GameItem {
} }
} }
proto.setEquip(Equip.newBuilder().setWeapon(weapon).setIsLocked(this.isLocked()).build()); return weapon.build();
break; }
case ITEM_RELIQUARY:
Reliquary relic = Reliquary.newBuilder() public Reliquary toReliquaryProto() {
Reliquary.Builder relic = Reliquary.newBuilder()
.setLevel(this.getLevel()) .setLevel(this.getLevel())
.setExp(this.getExp()) .setExp(this.getExp())
.setPromoteLevel(this.getPromoteLevel()) .setPromoteLevel(this.getPromoteLevel())
.setMainPropId(this.getMainPropId()) .setMainPropId(this.getMainPropId())
.addAllAppendPropIdList(this.getAppendPropIdList()) .addAllAppendPropIdList(this.getAppendPropIdList());
.build();
return relic.build();
}
public Item toProto() {
Item.Builder proto = Item.newBuilder()
.setGuid(this.getGuid())
.setItemId(this.getItemId());
switch (getItemType()) {
case ITEM_WEAPON:
Weapon weapon = this.toWeaponProto();
proto.setEquip(Equip.newBuilder().setWeapon(weapon).setIsLocked(this.isLocked()).build());
break;
case ITEM_RELIQUARY:
Reliquary relic = this.toReliquaryProto();
proto.setEquip(Equip.newBuilder().setReliquary(relic).setIsLocked(this.isLocked()).build()); proto.setEquip(Equip.newBuilder().setReliquary(relic).setIsLocked(this.isLocked()).build());
break; break;
case ITEM_MATERIAL: case ITEM_MATERIAL:
......
...@@ -33,6 +33,7 @@ import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo; ...@@ -33,6 +33,7 @@ import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo;
import emu.grasscutter.net.proto.PlayerApplyEnterMpResultNotifyOuterClass; import emu.grasscutter.net.proto.PlayerApplyEnterMpResultNotifyOuterClass;
import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo; import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo;
import emu.grasscutter.net.proto.PlayerWorldLocationInfoOuterClass; import emu.grasscutter.net.proto.PlayerWorldLocationInfoOuterClass;
import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass;
import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture; import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail; import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
import emu.grasscutter.net.proto.SocialShowAvatarInfoOuterClass; import emu.grasscutter.net.proto.SocialShowAvatarInfoOuterClass;
...@@ -828,7 +829,7 @@ public class Player { ...@@ -828,7 +829,7 @@ public class Player {
.setProfilePicture(ProfilePicture.newBuilder().setAvatarId(this.getHeadImage())); .setProfilePicture(ProfilePicture.newBuilder().setAvatarId(this.getHeadImage()));
if (this.getWorld() != null) { if (this.getWorld() != null) {
onlineInfo.setCurPlayerNumInWorld(this.getWorld().getPlayers().indexOf(this) + 1); onlineInfo.setCurPlayerNumInWorld(getWorld().getPlayerCount());
} else { } else {
onlineInfo.setCurPlayerNumInWorld(1); onlineInfo.setCurPlayerNumInWorld(1);
} }
...@@ -905,6 +906,35 @@ public class Player { ...@@ -905,6 +906,35 @@ public class Player {
return social; return social;
} }
public List<ShowAvatarInfoOuterClass.ShowAvatarInfo> getShowAvatarInfoList() {
List<ShowAvatarInfoOuterClass.ShowAvatarInfo> showAvatarInfoList = new ArrayList<>();
Player player;
boolean shouldRecalc;
if (this.isOnline()) {
player = this;
shouldRecalc = false;
} else {
player = DatabaseHelper.getPlayerById(id);
player.getAvatars().loadFromDatabase();
player.getInventory().loadFromDatabase();
shouldRecalc = true;
}
List<Integer> showAvatarList = player.getShowAvatarList();
AvatarStorage avatars = player.getAvatars();
if (showAvatarList != null) {
for (int avatarId : showAvatarList) {
Avatar avatar = avatars.getAvatarById(avatarId);
if (shouldRecalc) {
avatar.recalcStats();
}
showAvatarInfoList.add(avatar.toShowAvatarInfoProto());
}
}
return showAvatarInfoList;
}
public PlayerWorldLocationInfoOuterClass.PlayerWorldLocationInfo getWorldPlayerLocationInfo() { public PlayerWorldLocationInfoOuterClass.PlayerWorldLocationInfo getWorldPlayerLocationInfo() {
return PlayerWorldLocationInfoOuterClass.PlayerWorldLocationInfo.newBuilder() return PlayerWorldLocationInfoOuterClass.PlayerWorldLocationInfo.newBuilder()
.setSceneId(this.getSceneId()) .setSceneId(this.getSceneId())
......
...@@ -375,8 +375,8 @@ public class Scene { ...@@ -375,8 +375,8 @@ public class Scene {
this.broadcastPacket(new PacketLifeStateChangeNotify(attackerId, target, LifeState.LIFE_DEAD)); this.broadcastPacket(new PacketLifeStateChangeNotify(attackerId, target, LifeState.LIFE_DEAD));
// Reward drop // Reward drop
if (target instanceof EntityMonster) { if (target instanceof EntityMonster && this.getSceneType() != SceneType.SCENE_DUNGEON) {
Grasscutter.getGameServer().getDropManager().callDrop((EntityMonster) target); getWorld().getServer().getDropManager().callDrop((EntityMonster) target);
} }
this.removeEntity(target); this.removeEntity(target);
...@@ -508,6 +508,7 @@ public class Scene { ...@@ -508,6 +508,7 @@ public class Scene {
} }
group.triggers.forEach(getScriptManager()::registerTrigger); group.triggers.forEach(getScriptManager()::registerTrigger);
group.regions.forEach(getScriptManager()::registerRegion);
} }
// Spawn gadgets AFTER triggers are added // Spawn gadgets AFTER triggers are added
...@@ -526,6 +527,7 @@ public class Scene { ...@@ -526,6 +527,7 @@ public class Scene {
for (SceneGroup group : block.groups) { for (SceneGroup group : block.groups) {
group.triggers.forEach(getScriptManager()::deregisterTrigger); group.triggers.forEach(getScriptManager()::deregisterTrigger);
group.regions.forEach(getScriptManager()::deregisterRegion);
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment