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
106 changes: 106 additions & 0 deletions src/main/java/com/tacz/guns/client/gui/overlay/AimlessZoomOverlay.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.tacz.guns.client.gui.overlay;

import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.tacz.guns.api.client.gameplay.IClientPlayerGunOperator;
import com.tacz.guns.api.item.IGun;
import com.tacz.guns.config.client.RenderConfig;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.client.gui.overlay.ForgeGui;
import net.minecraftforge.client.gui.overlay.IGuiOverlay;


public class AimlessZoomOverlay implements IGuiOverlay {
private static long renderTimestamp = -1L;
private static float zoom = 0;

@Override
public void render(ForgeGui gui, GuiGraphics graphics, float partialTick, int width, int height) {
if (!RenderConfig.AIMLESS_ZOOM_ENABLE.get()) {
return;
}
int timeout = 4500;
int fadeInTime = 100; // fade in in 0.1s
double fadeOutTime = 3900; // fade out in 4.5 - 3.9 = 0.6s

long remainTime = System.currentTimeMillis() - renderTimestamp;
if (remainTime > timeout) {
return;
}
Minecraft mc = Minecraft.getInstance();
LocalPlayer player = mc.player;
if (!(player instanceof IClientPlayerGunOperator)) {
return;
}
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof IGun)) {
return;
}

Component text = Component.translatable(
"gui.tacz.aimless_zoom",
zoom
);

int alpha = 0xFF;

// Face in
if (remainTime < fadeInTime) {
alpha = 0x0F + (int)((remainTime / (double)fadeInTime) * (0xFF - 0x0F));
}
// Fade out
else if (remainTime > fadeOutTime) {
alpha = 0xFF - (int)(((remainTime - fadeOutTime) / (double)(timeout - fadeOutTime)) * (0xFF - 0x0F));
}

alpha = Math.max(0x0F, Math.min(0xFF, alpha));
int color = 0xFFFFFF | (alpha << 24);

float targetX = width * 4f / 5f;
float targetY = height * 7f / 12f;

RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();

PoseStack poseStack = graphics.pose();

float desiredScale = 1.35f;
float scale = desiredScale;

int screenW = graphics.guiWidth();
int screenH = graphics.guiHeight();

int textW = mc.font.width(text);
int textH = mc.font.lineHeight;

float maxW = screenW - targetX;
float maxH = screenH - targetY;

float scaleW = maxW / textW;
float scaleH = maxH / textH;
scale = Math.min(scale, Math.min(scaleW, scaleH));
scale = Math.max(scale, 0.5f);
poseStack.pushPose();
{
poseStack.scale(scale, scale, 1.0f);
graphics.drawString(
mc.font,
text,
(int)(targetX / scale),
(int)(targetY / scale),
color
);
}
poseStack.popPose();
RenderSystem.disableBlend();
}

public static void renderZoomChange(float Izoom) {
renderTimestamp = System.currentTimeMillis();
zoom = Izoom;
}
}
6 changes: 2 additions & 4 deletions src/main/java/com/tacz/guns/client/init/ClientSetupEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

import com.tacz.guns.GunMod;
import com.tacz.guns.api.client.other.ThirdPersonManager;
import com.tacz.guns.client.gui.overlay.GunHudOverlay;
import com.tacz.guns.client.gui.overlay.HeatBarOverlay;
import com.tacz.guns.client.gui.overlay.InteractKeyTextOverlay;
import com.tacz.guns.client.gui.overlay.KillAmountOverlay;
import com.tacz.guns.client.gui.overlay.*;
import com.tacz.guns.client.input.*;
import com.tacz.guns.client.resource.ClientAssetsManager;
import com.tacz.guns.client.tooltip.ClientAmmoBoxTooltip;
Expand Down Expand Up @@ -68,6 +65,7 @@ public static void onRegisterGuiOverlays(RegisterGuiOverlaysEvent event) {
event.registerAboveAll("tac_gun_hud_overlay", new GunHudOverlay());
event.registerAboveAll("tac_heat_bar", new HeatBarOverlay());
event.registerAboveAll("tac_kill_amount_overlay", new KillAmountOverlay());
event.registerAboveAll("tac_aimless_zoom", new AimlessZoomOverlay());
event.registerAbove(CROSSHAIR.id(), "tac_interact_key_overlay", new InteractKeyTextOverlay());

}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/tacz/guns/client/input/CrawlKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class CrawlKey {
KeyConflictContext.IN_GAME,
KeyModifier.NONE,
InputConstants.Type.KEYSYM,
GLFW.GLFW_KEY_C,
GLFW.GLFW_KEY_Z,
"key.category.tacz");

@SubscribeEvent
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/tacz/guns/client/input/RefitKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class RefitKey {
KeyConflictContext.IN_GAME,
KeyModifier.NONE,
InputConstants.Type.KEYSYM,
GLFW.GLFW_KEY_Z,
GLFW.GLFW_KEY_Y,
"key.category.tacz");

