Skip to content

Commit

Permalink
Merge branch 'version/main' into feature/colony_expeditions_120
Browse files Browse the repository at this point in the history
  • Loading branch information
Thodor12 committed Jan 12, 2025
2 parents 84820b3 + abbb0d9 commit a372d22
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 222 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.minecolonies.core.entity.pathfinding.navigation;
package com.minecolonies.api.entity.pathfinding;

/**
* Interface for navigators which keep an internal heuristic mod
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.minecolonies.api.entity.pathfinding;

import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate;
import com.minecolonies.core.entity.pathfinding.pathjobs.AbstractPathJob;
import com.minecolonies.core.entity.pathfinding.pathresults.PathResult;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Describes the Navigator used by minecolonies entities
*/
public interface IMinecoloniesNavigator
{
/**
* Sets a new pathjob to execute
*
* @param job to run
* @param dest
* @param speedFactor
* @param safeDestination
* @param <T>
* @return null or new pathresult
*/
@Nullable
<T extends AbstractPathJob> PathResult<T> setPathJob(
@NotNull AbstractPathJob job,
BlockPos dest,
double speedFactor, boolean safeDestination);

/**
* Indirectly triggers a recalulation, by marking the navigator as done
*/
void recalc();

/**
* Returns the pathresult holding the current pathing task and result
*
* @return
*/
PathResult getPathResult();

/**
* Gets the safe destination the entity wants to travel to
*
* @return
*/
BlockPos getSafeDestination();

/**
* Gets the entity of the navigator
*
* @return
*/
Mob getOurEntity();

/**
* Pauses the navigator for X ticks from starting any new pathing tasks
*
* @param pauseTicks
*/
void setPauseTicks(int pauseTicks);

/**
* Returns the stuck handler used by the navigator
*
* @return
*/
IStuckHandler<MinecoloniesAdvancedPathNavigate> getStuckHandler();
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
package com.minecolonies.api.entity.pathfinding;

import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate;
import net.minecraft.world.entity.ai.navigation.PathNavigation;

/**
* Stuck handler for pathing, gets called to check/deal with stuck status
*/
public interface IStuckHandler
public interface IStuckHandler<NAV extends PathNavigation & IMinecoloniesNavigator>
{
/**
* Checks if the navigator is stuck
*
* @param navigator navigator to check
*/
void checkStuck(final AbstractAdvancedPathNavigate navigator);
void checkStuck(final NAV navigator);

void resetGlobalStuckTimers();

/**
* Returns the stuck level (0-9) indicating how long the entity is stuck and which stuck actions got used
*
* @return
*/
public int getStuckLevel();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.minecolonies.api.colony.IColony;
import com.minecolonies.api.colony.IColonyManager;
import com.minecolonies.api.entity.citizen.AbstractEntityCitizen;
import com.minecolonies.api.entity.citizen.Skill;
import com.minecolonies.api.entity.pathfinding.IMinecoloniesNavigator;
import com.minecolonies.api.util.constant.translation.CommandTranslationConstants;
import com.minecolonies.core.colony.buildings.modules.WorkerBuildingModule;
import com.minecolonies.core.commands.commandTypes.IMCColonyOfficerCommand;
Expand All @@ -15,7 +15,9 @@
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;

Expand Down Expand Up @@ -44,18 +46,19 @@ public int onExecute(final CommandContext<CommandSourceStack> context)
final IColony colony = IColonyManager.getInstance().getColonyByDimension(colonyID, sender == null ? Level.OVERWORLD : context.getSource().getLevel().dimension());
if (colony == null)
{
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_COLONY_ID_NOT_FOUND, colonyID), true);
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_COLONY_ID_NOT_FOUND, colonyID), false);
return 0;
}

final ICitizenData citizenData = colony.getCitizenManager().getCivilian(IntegerArgumentType.getInteger(context, CITIZENID_ARG));

if (citizenData == null)
{
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_NOT_FOUND), true);
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_NOT_FOUND), false);
return 0;
}

context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO, citizenData.getId(), citizenData.getName()), false);
final Optional<AbstractEntityCitizen> optionalEntityCitizen = citizenData.getEntity();

if (optionalEntityCitizen.isPresent())
Expand All @@ -67,45 +70,31 @@ public int onExecute(final CommandContext<CommandSourceStack> context)
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_POSITION,
citizenPosition.getX(),
citizenPosition.getY(),
citizenPosition.getZ()), true);
final BlockPos homePosition = citizenData.getHomePosition();
context.getSource()
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_HOME_POSITION,
homePosition.getX(),
homePosition.getY(),
homePosition.getZ()), true);
citizenPosition.getZ()).withStyle(styleWithTeleport(citizenPosition)), false);

context.getSource()
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_HEALTH, entityCitizen.getHealth(), entityCitizen.getMaxHealth()), true);
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_HEALTH, entityCitizen.getHealth(), entityCitizen.getMaxHealth()), false);
}
else
{
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_POSITION,
citizenData.getLastPosition().getX(),
citizenData.getLastPosition().getY(),
citizenData.getLastPosition().getZ()), true);
citizenData.getLastPosition().getZ()).withStyle(styleWithTeleport(citizenData.getLastPosition())), false);

context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_NOT_LOADED), true);
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_NOT_LOADED), false);
}

context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO, citizenData.getId(), citizenData.getName()), true);

final AbstractEntityCitizen entityCitizen = optionalEntityCitizen.get();

final BlockPos citizenPosition = entityCitizen.blockPosition();
context.getSource()
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_POSITION,
citizenPosition.getX(),
citizenPosition.getY(),
citizenPosition.getZ()), true);
final BlockPos homePosition = citizenData.getHomePosition();
context.getSource()
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_HOME_POSITION, homePosition.getX(), homePosition.getY(), homePosition.getZ()),
true);
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_HOME_POSITION,
homePosition.getX(),
homePosition.getY(),
homePosition.getZ()).withStyle(styleWithTeleport(homePosition)), false);

if (citizenData.getWorkBuilding() == null)
{
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_NO_WORKING_POSITION), true);
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_NO_WORKING_POSITION), false);
}
else
{
Expand All @@ -114,45 +103,52 @@ public int onExecute(final CommandContext<CommandSourceStack> context)
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_WORKING_POSITION,
workingPosition.getX(),
workingPosition.getY(),
workingPosition.getZ()), true);
workingPosition.getZ()).withStyle(styleWithTeleport(workingPosition)), false);
}


Object[] skills =
new Object[] {citizenData.getCitizenSkillHandler().getSkills().get(Skill.Athletics).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Dexterity).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Strength).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Agility).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Stamina).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Mana).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Adaptability).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Focus).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Creativity).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Knowledge).getLevel(),
citizenData.getCitizenSkillHandler().getSkills().get(Skill.Intelligence).getLevel()};
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_SKILLS, skills), true);

if (citizenData.getJob() == null)
{
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_NO_JOB), true);
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_NO_ACTIVITY), true);
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_NO_JOB), false);
context.getSource().sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_NO_ACTIVITY), false);
}
else if (citizenData.getWorkBuilding() != null && citizenData.getWorkBuilding().hasModule(WorkerBuildingModule.class))
{
context.getSource()
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_JOB,
citizenData.getWorkBuilding().getFirstModuleOccurance(WorkerBuildingModule.class).getJobEntry().getTranslationKey()), true);
citizenData.getWorkBuilding().getFirstModuleOccurance(WorkerBuildingModule.class).getJobEntry().getTranslationKey()), false);

if (optionalEntityCitizen.isPresent())
{
final AbstractEntityCitizen entityCitizen = optionalEntityCitizen.get();
context.getSource()
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_ACTIVITY,
((EntityCitizen) entityCitizen).getCitizenAI().getState(),
entityCitizen.getCitizenJobHandler().getColonyJob().getNameTagDescription(),
entityCitizen.getCitizenJobHandler().getWorkAI().getState()), false);
}
}

if (optionalEntityCitizen.isPresent())
{
final AbstractEntityCitizen entityCitizen = optionalEntityCitizen.get();
context.getSource()
.sendSuccess(() -> Component.translatable(CommandTranslationConstants.COMMAND_CITIZEN_INFO_ACTIVITY,
((EntityCitizen) entityCitizen).getCitizenAI().getState(),
entityCitizen.getCitizenJobHandler().getColonyJob().getNameTagDescription(),
entityCitizen.getCitizenJobHandler().getWorkAI().getState()), true);
.sendSuccess(() -> Component.literal("Stuck level: " + ((IMinecoloniesNavigator) entityCitizen.getNavigation()).getStuckHandler().getStuckLevel()), false);
}

return 1;
}

/**
* Creates a style with clickable teleport
*
* @param pos
* @return
*/
private static Style styleWithTeleport(final BlockPos pos)
{
return Style.EMPTY.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/tp " + pos.getX() + " " + pos.getY() + " " + pos.getZ()));
}

