Skip to content

Commit c784b66

Browse files
committed
Bring back the PlayerSelection API
1 parent e6dfca5 commit c784b66

File tree

8 files changed

+404
-1
lines changed

8 files changed

+404
-1
lines changed

loader/src/main/java/com/fox2code/foxloader/event/interaction/PlayerBreakBlockEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import org.jetbrains.annotations.NotNull;
3131

3232
@Event.DelegateEvent
33-
public final class PlayerBreakBlockEvent extends WorldChangeEvent.SingleBlockChange {
33+
public final class PlayerBreakBlockEvent extends WorldChangeEvent.SingleBlockChange implements Event.Cancellable {
3434
private final EntityPlayer entityPlayer;
3535
private final ItemStack heldItem;
3636

loader/src/main/java/com/fox2code/foxloader/event/world/WorldChangeEvent.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,5 +128,17 @@ public int getBlockChangeMinZ() {
128128
public int getBlockChangeMaxZ() {
129129
return this.z;
130130
}
131+
132+
public int getX() {
133+
return this.x;
134+
}
135+
136+
public int getY() {
137+
return this.y;
138+
}
139+
140+
public int getZ() {
141+
return this.z;
142+
}
131143
}
132144
}

loader/src/main/java/com/fox2code/foxloader/loader/ModLoader.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.fox2code.foxloader.launcher.FoxLauncher;
3636
import com.fox2code.foxloader.loader.packet.LoaderNetworkManager;
3737
import com.fox2code.foxloader.network.SidedMetadataAPI;
38+
import com.fox2code.foxloader.selection.PlayerSelectionProvider;
3839
import com.fox2code.foxloader.registry.CommandRegistry;
3940
import com.fox2code.foxloader.registry.GameRegistry;
4041
import com.fox2code.foxloader.updater.UpdateManager;
@@ -57,6 +58,7 @@
5758
public final class ModLoader extends Mod {
5859
private static final ArrayList<Mod> mods = new ArrayList<>();
5960
private static boolean areAllModsLoaded = false;
61+
private static boolean areAllModsFullyLoaded = false;
6062
private static Thread gameThread;
6163

6264
static {
@@ -117,6 +119,8 @@ static void preInitializeMods(Collection<LoadingPlugin> loadingPlugins) throws E
117119
}
118120

119121
static void postInitializeMods() {
122+
if (ModLoader.areAllModsFullyLoaded())
123+
throw new IllegalStateException("Mods are already fully loaded!");
120124
if (ModContainer.getActiveModContainer() != null)
121125
throw new IllegalStateException("postInitializeMods() called with active mod container");
122126
gameThread = Thread.currentThread();
@@ -130,6 +134,8 @@ static void postInitializeMods() {
130134
mod.onPostInit();
131135
}
132136
ModContainer.setActiveModContainer(null);
137+
areAllModsFullyLoaded = true;
138+
ModLoaderInit.FOX_LOADER_CONTAINER.runInContext(PlayerSelectionProvider::initialize);
133139
if (FoxLauncher.isClient() && ModLoaderOptions.INSTANCE.checkForUpdates) {
134140
UpdateManager.getInstance().checkUpdates();
135141
}
@@ -192,6 +198,10 @@ public static boolean areAllModsLoaded() {
192198
return areAllModsLoaded;
193199
}
194200

201+
public static boolean areAllModsFullyLoaded() {
202+
return areAllModsFullyLoaded;
203+
}
204+
195205
public static Thread getGameThread() {
196206
return gameThread;
197207
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2023-2025 Fox2Code
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package com.fox2code.foxloader.selection;
25+
26+
import net.minecraft.common.entity.player.EntityPlayer;
27+
import net.minecraft.common.world.World;
28+
29+
import java.lang.ref.WeakReference;
30+
import java.util.Objects;
31+
32+
/**
33+
* Represent a player selection, made with a wooden axe in creative.
34+
*/
35+
public abstract class PlayerSelection {
36+
private final WeakReference<EntityPlayer> entityPlayerWeakReference;
37+
38+
public PlayerSelection(EntityPlayer entityPlayer) {
39+
Objects.requireNonNull(entityPlayer, "entityPlayer");
40+
this.entityPlayerWeakReference = new WeakReference<>(entityPlayer);
41+
}
42+
43+
public final EntityPlayer getPlayer() {
44+
return this.entityPlayerWeakReference.get();
45+
}
46+
47+
public abstract boolean hasSelection();
48+
49+
public World getSelectionWorld() {
50+
if (!this.hasSelection()) return null;
51+
EntityPlayer entityPlayer = this.getPlayer();
52+
return entityPlayer == null ? null :
53+
entityPlayer.worldObj;
54+
}
55+
56+
public abstract int getX1();
57+
58+
public abstract int getX2();
59+
60+
public abstract int getY1();
61+
62+
public abstract int getY2();
63+
64+
public abstract int getZ1();
65+
66+
public abstract int getZ2();
67+
68+
public int getMinX() {
69+
return Math.min(this.getX1(), this.getX2());
70+
}
71+
72+
public int getMaxX() {
73+
return Math.max(this.getX1(), this.getX2());
74+
}
75+
76+
public int getMinY() {
77+
return Math.min(this.getY1(), this.getY2());
78+
}
79+
80+
public int getMaxY() {
81+
return Math.max(this.getY1(), this.getY2());
82+
}
83+
84+
public int getMinZ() {
85+
return Math.min(this.getZ1(), this.getZ2());
86+
}
87+
88+
public int getMaxZ() {
89+
return Math.max(this.getZ1(), this.getZ2());
90+
}
91+
92+
public long getSelectionSize() {
93+
if (!this.hasSelection()) return 0;
94+
return (Math.abs(this.getX1() - this.getX2()) + 1L) *
95+
(Math.abs(this.getY1() - this.getY2()) + 1L) *
96+
(Math.abs(this.getZ1() - this.getZ2()) + 1L);
97+
}
98+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2023-2025 Fox2Code
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package com.fox2code.foxloader.selection;
25+
26+
import com.fox2code.foxloader.event.FoxLoaderEvents;
27+
import com.fox2code.foxloader.loader.ModLoader;
28+
import net.minecraft.common.entity.player.EntityPlayer;
29+
30+
import java.util.Objects;
31+
32+
public abstract class PlayerSelectionProvider {
33+
private static boolean initialized;
34+
private static PlayerSelectionProvider IMPLEMENTATION;
35+
36+
public static PlayerSelectionProvider getImplementation() {
37+
if (!ModLoader.areAllModsFullyLoaded()) {
38+
throw new IllegalStateException("Cannot get the current implementation before the game loaded.");
39+
}
40+
return IMPLEMENTATION;
41+
}
42+
43+
public static void setImplementation(PlayerSelectionProvider implementation) {
44+
if (ModLoader.areAllModsFullyLoaded()) {
45+
throw new IllegalStateException("Cannot change the implementation after the game has already started.");
46+
}
47+
Objects.requireNonNull(implementation);
48+
if (IMPLEMENTATION != null && IMPLEMENTATION != implementation) {
49+
throw new IllegalStateException("An alternative implementation already has been registered");
50+
}
51+
IMPLEMENTATION = implementation;
52+
}
53+
54+
public static void initialize() {
55+
if (initialized || !ModLoader.areAllModsFullyLoaded()) {
56+
throw new IllegalStateException("Only FoxLoader can call \"initialize()\"");
57+
}
58+
initialized = true;
59+
if (IMPLEMENTATION == null) {
60+
IMPLEMENTATION = new PlayerSelectionProviderFallback();
61+
FoxLoaderEvents.INSTANCE.registerEvents(IMPLEMENTATION);
62+
}
63+
}
64+
65+
public abstract PlayerSelection getPlayerSelection(EntityPlayer entityPlayer);
66+
}

0 commit comments

Comments
 (0)