PlayerCommands.java 21.9 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
package emu.grasscutter.commands;

KingRainbow44's avatar
KingRainbow44 committed
3
import emu.grasscutter.Grasscutter;
Melledy's avatar
Melledy committed
4
5
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.def.ItemData;
6
import emu.grasscutter.data.def.AvatarData;
7
import emu.grasscutter.data.def.AvatarSkillDepotData;
Melledy's avatar
Melledy committed
8
9
import emu.grasscutter.data.def.MonsterData;
import emu.grasscutter.game.GenshinPlayer;
Melledy's avatar
Melledy committed
10
import emu.grasscutter.game.GenshinScene;
KingRainbow44's avatar
KingRainbow44 committed
11
import emu.grasscutter.game.World;
Melledy's avatar
Melledy committed
12
13
14
15
16
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.entity.EntityItem;
import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.game.inventory.GenshinItem;
KingRainbow44's avatar
KingRainbow44 committed
17
import emu.grasscutter.game.inventory.Inventory;
Melledy's avatar
Melledy committed
18
19
20
import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.FightProperty;
SpikeHD's avatar
SpikeHD committed
21
import emu.grasscutter.game.props.PlayerProperty;
Melledy's avatar
Melledy committed
22
23
24
25
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import emu.grasscutter.utils.Position;

KingRainbow44's avatar
KingRainbow44 committed
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.util.LinkedList;
import java.util.List;

/**
 * A container for player-related commands.
 */
public final class PlayerCommands {
    @Command(label = "give", aliases = {"g", "item", "giveitem"}, 
            usage = "Usage: give [player] <itemId|itemName> [amount]")
    public static class GiveCommand implements CommandHandler {

        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            int target, item, amount = 1;

            switch(args.size()) {
                default:
                    CommandHandler.sendMessage(player, "Usage: give <player> <itemId|itemName> [amount]");
                    return;
                case 1:
                    try {
                        item = Integer.parseInt(args.get(0));
KingRainbow44's avatar
KingRainbow44 committed
48
                        target = player.getAccount().getPlayerId();
KingRainbow44's avatar
KingRainbow44 committed
49
50
51
52
53
54
55
56
57
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from item name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid item id.");
                        return;
                    }
                    break;
                case 2:
                    try {
                        target = Integer.parseInt(args.get(0));
Melledy's avatar
Melledy committed
58

59
60
                        if(Grasscutter.getGameServer().getPlayerByUid(target) == null) {
                            target = player.getUid(); amount = Integer.parseInt(args.get(1));
KingRainbow44's avatar
KingRainbow44 committed
61
62
63
64
65
66
67
68
69
70
71
72
73
                            item = Integer.parseInt(args.get(0));
                        } else {
                            item = Integer.parseInt(args.get(1));
                        }
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from item name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid item or player ID.");
                        return;
                    }
                    break;
                case 3:
                    try {
                        target = Integer.parseInt(args.get(0));
Melledy's avatar
Melledy committed
74
                        
75
                        if(Grasscutter.getGameServer().getPlayerByUid(target) == null) {
KingRainbow44's avatar
KingRainbow44 committed
76
77
78
79
80
81
82
83
84
85
86
87
88
                            CommandHandler.sendMessage(player, "Invalid player ID."); return;
                        }

                        item = Integer.parseInt(args.get(1));
                        amount = Integer.parseInt(args.get(2));
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from item name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid item or player ID.");
                        return;
                    }
                    break;
            }

89
            GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
Melledy's avatar
Melledy committed
90

KingRainbow44's avatar
KingRainbow44 committed
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
            if(targetPlayer == null) {
                CommandHandler.sendMessage(player, "Player not found."); return;
            }

            ItemData itemData = GenshinData.getItemDataMap().get(item);
            if(itemData == null) {
                CommandHandler.sendMessage(player, "Invalid item id."); return;
            }
            
            this.item(targetPlayer, itemData, amount);
        }

        /**
         * give [player] [itemId|itemName] [amount]
         */
        @Override public void execute(List<String> args) {
            if(args.size() < 2) {
                CommandHandler.sendMessage(null, "Usage: give <player> <itemId|itemName> [amount]");
                return;
            }
111

KingRainbow44's avatar
KingRainbow44 committed
112
113
114
115
116
            try {
                int target = Integer.parseInt(args.get(0));
                int item = Integer.parseInt(args.get(1));
                int amount = 1; if(args.size() > 2) amount = Integer.parseInt(args.get(2));
                
117
                GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
Melledy's avatar
Melledy committed
118

KingRainbow44's avatar
KingRainbow44 committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
                if(targetPlayer == null) {
                    CommandHandler.sendMessage(null, "Player not found."); return;
                }
                
                ItemData itemData = GenshinData.getItemDataMap().get(item);
                if(itemData == null) {
                    CommandHandler.sendMessage(null, "Invalid item id."); return;
                }
                
                this.item(targetPlayer, itemData, amount);
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid item or player ID.");
            }
        }
        