@SubscribeEvent
Expand Down
64 changes: 52 additions & 12 deletions src/main/java/com/tacz/guns/client/input/ZoomKey.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
package com.tacz.guns.client.input;

import com.mojang.blaze3d.platform.InputConstants;
import com.tacz.guns.api.DefaultAssets;
import com.tacz.guns.api.TimelessAPI;
import com.tacz.guns.api.client.gameplay.IClientPlayerGunOperator;
import com.tacz.guns.api.item.IGun;
import com.tacz.guns.api.item.attachment.AttachmentType;
import com.tacz.guns.api.item.nbt.AttachmentItemDataAccessor;
import com.tacz.guns.client.gui.overlay.AimlessZoomOverlay;
import com.tacz.guns.client.resource.index.ClientAttachmentIndex;
import com.tacz.guns.client.sound.SoundPlayManager;
import com.tacz.guns.config.client.RenderConfig;
import com.tacz.guns.network.NetworkHandler;
import com.tacz.guns.network.message.ClientMessagePlayerZoom;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.InputEvent;
Expand All @@ -25,7 +37,7 @@ public class ZoomKey {
KeyConflictContext.IN_GAME,
KeyModifier.NONE,
InputConstants.Type.KEYSYM,
GLFW.GLFW_KEY_V,
GLFW.GLFW_KEY_C,
"key.category.tacz");

