2
2
3
3
import java .util .*;
4
4
import java .io .File ;
5
- import java .io .Writer ;
6
- import java .io .FileWriter ;
5
+ import java .io .IOException ;
7
6
import java .util .regex .Pattern ;
8
7
9
8
import org .bukkit .*;
9
+ import org .bukkit .entity .Mob ;
10
10
import org .bukkit .block .Block ;
11
11
import org .bukkit .entity .Entity ;
12
12
import org .bukkit .entity .Player ;
13
+ import org .bukkit .util .RayTraceResult ;
13
14
import org .bukkit .entity .LivingEntity ;
14
15
import org .bukkit .inventory .ItemStack ;
15
16
import org .bukkit .scheduler .BukkitTask ;
16
17
import org .bukkit .command .CommandSender ;
17
18
import org .bukkit .inventory .EntityEquipment ;
18
19
import org .bukkit .command .ConsoleCommandSender ;
20
+ import org .bukkit .configuration .file .YamlConfiguration ;
19
21
20
22
import co .aikar .commands .*;
21
23
import co .aikar .commands .annotation .*;
22
24
import co .aikar .commands .annotation .Optional ;
23
25
import co .aikar .commands .bukkit .contexts .OnlinePlayer ;
24
26
27
+ import com .destroystokyo .paper .entity .ai .Goal ;
28
+ import com .destroystokyo .paper .profile .ProfileProperty ;
29
+
25
30
import com .nisovin .magicspells .Perm ;
26
31
import com .nisovin .magicspells .Spell ;
27
32
import com .nisovin .magicspells .util .*;
28
33
import com .nisovin .magicspells .Spellbook ;
29
34
import com .nisovin .magicspells .MagicSpells ;
30
35
import com .nisovin .magicspells .variables .Variable ;
31
36
import com .nisovin .magicspells .spells .PassiveSpell ;
37
+ import com .nisovin .magicspells .Spell .PostCastAction ;
32
38
import com .nisovin .magicspells .mana .ManaChangeReason ;
33
39
import com .nisovin .magicspells .handlers .MagicXpHandler ;
34
40
import com .nisovin .magicspells .util .magicitems .MagicItem ;
@@ -53,17 +59,15 @@ public MagicCommand() {
53
59
});
54
60
55
61
// Create command completions.
56
- commandManager .getCommandCompletions ().registerAsyncCompletion ("spells" , context -> {
57
- Set <String > spells = new HashSet <>();
58
- if (context .getConfig () != null && context .getConfig ().equals ("*" )) spells .add ("*" );
59
- // Collect spell names.
60
- spells .addAll (getSpellNames (MagicSpells .spells ()));
61
- return spells ;
62
- });
62
+ commandManager .getCommandCompletions ().registerAsyncCompletion ("spells" , context ->
63
+ getSpellNames (MagicSpells .spells ())
64
+ );
63
65
commandManager .getCommandCompletions ().registerAsyncCompletion ("owned_spells" , context -> {
64
- Set <Spell > spells = new HashSet <>();
65
66
Player player = context .getPlayer ();
67
+ if (player == null ) return getSpellNames (MagicSpells .spells ());
68
+
66
69
Spellbook spellbook = MagicSpells .getSpellbook (player );
70
+ Set <Spell > spells = new HashSet <>();
67
71
for (Spell spell : MagicSpells .getSpellsOrdered ()) {
68
72
if (spell .isHelperSpell ()) continue ;
69
73
if (spell instanceof PassiveSpell ) continue ;
@@ -72,52 +76,72 @@ public MagicCommand() {
72
76
}
73
77
return getSpellNames (spells );
74
78
});
75
- commandManager .getCommandCompletions ().registerAsyncCompletion ("players+" , context -> {
76
- Set <String > players = new HashSet <>();
77
- players .add ("*" );
78
- for (Player player : Bukkit .getOnlinePlayers ()) {
79
- players .add (player .getName ());
80
- }
81
- return players ;
82
- });
83
79
commandManager .getCommandCompletions ().registerAsyncCompletion ("variables" , context ->
84
80
MagicSpells .getVariableManager ().getVariables ().keySet ()
85
81
);
86
82
commandManager .getCommandCompletions ().registerAsyncCompletion ("magic_items" , context ->
87
83
MagicItems .getMagicItemKeys ()
88
84
);
89
85
commandManager .getCommandCompletions ().registerAsyncCompletion ("looking_at" , context -> {
90
- Set < String > completions = new HashSet <> ();
91
- if (! context . getIssuer (). isPlayer ()) return completions ;
86
+ Player player = context . getPlayer ();
87
+ if (player == null ) return Collections . emptySet () ;
92
88
93
89
String config = context .getConfig ();
94
- if (config == null || config .isEmpty ()) return completions ;
95
-
90
+ if (config == null || config .isEmpty ()) return Collections .emptySet ();
91
+
92
+ RayTraceResult result = player .rayTraceBlocks (6 , FluidCollisionMode .SOURCE_ONLY );
93
+ if (result == null ) return Collections .emptySet ();
94
+
95
+ Block block = result .getHitBlock ();
96
+ if (block == null ) return Collections .emptySet ();
97
+
98
+ String value = switch (config .toLowerCase ()) {
99
+ case "x" -> String .valueOf (block .getX ());
100
+ case "y" -> String .valueOf (block .getY ());
101
+ case "z" -> String .valueOf (block .getZ ());
102
+ case "pitch" -> String .valueOf (player .getLocation ().getPitch ());
103
+ case "yaw" -> String .valueOf (player .getLocation ().getYaw ());
104
+ default -> "" ;
105
+ };
106
+ return Set .of (value );
107
+ });
108
+ commandManager .getCommandCompletions ().registerAsyncCompletion ("spell_target" , context -> {
96
109
Player player = context .getPlayer ();
97
- Block block = player .getTargetBlockExact (6 , FluidCollisionMode .SOURCE_ONLY );
98
- if (block == null ) return null ;
99
- if (block .getType ().isAir ()) return completions ;
100
-
101
- Location location = block .getLocation ();
102
- String num = "" ;
103
- switch (config .toLowerCase ()) {
104
- case "x" -> num += location .getX ();
105
- case "y" -> num += location .getY ();
106
- case "z" -> num += location .getZ ();
107
- case "pitch" -> num += player .getLocation ().getPitch ();
108
- case "yaw" -> num += player .getLocation ().getYaw ();
110
+ if (player == null ) return getPlayers ();
111
+ RayTraceResult result = player .rayTraceEntities (6 );
112
+
113
+ Set <String > targets = new HashSet <>();
114
+ // Add the targeted entity's uuid/username first.
115
+ if (result != null && result .getHitEntity () instanceof LivingEntity entity ) {
116
+ targets .add (entity instanceof Player pl ? pl .getName () : entity .getUniqueId ().toString ());
109
117
}
110
- if (!num .isEmpty ()) completions .add (num );
111
- return completions ;
118
+ targets .addAll (getPlayers ());
119
+ return targets ;
120
+ });
121
+ commandManager .getCommandCompletions ().registerAsyncCompletion ("target_uuid" , context -> {
122
+ Player player = context .getPlayer ();
123
+ if (player == null ) return Collections .emptySet ();
124
+
125
+ RayTraceResult result = player .rayTraceEntities (6 );
126
+ if (result == null || !(result .getHitEntity () instanceof LivingEntity entity ))
127
+ return Collections .emptySet ();
128
+ return Set .of (entity .getUniqueId ().toString ());
112
129
});
113
130
commandManager .getCommandCompletions ().registerAsyncCompletion ("power" , context -> {
114
131
Player player = context .getPlayer ();
115
- if (player == null ) return Collections .emptyList ();
116
- if (!Perm .COMMAND_CAST_POWER .has (player )) return Collections .emptyList ();
132
+ if (player != null && !Perm .COMMAND_CAST_POWER .has (player )) return Collections .emptyList ();
117
133
return Collections .singleton ("-p:" );
118
134
});
119
135
}
120
136
137
+ private static Set <String > getPlayers () {
138
+ Set <String > players = new HashSet <>();
139
+ for (Player player : Bukkit .getOnlinePlayers ()) {
140
+ players .add (player .getName ());
141
+ }
142
+ return players ;
143
+ }
144
+
121
145
private static Set <String > getSpellNames (Collection <Spell > spells ) {
122
146
Set <String > spellNames = new HashSet <>();
123
147
boolean added ;
@@ -298,7 +322,7 @@ public static void onTask(CommandIssuer issuer) {
298
322
}
299
323
300
324
@ Subcommand ("resetcd" )
301
- @ CommandCompletion ("@players+ @spells:* @nothing" )
325
+ @ CommandCompletion ("*| @players *| @spells @nothing" )
302
326
@ Syntax ("[player/*] [spell/*]" )
303
327
@ Description ("Reset cooldown of all players or a player for a spell or all spells." )
304
328
@ HelpPermission (permission = Perm .COMMAND_RESET_COOLDOWN )
@@ -612,26 +636,61 @@ public void onUpdate(CommandIssuer issuer, String[] args) {
612
636
@ HelpPermission (permission = Perm .COMMAND_UTIL_SAVE_SKIN )
613
637
public void onSaveSkin (CommandIssuer issuer , @ Optional Player player ) {
614
638
if (!MagicSpells .isLoaded ()) return ;
639
+
615
640
if (noPermission (issuer .getIssuer (), Perm .COMMAND_UTIL_SAVE_SKIN )) return ;
616
641
if (player == null ) player = getPlayerFromIssuer (issuer );
617
642
if (player == null ) return ;
618
- String data = Util .getSkinData (player );
619
643
620
- File folder = new File (MagicSpells .getInstance ().getDataFolder (), "skins" );
644
+ List <ProfileProperty > skins = player .getPlayerProfile ().getProperties ().stream ().filter (prop -> prop .getName ().equals ("textures" )).toList ();
645
+ ProfileProperty latestSkin = skins .get (0 );
646
+
647
+ YamlConfiguration data = new YamlConfiguration ();
648
+ data .set ("skin" , latestSkin .getValue ());
649
+ data .set ("signature" , latestSkin .getSignature ());
650
+
651
+ File folder = new File (PLUGIN_FOLDER , "skins" );
621
652
if (!folder .exists ()) folder .mkdir ();
622
- File file = new File (folder , System .currentTimeMillis () + ".yml" );
623
653
try {
624
- Writer writer = new FileWriter (file );
625
- writer .write (data );
626
- writer .flush ();
627
- writer .close ();
628
- } catch (Exception e ) {
654
+ data .save (new File (folder , System .currentTimeMillis () + ".yml" ));
655
+ } catch (IOException e ) {
629
656
e .printStackTrace ();
657
+ return ;
630
658
}
631
659
632
660
issuer .sendMessage (MagicSpells .getTextColor () + TxtUtil .getPossessiveName (player .getName ()) + " skin was saved." );
633
661
}
634
662
663
+ @ Subcommand ("listgoals" )
664
+ @ CommandCompletion ("@target_uuid @nothing" )
665
+ @ Syntax ("[uuid]" )
666
+ @ Description ("List an entity's mob goals." )
667
+ @ HelpPermission (permission = Perm .COMMAND_UTIL_LIST_GOALS )
668
+ public void onListGoals (CommandIssuer issuer , String uuidString ) {
669
+ if (noPermission (issuer .getIssuer (), Perm .COMMAND_UTIL_LIST_GOALS )) return ;
670
+
671
+ UUID uuid ;
672
+ try {
673
+ uuid = UUID .fromString (uuidString );
674
+ } catch (IllegalArgumentException e ) {
675
+ throw new ConditionFailedException ("Passed UUID argument is not a valid UUIO." );
676
+ }
677
+ if (!(Bukkit .getEntity (uuid ) instanceof Mob mob ))
678
+ throw new ConditionFailedException ("UUID did not match an entity of Mob type." );
679
+
680
+ Collection <Goal <Mob >> goals = Bukkit .getMobGoals ().getAllGoals (mob );
681
+ if (goals .isEmpty ()) {
682
+ issuer .sendMessage (MagicSpells .getTextColor () + "Entity '" + uuid + "' has no mob goals." );
683
+ return ;
684
+ }
685
+
686
+ issuer .sendMessage (MagicSpells .getTextColor () + "Mob goals of entity '" + uuid + "':" );
687
+ for (Goal <Mob > goal : goals ) {
688
+ String entity = goal .getKey ().getEntityClass ().getSimpleName ();
689
+ String key = goal .getKey ().getNamespacedKey ().toString ();
690
+ issuer .sendMessage (MagicSpells .getTextColor () + " - " + entity + ": " + key + " " + goal .getTypes ());
691
+ }
692
+ }
693
+
635
694
}
636
695
637
696
@ Subcommand ("profilereport" )
@@ -743,7 +802,7 @@ public void onCastSelf(CommandIssuer issuer, String[] args) {
743
802
}
744
803
745
804
@ Subcommand ("as" )
746
- @ CommandCompletion ("@players @spells @power @nothing" )
805
+ @ CommandCompletion ("@spell_target @spells @power @nothing" )
747
806
@ Syntax ("<player/UUID> <spell> (-p:[power]) [spellArgs]" )
748
807
@ Description ("Force a player to cast a spell. (You can optionally define power: -p:1.0)" )
749
808
@ HelpPermission (permission = Perm .COMMAND_CAST_AS )
@@ -768,7 +827,7 @@ public void onCastAs(CommandIssuer issuer, String[] args) {
768
827
}
769
828
770
829
@ Subcommand ("on" )
771
- @ CommandCompletion ("@players @spells @nothing" )
830
+ @ CommandCompletion ("@spell_target @spells @nothing" )
772
831
@ Syntax ("<player/UUID> <spell>" )
773
832
@ Description ("Cast a spell on an entity." )
774
833
@ HelpPermission (permission = Perm .COMMAND_CAST_ON )
@@ -785,11 +844,10 @@ public void onCastOn(CommandIssuer issuer, String[] args) {
785
844
throw new ConditionFailedException ("Spell is not a targeted entity spell." );
786
845
}
787
846
788
- boolean casted ;
789
- // Handle with or without caster.
790
- if (issuer .getIssuer () instanceof LivingEntity ) casted = newSpell .castAtEntity (issuer .getIssuer (), target , 1F );
791
- else casted = newSpell .castAtEntity (target , 1F );
792
- if (!casted ) throw new ConditionFailedException ("Spell probably cannot be cast from console." );
847
+ LivingEntity caster = issuer .getIssuer () instanceof LivingEntity ? issuer .getIssuer () : null ;
848
+ CastResult result = newSpell .castAtEntity (new SpellData (caster , target ));
849
+ if (result .action () == PostCastAction .ALREADY_HANDLED )
850
+ throw new ConditionFailedException ("Spell probably cannot be cast from console." );
793
851
}
794
852
795
853
@ Subcommand ("at" )
@@ -851,7 +909,7 @@ else if (issuer.getIssuer() instanceof LivingEntity) {
851
909
SpellData data = new SpellData (issuer .getIssuer () instanceof LivingEntity le ? le : null , location , 1f , null );
852
910
CastResult result = newSpell .castAtLocation (data );
853
911
854
- if (result .action () == Spell . PostCastAction .ALREADY_HANDLED )
912
+ if (result .action () == PostCastAction .ALREADY_HANDLED )
855
913
throw new ConditionFailedException ("Spell probably cannot be cast from console." );
856
914
}
857
915
0 commit comments