        private void item(GenshinPlayer player, ItemData itemData, int amount) {
            GenshinItem genshinItem = new GenshinItem(itemData);
            if(itemData.isEquip()) {
                List<GenshinItem> items = new LinkedList<>();
                for(int i = 0; i < amount; i++) {
                    items.add(genshinItem);
                } player.getInventory().addItems(items);
                player.sendPacket(new PacketItemAddHintNotify(items, ActionReason.SubfieldDrop));
            } else {
                genshinItem.setCount(amount);
                player.getInventory().addItem(genshinItem);
                player.sendPacket(new PacketItemAddHintNotify(genshinItem, ActionReason.SubfieldDrop));
            }
        }
    }
    
    @Command(label = "drop", aliases = {"d", "dropitem"}, 
            usage = "Usage: drop <itemId|itemName> [amount]", 
            execution = Command.Execution.PLAYER)
    public static class DropCommand implements CommandHandler {
154

KingRainbow44's avatar
KingRainbow44 committed
155
156
157
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            if(args.size() < 1) {
KingRainbow44's avatar
KingRainbow44 committed
158
                CommandHandler.sendMessage(player, "Usage: drop <itemId|itemName> [amount]");
KingRainbow44's avatar
KingRainbow44 committed
159
160
                return;
            }
161

KingRainbow44's avatar
KingRainbow44 committed
162
163
164
            try {
                int item = Integer.parseInt(args.get(0));
                int amount = 1; if(args.size() > 1) amount = Integer.parseInt(args.get(1));
Melledy's avatar
Melledy committed
165

KingRainbow44's avatar
KingRainbow44 committed
166
167
                ItemData itemData = GenshinData.getItemDataMap().get(item);
                if(itemData == null) {
KingRainbow44's avatar
KingRainbow44 committed
168
                    CommandHandler.sendMessage(player, "Invalid item id."); return;
KingRainbow44's avatar
KingRainbow44 committed
169
                }
170

KingRainbow44's avatar
KingRainbow44 committed
171
172
173
174
                if (itemData.isEquip()) {
                    float range = (5f + (.1f * amount));
                    for (int i = 0; i < amount; i++) {
                        Position pos = player.getPos().clone().addX((float) (Math.random() * range) - (range / 2)).addY(3f).addZ((float) (Math.random() * range) - (range / 2));
Melledy's avatar
Melledy committed
175
176
                        EntityItem entity = new EntityItem(player.getScene(), player, itemData, pos, 1);
                        player.getScene().addEntity(entity);
KingRainbow44's avatar
KingRainbow44 committed
177
178
                    }
                } else {
Melledy's avatar
Melledy committed
179
180
                    EntityItem entity = new EntityItem(player.getScene(), player, itemData, player.getPos().clone().addY(3f), amount);
                    player.getScene().addEntity(entity);
KingRainbow44's avatar
KingRainbow44 committed
181
182
                }
            } catch (NumberFormatException ignored) {
KingRainbow44's avatar
KingRainbow44 committed
183
                CommandHandler.sendMessage(player, "Invalid item or player ID.");
KingRainbow44's avatar
KingRainbow44 committed
184
185
186
            }
        }
    }
SpikeHD's avatar
SpikeHD committed
187

KingRainbow44's avatar
KingRainbow44 committed
188
    @Command(label = "givechar", aliases = {"givec"}, 
KingRainbow44's avatar
KingRainbow44 committed
189
            usage = "Usage: givechar <player|avatarId> [level|avatarId] [level]")