@SubscribeEvent
Expand All @@ -44,27 +56,55 @@ public static void onZoomMousePress(InputEvent.MouseButton.Post event) {

public static boolean onZoomControllerPress(boolean isPress) {
if (isInGame() && isPress) {
LocalPlayer player = Minecraft.getInstance().player;
if (player == null || player.isSpectator()) {
return false;
}
IClientPlayerGunOperator operator = IClientPlayerGunOperator.fromLocalPlayer(player);
if (operator.isAim()) {
NetworkHandler.CHANNEL.sendToServer(new ClientMessagePlayerZoom());
return true;
}
return doZoomLogic();
}
return false;
}

private static void doZoomLogic() {
private static boolean doZoomLogic() {
LocalPlayer player = Minecraft.getInstance().player;
if (player == null || player.isSpectator()) {
return;
return false;
}
IClientPlayerGunOperator operator = IClientPlayerGunOperator.fromLocalPlayer(player);
if (operator.isAim()) {
NetworkHandler.CHANNEL.sendToServer(new ClientMessagePlayerZoom());
return true;
} else if (RenderConfig.AIMLESS_ZOOM_ENABLE.get()) {
NetworkHandler.CHANNEL.sendToServer(new ClientMessagePlayerZoom());
return maybeDisplayZoom(player, operator);
}
return false;
}

private static boolean maybeDisplayZoom(LocalPlayer player, IClientPlayerGunOperator operator) {
if (!operator.isAim()) {
ItemStack mainHandItem = player.getMainHandItem();
IGun iGun = IGun.getIGunOrNull(mainHandItem);
if (iGun == null) {
return true;
}

ResourceLocation scopeId = iGun.getAttachmentId(mainHandItem, AttachmentType.SCOPE);
CompoundTag scopeTag = iGun.getAttachmentTag(mainHandItem, AttachmentType.SCOPE);
if (!DefaultAssets.isEmptyAttachmentId(scopeId) && scopeTag != null) {
ClientAttachmentIndex index = TimelessAPI.getClientAttachmentIndex(scopeId).orElse(null);

if (index != null && index.getZoom() != null && index.getZoom().length != 1) {
int zoomNumber = AttachmentItemDataAccessor.getZoomNumberFromTag(scopeTag);
++zoomNumber;
zoomNumber = zoomNumber % (Integer.MAX_VALUE - 1);
AttachmentItemDataAccessor.setZoomNumberToTag(scopeTag, zoomNumber);

TimelessAPI.getGunDisplay(mainHandItem).ifPresent(gunIndex -> {
SoundPlayManager.playFireSelectSound(player, gunIndex);
});
float zoom = iGun.getAimingZoom(player.getMainHandItem());
AimlessZoomOverlay.renderZoomChange(zoom);

} // no index of scope?(why?) / only one zoom -> ignored
} // no scope / no scope tag -> ignored
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public static void init(ConfigBuilder root, ConfigEntryBuilder entryBuilder) {
.setDefaultValue(true).setTooltip(Component.translatable("config.tacz.client.render.gun_hud_enable.desc"))
.setSaveConsumer(RenderConfig.GUN_HUD_ENABLE::set).build());

render.addEntry(entryBuilder.startBooleanToggle(Component.translatable("config.tacz.client.render.aimless_zoom_enable"), RenderConfig.AIMLESS_ZOOM_ENABLE.get())
.setDefaultValue(true).setTooltip(Component.translatable("config.tacz.client.render.aimless_zoom_enable.desc"))
.setSaveConsumer(RenderConfig.AIMLESS_ZOOM_ENABLE::set).build());

render.addEntry(entryBuilder.startBooleanToggle(Component.translatable("config.tacz.client.render.kill_amount_enable"), RenderConfig.KILL_AMOUNT_ENABLE.get())
.setDefaultValue(true).setTooltip(Component.translatable("config.tacz.client.render.kill_amount_enable.desc"))
.setSaveConsumer(RenderConfig.KILL_AMOUNT_ENABLE::set).build());
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/tacz/guns/config/client/RenderConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class RenderConfig {
public static ForgeConfigSpec.DoubleValue HIT_MARKET_START_POSITION;
public static ForgeConfigSpec.BooleanValue HEAD_SHOT_DEBUG_HITBOX;
public static ForgeConfigSpec.BooleanValue GUN_HUD_ENABLE;
public static ForgeConfigSpec.BooleanValue AIMLESS_ZOOM_ENABLE;
public static ForgeConfigSpec.BooleanValue KILL_AMOUNT_ENABLE;
public static ForgeConfigSpec.DoubleValue KILL_AMOUNT_DURATION_SECOND;
public static ForgeConfigSpec.IntValue TARGET_RENDER_DISTANCE;
Expand Down Expand Up @@ -49,6 +50,9 @@ public static void init(ForgeConfigSpec.Builder builder) {
builder.comment("Whether or not to display the gun's HUD");
GUN_HUD_ENABLE = builder.define("GunHUDEnable", true);

builder.comment("Whether or not to allow a change of zoom if pressing a button without aiming");
AIMLESS_ZOOM_ENABLE = builder.define("AimlessZoomEnable", true);

builder.comment("Whether or not to display the kill amount");
KILL_AMOUNT_ENABLE = builder.define("KillAmountEnable", true);

Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/assets/tacz/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
"gui.tacz.gun_refit.property_diagrams.sprint_time": "SPT",
"gui.tacz.gun_refit.property_diagrams.ammo_speed": "Ammo Speed",
"gui.tacz.gun_refit.property_diagrams.weight": "Weight",
"gui.tacz.aimless_zoom": "Switched to x%.2f",
"gui.tacz.cloth_config_warning.tips": "You'll need to install the Cloth Config API mod to use the ingame configuration feature",
"gui.tacz.cloth_config_warning.download": "Download Cloth Config API",
"gui.tacz.client_gun_pack_downloader.fail.title": "Gun Pack Download Fail",
Expand Down Expand Up @@ -213,6 +214,8 @@
"config.tacz.client.render.head_shot_debug_hitbox.desc": "Whether or not to display the head shot's hitbox",
"config.tacz.client.render.gun_hud_enable": "Gun HUD Enable",
"config.tacz.client.render.gun_hud_enable.desc": "Whether or not to display the gun's HUD",
"config.tacz.client.render.aimless_zoom_enable": "Aimless Zoom Enable",
"config.tacz.client.render.aimless_zoom_enable.desc": "Whether or not to allow a change of zoom if pressing a button without aiming",
"config.tacz.client.render.kill_amount_enable": "Kill Amount Enable",
"config.tacz.client.render.kill_amount_enable.desc": "Whether or not to display the kill amount",
"config.tacz.client.render.kill_amount_duration_second": "Kill Amount Duration Second",
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/assets/tacz/lang/ru_ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
"gui.tacz.gun_refit.property_diagrams.sprint_time": "Выносливость",
"gui.tacz.gun_refit.property_diagrams.ammo_speed": "Скорость пули",
"gui.tacz.gun_refit.property_diagrams.weight": "Вес",
"gui.tacz.aimless_zoom": "Изменено на x%.2f",
"gui.tacz.cloth_config_warning.tips": "Вам нужно установить мод Cloth Config API, чтобы изменять конфигурацию в игре",
"gui.tacz.cloth_config_warning.download": "Скачать Cloth Config API",
"gui.tacz.client_gun_pack_downloader.fail.title": "Ошибка загрузки пака",
Expand Down Expand Up @@ -213,6 +214,8 @@
"config.tacz.client.render.head_shot_debug_hitbox.desc": "Показывать ли хитбокс выстрела в голову",
"config.tacz.client.render.gun_hud_enable": "Включить интерфейс оружия",
"config.tacz.client.render.gun_hud_enable.desc": "Показывать ли интерфейс оружия",
"config.tacz.client.render.aimless_zoom_enable": "Увеличение без прицеливания",
"config.tacz.client.render.aimless_zoom_enable.desc": "Разрешать ли переключать уровень прицеливания без прицеливания",
"config.tacz.client.render.kill_amount_enable": "Включить счётчик убийств",
"config.tacz.client.render.kill_amount_enable.desc": "Показывать ли счётчик убийств",
"config.tacz.client.render.kill_amount_duration_second": "Продолжительность счётчика убийств (в секундах)",
Expand Down