Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions src/main/java/dev/doctor4t/wathe/client/WatheClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import dev.doctor4t.wathe.client.gui.TimeRenderer;
import dev.doctor4t.wathe.client.model.WatheModelLayers;
import dev.doctor4t.wathe.client.model.item.KnifeModelLoadingPlugin;
import dev.doctor4t.wathe.client.particle.HandParticle;
import dev.doctor4t.wathe.client.render.WatheRenderLayers;
import dev.doctor4t.wathe.client.render.block_entity.PlateBlockEntityRenderer;
import dev.doctor4t.wathe.client.render.block_entity.SmallDoorBlockEntityRenderer;
import dev.doctor4t.wathe.client.render.block_entity.WheelBlockEntityRenderer;
Expand All @@ -26,6 +28,7 @@
import dev.doctor4t.wathe.game.GameConstants;
import dev.doctor4t.wathe.game.GameFunctions;
import dev.doctor4t.wathe.index.*;
import dev.doctor4t.wathe.item.RevolverItem;
import dev.doctor4t.wathe.util.*;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.fabricmc.api.ClientModInitializer;
Expand All @@ -35,6 +38,7 @@
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry;
import net.fabricmc.fabric.api.event.player.UseItemCallback;
import net.minecraft.block.Block;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.AbstractClientPlayerEntity;
Expand All @@ -53,14 +57,20 @@
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import net.minecraft.sound.SoundCategory;
import net.minecraft.util.Identifier;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import org.lwjgl.glfw.GLFW;

import java.util.*;
import java.util.function.Supplier;

public class WatheClient implements ClientModInitializer {
private static float soundLevel = 0f;
Expand All @@ -72,6 +82,7 @@ public class WatheClient implements ClientModInitializer {
public static PlayerMoodComponent moodComponent;

public static final Map<UUID, PlayerListEntry> PLAYER_ENTRIES_CACHE = Maps.newHashMap();
public static final Map<Item, Supplier<HandParticle>> GUN_PARTICLE_PROVIDERS = Maps.newHashMap();

public static KeyBinding instinctKeybind;
public static float prevInstinctLightLevel = -.04f;
Expand Down Expand Up @@ -291,6 +302,56 @@ public void onInitializeClient() {
GLFW.GLFW_KEY_LEFT_ALT,
"category." + Wathe.MOD_ID + ".keybinds"
));

GUN_PARTICLE_PROVIDERS.put(WatheItems.DERRINGER,
() -> new HandParticle()
.setTexture(Wathe.id("textures/particle/gunshot.png"))
.setPos(0.1f, 0.2f, -0.2f)
.setMaxAge(3)
.setSize(0.5f)
.setVelocity(0f, 0f, 0f)
.setLight(15, 15)
.setAlpha(1f, 0.1f)
.setRenderLayer(WatheRenderLayers::additive)
);

GUN_PARTICLE_PROVIDERS.put(WatheItems.REVOLVER,
() -> new HandParticle()
.setTexture(Wathe.id("textures/particle/gunshot.png"))
.setPos(0.1f, 0.275f, -0.2f)
.setMaxAge(3)
.setSize(0.5f)
.setVelocity(0f, 0f, 0f)
.setLight(15, 15)
.setAlpha(1f, 0.1f)
.setRenderLayer(WatheRenderLayers::additive)
);

UseItemCallback.EVENT.register((user, world, hand) -> {
ItemStack stack = user.getStackInHand(hand);
if (user.isSpectator() || !(stack.getItem() instanceof RevolverItem gun)) {
return TypedActionResult.pass(stack);
}

boolean used = gun.hasBeenUsed(stack, user);

if (world.isClient) {
HitResult collision = gun.getGunTarget(user, stack);
if (collision instanceof EntityHitResult entityHitResult) {
Entity target = entityHitResult.getEntity();
ClientPlayNetworking.send(new GunShootPayload(target.getId()));
} else {
ClientPlayNetworking.send(new GunShootPayload(-1));
}
if (!used) {
user.setPitch(user.getPitch() - 4);
if (GUN_PARTICLE_PROVIDERS.containsKey(gun)) {
handParticleManager.spawn(GUN_PARTICLE_PROVIDERS.get(gun).get());
}
}
}
return TypedActionResult.consume(stack);
});
}

