Skip to content

Commit 0dec601

Browse files
authored
Merge pull request #126 from MattSturgeon/main-cleanup
General cleanup; keypress handling; tripod storage; FreecamPosition
2 parents 095531f + b9c1b33 commit 0dec601

12 files changed

Lines changed: 225 additions & 112 deletions

File tree

common/src/main/java/net/xolt/freecam/Freecam.java

Lines changed: 93 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,40 @@
77
import net.minecraft.client.player.Input;
88
import net.minecraft.client.player.KeyboardInput;
99
import net.minecraft.network.chat.Component;
10+
import net.minecraft.world.entity.Entity;
1011
import net.minecraft.world.level.ChunkPos;
1112
import net.xolt.freecam.config.ModConfig;
13+
import net.xolt.freecam.tripod.TripodRegistry;
14+
import net.xolt.freecam.tripod.TripodSlot;
1215
import net.xolt.freecam.util.FreeCamera;
1316
import net.xolt.freecam.util.FreecamPosition;
1417
import net.xolt.freecam.variant.api.BuildVariant;
15-
import org.lwjgl.glfw.GLFW;
16-
17-
import java.util.HashMap;
18+
import org.jetbrains.annotations.Nullable;
1819

1920
import static net.xolt.freecam.config.ModBindings.*;
2021

