diff --git a/README.md b/README.md
index c2975ec3..452d0cac 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ The freecam bind can also be used in conjunction with any of the hotbar keys (`F
|Name|Description|Default Value|
|-|-|-|
|Flight Mode|The type of flight used by freecam.
**Options:**
- `DEFAULT` Static velocity with no drifting
- `CREATIVE` Vanilla creative flight|`DEFAULT`|
+|Interaction Mode|The source of block/entity interactions.
**Options:**
- `FREECAM` Interactions come from the freecamera
- `PLAYER` Interactions come from the player|`FREECAM`|
|Horizontal Speed|The horizontal speed of freecam.|`1.0`|
|Vertical Speed|The vertical speed of freecam.|`1.0`|
|No Clip|Whether you can travel through blocks in freecam.|`true`|
diff --git a/gradle.properties b/gradle.properties
index 9c7fafbc..2563b113 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,7 +6,7 @@ minecraft_version=1.19
yarn_mappings=1.19+build.4
loader_version=0.14.8
# Mod Properties
-mod_version=1.1.2
+mod_version=1.1.3
maven_group=net.xolt
archives_base_name=freecam
# Dependencies
diff --git a/src/main/java/net/xolt/freecam/config/ModConfig.java b/src/main/java/net/xolt/freecam/config/ModConfig.java
index 7df51422..a095211c 100644
--- a/src/main/java/net/xolt/freecam/config/ModConfig.java
+++ b/src/main/java/net/xolt/freecam/config/ModConfig.java
@@ -23,6 +23,10 @@ public static void init() {
@ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
public FlightMode flightMode = FlightMode.DEFAULT;
+ @Comment("The source of block/entity interactions.")
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ public InteractionMode interactionMode = InteractionMode.FREECAM;
+
@Comment("The horizontal speed of freecam.")
public double horizontalSpeed = 1.0;
@@ -35,7 +39,7 @@ public static void init() {
@Comment("Prevents player movement while freecam is active.\nWARNING: Multiplayer usage not advised.")
public boolean freezePlayer = false;
- @Comment("Whether you can interact with blocks/entities in freecam.\nWARNING: Multiplayer usage not advised.")
+ @Comment("Whether the freecamera can interact with blocks/entities.\nWARNING: Multiplayer usage not advised.")
public boolean allowInteract = false;
@Comment("Disables freecam when damage is received.")
@@ -67,4 +71,19 @@ public String getKey() {
return name;
}
}
+
+ public enum InteractionMode implements SelectionListEntry.Translatable {
+ FREECAM("Freecam"),
+ PLAYER("Player");
+
+ private final String name;
+
+ InteractionMode(String name) {
+ this.name = name;
+ }
+
+ public String getKey() {
+ return name;
+ }
+ }
}
diff --git a/src/main/java/net/xolt/freecam/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/net/xolt/freecam/mixins/ClientPlayNetworkHandlerMixin.java
index c6341b78..0b7450de 100644
--- a/src/main/java/net/xolt/freecam/mixins/ClientPlayNetworkHandlerMixin.java
+++ b/src/main/java/net/xolt/freecam/mixins/ClientPlayNetworkHandlerMixin.java
@@ -10,11 +10,12 @@
@Mixin(ClientPlayNetworkHandler.class)
public class ClientPlayNetworkHandlerMixin {
- // Disables freecam when the player respawns.
+ // Disables freecam when the player respawns/switches dimensions.
@Inject(method = "onPlayerRespawn", at = @At("HEAD"))
private void onPlayerRespawn(CallbackInfo ci) {
if (Freecam.isEnabled()) {
Freecam.toggle();
}
+ Freecam.clearPersistentCameras();
}
}
diff --git a/src/main/java/net/xolt/freecam/mixins/ClientPlayerInteractionManagerMixin.java b/src/main/java/net/xolt/freecam/mixins/ClientPlayerInteractionManagerMixin.java
index 642f3d4b..8e2ff238 100644
--- a/src/main/java/net/xolt/freecam/mixins/ClientPlayerInteractionManagerMixin.java
+++ b/src/main/java/net/xolt/freecam/mixins/ClientPlayerInteractionManagerMixin.java
@@ -24,7 +24,7 @@ public class ClientPlayerInteractionManagerMixin {
// Prevents interacting with blocks when allowInteract is disabled.
@Inject(method = "interactBlock", at = @At("HEAD"), cancellable = true)
private void onInteractBlock(ClientPlayerEntity player, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable cir) {
- if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.allowInteract) {
+ if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.interactionMode.equals(ModConfig.InteractionMode.PLAYER) && !ModConfig.INSTANCE.allowInteract) {
cir.setReturnValue(ActionResult.PASS);
}
}
@@ -32,7 +32,7 @@ private void onInteractBlock(ClientPlayerEntity player, Hand hand, BlockHitResul
// Prevents interacting with entities when allowInteract is disabled, and prevents interacting with self.
@Inject(method = "interactEntity", at = @At("HEAD"), cancellable = true)
private void onInteractEntity(PlayerEntity player, Entity entity, Hand hand, CallbackInfoReturnable cir) {
- if (entity.equals(MC.player) || (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.allowInteract)) {
+ if (entity.equals(MC.player) || (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.interactionMode.equals(ModConfig.InteractionMode.PLAYER) && !ModConfig.INSTANCE.allowInteract)) {
cir.setReturnValue(ActionResult.PASS);
}
}
@@ -40,7 +40,7 @@ private void onInteractEntity(PlayerEntity player, Entity entity, Hand hand, Cal
// Prevents interacting with entities when allowInteract is disabled, and prevents interacting with self.
@Inject(method = "interactEntityAtLocation", at = @At("HEAD"), cancellable = true)
private void onInteractEntityAtLocation(PlayerEntity player, Entity entity, EntityHitResult hitResult, Hand hand, CallbackInfoReturnable cir) {
- if (entity.equals(MC.player) || (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.allowInteract)) {
+ if (entity.equals(MC.player) || (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.interactionMode.equals(ModConfig.InteractionMode.PLAYER) && !ModConfig.INSTANCE.allowInteract)) {
cir.setReturnValue(ActionResult.PASS);
}
}
diff --git a/src/main/java/net/xolt/freecam/mixins/GameRendererMixin.java b/src/main/java/net/xolt/freecam/mixins/GameRendererMixin.java
index 87429f75..7237a643 100644
--- a/src/main/java/net/xolt/freecam/mixins/GameRendererMixin.java
+++ b/src/main/java/net/xolt/freecam/mixins/GameRendererMixin.java
@@ -18,15 +18,15 @@ public class GameRendererMixin {
// Disables block outlines when allowInteract is disabled.
@Inject(method = "shouldRenderBlockOutline", at = @At("HEAD"), cancellable = true)
private void onShouldRenderBlockOutline(CallbackInfoReturnable cir) {
- if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.allowInteract) {
+ if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.interactionMode.equals(ModConfig.InteractionMode.PLAYER) && !ModConfig.INSTANCE.allowInteract) {
cir.setReturnValue(false);
}
}
- // Makes mouse clicks come from the player rather than the freecam entity when player control is enabled.
+ // Makes mouse clicks come from the player rather than the freecam entity when player control is enabled or if interaction mode is set to player.
@ModifyVariable(method = "updateTargetedEntity", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;"))
private Entity onUpdateTargetedEntity(Entity entity) {
- if (Freecam.isEnabled() && Freecam.isPlayerControlEnabled()) {
+ if (Freecam.isEnabled() && (Freecam.isPlayerControlEnabled() || ModConfig.INSTANCE.interactionMode.equals(ModConfig.InteractionMode.PLAYER))) {
return MC.player;
}
return entity;
diff --git a/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java b/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java
index 9b571015..601e9f12 100644
--- a/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java
+++ b/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java
@@ -32,7 +32,7 @@ private void onTick(CallbackInfo ci) {
// Prevents attacks when allowInteract is disabled.
@Inject(method = "doAttack", at = @At("HEAD"), cancellable = true)
private void onDoAttack(CallbackInfoReturnable cir) {
- if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.allowInteract) {
+ if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.interactionMode.equals(ModConfig.InteractionMode.PLAYER) && !ModConfig.INSTANCE.allowInteract) {
cir.cancel();
}
}
@@ -40,7 +40,7 @@ private void onDoAttack(CallbackInfoReturnable cir) {
// Prevents item pick when allowInteract is disabled.
@Inject(method = "doItemPick", at = @At("HEAD"), cancellable = true)
private void onDoItemPick(CallbackInfo ci) {
- if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.allowInteract) {
+ if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.interactionMode.equals(ModConfig.InteractionMode.PLAYER) && !ModConfig.INSTANCE.allowInteract) {
ci.cancel();
}
}
@@ -48,7 +48,7 @@ private void onDoItemPick(CallbackInfo ci) {
// Prevents block breaking when allowInteract is disabled.
@Inject(method = "handleBlockBreaking", at = @At("HEAD"), cancellable = true)
private void onHandleBlockBreaking(CallbackInfo ci) {
- if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.allowInteract) {
+ if (Freecam.isEnabled() && !Freecam.isPlayerControlEnabled() && !ModConfig.INSTANCE.interactionMode.equals(ModConfig.InteractionMode.PLAYER) && !ModConfig.INSTANCE.allowInteract) {
ci.cancel();
}
}
diff --git a/src/main/resources/assets/freecam/lang/en_us.json b/src/main/resources/assets/freecam/lang/en_us.json
index 6c17ac03..9602e0b8 100644
--- a/src/main/resources/assets/freecam/lang/en_us.json
+++ b/src/main/resources/assets/freecam/lang/en_us.json
@@ -8,6 +8,7 @@
"msg.freecam.disablePersistent": "Closing camera #",
"text.autoconfig.freecam.title": "Freecam Options",
"text.autoconfig.freecam.option.flightMode": "Flight Mode",
+ "text.autoconfig.freecam.option.interactionMode": "Interaction Mode",
"text.autoconfig.freecam.option.horizontalSpeed": "Horizontal Speed",
"text.autoconfig.freecam.option.verticalSpeed": "Vertical Speed",
"text.autoconfig.freecam.option.noclip": "No Clip",