SpikeHD's avatar
SpikeHD committed
190
    public static class GiveCharCommand implements CommandHandler {
191
        @Override public void execute(GenshinPlayer player, List<String> args) {
KingRainbow44's avatar
KingRainbow44 committed
192
            int target, avatarId, level = 1, ascension = 1;
SpikeHD's avatar
SpikeHD committed
193

KingRainbow44's avatar
KingRainbow44 committed
194
            if(args.size() < 1) {
KingRainbow44's avatar
KingRainbow44 committed
195
                CommandHandler.sendMessage(player, "Usage: givechar <player> <avatarId> [level]");
196
197
198
199
200
                return;
            }
            
            switch(args.size()) {
                default:
KingRainbow44's avatar
KingRainbow44 committed
201
                CommandHandler.sendMessage(player, "Usage: givechar <player> <avatarId> [level]");
202
203
204
205
                    return;
                case 2:
                    try {
                        target = Integer.parseInt(args.get(0));
Melledy's avatar
Melledy committed
206
                        if(Grasscutter.getGameServer().getPlayerByUid(target) == null) {
KingRainbow44's avatar
KingRainbow44 committed
207
208
                            target = player.getUid(); 
                            level = Integer.parseInt(args.get(1));
KingRainbow44's avatar
KingRainbow44 committed
209
                            avatarId = Integer.parseInt(args.get(0));
210
                        } else {
KingRainbow44's avatar
KingRainbow44 committed
211
                            avatarId = Integer.parseInt(args.get(1));
212
213
214
215
216
217
218
219
220
221
                        }
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from avatar name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid avatar or player ID.");
                        return;
                    }
                    break;
                case 3:
                    try {
                        target = Integer.parseInt(args.get(0));
Melledy's avatar
Melledy committed
222
                        if(Grasscutter.getGameServer().getPlayerByUid(target) == null) {
223
224
225
                            CommandHandler.sendMessage(player, "Invalid player ID."); return;
                        }

KingRainbow44's avatar
KingRainbow44 committed
226
                        avatarId = Integer.parseInt(args.get(1));
227
228
229
230
231
232
233
234
                        level = Integer.parseInt(args.get(2));
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from avatar name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid avatar or player ID.");
                        return;
                    }
                    break;
            }
SpikeHD's avatar
SpikeHD committed
235

Melledy's avatar
Melledy committed
236
            GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
237
            if(targetPlayer == null) {
KingRainbow44's avatar
KingRainbow44 committed
238
                CommandHandler.sendMessage(player, "Player not found."); return;
SpikeHD's avatar
SpikeHD committed
239
            }
240
                
KingRainbow44's avatar
KingRainbow44 committed
241
            AvatarData avatarData = GenshinData.getAvatarDataMap().get(avatarId);
SpikeHD's avatar
SpikeHD committed
242
            if(avatarData == null) {
KingRainbow44's avatar
KingRainbow44 committed
243
                CommandHandler.sendMessage(player, "Invalid avatar id."); return;
SpikeHD's avatar
SpikeHD committed
244
245
            }

246
247
            // Calculate ascension level.
            if (level <= 40) {
KingRainbow44's avatar
KingRainbow44 committed
248
249
250
                ascension = (int) Math.ceil(level / 20f);
            } else {
                ascension = (int) Math.ceil(level / 10f) - 3;
251
252
            }

KingRainbow44's avatar
KingRainbow44 committed
253
            GenshinAvatar avatar = new GenshinAvatar(avatarId);
SpikeHD's avatar
SpikeHD committed
254
            avatar.setLevel(level);
255
            avatar.setPromoteLevel(ascension);
256
257
258
            
            // This will handle stats and talents
            avatar.recalcStats();
259
260
261
    
            targetPlayer.addAvatar(avatar);
        }
SpikeHD's avatar
SpikeHD committed
262

263
264
265
        @Override
        public void execute(List<String> args) {
            if(args.size() < 2) {
SpikeHD's avatar
SpikeHD committed
266
                CommandHandler.sendMessage(null, "Usage: givechar <player> <itemId|itemName> [amount]");
267
268
269
270
271
272
273
                return;
            }

            try {
                int target = Integer.parseInt(args.get(0));
                int avatarID = Integer.parseInt(args.get(1));
                int level = 1; if(args.size() > 2) level = Integer.parseInt(args.get(2));
KingRainbow44's avatar
KingRainbow44 committed
274
                int ascension;
275
                
Melledy's avatar
Melledy committed
276
                GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
277
278
279
280
281
282
283
284
285
                if(targetPlayer == null) {
                    CommandHandler.sendMessage(null, "Player not found."); return;
                }
                    
                AvatarData avatarData = GenshinData.getAvatarDataMap().get(avatarID);
                if(avatarData == null) {
                    CommandHandler.sendMessage(null, "Invalid avatar id."); return;
                }
                
286
287
                // Calculate ascension level.
                if (level <= 40) {
KingRainbow44's avatar
KingRainbow44 committed
288
289
290
                    ascension = (int) Math.ceil(level / 20f);
                } else {
                    ascension = (int) Math.ceil(level / 10f) - 3;
291
292
                }
                
293
294
                GenshinAvatar avatar = new GenshinAvatar(avatarID);
                avatar.setLevel(level);
295
                avatar.setPromoteLevel(ascension);
296
297
298

                // This will handle stats and talents
                avatar.recalcStats();
299
300
301
302
303
        
                targetPlayer.addAvatar(avatar);
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid item or player ID.");
            }
SpikeHD's avatar
SpikeHD committed
304
305
        }
    }
