Skip to content

Commit

Permalink
Add pawns selection to build mode, disalbed the ability to build for now
Browse files Browse the repository at this point in the history
  • Loading branch information
remmintan committed Mar 4, 2024
1 parent 18b9fe4 commit ccddb73
Show file tree
Hide file tree
Showing 30 changed files with 394 additions and 375 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

public enum FortressState {

BUILD,
BUILD_SELECTION,
BUILD_EDITING,
COMBAT,
AREAS_SELECTION,

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package net.remmintan.mods.minefortress.core;

public enum PawnsSelectionState {

SELECTING,
BUILDING,

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,20 +21,13 @@
import java.util.UUID;

public interface IClientFortressManager extends IFortressManager {
void select(LivingEntity colonist);

void jumpToCampfire();

void updateBuildings(List<IEssentialBuildingInfo> buildings);

void setSpecialBlocks(Map<Block, List<BlockPos>> specialBlocks, Map<Block, List<BlockPos>> blueprintSpecialBlocks);

boolean isSelectingColonist();

LivingEntity getSelectedPawn();

void stopSelectingColonist();

void open_HireScreen(MinecraftClient client, String screenName, Map<String, IHireInfo> professions);

void sync(
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package net.remmintan.mods.minefortress.core.interfaces.client;

import net.minecraft.entity.LivingEntity;

public interface ISelectedColonistProvider {

boolean isSelectingColonist();

LivingEntity getSelectedPawn();

}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
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();

boolean isSelecting();

boolean isSelectionStarted();

void forEachSelected(Consumer<ITargetedPawn> action);
void forEachSelected(Consumer<IFortressAwareEntity> action);

MousePos getMouseStartPos();

Expand Down
Original file line number Diff line number Diff line change
@@ -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<ITargetedPawn> action);

}
Original file line number Diff line number Diff line change
@@ -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<String, Long> 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;
}

}
52 changes: 52 additions & 0 deletions src/main/java/org/minefortress/controls/MouseEvents.java
Original file line number Diff line number Diff line change
@@ -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);
}

}
40 changes: 9 additions & 31 deletions src/main/java/org/minefortress/entity/renderer/PawnRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,14 @@
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;
import org.joml.Vector3f;
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;

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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<BasePawnEntity>)this.getModel();
colonistModel.hat.visible = true;
Expand Down
19 changes: 6 additions & 13 deletions src/main/java/org/minefortress/fight/ClientFightManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,21 @@
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;
import org.minefortress.entity.Colonist;
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) {
Expand All @@ -38,20 +31,20 @@ 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();
final var playerId= ModUtils.getCurrentPlayerUUID();
if(masterPlayerId.map(it -> it.equals(playerId)).orElse(false))
return;
}
selectionManager.forEachSelected(it -> it.setAttackTarget(livingEntity));
targetedSelectionManager.forEachTargetedPawn(it -> it.setAttackTarget(livingEntity));
}

@Override
Expand Down
Loading

0 comments on commit ccddb73

Please sign in to comment.