public static TrainWorldComponent getTrainComponent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.entity.player.ItemCooldownManager;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.EntityHitResult;
Expand All @@ -37,9 +38,8 @@ public static void renderCrosshair(@NotNull MinecraftClient client, @NotNull Cli
RenderSystem.defaultBlendFunc();
RenderSystem.disableBlend();
ItemStack mainHandStack = player.getMainHandStack();
if (mainHandStack.isOf(WatheItems.REVOLVER) && !player.getItemCooldownManager().isCoolingDown(mainHandStack.getItem()) && RevolverItem.getGunTarget(player) instanceof EntityHitResult) {
target = true;
} else if (mainHandStack.isOf(WatheItems.DERRINGER) && !player.getItemCooldownManager().isCoolingDown(mainHandStack.getItem()) && DerringerItem.getGunTarget(player) instanceof EntityHitResult) {
Item item = mainHandStack.getItem();
if (item instanceof RevolverItem gun && !player.getItemCooldownManager().isCoolingDown(gun) && gun.getGunTarget(player, mainHandStack) instanceof EntityHitResult) {
target = true;
} else if (mainHandStack.isOf(WatheItems.KNIFE)) {
ItemCooldownManager manager = player.getItemCooldownManager();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package dev.doctor4t.wathe.client.util;

import dev.doctor4t.ratatouille.util.TextUtils;
import dev.doctor4t.wathe.index.WatheDataComponentTypes;
import dev.doctor4t.wathe.index.WatheItems;
import dev.doctor4t.wathe.item.DerringerItem;
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.ItemCooldownManager;
Expand All @@ -20,6 +22,13 @@ public class WatheItemTooltips {

public static void addTooltips() {
ItemTooltipCallback.EVENT.register((itemStack, tooltipContext, tooltipType, tooltipList) -> {
if (itemStack.getItem() instanceof DerringerItem) {
boolean used = itemStack.getOrDefault(WatheDataComponentTypes.USED, false);
if (used) {
tooltipList.add(Text.translatable("tip.derringer.used").withColor(COOLDOWN_COLOR));
}
}

addCooldownText(WatheItems.KNIFE, tooltipList, itemStack);
addCooldownText(WatheItems.REVOLVER, tooltipList, itemStack);
addCooldownText(WatheItems.DERRINGER, tooltipList, itemStack);
Expand Down
68 changes: 4 additions & 64 deletions src/main/java/dev/doctor4t/wathe/item/DerringerItem.java
Original file line number Diff line number Diff line change
@@ -1,79 +1,19 @@
package dev.doctor4t.wathe.item;

import dev.doctor4t.wathe.Wathe;
import dev.doctor4t.wathe.client.WatheClient;
import dev.doctor4t.wathe.client.particle.HandParticle;
import dev.doctor4t.wathe.client.render.WatheRenderLayers;
import dev.doctor4t.wathe.client.util.WatheItemTooltips;
import dev.doctor4t.wathe.game.GameFunctions;
import dev.doctor4t.wathe.index.WatheDataComponentTypes;
import dev.doctor4t.wathe.util.GunShootPayload;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.text.Text;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.world.World;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class DerringerItem extends RevolverItem {
public DerringerItem(Settings settings) {
super(settings);
}

@Override
public TypedActionResult<ItemStack> use(@NotNull World world, @NotNull PlayerEntity user, Hand hand) {
ItemStack stack = user.getStackInHand(hand);
boolean used = stack.getOrDefault(WatheDataComponentTypes.USED, false);

if (world.isClient) {
HitResult collision = getGunTarget(user);
if (collision instanceof EntityHitResult entityHitResult) {
Entity target = entityHitResult.getEntity();
ClientPlayNetworking.send(new GunShootPayload(target.getId()));
} else {
ClientPlayNetworking.send(new GunShootPayload(-1));
}
if (!used) {
user.setPitch(user.getPitch() - 4);
spawnHandParticle();
}
}
return TypedActionResult.consume(stack);
}

public static void spawnHandParticle() {
HandParticle handParticle = new HandParticle()
.setTexture(Wathe.id("textures/particle/gunshot.png"))
.setPos(0.1f, 0.2f, -0.2f)
.setMaxAge(3)
.setSize(0.5f)
.setVelocity(0f, 0f, 0f)
.setLight(15, 15)
.setAlpha(1f, 0.1f)
.setRenderLayer(WatheRenderLayers::additive);
WatheClient.handParticleManager.spawn(handParticle);
}

@Override
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> tooltip, TooltipType type) {
Boolean used = stack.getOrDefault(WatheDataComponentTypes.USED, false);
if (used) {
tooltip.add(Text.translatable("tip.derringer.used").withColor(WatheItemTooltips.COOLDOWN_COLOR));
}

super.appendTooltip(stack, context, tooltip, type);
public boolean hasBeenUsed(ItemStack stack, PlayerEntity user) {
return stack.getOrDefault(WatheDataComponentTypes.USED, false);
}

public static HitResult getGunTarget(PlayerEntity user) {
return ProjectileUtil.getCollision(user, entity -> entity instanceof PlayerEntity player && GameFunctions.isPlayerAliveAndSurvival(player), 7f);
public float getRange(PlayerEntity user, ItemStack stack) {
return 7f;
}
}
47 changes: 14 additions & 33 deletions src/main/java/dev/doctor4t/wathe/item/RevolverItem.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
package dev.doctor4t.wathe.item;

import dev.doctor4t.wathe.Wathe;
import dev.doctor4t.wathe.client.WatheClient;
import dev.doctor4t.wathe.client.particle.HandParticle;
import dev.doctor4t.wathe.client.render.WatheRenderLayers;
import dev.doctor4t.wathe.game.GameFunctions;
import dev.doctor4t.wathe.util.GunShootPayload;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileUtil;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.world.World;
import org.jetbrains.annotations.NotNull;
Expand All @@ -26,34 +18,23 @@ public RevolverItem(Settings settings) {

@Override
public TypedActionResult<ItemStack> use(@NotNull World world, @NotNull PlayerEntity user, Hand hand) {
if (world.isClient) {
HitResult collision = getGunTarget(user);
if (collision instanceof EntityHitResult entityHitResult) {
Entity target = entityHitResult.getEntity();
ClientPlayNetworking.send(new GunShootPayload(target.getId()));
} else {
ClientPlayNetworking.send(new GunShootPayload(-1));
}
user.setPitch(user.getPitch() - 4);
spawnHandParticle();
}
return TypedActionResult.consume(user.getStackInHand(hand));
ItemStack stack = user.getStackInHand(hand);
return TypedActionResult.consume(stack);
}

public static void spawnHandParticle() {
HandParticle handParticle = new HandParticle()
.setTexture(Wathe.id("textures/particle/gunshot.png"))
.setPos(0.1f, 0.275f, -0.2f)
.setMaxAge(3)
.setSize(0.5f)
.setVelocity(0f, 0f, 0f)
.setLight(15, 15)
.setAlpha(1f, 0.1f)
.setRenderLayer(WatheRenderLayers::additive);
WatheClient.handParticleManager.spawn(handParticle);
public boolean hasBeenUsed(ItemStack stack, PlayerEntity user) {
return false;
}

public static HitResult getGunTarget(PlayerEntity user) {
return ProjectileUtil.getCollision(user, entity -> entity instanceof PlayerEntity player && GameFunctions.isPlayerAliveAndSurvival(player), 15f);
public static HitResult getGunTarget(PlayerEntity user, float range) {
return ProjectileUtil.getCollision(user, entity -> entity instanceof PlayerEntity player && GameFunctions.isPlayerAliveAndSurvival(player), range);
}

public final HitResult getGunTarget(PlayerEntity user, ItemStack stack) {
return getGunTarget(user, this.getRange(user, stack));
}

public float getRange(PlayerEntity user, ItemStack stack) {
return 15f;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

/**
* @author SkyNotTheLimit
*/
@Environment(EnvType.CLIENT)
@Mixin(NoteItem.class)
public class NoteItemMixin {
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/dev/doctor4t/wathe/util/GunShootPayload.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import dev.doctor4t.wathe.index.WatheItems;
import dev.doctor4t.wathe.index.WatheSounds;
import dev.doctor4t.wathe.index.tag.WatheItemTags;
import dev.doctor4t.wathe.item.RevolverItem;
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.entity.ItemEntity;
Expand All @@ -23,6 +24,8 @@
import net.minecraft.sound.SoundCategory;
import org.jetbrains.annotations.NotNull;

import java.util.function.Predicate;

public record GunShootPayload(int target) implements CustomPayload {
public static final Id<GunShootPayload> ID = new Id<>(Wathe.id("gunshoot"));
public static final PacketCodec<PacketByteBuf, GunShootPayload> CODEC = PacketCodec.tuple(PacketCodecs.INTEGER, GunShootPayload::target, GunShootPayload::new);
Expand Down Expand Up @@ -56,7 +59,14 @@ public void receive(@NotNull GunShootPayload payload, ServerPlayNetworking.@NotN
if (!player.isCreative()) mainHandStack.set(WatheDataComponentTypes.USED, true);
}

if (player.getServerWorld().getEntityById(payload.target()) instanceof PlayerEntity target && target.distanceTo(player) < 65.0) {
Predicate<PlayerEntity> distancePredicate;
if (mainHandStack.getItem() instanceof RevolverItem gun) {
distancePredicate = target -> player.distanceTo(target) < gun.getRange(player, mainHandStack) + 1.5;
} else {
distancePredicate = target -> player.distanceTo(target) < 65;
}

if (player.getServerWorld().getEntityById(payload.target()) instanceof PlayerEntity target && player.canSee(target) && distancePredicate.test(target)) {
GameWorldComponent game = GameWorldComponent.KEY.get(player.getWorld());
Item revolver = WatheItems.REVOLVER;

Expand Down