Melledy's avatar
Melledy committed
306

KingRainbow44's avatar
KingRainbow44 committed
307
308
309
310
311
312
313
314
315
316
    @Command(label = "spawn", execution = Command.Execution.PLAYER, 
            usage = "Usage: spawn <entityId|entityName> [level] [amount]")
    public static class SpawnCommand implements CommandHandler {
        
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            if(args.size() < 1) {
                CommandHandler.sendMessage(null, "Usage: spawn <entityId|entityName> [amount]");
                return;
            }
317

KingRainbow44's avatar
KingRainbow44 committed
318
319
320
321
            try {
                int entity = Integer.parseInt(args.get(0));
                int level = 1; if(args.size() > 1) level = Integer.parseInt(args.get(1));
                int amount = 1; if(args.size() > 2) amount = Integer.parseInt(args.get(2));
322

KingRainbow44's avatar
KingRainbow44 committed
323
324
325
326
                MonsterData entityData = GenshinData.getMonsterDataMap().get(entity);
                if(entityData == null) {
                    CommandHandler.sendMessage(null, "Invalid entity id."); return;
                }
327

KingRainbow44's avatar
KingRainbow44 committed
328
329
330
                float range = (5f + (.1f * amount));
                for (int i = 0; i < amount; i++) {
                    Position pos = player.getPos().clone().addX((float) (Math.random() * range) - (range / 2)).addY(3f).addZ((float) (Math.random() * range) - (range / 2));
Melledy's avatar
Melledy committed
331
332
                    EntityMonster monster = new EntityMonster(player.getScene(), entityData, pos, level);
                    player.getScene().addEntity(monster);
KingRainbow44's avatar
KingRainbow44 committed
333
334
335
336
337
338
339
340
                }
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid item or player ID.");
            }
        }
    }
    
    @Command(label = "killall", 
Melledy's avatar
Melledy committed
341
            usage = "Usage: killall [playerUid] [sceneId]")
KingRainbow44's avatar
KingRainbow44 committed
342
    public static class KillAllCommand implements CommandHandler {
343

KingRainbow44's avatar
KingRainbow44 committed
344
345
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
Melledy's avatar
Melledy committed
346
347
            GenshinScene scene = player.getScene();
            scene.getEntities().values().stream()
KingRainbow44's avatar
KingRainbow44 committed
348
                    .filter(entity -> entity instanceof EntityMonster)
Melledy's avatar
Melledy committed
349
350
                    .forEach(entity -> scene.killEntity(entity, 0));
            CommandHandler.sendMessage(null, "Killing all monsters in scene " + scene.getId());
KingRainbow44's avatar
KingRainbow44 committed
351
352
353
354
        }
        
        @Override
        public void execute(List<String> args) {
Melledy's avatar
Melledy committed
355
356
            if(args.size() < 2) {
                CommandHandler.sendMessage(null, "Usage: killall [playerUid] [sceneId]"); return;
KingRainbow44's avatar
KingRainbow44 committed
357
            }
358

KingRainbow44's avatar
KingRainbow44 committed
359
            try {
Melledy's avatar
Melledy committed
360
361
362
            	int playerUid = Integer.parseInt(args.get(0));
                int sceneId = Integer.parseInt(args.get(1));
                
363
                GenshinPlayer player = Grasscutter.getGameServer().getPlayerByUid(playerUid);
Melledy's avatar
Melledy committed
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
                if (player == null) {
                	CommandHandler.sendMessage(null, "Player not found or offline.");
                	return;
                }
                
                GenshinScene scene = player.getWorld().getSceneById(sceneId);
                if (scene == null) {
                	CommandHandler.sendMessage(null, "Scene not found in player world");
                	return;
                }
                
                scene.getEntities().values().stream()
                        .filter(entity -> entity instanceof EntityMonster)
                        .forEach(entity -> scene.killEntity(entity, 0));
                CommandHandler.sendMessage(null, "Killing all monsters in scene " + scene.getId());
KingRainbow44's avatar
KingRainbow44 committed
379
            } catch (NumberFormatException ignored) {
Melledy's avatar
Melledy committed
380
                CommandHandler.sendMessage(null, "Invalid arguments.");
KingRainbow44's avatar
KingRainbow44 committed
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
            }
        }
    }
    
    @Command(label = "resetconst", aliases = {"resetconstellation"}, 
            usage = "Usage: resetconst [all]", execution = Command.Execution.PLAYER)
    public static class ResetConstellationCommand implements CommandHandler {
        
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            if(args.size() > 0 && args.get(0).equalsIgnoreCase("all")) {
                player.getAvatars().forEach(this::resetConstellation);
                player.dropMessage("Reset all avatars' constellations.");
            } else {
                EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity(); 
                if(entity == null)
                    return;
                
                GenshinAvatar avatar = entity.getAvatar();
                this.resetConstellation(avatar);
401

KingRainbow44's avatar
KingRainbow44 committed
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
                player.dropMessage("Constellations for " + avatar.getAvatarData().getName() + " have been reset. Please relog to see changes.");
            }
        }
        
        private void resetConstellation(GenshinAvatar avatar) {
            avatar.getTalentIdList().clear();
            avatar.setCoreProudSkillLevel(0);
            avatar.recalcStats();
            avatar.save();
        }
    }
    
    @Command(label = "godmode",
            usage = "Usage: godmode", execution = Command.Execution.PLAYER)
    public static class GodModeCommand implements CommandHandler {
        
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            player.setGodmode(!player.inGodmode());
            player.dropMessage("Godmode is now " + (player.inGodmode() ? "enabled" : "disabled") + ".");
        }
    }
    
    @Command(label = "sethealth", aliases = {"sethp"}, 
            usage = "Usage: sethealth <hp>", execution = Command.Execution.PLAYER)
    public static class SetHealthCommand implements CommandHandler {
428

KingRainbow44's avatar
KingRainbow44 committed
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            if(args.size() < 1) {
                CommandHandler.sendMessage(null, "Usage: sethealth <hp>"); return;
            }
            
            try {
                int health = Integer.parseInt(args.get(0));
                EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
                if(entity == null)
                    return;
                
                entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, health);
                entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
                player.dropMessage("Health set to " + health + ".");
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid health value.");
            }
        }
    }