2122
public class Freecam {
2223

2324
public static final Minecraft MC = Minecraft.getInstance();
2425
public static final String MOD_ID = "freecam";
26+
private static final long TOGGLE_KEY_MAX_TICKS = 10;
2527

2628
private static boolean freecamEnabled = false;
2729
private static boolean tripodEnabled = false;
2830
private static boolean playerControlEnabled = false;
2931
private static boolean disableNextTick = false;
30-
private static Integer activeTripod = null;
32+
private static boolean toggleKeyUsedWhileHeld = false;
33+
private static long toggleKeyHeldTicks = 0;
34+
private static final TripodRegistry tripods = new TripodRegistry();
35+
private static TripodSlot activeTripod = TripodSlot.NONE;
3136
private static FreeCamera freeCamera;
32-
private static HashMap<Integer, FreecamPosition> overworld_tripods = new HashMap<>();
33-
private static HashMap<Integer, FreecamPosition> nether_tripods = new HashMap<>();
34-
private static HashMap<Integer, FreecamPosition> end_tripods = new HashMap<>();
3537
private static CameraType rememberedF5 = null;
3638

3739
public static void preTick(Minecraft mc) {
3840
if (isEnabled()) {
3941
// Disable if the previous tick asked us to
40-
if (disableNextTick()) {
42+
if (disableNextTick) {
4143
toggle();
42-
disableNextTick = false;
4344
}
4445

4546
// Prevent player from being controlled when freecam is enabled
@@ -51,35 +52,49 @@ public static void preTick(Minecraft mc) {
5152

5253
mc.gameRenderer.setRenderHand(ModConfig.INSTANCE.visual.showHand);
5354
}
55+
disableNextTick = false;
5456
}
5557

5658
public static void postTick(Minecraft mc) {
57-
if (KEY_TRIPOD_RESET.isPressed()) {
58-
for (KeyMapping hotbarKey : mc.options.keyHotbarSlots) {
59-
while (hotbarKey.consumeClick()) {
60-
resetCamera(hotbarKey.getDefaultKey().getValue());
61-
while (KEY_TRIPOD_RESET.wasPressed()) {}
59+
if (KEY_TOGGLE.isDown()) {
60+
// Count held ticks, so we can toggle on release
61+
toggleKeyHeldTicks++;
62+
KEY_TOGGLE.reset();
63+
64+
// Handle <toggle_key>+<hotbar_key> combos
65+
for (KeyMapping combo : mc.options.keyHotbarSlots) {
66+
while (combo.consumeClick()) {
67+
toggleTripod(TripodSlot.ofKeyCode(combo.getDefaultKey().getValue()));
68+
toggleKeyUsedWhileHeld = true;
6269
}
6370
}
6471
}
72+
// Check if toggle was pressed, and is now released
73+
else if (KEY_TOGGLE.consumeClick() || toggleKeyHeldTicks > 0) {
74+
// Only toggle if the key wasn't used (or held too long)
75+
if (!toggleKeyUsedWhileHeld && toggleKeyHeldTicks < TOGGLE_KEY_MAX_TICKS) {
76+
toggle();
77+
}
78+
// Reset state
79+
KEY_TOGGLE.reset();
80+
toggleKeyHeldTicks = 0;
81+
toggleKeyUsedWhileHeld = false;
82+
}
6583

66-
if (KEY_TOGGLE.isPressed()) {
67-
for (KeyMapping hotbarKey : mc.options.keyHotbarSlots) {
68-
while (hotbarKey.consumeClick()) {
69-
toggleTripod(hotbarKey.getDefaultKey().getValue());
70-
while (KEY_TOGGLE.wasPressed()) {}
84+
// Handle <reset_key>+<hotbar_key> combos
85+
if (KEY_TRIPOD_RESET.isDown()) {
86+
for (KeyMapping key : mc.options.keyHotbarSlots) {
87+
while (key.consumeClick()) {
88+
resetCamera(TripodSlot.ofKeyCode(key.getDefaultKey().getValue()));
7189
}
7290
}
73-
} else if (KEY_TOGGLE.wasPressed()) {
74-
toggle();
75-
while (KEY_TOGGLE.wasPressed()) {}
7691
}
7792

78-
while (KEY_PLAYER_CONTROL.wasPressed()) {
93+
while (KEY_PLAYER_CONTROL.consumeClick()) {
7994
switchControls();
8095
}
8196

82-
while (KEY_CONFIG_GUI.wasPressed()) {
97+
while (KEY_CONFIG_GUI.consumeClick()) {
8398
mc.setScreen(AutoConfig.getConfigScreen(ModConfig.class, mc.screen).get());
8499
}
85100
}
@@ -88,7 +103,7 @@ public static void onDisconnect() {
88103
if (isEnabled()) {
89104
toggle();
90105
}
91-
clearTripods();
106+
tripods.clear();
92107
}
93108

94109
public static void toggle() {
@@ -108,24 +123,24 @@ public static void toggle() {
108123
}
109124
}
110125

111-
private static void toggleTripod(Integer keyCode) {
112-
if (keyCode == null) {
126+
private static void toggleTripod(TripodSlot tripod) {
127+
if (tripod == TripodSlot.NONE) {
113128
return;
114129
}
115130

116131
if (tripodEnabled) {
117-
if (activeTripod.equals(keyCode)) {
132+
if (activeTripod == tripod) {
118133
onDisableTripod();
119134
tripodEnabled = false;
120135
} else {
121136
onDisableTripod();
122-
onEnableTripod(keyCode);
137+
onEnableTripod(tripod);
123138
}
124139
} else {
125140
if (freecamEnabled) {
126141
toggle();
127142
}
128-
onEnableTripod(keyCode);
143+
onEnableTripod(tripod);
129144
tripodEnabled = true;
130145
}
131146
if (!tripodEnabled) {
@@ -147,55 +162,53 @@ public static void switchControls() {
147162
playerControlEnabled = !playerControlEnabled;
148163
}
149164

150-
private static void onEnableTripod(int keyCode) {
165+
private static void onEnableTripod(TripodSlot tripod) {
151166
onEnable();
152167

153-
FreecamPosition position = getTripodsForDimension().get(keyCode);
168+
FreecamPosition position = tripods.get(tripod);
154169
boolean chunkLoaded = false;
155170
if (position != null) {
156171
ChunkPos chunkPos = position.getChunkPos();
157172
chunkLoaded = MC.level.getChunkSource().hasChunk(chunkPos.x, chunkPos.z);
158173
}
159174

160175
if (!chunkLoaded) {
161-
resetCamera(keyCode);
176+
resetCamera(tripod);
162177
position = null;
163178
}
164179

180+
freeCamera = new FreeCamera(-420 - tripod.ordinal());
165181
if (position == null) {
166-
freeCamera = new FreeCamera(-420 - (keyCode % GLFW.GLFW_KEY_0));
182+
moveToPlayer();
167183
} else {
168-
freeCamera = new FreeCamera(-420 - (keyCode % GLFW.GLFW_KEY_0), position);
184+
moveToPosition(position);
169185
}
170186

171187
freeCamera.spawn();
172188
MC.setCameraEntity(freeCamera);
173-
activeTripod = keyCode;
189+
activeTripod = tripod;
174190

175191
if (ModConfig.INSTANCE.notification.notifyTripod) {
176-
MC.player.displayClientMessage(Component.translatable("msg.freecam.openTripod").append("" + activeTripod % GLFW.GLFW_KEY_0), true);
192+
MC.player.displayClientMessage(Component.translatable("msg.freecam.openTripod", tripod), true);
177193
}
178194
}
179195

180196
private static void onDisableTripod() {
181-
getTripodsForDimension().put(activeTripod, new FreecamPosition(freeCamera));
197+
tripods.put(activeTripod, new FreecamPosition(freeCamera));
182198
onDisable();
183199

184200
if (MC.player != null) {
185201
if (ModConfig.INSTANCE.notification.notifyTripod) {
186-
MC.player.displayClientMessage(Component.translatable("msg.freecam.closeTripod").append("" + activeTripod % GLFW.GLFW_KEY_0), true);
202+
MC.player.displayClientMessage(Component.translatable("msg.freecam.closeTripod", activeTripod), true);
187203
}
188204
}
189-
activeTripod = null;
205+
activeTripod = TripodSlot.NONE;
190206
}
191207

192208
private static void onEnableFreecam() {
193209
onEnable();
194210
freeCamera = new FreeCamera(-420);
195-
freeCamera.applyPerspective(
196-
ModConfig.INSTANCE.visual.perspective,
197-
ModConfig.INSTANCE.collision.alwaysCheck || !(ModConfig.INSTANCE.collision.ignoreAll && BuildVariant.getInstance().cheatsPermitted())
198-
);
211+
moveToPlayer();
199212
freeCamera.spawn();
200213
MC.setCameraEntity(freeCamera);
201214

@@ -244,50 +257,57 @@ private static void onDisabled() {
244257
}
245258
}
246259

247-
private static void resetCamera(int keyCode) {
248-
if (tripodEnabled && activeTripod != null && activeTripod == keyCode && freeCamera != null) {
249-
freeCamera.copyPosition(MC.player);
260+
private static void resetCamera(TripodSlot tripod) {
261+
if (tripodEnabled && activeTripod != TripodSlot.NONE && activeTripod == tripod && freeCamera != null) {
262+
moveToPlayer();
250263
} else {
251-
getTripodsForDimension().put(keyCode, null);
264+
tripods.put(tripod, null);
252265
}
253266

254267
if (ModConfig.INSTANCE.notification.notifyTripod) {
255-
MC.player.displayClientMessage(Component.translatable("msg.freecam.tripodReset").append("" + keyCode % GLFW.GLFW_KEY_0), true);
268+
MC.player.displayClientMessage(Component.translatable("msg.freecam.tripodReset", tripod), true);
256269
}
257270
}
258271

259-
public static void clearTripods() {
260-
overworld_tripods = new HashMap<>();
261-
nether_tripods = new HashMap<>();
262-
end_tripods = new HashMap<>();
272+
public static void moveToEntity(@Nullable Entity entity) {
273+
if (freeCamera == null) {
274+
return;
275+
}
276+
if (entity == null) {
277+
moveToPlayer();
278+
return;
279+
}
280+
freeCamera.copyPosition(entity);
263281
}
264282

265-
public static FreeCamera getFreeCamera() {
266-
return freeCamera;
283+
public static void moveToPosition(@Nullable FreecamPosition position) {
284+
if (freeCamera == null) {
285+
return;
286+
}
287+
if (position == null) {
288+
moveToPlayer();
289+
return;
290+
}
291+
freeCamera.applyPosition(position);
267292
}
268293

269-
public static HashMap<Integer, FreecamPosition> getTripodsForDimension() {
270-
HashMap<Integer, FreecamPosition> result;
271-
switch (MC.level.dimensionTypeId().location().getPath()) {
272-
case "the_nether":
273-
result = nether_tripods;
274-
break;
275-
case "the_end":
276-
result = end_tripods;
277-
break;
278-
default:
279-
result = overworld_tripods;
280-
break;
281-
}
282-
return result;
294+
public static void moveToPlayer() {
295+
if (freeCamera == null) {
296+
return;
297+
}
298+
freeCamera.copyPosition(MC.player);
299+
freeCamera.applyPerspective(
300+
ModConfig.INSTANCE.visual.perspective,
301+
ModConfig.INSTANCE.collision.alwaysCheck || !(ModConfig.INSTANCE.collision.ignoreAll && BuildVariant.getInstance().cheatsPermitted())
302+
);
283303
}
284304

285-
public static boolean disableNextTick() {
286-
return disableNextTick;
305+
public static FreeCamera getFreeCamera() {
306+
return freeCamera;
287307
}
288308

289-
public static void setDisableNextTick(boolean damage) {
290-
disableNextTick = damage;
309+
public static void disableNextTick() {
310+
disableNextTick = true;
291311
}
292312

293313
public static boolean isEnabled() {

common/src/main/java/net/xolt/freecam/config/ModBindings.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import com.google.common.base.Supplier;
44
import com.google.common.base.Suppliers;
55
import com.mojang.blaze3d.platform.InputConstants;
6+
import net.minecraft.client.KeyMapping;
67
import org.jetbrains.annotations.NotNull;
78

89
import java.util.Arrays;
910
import java.util.Iterator;
1011
import java.util.Objects;
1112
import java.util.Spliterator;
1213
import java.util.function.Consumer;
13-
import net.minecraft.client.KeyMapping;
1414

1515
import static org.lwjgl.glfw.GLFW.GLFW_KEY_F4;
1616
import static org.lwjgl.glfw.GLFW.GLFW_KEY_UNKNOWN;
@@ -22,7 +22,7 @@ public enum ModBindings {
2222
KEY_TRIPOD_RESET("tripodReset"),
2323
KEY_CONFIG_GUI("configGui");
2424

25-
private final Supplier<KeyMapping> lazyBinding;
25+
private final Supplier<KeyMapping> lazyMapping;
2626

2727
ModBindings(String translationKey) {
2828
this(translationKey, InputConstants.Type.KEYSYM, GLFW_KEY_UNKNOWN);
@@ -37,26 +37,37 @@ public enum ModBindings {
3737
}
3838

3939
ModBindings(String translationKey, InputConstants.Type type, int code) {
40-
this.lazyBinding = Suppliers.memoize(() ->
40+
this.lazyMapping = Suppliers.memoize(() ->
4141
new KeyMapping("key.freecam." + translationKey, type, code, "category.freecam.freecam"));
4242
}
4343

4444
/**
4545
* @return the result of calling {@link KeyMapping#isDown()} on the represented {@link KeyMapping}.
4646
* @see KeyMapping#isDown()
4747
*/
48-
public boolean isPressed() {
48+
public boolean isDown() {
4949
return get().isDown();
5050
}
5151

5252
/**
5353
* @return the result of calling {@link KeyMapping#consumeClick()} on the represented {@link KeyMapping}.
5454
* @see KeyMapping#consumeClick()
5555
*/
56-
public boolean wasPressed() {
56+
public boolean consumeClick() {
5757
return get().consumeClick();
5858
}
5959

60+
/**
61+
* Reset whether the key was pressed.
62+
* <p>
63+
* Note: Cannot use {@link KeyMapping#release()} because it doesn't work as expected.
64+
*/
65+
@SuppressWarnings("StatementWithEmptyBody")
66+
public void reset() {
67+
final KeyMapping key = get();
68+
while (key.consumeClick()) {}
69+
}
70+
6071
/**
6172
* Lazily get the actual {@link KeyMapping} represented by this enum value.
6273
* <p>
@@ -65,7 +76,7 @@ public boolean wasPressed() {
6576
* @return the actual {@link KeyMapping}.
6677
*/
6778
public KeyMapping get() {
68-
return lazyBinding.get();
79+
return lazyMapping.get();
6980
}
7081

7182
/**

common/src/main/java/net/xolt/freecam/mixins/LivingEntityMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ private void onGetMovementSpeed(CallbackInfoReturnable<Float> cir) {
3232
private void onSetHealth(float health, CallbackInfo ci) {
3333
if (Freecam.isEnabled() && ModConfig.INSTANCE.utility.disableOnDamage && this.equals(MC.player)) {
3434
if (!MC.player.isCreative() && getHealth() > health) {
35-
Freecam.setDisableNextTick(true);
35+
Freecam.disableNextTick();
3636
}
3737
}
3838
}

0 commit comments

Comments
 (0)