Commit 7fdf7498 authored by omg-xtao's avatar omg-xtao Committed by GitHub
Browse files

Merge branch 'development' into tp

parents eaed1aa0 4c487e22
......@@ -113,9 +113,9 @@ There is a dummy user named "Server" in every player's friends list that you can
| clearartifacts | clearartifacts | player.clearartifacts | Client only | Deletes all unequipped and unlocked level 0 artifacts, including 5-star rarity ones from your inventory. | clearart |
| clearweapons | clearweapons | player.clearweapons | Client only | Deletes all unequipped and unlocked weapons, including 5-star rarity ones from your inventory. | clearwpns |
| drop | drop <itemID\|itemName> [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` |
| give | give [player] <itemId\|itemName> [amount] [level] | player.give | Both side | Gives item(s) to you or the specified player. | `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 |
| 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. | |
| heal | heal | player.heal | Client only | Heals all characters in your current team. | h |
| help | help [command] | | Both side | Sends the help message or shows information about a specified command. | |
......
......@@ -114,7 +114,7 @@ chmod +x gradlew
| clearartifacts | clearartifacts | player.clearartifacts | 仅客户端 | 删除所有未装备及未解锁的圣遗物,包括五星 | clearart |
| clearweapons | clearweapons | player.clearweapons | 仅客户端 | 删除所有未装备及未解锁的武器,包括五星 | clearwp |
| 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 |
| giveall | giveall [uid] [数量] | player.giveall | 均可使用 | 给予指定玩家全部物品 | givea |
| godmode | godmode [uid] | player.godmode | 仅客户端 | 保护你不受到任何伤害(依然会被击退) | |
......
......@@ -71,9 +71,10 @@ dependencies {
implementation group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.2'
implementation group: 'org.quartz-scheduler', name: 'quartz-jobs', version: '2.3.2'
implementation group: 'org.luaj', name: 'luaj-jse', version: '3.0.1'
protobuf files('proto/')
}
application {
......
......@@ -10,6 +10,7 @@ public final class Config {
public String PACKETS_FOLDER = "./packets/";
public String DUMPS_FOLDER = "./dumps/";
public String KEY_FOLDER = "./keys/";
public String SCRIPTS_FOLDER = "./resources/Scripts/";
public String PLUGINS_FOLDER = "./plugins/";
public String RunMode = "HYBRID"; // HYBRID, DISPATCH_ONLY, GAME_ONLY
......
......@@ -9,6 +9,7 @@ import java.net.InetSocketAddress;
import emu.grasscutter.command.CommandMap;
import emu.grasscutter.plugin.PluginManager;
import emu.grasscutter.scripts.ScriptLoader;
import emu.grasscutter.utils.Utils;
import org.reflections.Reflections;
import org.slf4j.LoggerFactory;
......@@ -67,6 +68,7 @@ public final class Grasscutter {
// Load all resources.
ResourceLoader.loadAll();
ScriptLoader.init();
// Database
DatabaseManager.initialize();
......
......@@ -18,79 +18,86 @@ public final class ClearCommand implements CommandHandler {
@Override
public void execute(Player sender, List<String> args) {
int target;
String cmdSwitch = "";
if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game.");
return;
return;
}
String cmdSwitch = args.get(1);
Inventory playerInventory = sender.getInventory();
try {
try {
if (args.size() == 1) {
cmdSwitch = args.get(0);
target = sender.getUid();
}else {
cmdSwitch = args.get(1);
target = Integer.parseInt(args.get(0));
Player targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
if (targetPlayer == null) {
target = sender.getUid();
} else {
switch (cmdSwitch) {
case "wp" -> {
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_WEAPON)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared weapons for " + targetPlayer.getNickname() + " .");
}
case "art" -> {
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_RELIQUARY)
.filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
}
case "mat" -> {
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_MATERIAL)
.filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
}
case "all" -> {
playerInventory.getItems().values().stream()
.filter(item1 -> item1.getItemType() == ItemType.ITEM_RELIQUARY)
.filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0)
.filter(item1 -> !item1.isLocked() && !item1.isEquipped())
.forEach(item1 -> playerInventory.removeItem(item1, item1.getCount()));
playerInventory.getItems().values().stream()
.filter(item2 -> item2.getItemType() == ItemType.ITEM_MATERIAL)
.filter(item2 -> !item2.isLocked() && !item2.isEquipped())
.forEach(item2 -> playerInventory.removeItem(item2, item2.getCount()));
playerInventory.getItems().values().stream()
.filter(item3 -> item3.getItemType() == ItemType.ITEM_WEAPON)
.filter(item3 -> item3.getLevel() == 1 && item3.getExp() == 0)
.filter(item3 -> !item3.isLocked() && !item3.isEquipped())
.forEach(item3 -> playerInventory.removeItem(item3, item3.getCount()));
playerInventory.getItems().values().stream()
.filter(item4 -> item4.getItemType() == ItemType.ITEM_FURNITURE)
.filter(item4 -> !item4.isLocked() && !item4.isEquipped())
.forEach(item4 -> playerInventory.removeItem(item4, item4.getCount()));
playerInventory.getItems().values().stream()
.filter(item5 -> item5.getItemType() == ItemType.ITEM_DISPLAY)
.filter(item5 -> !item5.isLocked() && !item5.isEquipped())
.forEach(item5 -> playerInventory.removeItem(item5, item5.getCount()));
playerInventory.getItems().values().stream()
.filter(item6 -> item6.getItemType() == ItemType.ITEM_VIRTUAL)
.filter(item6 -> !item6.isLocked() && !item6.isEquipped())
.forEach(item6 -> playerInventory.removeItem(item6, item6.getCount()));
sender.dropMessage("Cleared everything for " + targetPlayer.getNickname() + " .");
}
}
}
Player targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
switch (cmdSwitch) {
case "wp" -> {
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_WEAPON)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared weapons for " + targetPlayer.getNickname() + " .");
}
case "art" -> {
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_RELIQUARY)
.filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
}
case "mat" -> {
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_MATERIAL)
.filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
}
case "all" -> {
playerInventory.getItems().values().stream()
.filter(item1 -> item1.getItemType() == ItemType.ITEM_RELIQUARY)
.filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0)
.filter(item1 -> !item1.isLocked() && !item1.isEquipped())
.forEach(item1 -> playerInventory.removeItem(item1, item1.getCount()));
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
playerInventory.getItems().values().stream()
.filter(item2 -> item2.getItemType() == ItemType.ITEM_MATERIAL)
.filter(item2 -> !item2.isLocked() && !item2.isEquipped())
.forEach(item2 -> playerInventory.removeItem(item2, item2.getCount()));
sender.dropMessage("Cleared materials for " + targetPlayer.getNickname() + " .");
playerInventory.getItems().values().stream()
.filter(item3 -> item3.getItemType() == ItemType.ITEM_WEAPON)
.filter(item3 -> item3.getLevel() == 1 && item3.getExp() == 0)
.filter(item3 -> !item3.isLocked() && !item3.isEquipped())
.forEach(item3 -> playerInventory.removeItem(item3, item3.getCount()));
sender.dropMessage("Cleared weapons for " + targetPlayer.getNickname() + " .");
playerInventory.getItems().values().stream()
.filter(item4 -> item4.getItemType() == ItemType.ITEM_FURNITURE)
.filter(item4 -> !item4.isLocked() && !item4.isEquipped())
.forEach(item4 -> playerInventory.removeItem(item4, item4.getCount()));
sender.dropMessage("Cleared furniture for " + targetPlayer.getNickname() + " .");
playerInventory.getItems().values().stream()
.filter(item5 -> item5.getItemType() == ItemType.ITEM_DISPLAY)
.filter(item5 -> !item5.isLocked() && !item5.isEquipped())
.forEach(item5 -> playerInventory.removeItem(item5, item5.getCount()));
sender.dropMessage("Cleared displays for " + targetPlayer.getNickname() + " .");
playerInventory.getItems().values().stream()
.filter(item6 -> item6.getItemType() == ItemType.ITEM_VIRTUAL)
.filter(item6 -> !item6.isLocked() && !item6.isEquipped())
.forEach(item6 -> playerInventory.removeItem(item6, item6.getCount()));
sender.dropMessage("Cleared virtuals for " + targetPlayer.getNickname() + " .");
sender.dropMessage("Cleared everything for " + targetPlayer.getNickname() + " .");
}
} catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid playerId.");
return;
}
} catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid playerId.");
return;
}
Player targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
if (targetPlayer == null) {
......
......@@ -83,9 +83,6 @@ public class GiveAllCommand implements CommandHandler {
Avatar avatar = new Avatar(avatarData);
avatar.setLevel(90);
avatar.setPromoteLevel(6);
for (int i = 1; i <= 6; ++i) {
avatar.getTalentIdList().add((avatar.getAvatarId() - 10000000) * 10 + i);
}
// This will handle stats and talents
avatar.recalcStats();
player.addAvatar(avatar);
......@@ -98,7 +95,7 @@ public class GiveAllCommand implements CommandHandler {
if (isTestItem(itemdata.getId())) continue;
if (itemdata.isEquip()) {
for (int i = 0; i < 10; ++i) {
for (int i = 0; i < 5; ++i) {
GameItem item = new GameItem(itemdata);
if (itemdata.getItemType() == ItemType.ITEM_WEAPON) {
item.setLevel(90);
......@@ -114,7 +111,7 @@ public class GiveAllCommand implements CommandHandler {
itemList.add(item);
}
}
int packetNum = 20;
int packetNum = 10;
int itemLength = itemList.size();
int number = itemLength / packetNum;
int remainder = itemLength % packetNum;
......@@ -171,15 +168,27 @@ public class GiveAllCommand implements CommandHandler {
private static final Range[] testItemRanges = new Range[] {
new Range(106, 139),
new Range(1000, 1099),
new Range(2001, 2008),
new Range(2017, 2029),
// new Range(108001, 108387) //food
new Range(2001, 3022),
new Range(23300, 23340),
new Range(23383, 23385),
new Range(78310, 78554),
new Range(99310, 99554),
new Range(100001, 100187),
new Range(100210, 100214),
new Range(100303, 100398),
new Range(100414, 100425),
new Range(100454, 103008),
new Range(109000, 109492),
new Range(115001, 118004),
new Range(141001, 141072),
new Range(220050, 221016),
};
private static final Integer[] testItemsIds = new Integer[] {
210, 211, 314, 315, 317, 1005, 1007, 1105, 1107, 1201, 1202, 2800,
100001, 100002, 100244, 100305, 100312, 100313, 101212, 11411, 11506, 11507, 11508, 12505,
12506, 12508, 12509, 13503, 13506, 14411, 14503, 14505, 14508, 15411, 15504, 15505,
15506, 15508, 20001, 10002, 10003, 10004, 10005, 10006, 10008 //9
210, 211, 314, 315, 317, 1005, 1007, 1105, 1107, 1201, 1202,10366,
101212, 11411, 11506, 11507, 11508, 12505, 12506, 12508, 12509, 13503,
13506, 14411, 14503, 14505, 14508, 15411, 15504, 15505, 15506, 15508,
20001, 10002, 10003, 10004, 10005, 10006, 10008,100231,100232,100431,
101689,105001,105004, 106000,106001,108000,110000
};
private static final Collection<Integer> testItemsList = Arrays.asList(testItemsIds);
......
......@@ -6,20 +6,20 @@ import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.ItemData;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import java.util.LinkedList;
import java.util.List;
@Command(label = "give", usage = "give [player] <itemId|itemName> [amount] [level]", description = "Gives an item to you or the specified player", aliases = {
"g", "item", "giveitem" }, permission = "player.give")
"g", "item", "giveitem"}, permission = "player.give")
public final class GiveCommand implements CommandHandler {
@Override
public void execute(Player sender, List<String> args) {
int target, item, lvl, amount = 1;
int target, item, lvl, amount = 1, refinement = 0;
if (sender == null && args.size() < 2) {
CommandHandler.sendMessage(null, "Usage: give <player> <itemId|itemName> [amount] [level]");
return;
......@@ -79,7 +79,28 @@ public final class GiveCommand implements CommandHandler {
return;
}
break;
case 4: // [player] <itemId|itemName> [amount] [level]
case 4: // [player] <itemId|itemName> [amount] [level] | <itemId|itemName> [amount] [level] [refinement]
try {
target = Integer.parseInt(args.get(0));
if (Grasscutter.getGameServer().getPlayerByUid(target) == null && sender != null) {
target = sender.getUid();
item = Integer.parseInt(args.get(0));
amount = Integer.parseInt(args.get(1));
lvl = Integer.parseInt(args.get(2));
refinement = Integer.parseInt(args.get(3));
} else {
item = Integer.parseInt(args.get(1));
amount = Integer.parseInt(args.get(2));
lvl = Integer.parseInt(args.get(3));
}
} catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid item or player ID.");
return;
}
break;
case 5: // [player] <itemId|itemName> [amount] [level] [refinement]
try {
target = Integer.parseInt(args.get(0));
......@@ -90,6 +111,7 @@ public final class GiveCommand implements CommandHandler {
item = Integer.parseInt(args.get(1));
amount = Integer.parseInt(args.get(2));
lvl = Integer.parseInt(args.get(3));
refinement = Integer.parseInt(args.get(4));
}
} catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook.
......@@ -111,37 +133,58 @@ public final class GiveCommand implements CommandHandler {
CommandHandler.sendMessage(sender, "Invalid item id.");
return;
}
if (refinement != 0) {
if (itemData.getItemType() == ItemType.ITEM_WEAPON) {
if (refinement < 1 || refinement > 5) {
CommandHandler.sendMessage(sender, "Refinement must be between 1 and 5.");
return;
}
} else {
CommandHandler.sendMessage(sender, "Refinement is only applicable to weapons.");
return;
}
}
this.item(targetPlayer, itemData, amount, lvl);
this.item(targetPlayer, itemData, amount, lvl, refinement);
if (!itemData.isEquip())
if (!itemData.isEquip()) {
CommandHandler.sendMessage(sender, String.format("Given %s of %s to %s.", amount, item, target));
else
} else if (itemData.getItemType() == ItemType.ITEM_WEAPON) {
CommandHandler.sendMessage(sender,
String.format("Given %s with level %s, refinement %s %s times to %s", item, lvl, refinement, amount, target));
} else {
CommandHandler.sendMessage(sender,
String.format("Given %s with level %s %s times to %s", item, lvl, amount, target));
}
}
private void item(Player player, ItemData itemData, int amount, int lvl) {
private void item(Player player, ItemData itemData, int amount, int lvl, int refinement) {
if (itemData.isEquip()) {
List<GameItem> items = new LinkedList<>();
for (int i = 0; i < amount; i++) {
GameItem item = new GameItem(itemData);
item.setCount(amount);
item.setLevel(lvl);
item.setPromoteLevel(0);
if (lvl > 20) { // 20/40
if (lvl > 20 && lvl < 40) {
item.setPromoteLevel(1);
} else if (lvl > 40) { // 40/50
} else if (lvl > 40 && lvl <= 50) {
item.setPromoteLevel(2);
} else if (lvl > 50) { // 50/60
} else if (lvl > 50 && lvl <= 60) {
item.setPromoteLevel(3);
} else if (lvl > 60) { // 60/70
} else if (lvl > 60 && lvl <= 70) {
item.setPromoteLevel(4);
} else if (lvl > 70) { // 70/80
} else if (lvl > 70 && lvl <= 80) {
item.setPromoteLevel(5);
} else if (lvl > 80) { // 80/90
} else if (lvl > 80 && lvl <= 90) {
item.setPromoteLevel(6);
}
if (item.getItemType() == ItemType.ITEM_WEAPON) {
if (refinement > 0) {
item.setRefinement(refinement - 1);
} else {
item.setRefinement(0);
}
}
items.add(item);
}
player.getInventory().addItems(items, ActionReason.SubfieldDrop);
......
......@@ -61,13 +61,15 @@ public class GameData {
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
// Cache
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
public static char EJWOA = 's';
public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) {
Int2ObjectMap<?> map = null;
......@@ -100,6 +102,11 @@ public class GameData {
public static Map<String, ScenePointEntry> getScenePointEntries() {
return scenePointEntries;
}
// TODO optimize
public static ScenePointEntry getScenePointEntryById(int sceneId, int pointId) {
return getScenePointEntries().get(sceneId + "_" + pointId);
}
public static Int2ObjectMap<AvatarData> getAvatarDataMap() {
return avatarDataMap;
......@@ -269,8 +276,10 @@ public class GameData {
return worldLevelDataMap;
}
public static char EJWOA = 's';
public static Int2ObjectMap<DungeonData> getDungeonDataMap() {
return dungeonDataMap;
}
public static Map<Integer, List<ShopGoodsData>> getShopGoodsDataEntries() {
if (shopGoods.isEmpty()) {
shopGoodsDataMap.forEach((k, v) -> {
......
......@@ -164,6 +164,7 @@ public class ResourceLoader {
for (Map.Entry<String, JsonElement> entry : config.points.entrySet()) {
PointData pointData = Grasscutter.getGsonFactory().fromJson(entry.getValue(), PointData.class);
pointData.setId(Integer.parseInt(entry.getKey()));
ScenePointEntry sl = new ScenePointEntry(sceneId + "_" + entry.getKey(), pointData);
scenePointList.add(sl);
......
package emu.grasscutter.data.common;
public class PointData {
private pos tranPos;
import emu.grasscutter.utils.Position;
public pos getTranPos() {
public class PointData {
private int id;
private String $type;
private Position tranPos;
private int[] dungeonIds;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getType() {
return $type;
}
public Position getTranPos() {
return tranPos;
}
public void setTranPos(pos tranPos) {
this.tranPos = tranPos;
}
public class pos {
private float x;
private float y;
private float z;
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public float getZ() {
return z;
}
public void setZ(float z) {
this.z = z;
}
}
public int[] getDungeonIds() {
return dungeonIds;
}
}
package emu.grasscutter.data.def;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.SceneType;
@ResourceType(name = "DungeonExcelConfigData.json")
public class DungeonData extends GameResource {
private int Id;
private int SceneId;
private int ShowLevel;
private String InvolveType; // TODO enum
@Override
public int getId() {
return this.Id;
}
public int getSceneId() {
return SceneId;
}
public int getShowLevel() {
return ShowLevel;
}
@Override
public void onLoad() {
}
}
......@@ -2,12 +2,13 @@ package emu.grasscutter.data.def;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.EntityType;
@ResourceType(name = "GadgetExcelConfigData.json")
public class GadgetData extends GameResource {
private int Id;
private String Type;
private EntityType Type;
private String JsonName;
private boolean IsInteractive;
private String[] Tags;
......@@ -22,7 +23,7 @@ public class GadgetData extends GameResource {
return this.Id;
}
public String getType() {
public EntityType getType() {
return Type;
}
......
......@@ -9,8 +9,9 @@ import emu.grasscutter.game.props.SceneType;
@ResourceType(name = "SceneExcelConfigData.json")
public class SceneData extends GameResource {
private int Id;
private SceneType SceneType;
private SceneType Type;
private String ScriptData;
@Override
public int getId() {
......@@ -18,7 +19,7 @@ public class SceneData extends GameResource {
}
public SceneType getSceneType() {
return SceneType;
return Type;
}
public String getScriptData() {
......@@ -27,6 +28,6 @@ public class SceneData extends GameResource {
@Override
public void onLoad() {
}
}
package emu.grasscutter.game.dungeons;
import java.util.ArrayList;
import java.util.List;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.MonsterData;
import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
import emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify;
import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
public class DungeonChallenge {
private final Scene scene;
private final SceneGroup group;
private int challengeIndex;
private int challengeId;
private boolean success;
private boolean progress;
private int score;
private int objective = 0;
public DungeonChallenge(Scene scene, SceneGroup group) {
this.scene = scene;
this.group = group;
objective += group.monsters.size();
}
public Scene getScene() {
return scene;
}
public SceneGroup getGroup() {
return group;
}
public int getChallengeIndex() {
return challengeIndex;
}
public void setChallengeIndex(int challengeIndex) {
this.challengeIndex = challengeIndex;
}
public int getChallengeId() {
return challengeId;
}
public void setChallengeId(int challengeId) {
this.challengeId = challengeId;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean isSuccess) {
this.success = isSuccess;
}
public boolean inProgress() {
return progress;
}
public int getScore() {
return score;
}
public void start() {
this.progress = true;
getScene().broadcastPacket(new PacketDungeonChallengeBeginNotify(this));
}
public void finish() {
this.progress = false;
getScene().broadcastPacket(new PacketDungeonChallengeFinishNotify(this));
if (this.isSuccess()) {
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS, null);
} else {
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_FAIL, null);
}
}
public void onMonsterDie(EntityMonster entity) {
score = getScore() + 1;
getScene().broadcastPacket(new PacketChallengeDataNotify(this, 1, getScore()));
if (getScore() >= objective) {
this.setSuccess(true);
finish();
}
}
}
package emu.grasscutter.game.dungeons;
import emu.grasscutter.GameConstants;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.custom.ScenePointEntry;
import emu.grasscutter.data.def.DungeonData;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.SceneType;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.packet.send.PacketDungeonEntryInfoRsp;
import emu.grasscutter.server.packet.send.PacketPlayerEnterDungeonRsp;
import emu.grasscutter.utils.Position;
public class DungeonManager {
private final GameServer server;
......@@ -12,4 +24,59 @@ public class DungeonManager {
public GameServer getServer() {
return server;
}
public void getEntryInfo(Player player, int pointId) {
ScenePointEntry entry = GameData.getScenePointEntryById(player.getScene().getId(), pointId);
if (entry == null || entry.getPointData().getDungeonIds() == null) {
// Error
player.sendPacket(new PacketDungeonEntryInfoRsp());
return;
}
player.sendPacket(new PacketDungeonEntryInfoRsp(player, entry.getPointData()));
}
public void enterDungeon(Player player, int pointId, int dungeonId) {
DungeonData data = GameData.getDungeonDataMap().get(dungeonId);
if (data == null) {
return;
}
Grasscutter.getLogger().info(player.getNickname() + " is trying to enter dungeon " + dungeonId);
int sceneId = data.getSceneId();
player.getScene().setPrevScene(sceneId);
player.getWorld().transferPlayerToScene(player, sceneId, data);
player.getScene().setPrevScenePoint(pointId);
player.sendPacket(new PacketPlayerEnterDungeonRsp(pointId, dungeonId));
}
public void exitDungeon(Player player) {
if (player.getScene().getSceneType() != SceneType.SCENE_DUNGEON) {
return;
}
// Get previous scene
int prevScene = player.getScene().getPrevScene() > 0 ? player.getScene().getPrevScene() : 3;
// Get previous position
DungeonData dungeonData = player.getScene().getDungeonData();
Position prevPos = new Position(GameConstants.START_POSITION);
if (dungeonData != null) {
ScenePointEntry entry = GameData.getScenePointEntryById(prevScene, player.getScene().getPrevScenePoint());
if (entry != null) {
prevPos.set(entry.getPointData().getTranPos());
}
}
// Transfer player back to world
player.getWorld().transferPlayerToScene(player, prevScene, prevPos);
player.sendPacket(new BasePacket(PacketOpcodes.PlayerQuitDungeonRsp));
}
}
package emu.grasscutter.game.entity;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.game.world.World;
public abstract class EntityBaseGadget extends GameEntity {
public EntityBaseGadget(Scene scene) {
super(scene);
}
public abstract int getGadgetId();
@Override
public void onDeath(int killerId) {
}
}
......@@ -23,7 +23,7 @@ import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.ProtoHelper;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
public class EntityClientGadget extends EntityGadget {
public class EntityClientGadget extends EntityBaseGadget {
private final Player owner;
private final Position pos;
......
package emu.grasscutter.game.entity;
import java.util.Arrays;
import java.util.List;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.GadgetData;
import emu.grasscutter.game.props.EntityIdType;
import emu.grasscutter.game.props.EntityType;
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.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData;
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType;
import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
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;
public abstract class EntityGadget extends GameEntity {
public class EntityGadget extends EntityBaseGadget {
private final GadgetData data;
private final Position pos;
private final Position rot;
private int gadgetId;
private int state;
private IntSet worktopOptions;
public EntityGadget(Scene scene) {
public EntityGadget(Scene scene, int gadgetId, Position pos) {
super(scene);
this.data = GameData.getGadgetDataMap().get(gadgetId);
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
this.gadgetId = gadgetId;
this.pos = pos.clone();
this.rot = new Position();
}
public abstract int getGadgetId();
public GadgetData getGadgetData() {
return data;
}
@Override
public Position getPosition() {
// TODO Auto-generated method stub
return this.pos;
}
@Override
public Position getRotation() {
// TODO Auto-generated method stub
return this.rot;
}
public int getGadgetId() {
return gadgetId;
}
public void setGadgetId(int gadgetId) {
this.gadgetId = gadgetId;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public IntSet getWorktopOptions() {
return worktopOptions;
}
public void addWorktopOptions(int[] options) {
if (this.worktopOptions == null) {
this.worktopOptions = new IntOpenHashSet();
}
Arrays.stream(options).forEach(this.worktopOptions::add);
}
public void removeWorktopOption(int option) {
if (this.worktopOptions == null) {
return;
}
this.worktopOptions.remove(option);
}
@Override
public Int2FloatOpenHashMap getFightProperties() {
// TODO Auto-generated method stub
return null;
}
@Override
public void onDeath(int killerId) {
}
@Override
public SceneEntityInfo toProto() {
EntityAuthorityInfo authority = EntityAuthorityInfo.newBuilder()
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
.setAiInfo(SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(Vector.newBuilder()))
.setBornPos(Vector.newBuilder())
.build();
SceneEntityInfo.Builder entityInfo = SceneEntityInfo.newBuilder()
.setEntityId(getId())
.setEntityType(ProtEntityType.PROT_ENTITY_GADGET)
.setMotionInfo(MotionInfo.newBuilder().setPos(getPosition().toProto()).setRot(getRotation().toProto()).setSpeed(Vector.newBuilder()))
.addAnimatorParaList(AnimatorParameterValueInfoPair.newBuilder())
.setEntityClientData(EntityClientData.newBuilder())
.setEntityAuthorityInfo(authority)
.setLifeState(1);
PropPair pair = PropPair.newBuilder()
.setType(PlayerProperty.PROP_LEVEL.getId())
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, 1))
.build();
entityInfo.addPropList(pair);
SceneGadgetInfo.Builder gadgetInfo = SceneGadgetInfo.newBuilder()
.setGadgetId(this.getGadgetId())
.setGroupId(this.getGroupId())
.setConfigId(this.getConfigId())
.setGadgetState(this.getState())
.setIsEnableInteract(true)
.setAuthorityPeerId(this.getScene().getWorld().getHostPeerId());
if (this.getGadgetData().getType() == EntityType.Worktop && this.getWorktopOptions() != null) {
WorktopInfo worktop = WorktopInfo.newBuilder()
.addAllOptionList(this.getWorktopOptions())
.build();
gadgetInfo.setWorktop(worktop);
}
entityInfo.setGadget(gadgetInfo);
return entityInfo.build();
}
}
......@@ -23,7 +23,7 @@ import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.ProtoHelper;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
public class EntityItem extends EntityGadget {
public class EntityItem extends EntityBaseGadget {
private final Position pos;
private final Position rot;
......
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