SpikeHD's avatar
SpikeHD committed
449
450
451
452
453
454
455

    @Command(label = "setworldlevel", aliases = {"setworldlvl"}, 
            usage = "Usage: setworldlevel <level>", execution = Command.Execution.PLAYER)
    public static class SetWorldLevelCommand implements CommandHandler {
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            if(args.size() < 1) {
KingRainbow44's avatar
KingRainbow44 committed
456
                CommandHandler.sendMessage(player, "Usage: setworldlevel <level>"); return;
SpikeHD's avatar
SpikeHD committed
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
            }
            
            try {
                int level = Integer.parseInt(args.get(0));

                // Set in both world and player props
                player.getWorld().setWorldLevel(level);
                player.setProperty(PlayerProperty.PROP_PLAYER_WORLD_LEVEL, level);

                player.dropMessage("World level set to " + level + ".");
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid world level.");
            }
        }
    }
KingRainbow44's avatar
KingRainbow44 committed
472
473
474
475
476
477
478
479
480
481
482
483
484
485
    
    @Command(label = "clearartifacts", aliases = {"clearart"}, 
            usage = "Usage: clearartifacts", execution = Command.Execution.PLAYER)
    public static class ClearArtifactsCommand implements CommandHandler {
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            Inventory playerInventory = player.getInventory();
            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()));
        }
    }
486

Melledy's avatar
Melledy committed
487
488
489
490
491
492
    @Command(label = "changescene", aliases = {"scene"}, 
            usage = "Usage: changescene <scene id>", execution = Command.Execution.PLAYER)
    public static class ChangeSceneCommand implements CommandHandler {
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            if(args.size() < 1) {
KingRainbow44's avatar
KingRainbow44 committed
493
                CommandHandler.sendMessage(player, "Usage: changescene <scene id>"); return;
Melledy's avatar
Melledy committed
494
495
496
            }
        
            try {
KingRainbow44's avatar
KingRainbow44 committed
497
498
499
500
501
502
                int sceneId = Integer.parseInt(args.get(0));
                boolean result = player.getWorld().transferPlayerToScene(player, sceneId, player.getPos());

                if (!result) {
                    CommandHandler.sendMessage(null, "Scene does not exist or you are already in it");
                }
Melledy's avatar
Melledy committed
503
            } catch (Exception e) {
KingRainbow44's avatar
KingRainbow44 committed
504
                CommandHandler.sendMessage(player, "Usage: changescene <scene id>"); return;
Melledy's avatar
Melledy committed
505
506
507
            }
        }
    }
Melledy's avatar
Melledy committed
508
}