This commit is contained in:
parent
cc89a22c53
commit
f3d9ec1ef6
8 changed files with 240 additions and 75 deletions
10
README.md
10
README.md
|
|
@ -4,6 +4,16 @@ which was originally for 1.20.1. I've ported the mod to 1.21.8, but
|
|||
there's still a major bug, which is if you're using the powered jetback in quirk armor,
|
||||
it won't show it on your player model.
|
||||
|
||||
|
||||
This version also adds hover flying and creative flying.
|
||||
Hover is by default bound to H, and creative fly is bound by default to J.
|
||||
|
||||
| Jetpack type | Hover | Creative |
|
||||
|-------------- |------- |---------- |
|
||||
| Basic | ❌ | ❌ |
|
||||
| Advanced | ✅ | ❌ |
|
||||
| Industrial | ✅ | ✅ |
|
||||
|
||||
# Powered Jetpacks
|
||||
A simple fabric mod about jetpacks powered with E energy.
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ maven_group=konhaiii.powered_jetpacks
|
|||
archives_base_name=powered_jetpacks
|
||||
|
||||
# Dependencies
|
||||
energy_version=4.2.0
|
||||
energy_version=4.2.1
|
||||
trinkets_version=3.11.0-1.21.6
|
||||
fabric_version=0.134.0+1.21.8
|
||||
cca_version=7.0.0-beta.1
|
||||
|
|
@ -1,27 +1,134 @@
|
|||
package konhaiii.powered_jetpacks;
|
||||
|
||||
import konhaiii.powered_jetpacks.hud.JetpackHUD;
|
||||
import konhaiii.powered_jetpacks.item.special.JetpackItem;
|
||||
import konhaiii.powered_jetpacks.models.JetpackModel;
|
||||
import konhaiii.powered_jetpacks.renderers.JetpackRenderer;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityFeatureRendererRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.hud.HudElementRegistry;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.hud.VanillaHudElements;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.registry.tag.EntityTypeTags;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
|
||||
public class PoweredJetpacksClient implements ClientModInitializer {
|
||||
public static KeyBinding hoverKeybinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
||||
"key.powered_jetpack.hover",
|
||||
InputUtil.Type.KEYSYM,
|
||||
GLFW.GLFW_KEY_H,
|
||||
"category.powered_jetpack"
|
||||
));
|
||||
|
||||
public static KeyBinding creativeKeybinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
||||
"key.powered_jetpack.creative",
|
||||
InputUtil.Type.KEYSYM,
|
||||
GLFW.GLFW_KEY_J,
|
||||
"category.powered_jetpack"
|
||||
));
|
||||
|
||||
public static boolean toggledHover = false;
|
||||
public static boolean toggledCreative = false;
|
||||
|
||||
public static ItemStack getJetpack(ClientPlayerEntity player) {
|
||||
ItemStack chestStack = player.getEquippedStack(EquipmentSlot.CHEST);
|
||||
ItemStack backStack = ItemStack.EMPTY;
|
||||
|
||||
if (PoweredJetpacks.isTrinketsLoaded) {
|
||||
try {
|
||||
Class<?> optionalClass = Class.forName("konhaiii.powered_jetpacks.compat.TrinketsServer");
|
||||
Method getBackStackMethod = optionalClass.getMethod("getBackStack", LivingEntity.class);
|
||||
backStack = (ItemStack) getBackStackMethod.invoke(null, player);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
|
||||
IllegalAccessException e) {
|
||||
PoweredJetpacks.LOGGER.error("ClientPlayerEntityMixin: Could not load Trinkets compat class.");
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack jetpackStack = ItemStack.EMPTY;
|
||||
if (isValidJetpack(chestStack)) {
|
||||
jetpackStack = chestStack;
|
||||
} else if (isValidJetpack(backStack)) {
|
||||
jetpackStack = backStack;
|
||||
}
|
||||
|
||||
|
||||
return jetpackStack;
|
||||
}
|
||||
@Unique
|
||||
private static boolean isValidJetpack(ItemStack stack) {
|
||||
if (stack.getItem() instanceof JetpackItem jetpack) {
|
||||
if (jetpack.getEnergyCost() <= 0) {
|
||||
return true;
|
||||
}
|
||||
return jetpack.getStoredEnergy(stack) > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ItemTooltipCallback.EVENT.register(new StackToolTipHandler());
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
while (creativeKeybinding.wasPressed()) {
|
||||
if (client.player != null) {
|
||||
ItemStack stack = getJetpack(client.player);
|
||||
if (!stack.isEmpty() && ((JetpackItem)stack.getItem()).allowCreative) {
|
||||
if (toggledHover) {
|
||||
toggledHover = false;
|
||||
client.player.setNoGravity(toggledHover);
|
||||
}
|
||||
|
||||
toggledCreative = !toggledCreative;
|
||||
if (!toggledCreative) {
|
||||
client.player.getAbilities().allowFlying = false;
|
||||
client.player.getAbilities().flying = false;
|
||||
} else {
|
||||
client.player.getAbilities().allowFlying = true;
|
||||
client.player.getAbilities().flying = true;
|
||||
client.player.sendAbilitiesUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
while (hoverKeybinding.wasPressed()) {
|
||||
if (client.player != null) {
|
||||
ItemStack stack = getJetpack(client.player);
|
||||
if (!stack.isEmpty() && ((JetpackItem)stack.getItem()).allowHover) {
|
||||
if (toggledCreative) {
|
||||
toggledCreative = false;
|
||||
client.player.getAbilities().allowFlying = false;
|
||||
client.player.getAbilities().flying = false;
|
||||
}
|
||||
|
||||
toggledHover = !toggledHover;
|
||||
client.player.setNoGravity(toggledHover);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
LivingEntityFeatureRendererRegistrationCallback.EVENT.register(
|
||||
(entityType, entityRenderer, registrationHelper, context) -> {
|
||||
if (entityRenderer != null && entityType == EntityType.PLAYER) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package konhaiii.powered_jetpacks.hud;
|
||||
|
||||
import konhaiii.powered_jetpacks.PoweredJetpacks;
|
||||
import konhaiii.powered_jetpacks.PoweredJetpacksClient;
|
||||
import konhaiii.powered_jetpacks.item.special.JetpackItem;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.hud.HudElement;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.hud.HudElementRegistry;
|
||||
|
|
@ -59,8 +60,22 @@ public class JetpackHUD implements HudElement {
|
|||
TextRenderer textRenderer = client.textRenderer;
|
||||
int percentage = percentage(energy, maxEnergy);
|
||||
String energyText = translate("hud.powered_jetpacks.jetpack_power").concat(String.valueOf(percentage)).concat("%");
|
||||
|
||||
drawContext.drawTextWithShadow(textRenderer, energyText, 10, 10, 0xFFFFFFFF);
|
||||
|
||||
String hoverStatus = PoweredJetpacksClient.toggledHover ? "ON" : "OFF";
|
||||
String creativeStatus = PoweredJetpacksClient.toggledCreative ? "ON" : "OFF";
|
||||
|
||||
if(!jetpack.allowCreative) {
|
||||
creativeStatus = "DISABLED";
|
||||
}
|
||||
if(!jetpack.allowHover) {
|
||||
hoverStatus = "DISABLED";
|
||||
}
|
||||
|
||||
if(jetpack.allowHover || jetpack.allowCreative) {
|
||||
String statusText = translate("hud.powered_jetpacks.status", hoverStatus, creativeStatus);
|
||||
drawContext.drawTextWithShadow(textRenderer, statusText, 10, 20, 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,11 @@
|
|||
package konhaiii.powered_jetpacks.mixin.client;
|
||||
|
||||
import konhaiii.powered_jetpacks.PoweredJetpacks;
|
||||
import konhaiii.powered_jetpacks.PoweredJetpacksClient;
|
||||
import konhaiii.powered_jetpacks.item.special.JetpackItem;
|
||||
import konhaiii.powered_jetpacks.packet.JetpackPacket;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
|
@ -17,9 +13,6 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@Mixin(ClientPlayerEntity.class)
|
||||
public abstract class ClientPlayerEntityMixin {
|
||||
@Unique
|
||||
|
|
@ -28,42 +21,73 @@ public abstract class ClientPlayerEntityMixin {
|
|||
@Inject(method = "tick", at = @At("HEAD"))
|
||||
private void onTick(CallbackInfo ci) {
|
||||
ClientPlayerEntity player = (ClientPlayerEntity) (Object) this;
|
||||
if (player.input.playerInput.jump()) {
|
||||
ItemStack chestStack = player.getEquippedStack(EquipmentSlot.CHEST);
|
||||
ItemStack backStack = ItemStack.EMPTY;
|
||||
|
||||
if (PoweredJetpacks.isTrinketsLoaded) {
|
||||
try {
|
||||
Class<?> optionalClass = Class.forName("konhaiii.powered_jetpacks.compat.TrinketsServer");
|
||||
Method getBackStackMethod = optionalClass.getMethod("getBackStack", LivingEntity.class);
|
||||
backStack = (ItemStack) getBackStackMethod.invoke(null, player);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
|
||||
IllegalAccessException e) {
|
||||
PoweredJetpacks.LOGGER.error("ClientPlayerEntityMixin: Could not load Trinkets compat class.");
|
||||
}
|
||||
}
|
||||
ItemStack jetpackStack = PoweredJetpacksClient.getJetpack(player);
|
||||
|
||||
ItemStack jetpackStack = null;
|
||||
if (isValidJetpack(chestStack)) {
|
||||
jetpackStack = chestStack;
|
||||
} else if (isValidJetpack(backStack)) {
|
||||
jetpackStack = backStack;
|
||||
}
|
||||
|
||||
if (jetpackStack != null) {
|
||||
if (!jetpackStack.isEmpty()) {
|
||||
JetpackPacket packet;
|
||||
|
||||
JetpackItem jetpack = (JetpackItem) jetpackStack.getItem();
|
||||
if (PoweredJetpacksClient.toggledCreative && !jetpack.allowCreative) {
|
||||
PoweredJetpacksClient.toggledCreative = false;
|
||||
player.getAbilities().allowFlying = false;
|
||||
player.getAbilities().flying = false;
|
||||
}
|
||||
|
||||
if (PoweredJetpacksClient.toggledHover && !jetpack.allowHover) {
|
||||
PoweredJetpacksClient.toggledHover = false;
|
||||
player.setNoGravity(false);
|
||||
}
|
||||
|
||||
Vec3d velocity = player.getVelocity();
|
||||
|
||||
boolean sendPacket = PoweredJetpacksClient.toggledCreative && !player.isOnGround();
|
||||
|
||||
if (PoweredJetpacksClient.toggledHover && jetpack.allowHover && !player.isOnGround()) {
|
||||
double vertical = 0.0;
|
||||
double hoverUpSpeed = 0.5;
|
||||
double hoverDownSpeed = 0.4;
|
||||
double horizontalSpeed = 0.35;
|
||||
double inertia = 0.25;
|
||||
|
||||
if (player.input.playerInput.jump()) {
|
||||
vertical += hoverUpSpeed;
|
||||
} else if (player.input.playerInput.sneak()) {
|
||||
vertical -= hoverDownSpeed;
|
||||
} else {
|
||||
vertical = 0.0;
|
||||
}
|
||||
|
||||
Vec3d lookDir = player.getRotationVector().normalize();
|
||||
Vec3d strafeDir = new Vec3d(-lookDir.z, 0, lookDir.x).normalize();
|
||||
Vec3d move = Vec3d.ZERO;
|
||||
|
||||
if (player.input.playerInput.forward()) move = move.add(lookDir);
|
||||
if (player.input.playerInput.backward()) move = move.subtract(lookDir);
|
||||
if (player.input.playerInput.right()) move = move.add(strafeDir);
|
||||
if (player.input.playerInput.left()) move = move.subtract(strafeDir);
|
||||
|
||||
if (move.lengthSquared() > 0) {
|
||||
move = move.normalize().multiply(horizontalSpeed);
|
||||
}
|
||||
|
||||
Vec3d targetVel = new Vec3d(move.x, vertical, move.z);
|
||||
Vec3d currentVel = player.getVelocity();
|
||||
|
||||
Vec3d blended = currentVel.multiply(inertia).add(targetVel.multiply(1 - inertia));
|
||||
player.setVelocity(blended);
|
||||
sendPacket = true;
|
||||
} else if (player.input.playerInput.jump()) {
|
||||
float horizontalBoost = jetpack.getFlightSpeed();
|
||||
player.setVelocity(
|
||||
velocity.x + (player.getRotationVector().x * horizontalBoost),
|
||||
jetpack.addToVerticalVelocity(player.getVelocity().y),
|
||||
velocity.z + (player.getRotationVector().z * horizontalBoost)
|
||||
);
|
||||
player.setVelocity(velocity.x + (player.getRotationVector().x * horizontalBoost), jetpack.addToVerticalVelocity(player.getVelocity().y), velocity.z + (player.getRotationVector().z * horizontalBoost));
|
||||
sendPacket = true;
|
||||
}
|
||||
|
||||
player.fallDistance = 0;
|
||||
|
||||
if (sendPacket) {
|
||||
soundCounter++;
|
||||
|
||||
if (soundCounter >= 8) {
|
||||
packet = new JetpackPacket(true);
|
||||
soundCounter = 0;
|
||||
|
|
@ -71,21 +95,21 @@ public abstract class ClientPlayerEntityMixin {
|
|||
packet = new JetpackPacket(false);
|
||||
}
|
||||
ClientPlayNetworking.send(packet);
|
||||
} else if (soundCounter != 8) {
|
||||
}
|
||||
} else {
|
||||
if (PoweredJetpacksClient.toggledCreative) {
|
||||
PoweredJetpacksClient.toggledCreative = false;
|
||||
player.getAbilities().allowFlying = false;
|
||||
player.getAbilities().flying = false;
|
||||
}
|
||||
|
||||
if (PoweredJetpacksClient.toggledHover) {
|
||||
PoweredJetpacksClient.toggledHover = false;
|
||||
player.setNoGravity(false);
|
||||
}
|
||||
}
|
||||
if (soundCounter != 8) {
|
||||
soundCounter = 8;
|
||||
}
|
||||
} else if (soundCounter != 8) {
|
||||
soundCounter = 8;
|
||||
}
|
||||
}
|
||||
@Unique
|
||||
private boolean isValidJetpack(ItemStack stack) {
|
||||
if (stack.getItem() instanceof JetpackItem jetpack) {
|
||||
if (jetpack.getEnergyCost() <= 0) {
|
||||
return true;
|
||||
}
|
||||
return jetpack.getStoredEnergy(stack) > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -35,19 +35,19 @@ public class ModItems {
|
|||
|
||||
public static final Item BASIC_JETPACK = register(
|
||||
"basic_jetpack",
|
||||
settings -> new JetpackItem(settings, PoweredJetpacks.config.basicJetpackMaxEnergy, PoweredJetpacks.config.basicJetpackInputEnergy, PoweredJetpacks.config.basicJetpackVerticalSpeed, PoweredJetpacks.config.basicJetpackHorizontalSpeed, PoweredJetpacks.config.basicJetpackEnergyCost),
|
||||
settings -> new JetpackItem(settings, PoweredJetpacks.config.basicJetpackMaxEnergy, PoweredJetpacks.config.basicJetpackInputEnergy, PoweredJetpacks.config.basicJetpackVerticalSpeed, PoweredJetpacks.config.basicJetpackHorizontalSpeed, PoweredJetpacks.config.basicJetpackEnergyCost, false, false),
|
||||
new Item.Settings().armor(ArmorMaterials.IRON, EquipmentType.CHESTPLATE)
|
||||
);
|
||||
|
||||
public static final Item ADVANCED_JETPACK = register(
|
||||
"advanced_jetpack",
|
||||
settings -> new JetpackItem(settings, PoweredJetpacks.config.advancedJetpackMaxEnergy, PoweredJetpacks.config.advancedJetpackInputEnergy, PoweredJetpacks.config.advancedJetpackVerticalSpeed, PoweredJetpacks.config.advancedJetpackHorizontalSpeed, PoweredJetpacks.config.advancedJetpackEnergyCost),
|
||||
settings -> new JetpackItem(settings, PoweredJetpacks.config.advancedJetpackMaxEnergy, PoweredJetpacks.config.advancedJetpackInputEnergy, PoweredJetpacks.config.advancedJetpackVerticalSpeed, PoweredJetpacks.config.advancedJetpackHorizontalSpeed, PoweredJetpacks.config.advancedJetpackEnergyCost, true, false),
|
||||
new Item.Settings().armor(ArmorMaterials.DIAMOND, EquipmentType.CHESTPLATE)
|
||||
);
|
||||
|
||||
public static final Item INDUSTRIAL_JETPACK = register(
|
||||
"industrial_jetpack",
|
||||
settings -> new JetpackItem(settings, PoweredJetpacks.config.industrialJetpackMaxEnergy, PoweredJetpacks.config.industrialJetpackInputEnergy, PoweredJetpacks.config.industrialJetpackVerticalSpeed, PoweredJetpacks.config.industrialJetpackHorizontalSpeed, PoweredJetpacks.config.industrialJetpackEnergyCost),
|
||||
settings -> new JetpackItem(settings, PoweredJetpacks.config.industrialJetpackMaxEnergy, PoweredJetpacks.config.industrialJetpackInputEnergy, PoweredJetpacks.config.industrialJetpackVerticalSpeed, PoweredJetpacks.config.industrialJetpackHorizontalSpeed, PoweredJetpacks.config.industrialJetpackEnergyCost, true, true),
|
||||
new Item.Settings().armor(ArmorMaterials.NETHERITE, EquipmentType.CHESTPLATE)
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,14 +21,19 @@ public class JetpackItem extends Item implements SimpleEnergyItem {
|
|||
private final float flightPower;
|
||||
private final float flightSpeed;
|
||||
private final int energyCost;
|
||||
public final boolean allowHover;
|
||||
public final boolean allowCreative;
|
||||
|
||||
public JetpackItem(Settings settings, int maxEnergy, int inputEnergy, float flightPower, float flightSpeed, int energyCost) {
|
||||
public JetpackItem(Settings settings, int maxEnergy, int inputEnergy, float flightPower, float flightSpeed, int energyCost, boolean allowHover, boolean allowCreative) {
|
||||
super(settings.maxCount(1));
|
||||
this.maxEnergy = maxEnergy;
|
||||
this.inputEnergy = inputEnergy;
|
||||
this.flightPower = flightPower;
|
||||
this.flightSpeed = flightSpeed;
|
||||
this.energyCost = energyCost;
|
||||
this.allowHover = allowHover;
|
||||
this.allowCreative = allowCreative;
|
||||
|
||||
DispenserBlock.registerBehavior(this, DispenserBehavior.NOOP);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,5 +8,9 @@
|
|||
"tooltip.powered_jetpacks.input_rate": "Input Rate",
|
||||
"tooltip.powered_jetpacks.output_rate": "Output Rate",
|
||||
"tooltip.powered_jetpacks.transfer_rate": "Transfer Rate",
|
||||
"hud.powered_jetpacks.jetpack_power": "Jetpack Power: "
|
||||
"hud.powered_jetpacks.jetpack_power": "Jetpack Power: ",
|
||||
"key.powered_jetpack.hover": "Hover",
|
||||
"key.powered_jetpack.creative": "Creative Fly",
|
||||
"category.powered_jetpack": "Powered Jetpacks",
|
||||
"hud.powered_jetpacks.status": "HOVER: %s, CREATIVE: %s"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue