diff --git a/src/core/java/net/remmintan/mods/minefortress/core/FortressState.java b/src/core/java/net/remmintan/mods/minefortress/core/FortressState.java index 6049ec2b..6aa90032 100644 --- a/src/core/java/net/remmintan/mods/minefortress/core/FortressState.java +++ b/src/core/java/net/remmintan/mods/minefortress/core/FortressState.java @@ -2,7 +2,8 @@ public enum FortressState { - BUILD, + BUILD_SELECTION, + BUILD_EDITING, COMBAT, AREAS_SELECTION, diff --git a/src/core/java/net/remmintan/mods/minefortress/core/PawnsSelectionState.java b/src/core/java/net/remmintan/mods/minefortress/core/PawnsSelectionState.java new file mode 100644 index 00000000..236d8c1a --- /dev/null +++ b/src/core/java/net/remmintan/mods/minefortress/core/PawnsSelectionState.java @@ -0,0 +1,8 @@ +package net.remmintan.mods.minefortress.core; + +public enum PawnsSelectionState { + + SELECTING, + BUILDING, + +} diff --git a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/IClientFortressManager.java b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/IClientFortressManager.java index bbc2b190..a7a76183 100644 --- a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/IClientFortressManager.java +++ b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/IClientFortressManager.java @@ -4,7 +4,6 @@ import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.WorldRenderer; -import net.minecraft.entity.LivingEntity; import net.minecraft.util.math.BlockPos; import net.remmintan.mods.minefortress.core.FortressGamemode; import net.remmintan.mods.minefortress.core.FortressState; @@ -22,7 +21,6 @@ import java.util.UUID; public interface IClientFortressManager extends IFortressManager { - void select(LivingEntity colonist); void jumpToCampfire(); @@ -30,12 +28,6 @@ public interface IClientFortressManager extends IFortressManager { void setSpecialBlocks(Map> specialBlocks, Map> blueprintSpecialBlocks); - boolean isSelectingColonist(); - - LivingEntity getSelectedPawn(); - - void stopSelectingColonist(); - void open_HireScreen(MinecraftClient client, String screenName, Map professions); void sync( diff --git a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/IClientManagersProvider.java b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/IClientManagersProvider.java index b3667d3f..9469f4d2 100644 --- a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/IClientManagersProvider.java +++ b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/IClientManagersProvider.java @@ -1,6 +1,8 @@ package net.remmintan.mods.minefortress.core.interfaces.client; import net.remmintan.mods.minefortress.core.interfaces.blueprints.IClientBlueprintManager; +import net.remmintan.mods.minefortress.core.interfaces.combat.IClientPawnsSelectionManager; +import net.remmintan.mods.minefortress.core.interfaces.combat.ITargetedSelectionManager; import net.remmintan.mods.minefortress.core.interfaces.infuence.IClientInfluenceManager; import net.remmintan.mods.minefortress.core.interfaces.selections.ISelectionManager; import net.remmintan.mods.minefortress.core.interfaces.tasks.IAreasClientManager; @@ -11,4 +13,21 @@ public interface IClientManagersProvider { IClientBlueprintManager get_BlueprintManager(); IClientFortressManager get_ClientFortressManager(); IClientInfluenceManager get_InfluenceManager(); + IClientPawnsSelectionManager get_PawnsSelectionManager(); + default ISelectedColonistProvider getSelectedColonistProvider() { + final var pawnsSelectionManager = get_PawnsSelectionManager(); + if (pawnsSelectionManager instanceof ISelectedColonistProvider) { + return (ISelectedColonistProvider) pawnsSelectionManager; + } + throw new IllegalStateException("The pawns selection manager is not an instance of ISelectedColonistProvider"); + } + + default ITargetedSelectionManager getTargetedSelectionManager() { + final var pawnsSelectionManager = get_PawnsSelectionManager(); + if (pawnsSelectionManager instanceof ITargetedSelectionManager) { + return (ITargetedSelectionManager) pawnsSelectionManager; + } + throw new IllegalStateException("The pawns selection manager is not an instance of ITargetedSelectionManager"); + } + } diff --git a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/ISelectedColonistProvider.java b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/ISelectedColonistProvider.java new file mode 100644 index 00000000..77323d98 --- /dev/null +++ b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/client/ISelectedColonistProvider.java @@ -0,0 +1,11 @@ +package net.remmintan.mods.minefortress.core.interfaces.client; + +import net.minecraft.entity.LivingEntity; + +public interface ISelectedColonistProvider { + + boolean isSelectingColonist(); + + LivingEntity getSelectedPawn(); + +} diff --git a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientFightManager.java b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientFightManager.java index fd743f60..79f008b4 100644 --- a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientFightManager.java +++ b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientFightManager.java @@ -4,11 +4,10 @@ import net.minecraft.util.hit.HitResult; public interface IClientFightManager { - IClientFightSelectionManager getSelectionManager(); - void setTarget(HitResult hitResult); + void setTarget(HitResult hitResult, ITargetedSelectionManager targetedSelectionManager); - void setTarget(Entity entity); + void setTarget(Entity entity, ITargetedSelectionManager targetedSelectionManager); void sync(int warriorsCount); int getWarriorCount(); void attractWarriorsToCampfire(); diff --git a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientFightSelectionManager.java b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientPawnsSelectionManager.java similarity index 60% rename from src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientFightSelectionManager.java rename to src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientPawnsSelectionManager.java index 3c4d2ea1..c5fd61b8 100644 --- a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientFightSelectionManager.java +++ b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/IClientPawnsSelectionManager.java @@ -1,27 +1,21 @@ package net.remmintan.mods.minefortress.core.interfaces.combat; import net.minecraft.client.Mouse; -import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.Vec2f; -import net.minecraft.util.math.Vec3d; import net.remmintan.mods.minefortress.core.dtos.combat.MousePos; import net.remmintan.mods.minefortress.core.interfaces.entities.pawns.IFortressAwareEntity; -import net.remmintan.mods.minefortress.core.interfaces.entities.pawns.ITargetedPawn; -import org.jetbrains.annotations.Nullable; import java.util.Set; import java.util.function.Consumer; -public interface IClientFightSelectionManager { +public interface IClientPawnsSelectionManager { void startSelection(double x, double y); - void endSelection(); + void endSelection(double x, double y); boolean hasSelected(); - void updateSelection(Mouse mouse, BlockHitResult target); - - void updateSelection(double x, double y); + void updateSelection(Mouse mouse); void resetSelection(); @@ -29,7 +23,7 @@ public interface IClientFightSelectionManager { boolean isSelectionStarted(); - void forEachSelected(Consumer action); + void forEachSelected(Consumer action); MousePos getMouseStartPos(); diff --git a/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/ITargetedSelectionManager.java b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/ITargetedSelectionManager.java new file mode 100644 index 00000000..d209d64e --- /dev/null +++ b/src/core/java/net/remmintan/mods/minefortress/core/interfaces/combat/ITargetedSelectionManager.java @@ -0,0 +1,11 @@ +package net.remmintan.mods.minefortress.core.interfaces.combat; + +import net.remmintan.mods.minefortress.core.interfaces.entities.pawns.ITargetedPawn; + +import java.util.function.Consumer; + +public interface ITargetedSelectionManager { + + void forEachTargetedPawn(Consumer action); + +} diff --git a/src/core/java/net/remmintan/mods/minefortress/core/utils/GlobalProjectionCache.java b/src/core/java/net/remmintan/mods/minefortress/core/utils/GlobalProjectionCache.java new file mode 100644 index 00000000..28117ff9 --- /dev/null +++ b/src/core/java/net/remmintan/mods/minefortress/core/utils/GlobalProjectionCache.java @@ -0,0 +1,56 @@ +package net.remmintan.mods.minefortress.core.utils; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.util.math.Vec3d; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class GlobalProjectionCache { + + public static final int UPDATE_DELAY = 100; + private static double cachedMouseX = Double.MIN_VALUE; + private static double cachedMouseY = Double.MIN_VALUE; + // head rotation and player position + private static float cachedPlayerXRot = Float.MIN_VALUE; + private static float cachedPlayerYRot = Float.MIN_VALUE; + private static Vec3d cachedPlayerPos = Vec3d.ZERO; + + // time + private static Map lastUpdateTimes = new ConcurrentHashMap<>(); + + public static boolean shouldUpdateValues(String timeKey) { + final var minecraft = MinecraftClient.getInstance(); + if(minecraft == null) return false; + + final var mouseX = minecraft.mouse.getX(); + final var mouseY = minecraft.mouse.getY(); + + final var player = minecraft.player; + if(player == null) return false; + + final var playerXRot = player.getPitch(); + final var playerYRot = player.getYaw(); + final var playerPos = player.getPos(); + if(playerPos == null) return false; + + if(mouseX != cachedMouseX || + mouseY != cachedMouseY || + playerXRot != cachedPlayerXRot || + playerYRot != cachedPlayerYRot || + !playerPos.equals(cachedPlayerPos) || + System.currentTimeMillis() - lastUpdateTimes.computeIfAbsent(timeKey, it -> 0L) > UPDATE_DELAY + ) { + cachedMouseX = mouseX; + cachedMouseY = mouseY; + cachedPlayerXRot = playerXRot; + cachedPlayerYRot = playerYRot; + cachedPlayerPos = new Vec3d(playerPos.x, playerPos.y, playerPos.z); + lastUpdateTimes.put(timeKey, System.currentTimeMillis()); + return true; + } + + return false; + } + +} diff --git a/src/main/java/org/minefortress/controls/MouseEvents.java b/src/main/java/org/minefortress/controls/MouseEvents.java new file mode 100644 index 00000000..8a2b7499 --- /dev/null +++ b/src/main/java/org/minefortress/controls/MouseEvents.java @@ -0,0 +1,52 @@ +package org.minefortress.controls; + +import net.minecraft.client.MinecraftClient; +import net.remmintan.mods.minefortress.core.FortressState; +import net.remmintan.mods.minefortress.core.utils.CoreModUtils; +import org.minefortress.utils.ModUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MouseEvents { + + private static final Logger LOGGER = LoggerFactory.getLogger(MouseEvents.class); + + private static boolean mousePressedInpreviousTick = false; + + public static void checkMouseStateAndFireEvents() { + final var mouse = MinecraftClient.getInstance().mouse; + final var isMousePressed = mouse.wasLeftButtonClicked(); + // mouse x and y coordinates + final var mouseX = mouse.getX(); + final var mouseY = mouse.getY(); + if(isMousePressed) { + if(!mousePressedInpreviousTick) { + firePressEvent(mouseX, mouseY); + } + } else { + if(mousePressedInpreviousTick) { + fireReleaseEvent(mouseX, mouseY); + } + } + mousePressedInpreviousTick = isMousePressed; + } + + private static void firePressEvent(double mouseX, double mouseY) { + final var fortressManager = ModUtils.getFortressClientManager(); + final var state = fortressManager.getState(); + final var correctState = state == FortressState.COMBAT || state == FortressState.BUILD_SELECTION; + + if(correctState) { + final var provider = CoreModUtils.getMineFortressManagersProvider(); + final var pawnsSelection = provider.get_PawnsSelectionManager(); + pawnsSelection.startSelection(mouseX, mouseY); + } + } + + private static void fireReleaseEvent(double mouseX, double mouseY) { + final var provider = CoreModUtils.getMineFortressManagersProvider(); + final var pawnsSelection = provider.get_PawnsSelectionManager(); + pawnsSelection.endSelection(mouseX, mouseY); + } + +} diff --git a/src/main/java/org/minefortress/entity/renderer/PawnRenderer.java b/src/main/java/org/minefortress/entity/renderer/PawnRenderer.java index 7422561a..91942a85 100644 --- a/src/main/java/org/minefortress/entity/renderer/PawnRenderer.java +++ b/src/main/java/org/minefortress/entity/renderer/PawnRenderer.java @@ -17,10 +17,7 @@ import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.math.Box; import net.minecraft.world.GameMode; -import net.remmintan.mods.minefortress.core.interfaces.client.IClientFortressManager; -import net.remmintan.mods.minefortress.core.interfaces.client.IClientManagersProvider; -import net.remmintan.mods.minefortress.core.interfaces.entities.pawns.IFortressAwareEntity; -import net.remmintan.mods.minefortress.core.interfaces.entities.pawns.ITargetedPawn; +import net.remmintan.mods.minefortress.core.utils.CoreModUtils; import org.jetbrains.annotations.Nullable; import org.joml.AxisAngle4f; import org.joml.Quaternionf; @@ -28,7 +25,6 @@ import org.minefortress.MineFortressMod; import org.minefortress.entity.BasePawnEntity; import org.minefortress.entity.renderer.models.PawnModel; -import org.minefortress.interfaces.IFortressMinecraftClient; import java.util.Optional; @@ -73,29 +69,23 @@ public void render(BasePawnEntity pawn, float f, float g, MatrixStack matrixStac if(currentGamemode == MineFortressMod.FORTRESS) { final boolean hovering = client.crosshairTarget instanceof EntityHitResult entityHitResult && entityHitResult.getEntity() == pawn; - final var fightSelecting = selectedAsTargeted(pawn); - final boolean selecting = getFortressClientManager().getSelectedPawn() == pawn; + final var fightSelecting = isThisPawnSelected(pawn); var color = getHealthFoodLevelColor(pawn); - if(hovering || selecting || color != null || fightSelecting) { + if(hovering || color != null || fightSelecting) { final VertexConsumer buffer = vertexConsumerProvider.getBuffer(RenderLayer.getLines()); - if(color != null && !(hovering || fightSelecting)) { - color.mul(0.7f); - } + if(color == null) + color = new Vector3f(0.0f, 1.0f, 0.0f); - if(color == null) { - color = new Vector3f(selecting ? 0.7f : 0.0f, selecting ? 0.7f : 1.0f, selecting ? 0.7f : 0.0f); - if(fightSelecting) { - color = new Vector3f(0.0f, 1.0f, 0.0f); - } - } + if(!hovering) + color.mul(0.7f); PawnRenderer.renderRhombus(matrixStack, buffer, pawn, color); } } } - private boolean selectedAsTargeted (BasePawnEntity pawn) { - return getFortressClientManager().getFightManager().getSelectionManager().isSelected(pawn); + private boolean isThisPawnSelected(BasePawnEntity pawn) { + return CoreModUtils.getMineFortressManagersProvider().get_PawnsSelectionManager().isSelected(pawn); } private float getHealthFoodLevel(BasePawnEntity colonist) { @@ -132,18 +122,6 @@ private MinecraftClient getClient() { return MinecraftClient.getInstance(); } - private IFortressMinecraftClient getFortressClient() { - return (IFortressMinecraftClient) getClient(); - } - - private IClientManagersProvider getManagersProvider() { - return (IClientManagersProvider) getClient(); - } - - private IClientFortressManager getFortressClientManager() { - return getManagersProvider().get_ClientFortressManager(); - } - private void setClothesVilibility(MobEntity colonist) { final var colonistModel = (PlayerEntityModel)this.getModel(); colonistModel.hat.visible = true; diff --git a/src/main/java/org/minefortress/fight/ClientFightManager.java b/src/main/java/org/minefortress/fight/ClientFightManager.java index 7a45c15c..6fb2dffe 100644 --- a/src/main/java/org/minefortress/fight/ClientFightManager.java +++ b/src/main/java/org/minefortress/fight/ClientFightManager.java @@ -6,7 +6,7 @@ import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.HitResult; import net.remmintan.mods.minefortress.core.interfaces.combat.IClientFightManager; -import net.remmintan.mods.minefortress.core.interfaces.combat.IClientFightSelectionManager; +import net.remmintan.mods.minefortress.core.interfaces.combat.ITargetedSelectionManager; import net.remmintan.mods.minefortress.networking.c2s.C2SAttractWarriorsToCampfire; import net.remmintan.mods.minefortress.networking.c2s.C2SSetNavigationTargetEntity; import net.remmintan.mods.minefortress.networking.helpers.FortressClientNetworkHelper; @@ -14,20 +14,13 @@ import org.minefortress.utils.ModUtils; public class ClientFightManager implements IClientFightManager { - - private final IClientFightSelectionManager selectionManager = new ClientFightSelectionManager(); private int warriorCount; @Override - public IClientFightSelectionManager getSelectionManager() { - return selectionManager; - } - - @Override - public void setTarget(HitResult hitResult) { + public void setTarget(HitResult hitResult, ITargetedSelectionManager targetedSelectionManager) { if(hitResult instanceof BlockHitResult blockHitResult) { final var blockPos = blockHitResult.getBlockPos(); - selectionManager.forEachSelected(it -> it.setMoveTarget(blockPos)); + targetedSelectionManager.forEachTargetedPawn(it -> it.setMoveTarget(blockPos)); final var packet = new C2SSetNavigationTargetEntity(blockPos); FortressClientNetworkHelper.send(C2SSetNavigationTargetEntity.CHANNEL, packet); } else if (hitResult instanceof EntityHitResult entityHitResult) { @@ -38,12 +31,12 @@ public void setTarget(HitResult hitResult) { if(masterPlayerId.map(it -> it.equals(ModUtils.getCurrentPlayerUUID())).orElse(false)) return; } - selectionManager.forEachSelected(it -> it.setAttackTarget(livingEntity)); + targetedSelectionManager.forEachTargetedPawn(it -> it.setAttackTarget(livingEntity)); } } @Override - public void setTarget(Entity entity) { + public void setTarget(Entity entity, ITargetedSelectionManager targetedSelectionManager) { if(!(entity instanceof LivingEntity livingEntity)) return; if(entity instanceof Colonist col) { final var masterPlayerId = col.getMasterId(); @@ -51,7 +44,7 @@ public void setTarget(Entity entity) { if(masterPlayerId.map(it -> it.equals(playerId)).orElse(false)) return; } - selectionManager.forEachSelected(it -> it.setAttackTarget(livingEntity)); + targetedSelectionManager.forEachTargetedPawn(it -> it.setAttackTarget(livingEntity)); } @Override diff --git a/src/main/java/org/minefortress/fight/ClientFightSelectionManager.java b/src/main/java/org/minefortress/fight/ClientPawnsSelectionManager.java similarity index 61% rename from src/main/java/org/minefortress/fight/ClientFightSelectionManager.java rename to src/main/java/org/minefortress/fight/ClientPawnsSelectionManager.java index 2af775ed..da25e56b 100644 --- a/src/main/java/org/minefortress/fight/ClientFightSelectionManager.java +++ b/src/main/java/org/minefortress/fight/ClientPawnsSelectionManager.java @@ -2,28 +2,30 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.Mouse; -import net.minecraft.entity.EntityType; -import net.minecraft.text.Text; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; +import net.minecraft.entity.LivingEntity; import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec3d; +import net.remmintan.mods.minefortress.core.FortressState; import net.remmintan.mods.minefortress.core.dtos.combat.MousePos; -import net.remmintan.mods.minefortress.core.interfaces.combat.IClientFightSelectionManager; +import net.remmintan.mods.minefortress.core.interfaces.client.ISelectedColonistProvider; +import net.remmintan.mods.minefortress.core.interfaces.combat.IClientPawnsSelectionManager; +import net.remmintan.mods.minefortress.core.interfaces.combat.ITargetedSelectionManager; import net.remmintan.mods.minefortress.core.interfaces.entities.pawns.IFortressAwareEntity; import net.remmintan.mods.minefortress.core.interfaces.entities.pawns.ITargetedPawn; +import net.remmintan.mods.minefortress.core.utils.GlobalProjectionCache; import org.minefortress.renderer.CameraTools; import org.minefortress.utils.ModUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; import java.util.function.Consumer; -public class ClientFightSelectionManager implements IClientFightSelectionManager { +public class ClientPawnsSelectionManager implements IClientPawnsSelectionManager, ITargetedSelectionManager, ISelectedColonistProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(ClientPawnsSelectionManager.class); - public static final int RAY_LENGTH = 200; private MousePos mouseStartPos; private MousePos mouseEndPos; - private MousePos cachedMousePos; private final List selectedPawns = new ArrayList<>(); @@ -37,17 +39,9 @@ public void startSelection(double x, double y) { } @Override - public void endSelection() { + public void endSelection(double x, double y) { this.mouseStartPos = null; this.mouseEndPos = null; - if(!hasSelected()) { - final var message = Text.of("Only warriors and archers can be selected and controlled directly."); - MinecraftClient - .getInstance() - .inGameHud - .getChatHud() - .addMessage(message); - } } @Override @@ -56,19 +50,23 @@ public boolean hasSelected() { } @Override - public void updateSelection(Mouse mouse, BlockHitResult target) { + public void updateSelection(Mouse mouse) { this.updateSelection(mouse.getX(), mouse.getY()); } - @Override - public void updateSelection(double x, double y) { + private void updateSelection(double x, double y) { if(!isSelectionStarted()) return; + + this.mouseEndPos = new MousePos(x, y); + LOGGER.info("Updating selection"); + LOGGER.info("Mouse start pos: " + mouseStartPos.getX() + " " + mouseStartPos.getY()); + LOGGER.info("Mouse end pos: " + x + " " + y); - if(!this.mouseEndPos.equals(this.cachedMousePos)) { + if(GlobalProjectionCache.shouldUpdateValues("pawnsSelectionManager")) { + LOGGER.info("Trying to update selection"); selectedPawns.clear(); - final var world = MinecraftClient.getInstance().world; final Map entitesMap = new HashMap<>(); @@ -89,43 +87,17 @@ public void updateSelection(double x, double y) { int minY = Math.min(mouseStartPos.getY(), mouseEndPos.getY()); int maxY = Math.max(mouseStartPos.getY(), mouseEndPos.getY()); - - // log max and min x and y in one line -// LoggerFactory.getLogger(ClientFightSelectionManager.class).info("minX: " + minX + ", maxX: " + maxX + ", minY: " + minY + ", maxY: " + maxY); - final var screenPositions = CameraTools.projectToScreenSpace(entitesMap.keySet(), MinecraftClient.getInstance()); this.screenPositions = screenPositions.keySet(); for (Map.Entry entry : screenPositions.entrySet()) { final var screenPos = entry.getKey(); final var entityPos = entry.getValue(); // log screen pos -// LoggerFactory.getLogger(ClientFightSelectionManager.class).info("screenPos: " + screenPos.x + ", " + screenPos.y); if (screenPos.x >= minX && screenPos.x <= maxX && screenPos.y >= minY && screenPos.y <= maxY) { final var entity = entitesMap.get(entityPos); selectedPawns.add(entity); } } - -// selectPawnsByType(FortressEntities.WARRIOR_PAWN_ENTITY_TYPE, blockPositions); -// selectPawnsByType(FortressEntities.ARCHER_PAWN_ENTITY_TYPE, blockPositions); - - this.cachedMousePos = this.mouseEndPos; - } - } - - private void selectPawnsByType(EntityType type, List blockPositions) { - final List selectedPawns1; - -// final var selectionBox = new Box(selectionStartBlock.getX(), -64, selectionStartBlock.getZ(), selectionCurBlock.getX(), 256, selectionCurBlock.getZ()); - final var world = MinecraftClient.getInstance().world; - if(world != null) { - final var playerId = ModUtils.getCurrentPlayerUUID(); - selectedPawns1 = world - .getEntitiesByType(type, null, it -> it.getMasterId().map(playerId::equals).orElse(false)) - .stream() - .map(ITargetedPawn.class::cast) - .toList(); - selectedPawns.addAll(selectedPawns1); } } @@ -133,7 +105,6 @@ private void selectPawnsByType(EntityType type, List action) { -// selectedPawns.forEach(action); + public void forEachSelected(Consumer action) { + selectedPawns.forEach(action); } @Override @@ -172,4 +143,25 @@ public Set getScreenPositions() { return screenPositions; } + @Override + public void forEachTargetedPawn(Consumer action) { + this.forEachSelected(it -> {if(it instanceof ITargetedPawn tp) action.accept(tp);}); + } + + @Override + public boolean isSelectingColonist() { + final var state = ModUtils.getFortressClientManager().getState(); + return (state == FortressState.COMBAT || state == FortressState.BUILD_SELECTION || state==FortressState.BUILD_EDITING) && this.getSelectedPawn() != null; + } + + @Override + public LivingEntity getSelectedPawn() { + if(selectedPawns.size() == 1) { + final var pawn = selectedPawns.get(0); + if(pawn instanceof LivingEntity le) { + return le; + } + } + return null; + } } diff --git a/src/main/java/org/minefortress/fortress/ClientFortressManager.java b/src/main/java/org/minefortress/fortress/ClientFortressManager.java index 010292f6..fd8b9b86 100644 --- a/src/main/java/org/minefortress/fortress/ClientFortressManager.java +++ b/src/main/java/org/minefortress/fortress/ClientFortressManager.java @@ -4,7 +4,6 @@ import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.WorldRenderer; -import net.minecraft.entity.LivingEntity; import net.minecraft.item.Items; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -46,7 +45,6 @@ public final class ClientFortressManager implements IClientFortressManager { private final IClientProfessionManager professionManager; private final IClientResourceManager resourceManager = new ClientResourceManagerImpl(); private final IClientFightManager fightManager = new ClientFightManager(); - private boolean connectedToTheServer = false; private boolean initialized = false; @@ -60,9 +58,6 @@ public final class ClientFortressManager implements IClientFortressManager { private BlockPos posAppropriateForCenter; private BlockPos oldPosAppropriateForCenter; - - private LivingEntity selectedPawn; - private List buildings = new ArrayList<>(); private Map> specialBlocks = new HashMap<>(); private Map> blueprintsSpecialBlocks = new HashMap<>(); @@ -71,9 +66,8 @@ public final class ClientFortressManager implements IClientFortressManager { private int maxColonistsCount; - private FortressState state = FortressState.BUILD; + private FortressState state = FortressState.BUILD_SELECTION; - private boolean campfireEnabled = true; private boolean borderEnabled = true; public ClientFortressManager() { @@ -83,21 +77,6 @@ public ClientFortressManager() { ); } - @Override - public void select(LivingEntity colonist) { - if(state == FortressState.COMBAT) { - final var mouse = MinecraftClient.getInstance().mouse; - final var selectionManager = fightManager.getSelectionManager(); - selectionManager.startSelection(mouse.getX(), mouse.getY()); - selectionManager.updateSelection(mouse.getX(), mouse.getY()); - selectionManager.endSelection(); - - selectedPawn = null; - return; - } - this.selectedPawn = colonist; - } - @Override public void jumpToCampfire() { final var packet = new C2SJumpToCampfire(); @@ -115,21 +94,6 @@ public void setSpecialBlocks(Map> specialBlocks, Map it.setNeedRebuild(true)); } } @@ -413,7 +373,7 @@ public List getBuildingHealths() { .filter(it -> it.getHealth() < 100) .map(this::buildingToHealthRenderInfo) .toList(); - case BUILD -> buildings + case BUILD_SELECTION, BUILD_EDITING -> buildings .stream() .filter(it -> it.getHealth() < 33) .map(this::buildingToHealthRenderInfo) diff --git a/src/main/java/org/minefortress/mixins/FortressMinecraftClientMixin.java b/src/main/java/org/minefortress/mixins/FortressMinecraftClientMixin.java index 4995668e..8f506abd 100644 --- a/src/main/java/org/minefortress/mixins/FortressMinecraftClientMixin.java +++ b/src/main/java/org/minefortress/mixins/FortressMinecraftClientMixin.java @@ -22,6 +22,7 @@ import net.remmintan.mods.minefortress.core.FortressState; import net.remmintan.mods.minefortress.core.interfaces.blueprints.IBlockDataProvider; import net.remmintan.mods.minefortress.core.interfaces.client.IClientManagersProvider; +import net.remmintan.mods.minefortress.core.interfaces.combat.IClientPawnsSelectionManager; import net.remmintan.mods.minefortress.core.interfaces.selections.ISelectionInfoProvider; import net.remmintan.mods.minefortress.core.interfaces.selections.ISelectionManager; import net.remmintan.mods.minefortress.core.interfaces.selections.ISelectionModelBuilderInfoProvider; @@ -34,6 +35,7 @@ import org.minefortress.MineFortressMod; import org.minefortress.blueprints.manager.ClientBlueprintManager; import org.minefortress.blueprints.world.BlueprintsWorld; +import org.minefortress.fight.ClientPawnsSelectionManager; import org.minefortress.fight.influence.ClientInfluenceManager; import org.minefortress.fortress.ClientFortressManager; import org.minefortress.fortress.automation.areas.AreasClientManager; @@ -80,6 +82,8 @@ public abstract class FortressMinecraftClientMixin extends ReentrantThreadExecut @Unique private AreasClientManager areasClientManager; + private IClientPawnsSelectionManager pawnsSelectionManager = new ClientPawnsSelectionManager(); + @Shadow @Final public GameOptions options; @@ -133,13 +137,12 @@ public void constructor(RunArgs args, CallbackInfo ci) { final var provider = CoreModUtils.getMineFortressManagersProvider(); final var manager = provider.get_ClientFortressManager(); + final var isInBuildState = manager.getState() == FortressState.BUILD_SELECTION || manager.getState() == FortressState.BUILD_EDITING; final Supplier selectInfProvSup = () -> - manager.getState() == FortressState.BUILD ? - ModUtils.getSelectionManager() : ModUtils.getAreasClientManager(); + isInBuildState ? ModUtils.getSelectionManager() : ModUtils.getAreasClientManager(); final Supplier selModBuildInfProv = () -> - manager.getState() == FortressState.BUILD ? - ModUtils.getSelectionManager() : ModUtils.getAreasClientManager(); + isInBuildState ? ModUtils.getSelectionManager() : ModUtils.getAreasClientManager(); selectionRenderer = new SelectionRenderer( client, @@ -281,6 +284,10 @@ public ClientInfluenceManager get_InfluenceManager() { return this.influenceManager; } + public IClientPawnsSelectionManager get_PawnsSelectionManager() { + return pawnsSelectionManager; + } + @Inject(method = "close", at = @At("HEAD")) public void close(CallbackInfo ci) { this.blueprintRenderer.close(); diff --git a/src/main/java/org/minefortress/mixins/interaction/FortressClientInteractionManagerMixin.java b/src/main/java/org/minefortress/mixins/interaction/FortressClientInteractionManagerMixin.java index 04cf1646..0f2c357d 100644 --- a/src/main/java/org/minefortress/mixins/interaction/FortressClientInteractionManagerMixin.java +++ b/src/main/java/org/minefortress/mixins/interaction/FortressClientInteractionManagerMixin.java @@ -22,6 +22,7 @@ import net.remmintan.mods.minefortress.core.FortressState; import net.remmintan.mods.minefortress.core.interfaces.client.IClientFortressManager; import net.remmintan.mods.minefortress.core.interfaces.client.IClientManagersProvider; +import net.remmintan.mods.minefortress.core.utils.CoreModUtils; import org.minefortress.MineFortressMod; import org.minefortress.renderer.gui.fortress.ManageBuildingScreen; import org.minefortress.utils.BlockUtils; @@ -86,29 +87,29 @@ public void attackBlock(BlockPos pos, Direction direction, CallbackInfoReturnabl final var manager = fortressClient.get_ClientFortressManager(); if(manager.getState() == FortressState.COMBAT) { - final var influenceManager = ModUtils.getInfluenceManager(); - if(influenceManager.isSelecting()) { - influenceManager.cancelSelectingInfluencePosition(); - cir.setReturnValue(false); - return; - } - final var selectionManager = manager.getFightManager().getSelectionManager(); - final var mouse = client.mouse; - - if(selectionManager.isSelecting()) - selectionManager.endSelection(); - else { - if(selectionManager.hasSelected()) { - selectionManager.resetSelection(); - } else { - final var crosshairTarget = client.crosshairTarget; - if (crosshairTarget!=null) - selectionManager.startSelection(mouse.getX(), mouse.getY()); - } - } - - cir.setReturnValue(false); - return; +// final var influenceManager = ModUtils.getInfluenceManager(); +// if(influenceManager.isSelecting()) { +// influenceManager.cancelSelectingInfluencePosition(); +// cir.setReturnValue(false); +// return; +// } +// final var selectionManager = manager.getFightManager().getSelectionManager(); +// final var mouse = client.mouse; +// +// if(selectionManager.isSelecting()) +// selectionManager.endSelection(); +// else { +// if(selectionManager.hasSelected()) { +// selectionManager.resetSelection(); +// } else { +// final var crosshairTarget = client.crosshairTarget; +// if (crosshairTarget!=null) +// selectionManager.startSelection(mouse.getX(), mouse.getY()); +// } +// } +// +// cir.setReturnValue(false); +// return; } if(manager.getState() == FortressState.AREAS_SELECTION) { @@ -118,12 +119,6 @@ public void attackBlock(BlockPos pos, Direction direction, CallbackInfoReturnabl return; } - if(manager.isSelectingColonist()){ - manager.stopSelectingColonist(); - cir.setReturnValue(false); - return; - } - if(manager.isCenterNotSet()) { cir.setReturnValue(false); return; @@ -169,13 +164,9 @@ public void interactEntity(PlayerEntity player, Entity entity, Hand hand, Callba final var manager = provider.get_ClientFortressManager(); if (manager.getState() == FortressState.COMBAT) { final var fightManager = manager.getFightManager(); - final var selectionManager = fightManager.getSelectionManager(); - if(selectionManager.isSelecting()) - selectionManager.resetSelection(); + final var targetedSelectionManager = provider.getTargetedSelectionManager(); - if(selectionManager.hasSelected()) { - fightManager.setTarget(entity); - } + fightManager.setTarget(entity, targetedSelectionManager); cir.setReturnValue(ActionResult.FAIL); return; } @@ -261,13 +252,7 @@ public void interactBlock(ClientPlayerEntity player, Hand hand, BlockHitResult h @Unique private static void updateFightSelection(BlockHitResult hitResult, IClientFortressManager fortressManager) { final var fightManager = fortressManager.getFightManager(); - final var selectionManager = fightManager.getSelectionManager(); - if(selectionManager.isSelecting()) - selectionManager.resetSelection(); - - if(selectionManager.hasSelected()) { - fightManager.setTarget(hitResult); - } + fightManager.setTarget(hitResult, CoreModUtils.getMineFortressManagersProvider().getTargetedSelectionManager()); } @Inject(method = "getReachDistance", at = @At("HEAD"), cancellable = true) diff --git a/src/main/java/org/minefortress/mixins/renderer/FortressGameRendererMixin.java b/src/main/java/org/minefortress/mixins/renderer/FortressGameRendererMixin.java index a4c81d5d..2514d76b 100644 --- a/src/main/java/org/minefortress/mixins/renderer/FortressGameRendererMixin.java +++ b/src/main/java/org/minefortress/mixins/renderer/FortressGameRendererMixin.java @@ -1,7 +1,6 @@ package org.minefortress.mixins.renderer; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.Mouse; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.render.Camera; import net.minecraft.client.render.GameRenderer; @@ -11,8 +10,8 @@ import net.remmintan.mods.minefortress.core.FortressState; import net.remmintan.mods.minefortress.core.interfaces.blueprints.IClientBlueprintManager; import net.remmintan.mods.minefortress.core.interfaces.client.IClientManagersProvider; +import net.remmintan.mods.minefortress.core.utils.CoreModUtils; import org.minefortress.interfaces.FortressGameRenderer; -import org.minefortress.interfaces.IFortressMinecraftClient; import org.minefortress.renderer.CameraTools; import org.minefortress.utils.ModUtils; import org.spongepowered.asm.mixin.Final; @@ -55,11 +54,15 @@ public void tick(CallbackInfo ci) { final var provider = (IClientManagersProvider) this.client; final var selectionManager = provider.get_SelectionManager(); final var clientFortressManager = provider.get_ClientFortressManager(); - final var fightSelectionManager = clientFortressManager - .getFightManager() - .getSelectionManager(); + final var pawnsSelectionManager = provider.get_PawnsSelectionManager(); final var areasClientManager = ModUtils.getAreasClientManager(); - if (((IFortressMinecraftClient)getClient()).is_FortressGamemode()) { + + if (ModUtils.isClientInFortressGamemode()) { + final var clientState = clientFortressManager.getState(); + if(clientState == FortressState.COMBAT || clientState == FortressState.BUILD_SELECTION) { + pawnsSelectionManager.updateSelection(client.mouse); + } + if(client.crosshairTarget instanceof BlockHitResult blockHitResult) { if(clientFortressManager.isCenterNotSet()) { resetAllSelectionManagers(); @@ -73,20 +76,13 @@ public void tick(CallbackInfo ci) { return; } - final var clientState = clientFortressManager.getState(); if(clientState == FortressState.AREAS_SELECTION) { areasClientManager.updateSelection(blockHitResult); } else { areasClientManager.resetSelection(); } - if(clientState == FortressState.COMBAT) { - fightSelectionManager.updateSelection(client.mouse, blockHitResult); - } else { - fightSelectionManager.resetSelection(); - } - - if(clientState == FortressState.BUILD) { + if(clientState == FortressState.BUILD_EDITING) { selectionManager.tickSelectionUpdate(blockHitResult.getBlockPos(), blockHitResult.getSide()); } else { selectionManager.resetSelection(); @@ -99,8 +95,10 @@ public void tick(CallbackInfo ci) { @Unique private static void resetAllSelectionManagers() { + final var provider = CoreModUtils.getMineFortressManagersProvider(); + ModUtils.getSelectionManager().resetSelection(); - ModUtils.getFortressClientManager().getFightManager().getSelectionManager().resetSelection(); + provider.get_PawnsSelectionManager().resetSelection(); ModUtils.getAreasClientManager().resetSelection(); } diff --git a/src/main/java/org/minefortress/mixins/renderer/FortressWorldRendererMixin.java b/src/main/java/org/minefortress/mixins/renderer/FortressWorldRendererMixin.java index 85668a68..1d42fbf3 100644 --- a/src/main/java/org/minefortress/mixins/renderer/FortressWorldRendererMixin.java +++ b/src/main/java/org/minefortress/mixins/renderer/FortressWorldRendererMixin.java @@ -83,7 +83,7 @@ public void renderObjectsOnTerrain(MatrixStack matrices, float tickDelta, long l final var immediate = this.bufferBuilders.getEntityVertexConsumers(); final var vertexConsumer = immediate.getBuffer(RenderLayer.getLines()); final var fcm = provider.get_ClientFortressManager(); - if (!selectionManager.isSelecting() && fcm.getState() == FortressState.BUILD) { + if (!selectionManager.isSelecting() && (fcm.getState() == FortressState.BUILD_EDITING)) { if(ModUtils.isClientInFortressGamemode()) { final HitResult crosshairTarget = client.crosshairTarget; if(crosshairTarget instanceof BlockHitResult bhr) { diff --git a/src/main/java/org/minefortress/registries/FortressClientEvents.java b/src/main/java/org/minefortress/registries/FortressClientEvents.java index 0e2addcc..8f628e17 100644 --- a/src/main/java/org/minefortress/registries/FortressClientEvents.java +++ b/src/main/java/org/minefortress/registries/FortressClientEvents.java @@ -13,6 +13,7 @@ import net.remmintan.mods.minefortress.core.utils.CoreModUtils; import net.remmintan.mods.minefortress.networking.c2s.C2SRequestResourcesRefresh; import net.remmintan.mods.minefortress.networking.helpers.FortressClientNetworkHelper; +import org.minefortress.controls.MouseEvents; import org.minefortress.interfaces.IFortressMinecraftClient; import org.minefortress.renderer.gui.ChooseModeScreen; import org.minefortress.utils.ModUtils; @@ -20,7 +21,8 @@ public class FortressClientEvents { public static void register() { - ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> ModUtils.getFortressClientManager().reset()); + final var fortressManager = ModUtils.getFortressClientManager(); + ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> fortressManager.reset()); ClientTickEvents.START_CLIENT_TICK.register(FortressClientEvents::startClientTick); ClientTickEvents.END_CLIENT_TICK.register(FortressClientEvents::endClientTick); ClientPlayConnectionEvents.JOIN.register(((handler, sender, client) -> { @@ -31,22 +33,21 @@ public static void register() { } private static void startClientTick(MinecraftClient client) { - final var clientInFortressGamemode = ModUtils.isClientInFortressGamemode(); - final var provider = CoreModUtils.getMineFortressManagersProvider(); - if(clientInFortressGamemode) { - final var mouse = client.mouse; - if(ModUtils.shouldReleaseCamera()) { - if(!mouse.isCursorLocked()) - mouse.lockCursor(); - } else { - if(mouse.isCursorLocked()) - mouse.unlockCursor(); - } + MouseEvents.checkMouseStateAndFireEvents(); + + if(!ModUtils.isClientInFortressGamemode()) return; + final var mouse = client.mouse; + if(ModUtils.shouldReleaseCamera()) { + if(!mouse.isCursorLocked()) + mouse.lockCursor(); + } else { + if(mouse.isCursorLocked()) + mouse.unlockCursor(); } final var fortressClient = (IFortressMinecraftClient) client; - fortressClient.get_FortressHud().tick(); + final var provider = CoreModUtils.getMineFortressManagersProvider(); final var fortressClientManager = provider.get_ClientFortressManager(); fortressClientManager.tick(hoveredBlockProvider()); if(fortressClientManager.gamemodeNeedsInitialization() && !(client.currentScreen instanceof ChooseModeScreen)) { diff --git a/src/main/java/org/minefortress/registries/FortressServerEvents.java b/src/main/java/org/minefortress/registries/FortressServerEvents.java index 768b9a33..03f50ae3 100644 --- a/src/main/java/org/minefortress/registries/FortressServerEvents.java +++ b/src/main/java/org/minefortress/registries/FortressServerEvents.java @@ -5,17 +5,13 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.player.AttackEntityCallback; +import net.fabricmc.fabric.api.event.player.UseEntityCallback; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; -import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.math.Direction; import net.remmintan.mods.minefortress.core.interfaces.entities.player.FortressServerPlayerEntity; import net.remmintan.mods.minefortress.core.interfaces.server.IFortressServer; -import net.remmintan.mods.minefortress.networking.helpers.FortressChannelNames; -import net.remmintan.mods.minefortress.networking.helpers.FortressServerNetworkHelper; -import net.remmintan.mods.minefortress.networking.s2c.ClientboundFollowColonistPacket; import org.minefortress.blueprints.world.BlueprintsWorld; -import org.minefortress.entity.BasePawnEntity; import org.minefortress.interfaces.FortressWorldCreator; import org.minefortress.utils.ModUtils; @@ -44,6 +40,20 @@ public static void register() { return ActionResult.PASS; }); + AttackEntityCallback.EVENT.register((player, world, hand, entity, entityHitResult) -> { + if(ModUtils.isFortressGamemode(player)) { + return ActionResult.FAIL; + } + return ActionResult.PASS; + }); + + UseEntityCallback.EVENT.register((player, world, hand, entity, entityHitResult) -> { + if(ModUtils.isFortressGamemode(player)) { + return ActionResult.FAIL; + } + return ActionResult.PASS; + }); + // initialising the fortress server on join ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { final var fortressServer = (IFortressServer) server; @@ -94,19 +104,6 @@ public static void register() { IFortressServer.get_FortressModServerManager().tick(server.getPlayerManager()); } }); - - AttackEntityCallback.EVENT.register((player, world, hand, entity, hitResult) -> { - if(ModUtils.isFortressGamemode(player)) { - if (player instanceof ServerPlayerEntity serverPlayer && entity instanceof BasePawnEntity pawn) { - final var id = pawn.getId(); - final var packet = new ClientboundFollowColonistPacket(id); - FortressServerNetworkHelper.send(serverPlayer, FortressChannelNames.FORTRESS_SELECT_COLONIST, packet); - } - - return ActionResult.SUCCESS; - } - return ActionResult.PASS; - }); } } diff --git a/src/main/java/org/minefortress/renderer/CameraTools.java b/src/main/java/org/minefortress/renderer/CameraTools.java index 6e8d72bc..ac136e3f 100644 --- a/src/main/java/org/minefortress/renderer/CameraTools.java +++ b/src/main/java/org/minefortress/renderer/CameraTools.java @@ -5,35 +5,26 @@ import net.minecraft.client.render.GameRenderer; import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec3d; -import net.remmintan.mods.minefortress.core.dtos.combat.MousePos; +import net.remmintan.mods.minefortress.core.utils.GlobalProjectionCache; import org.jetbrains.annotations.NotNull; import org.joml.Matrix4f; import org.joml.Vector3f; import org.lwjgl.system.MemoryUtil; import org.minefortress.interfaces.FortressGameRenderer; -import org.minefortress.utils.ModUtils; import java.nio.FloatBuffer; import java.nio.IntBuffer; -import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; public class CameraTools { private static Vec3d mouseBasedViewVector; - private static double oldMouseX, oldMouseY; - private static float oldPlayerXRot; - private static float oldPlayerYRot; public static Vec3d getMouseBasedViewVector(MinecraftClient minecraft, double xpos, double ypos) { - final var xRot = ModUtils.getClientPlayer().getPitch(); - final var yRot = ModUtils.getClientPlayer().getYaw(); - - if(Math.abs(xpos - oldMouseX) + Math.abs(ypos - oldMouseY) > 0.01 || xRot != oldPlayerXRot || yRot != oldPlayerYRot) { + if(GlobalProjectionCache.shouldUpdateValues("mouseBasedViewVector")) { mouseBasedViewVector = getMouseBasedViewVector(xpos, ypos, minecraft); - oldMouseX = xpos; - oldMouseY = ypos; - oldPlayerXRot = xRot; - oldPlayerYRot = yRot; } return mouseBasedViewVector; @@ -94,11 +85,9 @@ private static FloatBuffer getModelViewMatrix(MinecraftClient minecraft, boolean final var modelViewMatrix = new Matrix4f(RenderSystem.getModelViewMatrix()); final var player = minecraft.player; if(player != null) { - - - final var xRads = (float) Math.toRadians(player.getRotationClient().x); + final var xRads = (float) Math.toRadians(player.getPitch()); modelViewMatrix.rotate(xRads, new Vector3f(1, 0,0)); - final float yRads = (float) Math.toRadians(player.getRotationClient().y + 180f); + final float yRads = (float) Math.toRadians(player.getYaw() + 180f); modelViewMatrix.rotate(yRads, new Vector3f(0, 1,0)); if(translateToPlayer) { diff --git a/src/main/java/org/minefortress/renderer/gui/hud/FightHudLayer.java b/src/main/java/org/minefortress/renderer/gui/hud/CombatHudLayer.java similarity index 59% rename from src/main/java/org/minefortress/renderer/gui/hud/FightHudLayer.java rename to src/main/java/org/minefortress/renderer/gui/hud/CombatHudLayer.java index 8f2990cf..79daf1c8 100644 --- a/src/main/java/org/minefortress/renderer/gui/hud/FightHudLayer.java +++ b/src/main/java/org/minefortress/renderer/gui/hud/CombatHudLayer.java @@ -7,18 +7,14 @@ import net.minecraft.text.Text; import net.minecraft.util.BlockRotation; import net.remmintan.mods.minefortress.core.interfaces.combat.IClientFightManager; -import net.remmintan.mods.minefortress.core.interfaces.combat.IClientFightSelectionManager; import net.remmintan.mods.minefortress.core.utils.CoreModUtils; import org.minefortress.renderer.gui.widget.ItemHudElement; import org.minefortress.utils.ModUtils; import static org.minefortress.renderer.gui.blueprints.BlueprintsScreen.convertItemIconInTheGUI; -class FightHudLayer extends AbstractHudLayer { - - private static final int SELECTION_COLOR = 0xFF00FF00; - - FightHudLayer(MinecraftClient client) { +class CombatHudLayer extends AbstractHudLayer{ + CombatHudLayer(MinecraftClient client) { super(client); this.setBasepoint(0, 0, PositionX.CENTER, PositionY.BOTTOM); this.addElement( @@ -35,7 +31,11 @@ class FightHudLayer extends AbstractHudLayer { protected void renderHud(DrawContext drawContext, int screenWidth, int screenHeight) { drawTotalWarriorsAmount(drawContext, screenWidth, screenHeight); renderInfluenceFlagCosts(drawContext, screenWidth, screenHeight); - renderCurrentSelection(drawContext); + } + + @Override + public boolean shouldRender(HudState hudState) { + return hudState == HudState.COMBAT; } private void drawTotalWarriorsAmount(DrawContext drawContext, int screenWidth, int screenHeight) { @@ -69,45 +69,8 @@ private void renderInfluenceFlagCosts(DrawContext drawContext, int screenWidth, } } - private void renderCurrentSelection(DrawContext drawContext) { - final var fightSelectionManager = getFightSelectionManager(); - if(fightSelectionManager.isSelecting()) { - final var selectionStartPos = fightSelectionManager.getMouseStartPos(); - final var selectionCurPos = fightSelectionManager.getMouseEndPos(); - - final var widthScaleFactor = (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); - final var heightScaleFactor = (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); - - final var selectionStartX = (int) (selectionStartPos.x() * widthScaleFactor); - final var selectionStartY = (int) (selectionStartPos.y() * heightScaleFactor); - final var selectionCurX = (int) (selectionCurPos.x() * widthScaleFactor); - final var selectionCurY = (int) (selectionCurPos.y() * heightScaleFactor); - - drawContext.drawHorizontalLine(selectionStartX, selectionCurX, selectionStartY, SELECTION_COLOR); - drawContext.drawVerticalLine(selectionCurX, selectionStartY, selectionCurY, SELECTION_COLOR); - drawContext.drawHorizontalLine(selectionStartX, selectionCurX, selectionCurY, SELECTION_COLOR); - drawContext.drawVerticalLine(selectionStartX, selectionStartY, selectionCurY, SELECTION_COLOR); - - fightSelectionManager.getScreenPositions().forEach(screenPos -> { - final var x = (int) (screenPos.x * widthScaleFactor); - final var y = (int) (screenPos.y * heightScaleFactor); - drawContext.drawHorizontalLine(x - 2, x + 2, y, SELECTION_COLOR); - drawContext.drawVerticalLine(x, y - 2, y + 2, SELECTION_COLOR); - }); - - } - } - - private IClientFightSelectionManager getFightSelectionManager() { - return getFightManager().getSelectionManager(); - } - private static IClientFightManager getFightManager() { return ModUtils.getFortressClientManager().getFightManager(); } - @Override - public boolean shouldRender(HudState hudState) { - return hudState == HudState.COMBAT; - } } diff --git a/src/main/java/org/minefortress/renderer/gui/hud/FortressHud.java b/src/main/java/org/minefortress/renderer/gui/hud/FortressHud.java index 2737e5f3..9f22bc36 100644 --- a/src/main/java/org/minefortress/renderer/gui/hud/FortressHud.java +++ b/src/main/java/org/minefortress/renderer/gui/hud/FortressHud.java @@ -39,7 +39,8 @@ public FortressHud(MinecraftClient client) { hudLayers.add(new HoveredEntityHudLayer(client)); hudLayers.add(new ToolsHudLayer(client)); hudLayers.add(new TimeHudLayer(client)); - hudLayers.add(new FightHudLayer(client)); + hudLayers.add(new PawnsSelectionHudLayer(client)); + hudLayers.add(new CombatHudLayer(client)); hudLayers.add(new AreasHudLayer(client)); hudLayers.add(new InfluenceHudLayer(client)); hudLayers.add(new UtilsHudLayer(client)); @@ -112,7 +113,7 @@ private HudState getState() { if(BlueprintsWorld.isBlueprintsWorld(client.world)) return HudState.BLUEPRINT_EDITING; return switch (ModUtils.getFortressClientManager().getState()) { - case BUILD -> HudState.BUILD; + case BUILD_EDITING, BUILD_SELECTION -> HudState.BUILD; case COMBAT -> HudState.COMBAT; case AREAS_SELECTION -> HudState.AREAS_SELECTION; }; diff --git a/src/main/java/org/minefortress/renderer/gui/hud/ModeHudLayer.java b/src/main/java/org/minefortress/renderer/gui/hud/ModeHudLayer.java index b370321e..c49c6e87 100644 --- a/src/main/java/org/minefortress/renderer/gui/hud/ModeHudLayer.java +++ b/src/main/java/org/minefortress/renderer/gui/hud/ModeHudLayer.java @@ -38,9 +38,9 @@ protected void init() { 12, 0, Items.STONE_SHOVEL, - (btn) -> fcm.setState(FortressState.BUILD), + (btn) -> fcm.setState(FortressState.BUILD_SELECTION), "Build Mode", - () -> fcm.getState() == FortressState.BUILD + () -> fcm.getState() == FortressState.BUILD_EDITING || fcm.getState() == FortressState.BUILD_SELECTION ) ); } diff --git a/src/main/java/org/minefortress/renderer/gui/hud/PawnsSelectionHudLayer.java b/src/main/java/org/minefortress/renderer/gui/hud/PawnsSelectionHudLayer.java new file mode 100644 index 00000000..6cc5e242 --- /dev/null +++ b/src/main/java/org/minefortress/renderer/gui/hud/PawnsSelectionHudLayer.java @@ -0,0 +1,55 @@ +package org.minefortress.renderer.gui.hud; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.remmintan.mods.minefortress.core.utils.CoreModUtils; + +class PawnsSelectionHudLayer extends AbstractHudLayer { + + private static final int SELECTION_COLOR = 0xFF00FF00; +// private static final int CROSS_COLOR = 0xFF808080; + + PawnsSelectionHudLayer(MinecraftClient client) { + super(client); + this.setBasepoint(0, 0, PositionX.CENTER, PositionY.BOTTOM); + } + + @Override + protected void renderHud(DrawContext drawContext, int screenWidth, int screenHeight) { + renderCurrentSelection(drawContext); + } + + private void renderCurrentSelection(DrawContext drawContext) { + final var pawnsSelectionManager = CoreModUtils.getMineFortressManagersProvider().get_PawnsSelectionManager(); + if(pawnsSelectionManager.isSelecting()) { + final var selectionStartPos = pawnsSelectionManager.getMouseStartPos(); + final var selectionCurPos = pawnsSelectionManager.getMouseEndPos(); + + final var widthScaleFactor = (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth(); + final var heightScaleFactor = (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight(); + + final var selectionStartX = (int) (selectionStartPos.x() * widthScaleFactor); + final var selectionStartY = (int) (selectionStartPos.y() * heightScaleFactor); + final var selectionCurX = (int) (selectionCurPos.x() * widthScaleFactor); + final var selectionCurY = (int) (selectionCurPos.y() * heightScaleFactor); + + drawContext.drawHorizontalLine(selectionStartX, selectionCurX, selectionStartY, SELECTION_COLOR); + drawContext.drawVerticalLine(selectionCurX, selectionStartY, selectionCurY, SELECTION_COLOR); + drawContext.drawHorizontalLine(selectionStartX, selectionCurX, selectionCurY, SELECTION_COLOR); + drawContext.drawVerticalLine(selectionStartX, selectionStartY, selectionCurY, SELECTION_COLOR); + +// pawnsSelectionManager.getScreenPositions().forEach(screenPos -> { +// final var x = (int) (screenPos.x * widthScaleFactor); +// final var y = (int) (screenPos.y * heightScaleFactor); +// drawContext.drawHorizontalLine(x - 2, x + 2, y, CROSS_COLOR); +// drawContext.drawVerticalLine(x, y - 2, y + 2, CROSS_COLOR); +// }); + + } + } + + @Override + public boolean shouldRender(HudState hudState) { + return hudState == HudState.COMBAT || hudState == HudState.BUILD; + } +} diff --git a/src/main/java/org/minefortress/renderer/gui/hud/SelectedColonistHudLayer.java b/src/main/java/org/minefortress/renderer/gui/hud/SelectedColonistHudLayer.java index 1ba76b39..86dde070 100644 --- a/src/main/java/org/minefortress/renderer/gui/hud/SelectedColonistHudLayer.java +++ b/src/main/java/org/minefortress/renderer/gui/hud/SelectedColonistHudLayer.java @@ -6,10 +6,12 @@ import net.minecraft.entity.player.HungerConstants; import net.minecraft.text.Text; import net.remmintan.mods.minefortress.core.interfaces.entities.pawns.IHungerAwareEntity; -import org.minefortress.entity.Colonist; import net.remmintan.mods.minefortress.core.interfaces.entities.pawns.IProfessional; import net.remmintan.mods.minefortress.core.interfaces.professions.IProfession; +import net.remmintan.mods.minefortress.core.utils.CoreModUtils; +import org.minefortress.entity.Colonist; import org.minefortress.utils.ModUtils; + import java.util.Optional; public class SelectedColonistHudLayer extends AbstractHudLayer{ @@ -21,9 +23,9 @@ protected SelectedColonistHudLayer(MinecraftClient client) { @Override protected void renderHud(DrawContext drawContext, int screenWidth, int screenHeight) { - final var fortressManager = ModUtils.getFortressClientManager(); - if(fortressManager.isSelectingColonist()){ - final var pawn = fortressManager.getSelectedPawn(); + final var selectedPawnsProvider = CoreModUtils.getMineFortressManagersProvider().getSelectedColonistProvider(); + if(selectedPawnsProvider.isSelectingColonist()) { + final var pawn = selectedPawnsProvider.getSelectedPawn(); final int colonistWinX = 0; final int colonistWinY = screenHeight - 85; @@ -40,7 +42,6 @@ protected void renderHud(DrawContext drawContext, int screenWidth, int screenHei renderIcon(drawContext, heartIconX, heartIconY, 0); drawContext.drawTextWithShadow(textRenderer, healthString, heartIconX + 10, heartIconY + 2, 0xFFFFFF); - if(pawn instanceof IHungerAwareEntity hungerAwareEntity) { final String hungerString = String.format("%d/%d", hungerAwareEntity.getCurrentFoodLevel(), HungerConstants.FULL_FOOD_LEVEL); int hungerIconX = colonistWinX + width/2 + 5; @@ -49,16 +50,16 @@ protected void renderHud(DrawContext drawContext, int screenWidth, int screenHei } if(pawn instanceof IProfessional professional) { - final String professionId = professional.getProfessionId(); - final String professionName = Optional.ofNullable(fortressManager.getProfessionManager().getProfession(professionId)).map(IProfession::getTitle).orElse(""); + final var professionId = professional.getProfessionId(); + final var professionManager = ModUtils.getProfessionManager(); + final var professionName = Optional.ofNullable(professionManager.getProfession(professionId)).map(IProfession::getTitle).orElse(""); drawContext.drawTextWithShadow(textRenderer, "Profession:", colonistWinX + 5, heartIconY + textRenderer.fontHeight + 5, 0xFFFFFF); drawContext.drawTextWithShadow(textRenderer, professionName, colonistWinX + 5, heartIconY + 2 * textRenderer.fontHeight + 5 , 0xFFFFFF); } - if(pawn instanceof Colonist colonist) { drawContext.drawTextWithShadow(textRenderer, "Task:", colonistWinX + 5, heartIconY + 3 * textRenderer.fontHeight + 10, 0xFFFFFF); - final String task = colonist.getCurrentTaskDesc(); + final var task = colonist.getCurrentTaskDesc(); drawContext.drawTextWithShadow(textRenderer, task, colonistWinX + 5, heartIconY + 4 * textRenderer.fontHeight + 10, 0xFFFFFF); } } diff --git a/src/main/java/org/minefortress/renderer/gui/hud/hints/AbstractHintsLayer.java b/src/main/java/org/minefortress/renderer/gui/hud/hints/AbstractHintsLayer.java index b05229af..fd09b784 100644 --- a/src/main/java/org/minefortress/renderer/gui/hud/hints/AbstractHintsLayer.java +++ b/src/main/java/org/minefortress/renderer/gui/hud/hints/AbstractHintsLayer.java @@ -40,6 +40,6 @@ protected final void renderHud(DrawContext drawContext, int screenWidth, int scr @Override public boolean shouldRender(HudState hudState) { - return !CoreModUtils.getMineFortressManagersProvider().get_ClientFortressManager().isSelectingColonist(); + return !CoreModUtils.getMineFortressManagersProvider().getSelectedColonistProvider().isSelectingColonist(); } } diff --git a/src/main/java/org/minefortress/utils/ModUtils.java b/src/main/java/org/minefortress/utils/ModUtils.java index db2ffb9f..de04fb64 100644 --- a/src/main/java/org/minefortress/utils/ModUtils.java +++ b/src/main/java/org/minefortress/utils/ModUtils.java @@ -3,8 +3,6 @@ import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.client.option.GameOptions; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.network.ServerPlayerEntity; @@ -121,7 +119,6 @@ public static boolean shouldReleaseCamera() { final var client = MinecraftClient.getInstance(); final var options = client.options; - final var blueprintManager = getBlueprintManager(); final var selectionManager = getSelectionManager(); final var areasClientManager = getAreasClientManager(); diff --git a/src/networking/java/net/remmintan/mods/minefortress/networking/registries/ClientNetworkReceivers.java b/src/networking/java/net/remmintan/mods/minefortress/networking/registries/ClientNetworkReceivers.java index 5549e854..6be01124 100644 --- a/src/networking/java/net/remmintan/mods/minefortress/networking/registries/ClientNetworkReceivers.java +++ b/src/networking/java/net/remmintan/mods/minefortress/networking/registries/ClientNetworkReceivers.java @@ -3,9 +3,8 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.minecraft.network.PacketByteBuf; import net.minecraft.util.Identifier; -import net.remmintan.mods.minefortress.networking.s2c.S2CSyncAreasPacket; -import net.remmintan.mods.minefortress.networking.helpers.FortressChannelNames; import net.remmintan.mods.minefortress.core.interfaces.networking.FortressS2CPacket; +import net.remmintan.mods.minefortress.networking.helpers.FortressChannelNames; import net.remmintan.mods.minefortress.networking.s2c.*; import java.util.function.Function; @@ -15,7 +14,6 @@ public class ClientNetworkReceivers { public static void registerReceivers() { registerReceiver(FortressChannelNames.FINISH_TASK, ClientboundTaskExecutedPacket::new); registerReceiver(FortressChannelNames.FORTRESS_MANAGER_SYNC, ClientboundSyncFortressManagerPacket::new); - registerReceiver(FortressChannelNames.FORTRESS_SELECT_COLONIST, ClientboundFollowColonistPacket::new); registerReceiver(FortressChannelNames.FORTRESS_ADD_BLUEPRINT, ClientboundAddBlueprintPacket::new); registerReceiver(FortressChannelNames.FORTRESS_UPDATE_BLUEPRINT, ClientboundUpdateBlueprintPacket::new); registerReceiver(FortressChannelNames.FORTRESS_RESET_BLUEPRINT, ClientboundResetBlueprintPacket::new); diff --git a/src/networking/java/net/remmintan/mods/minefortress/networking/s2c/ClientboundFollowColonistPacket.java b/src/networking/java/net/remmintan/mods/minefortress/networking/s2c/ClientboundFollowColonistPacket.java deleted file mode 100644 index bdcb4f17..00000000 --- a/src/networking/java/net/remmintan/mods/minefortress/networking/s2c/ClientboundFollowColonistPacket.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.remmintan.mods.minefortress.networking.s2c; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.entity.LivingEntity; -import net.minecraft.network.PacketByteBuf; -import net.remmintan.mods.minefortress.core.interfaces.networking.FortressS2CPacket; - -public class ClientboundFollowColonistPacket implements FortressS2CPacket { - - private final int entityId; - - public ClientboundFollowColonistPacket(int entityId) { - this.entityId = entityId; - } - - public ClientboundFollowColonistPacket(PacketByteBuf buf) { - this.entityId = buf.readInt(); - } - - @Override - public void handle(MinecraftClient client) { - final var fortressManager = getManagersProvider().get_ClientFortressManager(); - - final ClientWorld world = client.world; - if(world == null) throw new IllegalStateException("Client world is null"); - final Entity entity = world.getEntityById(entityId); - if(entity == null) throw new IllegalStateException("Entity with id " + entityId + " does not exist!"); - if(entity instanceof LivingEntity le) { - fortressManager.select(le); - } - } - - @Override - public void write(PacketByteBuf buf) { - buf.writeInt(this.entityId); - } -}