/**
* Name string of the command.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ private void findBedAndTryToSleep()
usedBed = homePos;
}

if (EntityNavigationUtils.walkToPosInBuilding(citizen, usedBed, citizen.getCitizenData().getHomeBuilding(), 5))
if (EntityNavigationUtils.walkToPosInBuilding(citizen, usedBed, citizen.getCitizenData().getHomeBuilding(), 12))
{
bedTicks++;
if (!citizen.getCitizenSleepHandler().trySleep(usedBed))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
import com.minecolonies.core.colony.jobs.JobDeliveryman;
import com.minecolonies.core.colony.requestsystem.resolvers.StationRequestResolver;
import com.minecolonies.core.entity.pathfinding.navigation.EntityNavigationUtils;
import com.minecolonies.core.util.citizenutils.CitizenItemUtils;
import com.minecolonies.core.entity.pathfinding.proxy.EntityCitizenWalkToProxy;
import com.minecolonies.core.tileentities.TileEntityRack;
import com.minecolonies.core.util.WorkerUtil;
import com.minecolonies.core.util.citizenutils.CitizenItemUtils;
import com.mojang.authlib.GameProfile;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
Expand Down Expand Up @@ -286,7 +286,7 @@ public void setWalkTo(final BlockPos walkto)
*/
private IAIState walkToState()
{
if (!walkWithProxy(walkTo, DEFAULT_RANGE_FOR_DELAY))
if (!walkToSafePos(walkTo))
{
return getState();
}
Expand Down Expand Up @@ -900,6 +900,8 @@ protected final boolean walkWithProxy(@NotNull final BlockPos stand, final int r
workOnBlock(null, DELAY_RECHECK);
return true;
}

worker.getNavigation().stop();
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ else if (raider.blockPosition().distSqr(targetBlock) < 25)
walkTimer = raider.level.getGameTime() + TICKS_SECOND * 30;
walkInBuilding = raider.getColony().getBuildingManager().getBuilding(targetBlock);
}
else if (raider.getNavigation().isDone() || raider.getNavigation().getDesiredPos() == null)
else if (raider.getNavigation().isDone())
{
final List<BlockPos> wayPoints = ((IColonyRaidEvent) event).getWayPoints();
final BlockPos moveToPos = ShipBasedRaiderUtils.chooseWaypointFor(wayPoints, raider.blockPosition(), targetBlock);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,40 @@ public static void syncDebugReachedPositions(final HashSet<BlockPos> reached, fi
*/
public static BlockPos prepareStart(@NotNull final LivingEntity entity)
{
@NotNull BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(Mth.floor(entity.getX()),
final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(Mth.floor(entity.getX()),
Mth.floor(entity.getY()),
Mth.floor(entity.getZ()));
final Level level = entity.level;
BlockState bs = level.getBlockState(pos);

// Check if the entity is standing ontop of another block with part of its bb
final BlockPos.MutableBlockPos below = new BlockPos.MutableBlockPos(pos.getX(), pos.getY() - 1, pos.getZ());
if (entity.onGround() && SurfaceType.getSurfaceType(level, level.getBlockState(below), below) != SurfaceType.WALKABLE)
{
int minX = Mth.floor(entity.getBoundingBox().minX);
int minZ = Mth.floor(entity.getBoundingBox().minZ);
int maxX = Mth.floor(entity.getBoundingBox().maxX);
int maxZ = Mth.floor(entity.getBoundingBox().maxZ);

for (int x = minX; x <= maxX; x++)
{
for (int z = minZ; z <= maxZ; z++)
{
final BlockPos toCheck = new BlockPos(x, below.getY(), z);
// Only check other positions than the current
if ((x != pos.getX() || z != pos.getZ())
&& SurfaceType.getSurfaceType(level, level.getBlockState(toCheck), toCheck) == SurfaceType.WALKABLE
&& Math.abs(ShapeUtil.max(level.getBlockState(toCheck).getCollisionShape(level, toCheck), Direction.Axis.Y) + toCheck.getY() - entity.getY()) < 0.1)
{
pos.setX(x);
pos.setZ(z);
below.setX(x);
below.setZ(z);
}
}
}
}

// 1 Up when we're standing within this collision shape
final VoxelShape collisionShape = bs.getCollisionShape(level, pos);
final boolean isFineToStandIn = canStandInSolidBlock(bs);
Expand Down
Loading

0 comments on commit a372d22

Please sign in to comment.