From 1351e95380c43a8918eae58ea9a715210d4a2d39 Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Fri, 20 Sep 2024 15:42:42 +0200 Subject: [PATCH 1/4] Fix teams assignment for entities and deletion improvements --- .../entity/citizen/AbstractEntityCitizen.java | 14 ++++ .../entity/mobs/AbstractEntityRaiderMob.java | 42 +++-------- .../other/AbstractFastMinecoloniesEntity.java | 71 +++++++++++++++++++ .../com/minecolonies/core/colony/Colony.java | 35 ++++++--- .../core/colony/ColonyManager.java | 64 ++++++++++++----- .../core/colony/managers/CitizenManager.java | 17 +---- .../core/entity/citizen/EntityCitizen.java | 26 +------ .../core/entity/mobs/EntityMercenary.java | 47 ++++++------ .../server/colony/ColonyDeleteOwnMessage.java | 22 ++---- 9 files changed, 199 insertions(+), 139 deletions(-) diff --git a/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java b/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java index 5f9b3a51179..6d631267eb1 100755 --- a/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java +++ b/src/main/java/com/minecolonies/api/entity/citizen/AbstractEntityCitizen.java @@ -46,8 +46,10 @@ import net.minecraft.world.item.ShieldItem; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; +import net.minecraft.world.scores.PlayerTeam; import net.minecraftforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -233,6 +235,18 @@ public boolean isNoAi() return false; } + @Override + @Nullable + protected PlayerTeam getAssignedTeam() + { + final ICitizenColonyHandler citizenColonyHandler = getCitizenColonyHandler(); + if (citizenColonyHandler == null || citizenColonyHandler.getColony() == null) + { + return null; + } + return citizenColonyHandler.getColony().getTeam(); + } + /** * Sets the textures of all citizens and distinguishes between male and female. */ diff --git a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java index 1512667c435..b1172cc3ffe 100644 --- a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java @@ -21,6 +21,7 @@ import com.minecolonies.api.util.ColonyUtils; import com.minecolonies.api.util.DamageSourceKeys; import com.minecolonies.api.util.Log; +import com.minecolonies.core.colony.Colony; import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.navigation.PathingStuckHandler; import net.minecraft.nbt.CompoundTag; @@ -521,23 +522,23 @@ private void onEnterChunk(final ChunkPos newChunkPos) } } - @org.jetbrains.annotations.Nullable + @Nullable @Override public SpawnGroupData finalizeSpawn( final ServerLevelAccessor worldIn, final DifficultyInstance difficultyIn, final MobSpawnType reason, - @org.jetbrains.annotations.Nullable final SpawnGroupData spawnDataIn, - @org.jetbrains.annotations.Nullable final CompoundTag dataTag) + @Nullable final SpawnGroupData spawnDataIn, + @Nullable final CompoundTag dataTag) { RaiderMobUtils.setEquipment(this); return super.finalizeSpawn(worldIn, difficultyIn, reason, spawnDataIn, dataTag); } @Override - public void remove(RemovalReason reason) + public void remove(@NotNull final RemovalReason reason) { - if (!level().isClientSide && colony != null && eventID > 0) + if (!level.isClientSide && colony != null && eventID > 0) { colony.getEventManager().unregisterEntity(this, eventID); } @@ -732,38 +733,15 @@ public void initStatsFor(final double baseHealth, final double difficulty, final this.setEnvDamageImmunity(true); } - if (difficulty >= TEAM_DIFFICULTY) - { - level().getScoreboard().addPlayerToTeam(getScoreboardName(), checkOrCreateTeam()); - } - this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(baseHealth); this.setHealth(this.getMaxHealth()); } - /** - * Creates or gets the scoreboard team - * - * @return Scoreboard team - */ - private PlayerTeam checkOrCreateTeam() - { - if (this.level().getScoreboard().getPlayerTeam(getTeamName()) == null) - { - this.level().getScoreboard().addPlayerTeam(getTeamName()); - this.level().getScoreboard().getPlayerTeam(getTeamName()).setAllowFriendlyFire(false); - } - return this.level().getScoreboard().getPlayerTeam(getTeamName()); - } - - /** - * Gets the scoreboard team name - * - * @return - */ - protected String getTeamName() + @Override + @Nullable + protected PlayerTeam getAssignedTeam() { - return RAID_TEAM; + return Colony.checkOrCreateTeam(level, RAID_TEAM); } /** diff --git a/src/main/java/com/minecolonies/api/entity/other/AbstractFastMinecoloniesEntity.java b/src/main/java/com/minecolonies/api/entity/other/AbstractFastMinecoloniesEntity.java index b124e73d7e4..c699dfb68c5 100644 --- a/src/main/java/com/minecolonies/api/entity/other/AbstractFastMinecoloniesEntity.java +++ b/src/main/java/com/minecolonies/api/entity/other/AbstractFastMinecoloniesEntity.java @@ -14,12 +14,15 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.entity.EntityTypeTest; import net.minecraft.world.phys.Vec3; +import net.minecraft.world.scores.PlayerTeam; +import net.minecraft.world.scores.Team; import net.minecraftforge.common.util.ITeleporter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * Special abstract minecolonies mob that overrides laggy vanilla behaviour. @@ -311,6 +314,74 @@ public void updateSwimAmount() } + /** + * Get the team this entity is assigned to. + * + * @return the team instance. + */ + @Nullable + protected abstract PlayerTeam getAssignedTeam(); + + @Override + @Nullable + public final Team getTeam() + { + final PlayerTeam assignedTeam = getAssignedTeam(); + registerToTeamInternal(assignedTeam); + return assignedTeam; + } + + /** + * Register this entity to its own assigned team. + */ + public void registerToTeam() + { + registerToTeamInternal(getAssignedTeam()); + } + + /** + * Internal method for team registration. + * + * @param team the team to register to. + */ + private void registerToTeamInternal(@Nullable final PlayerTeam team) + { + if (team != null && !isInTeam(team)) + { + level.getScoreboard().addPlayerToTeam(getScoreboardName(), team); + } + } + + /** + * Remove the entity from its own assigned team. + */ + public void removeFromTeam() + { + final PlayerTeam team = getAssignedTeam(); + if (team != null && isInTeam(team)) + { + level.getScoreboard().removePlayerFromTeam(getScoreboardName(), team); + } + } + + /** + * Check if the current entity is assigned to the provided team. + * + * @param team the input team. + * @return true if so. + */ + private boolean isInTeam(@NotNull final PlayerTeam team) + { + return Objects.equals(level.getScoreboard().getPlayersTeam(getScoreboardName()), team); + } + + @Override + public void remove(@NotNull final RemovalReason reason) + { + super.remove(reason); + removeFromTeam(); + } + /** * Static Byte values to avoid frequent autoboxing */ diff --git a/src/main/java/com/minecolonies/core/colony/Colony.java b/src/main/java/com/minecolonies/core/colony/Colony.java index 317800d5601..df1967fe0b1 100644 --- a/src/main/java/com/minecolonies/core/colony/Colony.java +++ b/src/main/java/com/minecolonies/core/colony/Colony.java @@ -366,7 +366,7 @@ protected Colony(final int id, @Nullable final Level world) { this.dimensionId = world.dimension(); onWorldLoad(world); - checkOrCreateTeam(); + checkOrCreateTeam(world, getTeamName()); } this.permissions = new Permissions(this); researchManager = new ResearchManager(this); @@ -631,23 +631,33 @@ public void updateAttackingPlayers() } @Override + @Nullable public PlayerTeam getTeam() { // This getter will create the team if it doesn't exist. Could do something different though in the future. - return checkOrCreateTeam(); + return checkOrCreateTeam(world, getTeamName()); } /** - * Check or create the team. + * Check or create a team. + * + * @param level the level to create the team in. + * @param name the team name. */ - private PlayerTeam checkOrCreateTeam() + @Nullable + public static PlayerTeam checkOrCreateTeam(@Nullable Level level, String name) { - if (this.world.getScoreboard().getPlayerTeam(getTeamName()) == null) + if (level == null) + { + return null; + } + + PlayerTeam team = level.getScoreboard().getPlayerTeam(name); + if (team == null) { - this.world.getScoreboard().addPlayerTeam(getTeamName()); - this.world.getScoreboard().getPlayerTeam(getTeamName()).setAllowFriendlyFire(false); + team = level.getScoreboard().addPlayerTeam(name); } - return this.world.getScoreboard().getPlayerTeam(getTeamName()); + return team; } /** @@ -659,10 +669,13 @@ public void setColonyColor(final ChatFormatting colonyColor) { if (this.world != null) { - checkOrCreateTeam(); this.colonyTeamColor = colonyColor; - this.world.getScoreboard().getPlayerTeam(getTeamName()).setColor(colonyColor); - this.world.getScoreboard().getPlayerTeam(getTeamName()).setPlayerPrefix(Component.literal(colonyColor.toString())); + final PlayerTeam team = getTeam(); + if (team != null) + { + team.setColor(colonyColor); + team.setPlayerPrefix(Component.literal(colonyColor.toString())); + } } this.markDirty(); } diff --git a/src/main/java/com/minecolonies/core/colony/ColonyManager.java b/src/main/java/com/minecolonies/core/colony/ColonyManager.java index 073006e0c75..d315237be53 100755 --- a/src/main/java/com/minecolonies/core/colony/ColonyManager.java +++ b/src/main/java/com/minecolonies/core/colony/ColonyManager.java @@ -1,9 +1,13 @@ package com.minecolonies.core.colony; import com.minecolonies.api.blocks.AbstractBlockHut; -import com.minecolonies.api.colony.*; +import com.minecolonies.api.colony.ICitizenData; +import com.minecolonies.api.colony.IColony; +import com.minecolonies.api.colony.IColonyManager; +import com.minecolonies.api.colony.IColonyView; import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.colony.buildings.views.IBuildingView; +import com.minecolonies.api.colony.event.ColonyDeletedEvent; import com.minecolonies.api.colony.event.ColonyViewUpdatedEvent; import com.minecolonies.api.colony.managers.events.ColonyManagerLoadedEvent; import com.minecolonies.api.colony.managers.events.ColonyManagerUnloadedEvent; @@ -32,6 +36,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.scores.PlayerTeam; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.TickEvent; import net.minecraftforge.server.ServerLifecycleHooks; @@ -59,7 +64,7 @@ public final class ColonyManager implements IColonyManager private final Map, ColonyList> colonyViews = new HashMap<>(); /** - * Recipemanager of this server. + * Recipe manager of this server. */ private final IRecipeManager recipeManager = new StandardRecipeManager(); @@ -102,7 +107,7 @@ public IColony createColony(@NotNull final Level w, final BlockPos pos, @NotNull colony.getPackageManager().addImportantColonyPlayer((ServerPlayer) player); colony.getPackageManager().addCloseSubscriber((ServerPlayer) player); - Log.getLogger().info(String.format("New Colony Id: %d by %s", colony.getID(), player.getName().getString())); + Log.getLogger().info("New Colony Id: {} by {}", colony.getID(), player.getName().getString()); if (colony.getWorld() == null) { @@ -134,38 +139,46 @@ public void deleteColonyByDimension(final int id, final boolean canDestroy, fina */ private void deleteColony(@Nullable final IColony iColony, final boolean canDestroy) { - if (!(iColony instanceof Colony)) + if (!(iColony instanceof final Colony colony)) { return; } - final Colony colony = (Colony) iColony; final int id = colony.getID(); final Level world = colony.getWorld(); if (world == null) { - Log.getLogger().warn("Deleting Colony " + id + " errored: World is Null"); + Log.getLogger().warn("Deleting Colony {} errored: World is Null", id); + return; + } + + final IColonyManagerCapability cap = world.getCapability(COLONY_MANAGER_CAP, null).resolve().orElse(null); + if (cap == null) + { + Log.getLogger().warn(MISSING_WORLD_CAP_MESSAGE); return; } try { + Log.getLogger().info("Removing claimed area for {}", id); ChunkDataHelper.claimColonyChunks(world, false, id, colony.getCenter()); - Log.getLogger().info("Removing citizens for " + id); + + Log.getLogger().info("Removing citizens for {}", id); for (final ICitizenData citizenData : new ArrayList<>(colony.getCitizenManager().getCitizens())) { - Log.getLogger().info("Kill Citizen " + citizenData.getName()); + Log.getLogger().info("Kill Citizen {}", citizenData.getName()); citizenData.getEntity().ifPresent(entityCitizen -> entityCitizen.die(world.damageSources().source(DamageSourceKeys.CONSOLE))); } - Log.getLogger().info("Removing buildings for " + id); + Log.getLogger().info("Removing buildings for {}", id); for (final IBuilding building : new ArrayList<>(colony.getBuildingManager().getBuildings().values())) { try { final BlockPos location = building.getPosition(); - Log.getLogger().info("Delete Building at " + location); + Log.getLogger().info("Delete Building at {}", location); if (canDestroy) { building.deconstruct(); @@ -173,7 +186,7 @@ private void deleteColony(@Nullable final IColony iColony, final boolean canDest building.destroy(); if (world.getBlockState(location).getBlock() instanceof AbstractBlockHut) { - Log.getLogger().info("Found Block, deleting " + world.getBlockState(location).getBlock()); + Log.getLogger().info("Found Block, deleting {}", world.getBlockState(location).getBlock()); world.removeBlock(location, false); } } @@ -185,6 +198,7 @@ private void deleteColony(@Nullable final IColony iColony, final boolean canDest try { + Log.getLogger().info("Unregistering event handlers for {}", id); MinecraftForge.EVENT_BUS.unregister(colony.getEventHandler()); } catch (final NullPointerException e) @@ -192,24 +206,36 @@ private void deleteColony(@Nullable final IColony iColony, final boolean canDest Log.getLogger().warn("Can't unregister the event handler twice"); } - Log.getLogger().info("Deleting colony: " + colony.getID()); + // Delete the colony + Log.getLogger().info("Deleting colony {}", colony.getID()); + cap.deleteColony(id); - final IColonyManagerCapability cap = world.getCapability(COLONY_MANAGER_CAP, null).resolve().orElse(null); - if (cap == null) + // Delete the colony team + Log.getLogger().info("Deleting team for colony {}", id); + final PlayerTeam team = colony.getTeam(); + if (team != null) { - Log.getLogger().warn(MISSING_WORLD_CAP_MESSAGE); - return; + world.getScoreboard().removePlayerTeam(team); + } + + // Send the deletion event + try + { + MinecraftForge.EVENT_BUS.post(new ColonyDeletedEvent(colony)); + } + catch (final Exception e) + { + Log.getLogger().error("Error during ColonyDeletedEvent", e); } - cap.deleteColony(id); BackUpHelper.markColonyDeleted(colony.getID(), colony.getDimension()); colony.getImportantMessageEntityPlayers() .forEach(player -> Network.getNetwork().sendToPlayer(new ColonyViewRemoveMessage(colony.getID(), colony.getDimension()), (ServerPlayer) player)); - Log.getLogger().info("Successfully deleted colony: " + id); + Log.getLogger().info("Successfully deleted colony {}", id); } catch (final RuntimeException e) { - Log.getLogger().warn("Deleting Colony " + id + " errored:", e); + Log.getLogger().warn("Deleting Colony {} errored:", id, e); } } diff --git a/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java b/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java index b70d89af673..fedcd319d8b 100755 --- a/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java +++ b/src/main/java/com/minecolonies/core/colony/managers/CitizenManager.java @@ -138,10 +138,10 @@ public void registerCivilian(final AbstractCivilianEntity entity) final Optional existingCitizen = data.getEntity(); - if (!existingCitizen.isPresent()) + if (existingCitizen.isEmpty()) { data.setEntity(entity); - entity.level.getScoreboard().addPlayerToTeam(entity.getScoreboardName(), colony.getTeam()); + entity.registerToTeam(); return; } @@ -158,18 +158,7 @@ public void unregisterCivilian(final AbstractCivilianEntity entity) final ICitizenData data = citizens.get(entity.getCivilianID()); if (data != null && data.getEntity().isPresent() && data.getEntity().get() == entity) { - try - { - if (colony.getWorld().getScoreboard().getPlayersTeam(entity.getScoreboardName()) == colony.getTeam()) - { - colony.getWorld().getScoreboard().removePlayerFromTeam(entity.getScoreboardName(), colony.getTeam()); - } - } - catch (Exception ignored) - { - // For some weird reason we can get an exception here, though the exception is thrown for team != colony team which we check == on before - } - + entity.removeFromTeam(); citizens.get(entity.getCivilianID()).setEntity(null); } } diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java index 1306c05bd1a..c2dde9b5526 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java @@ -635,6 +635,7 @@ private void eatFoodInteraction(final ItemStack usedStack, final Player player, } @Override + @NotNull public String getScoreboardName() { return getName().getString() + " (" + getCivilianID() + ")"; @@ -1790,31 +1791,6 @@ public void setRemoved(final RemovalReason reason) super.setRemoved(reason); } - @Override - public Team getTeam() - { - if (level == null || (level.isClientSide && cachedTeamName == null)) - { - return null; - } - - if (cachedTeam != null) - { - return cachedTeam; - } - - if (level.isClientSide) - { - cachedTeam = level.getScoreboard().getPlayerTeam(this.cachedTeamName); - } - else - { - cachedTeam = level.getScoreboard().getPlayerTeam(getScoreboardName()); - } - - return cachedTeam; - } - @Override public void setCustomName(@Nullable final Component name) { diff --git a/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenary.java b/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenary.java index 36ec2876868..2e47c72d2a9 100755 --- a/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenary.java +++ b/src/main/java/com/minecolonies/core/entity/mobs/EntityMercenary.java @@ -10,7 +10,6 @@ import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickRateStateMachine; import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.TickingTransition; import com.minecolonies.api.entity.other.AbstractFastMinecoloniesEntity; -import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; import com.minecolonies.api.sounds.MercenarySounds; import com.minecolonies.api.util.DamageSourceKeys; import com.minecolonies.api.util.ItemStackUtils; @@ -18,28 +17,37 @@ import com.minecolonies.api.util.MessageUtils; import com.minecolonies.core.entity.ai.minimal.EntityAIInteractToggleAble; import com.minecolonies.core.entity.citizen.EntityCitizen; -import com.minecolonies.core.entity.pathfinding.proxy.GeneralEntityWalkToProxy; +import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.navigation.MinecoloniesAdvancedPathNavigate; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.item.enchantment.Enchantments; +import com.minecolonies.core.entity.pathfinding.proxy.GeneralEntityWalkToProxy; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.util.Tuple; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; import net.minecraft.world.entity.ai.goal.FloatGoal; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.animal.horse.Llama; import net.minecraft.world.entity.monster.Enemy; import net.minecraft.world.entity.monster.Monster; -import net.minecraft.world.entity.animal.horse.Llama; +import net.minecraft.world.entity.npc.Npc; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.*; -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.scores.PlayerTeam; import net.minecraftforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; @@ -56,14 +64,6 @@ import static com.minecolonies.api.util.constant.TranslationConstants.MESSAGE_INFO_COLONY_MERCENARY_STEAL_CITIZEN; import static com.minecolonies.core.entity.ai.minimal.EntityAIInteractToggleAble.*; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.npc.Npc; - /** * Class for Mercenary entities, which can be spawned to protect the colony @@ -563,4 +563,11 @@ private static boolean isValidSpawnForMercenaries(final LevelAccessor world, fin } return true; } + + @Override + @Nullable + protected PlayerTeam getAssignedTeam() + { + return colony.getTeam(); + } } diff --git a/src/main/java/com/minecolonies/core/network/messages/server/colony/ColonyDeleteOwnMessage.java b/src/main/java/com/minecolonies/core/network/messages/server/colony/ColonyDeleteOwnMessage.java index 5adf8b4d2de..9e32176ff75 100755 --- a/src/main/java/com/minecolonies/core/network/messages/server/colony/ColonyDeleteOwnMessage.java +++ b/src/main/java/com/minecolonies/core/network/messages/server/colony/ColonyDeleteOwnMessage.java @@ -2,18 +2,16 @@ import com.minecolonies.api.colony.IColony; import com.minecolonies.api.colony.IColonyManager; -import com.minecolonies.api.colony.event.ColonyDeletedEvent; import com.minecolonies.api.network.IMessage; -import com.minecolonies.api.util.Log; -import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.common.MinecraftForge; -import net.minecraft.network.FriendlyByteBuf; import com.minecolonies.api.util.MessageUtils; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.network.NetworkEvent; import org.jetbrains.annotations.Nullable; -import static com.minecolonies.api.util.constant.TranslationConstants.*; +import static com.minecolonies.api.util.constant.TranslationConstants.MESSAGE_INFO_COLONY_DESTROY_SUCCESS; +import static com.minecolonies.api.util.constant.TranslationConstants.MESSAGE_INFO_COLONY_NOT_FOUND; /** * Message for deleting an owned colony @@ -53,18 +51,6 @@ public void onExecute(final NetworkEvent.Context ctxIn, final boolean isLogicalS { IColonyManager.getInstance().deleteColonyByDimension(colony.getID(), false, colony.getDimension()); MessageUtils.format(MESSAGE_INFO_COLONY_DESTROY_SUCCESS).sendTo(player); - - if (isLogicalServer) - { - try - { - MinecraftForge.EVENT_BUS.post(new ColonyDeletedEvent(colony)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during ColonyDeletedEvent", e); - } - } } else { From 0c6a9b9cfcd881479dc711c5fd6c8cd4f458083e Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Fri, 20 Sep 2024 15:44:53 +0200 Subject: [PATCH 2/4] Remove unnecessary variable --- .../core/entity/citizen/EntityCitizen.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java index c2dde9b5526..6ede81d71e2 100755 --- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java +++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java @@ -101,7 +101,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; -import net.minecraft.world.scores.Team; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ForgeCapabilities; @@ -229,11 +228,6 @@ public class EntityCitizen extends AbstractEntityCitizen implements IThreatTable */ private ILocation location = null; - /** - * Cached team name the entity belongs to. - */ - private String cachedTeamName; - /** * The current chunkpos. */ @@ -245,11 +239,6 @@ public class EntityCitizen extends AbstractEntityCitizen implements IThreatTable private final ThreatTable threatTable = new ThreatTable<>(this); private int interactionCooldown = 0; - /** - * Cache the entire team object. - */ - private Team cachedTeam; - /** * The citizen AI */ @@ -339,7 +328,6 @@ private EntityState initialize() final IColonyView colonyView = IColonyManager.getInstance().getColonyView(citizenColonyHandler.getColonyId(), level.dimension()); if (colonyView != null) { - this.cachedTeamName = colonyView.getTeamName(); this.citizenDataView = colonyView.getCitizen(citizenId); if (citizenDataView != null) { From de21f32afb3b18345e2dea667e8ff81d0304860e Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Sat, 21 Sep 2024 18:40:00 +0200 Subject: [PATCH 3/4] Move to util class --- .../entity/mobs/AbstractEntityRaiderMob.java | 4 +-- .../com/minecolonies/core/colony/Colony.java | 23 +------------ .../com/minecolonies/core/util/TeamUtils.java | 33 +++++++++++++++++++ 3 files changed, 36 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/minecolonies/core/util/TeamUtils.java diff --git a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java index b1172cc3ffe..b45042f6776 100644 --- a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java @@ -21,7 +21,6 @@ import com.minecolonies.api.util.ColonyUtils; import com.minecolonies.api.util.DamageSourceKeys; import com.minecolonies.api.util.Log; -import com.minecolonies.core.colony.Colony; import com.minecolonies.core.entity.pathfinding.navigation.AbstractAdvancedPathNavigate; import com.minecolonies.core.entity.pathfinding.navigation.PathingStuckHandler; import net.minecraft.nbt.CompoundTag; @@ -53,6 +52,7 @@ import static com.minecolonies.api.util.constant.ColonyManagerConstants.NO_COLONY_ID; import static com.minecolonies.api.util.constant.NbtTagConstants.*; import static com.minecolonies.api.util.constant.RaiderConstants.*; +import static com.minecolonies.core.util.TeamUtils.checkOrCreateTeam; /** * Abstract for all raider entities. @@ -741,7 +741,7 @@ public void initStatsFor(final double baseHealth, final double difficulty, final @Nullable protected PlayerTeam getAssignedTeam() { - return Colony.checkOrCreateTeam(level, RAID_TEAM); + return checkOrCreateTeam(level, RAID_TEAM); } /** diff --git a/src/main/java/com/minecolonies/core/colony/Colony.java b/src/main/java/com/minecolonies/core/colony/Colony.java index df1967fe0b1..59710df8423 100644 --- a/src/main/java/com/minecolonies/core/colony/Colony.java +++ b/src/main/java/com/minecolonies/core/colony/Colony.java @@ -84,6 +84,7 @@ import static com.minecolonies.api.util.constant.NbtTagConstants.*; import static com.minecolonies.api.util.constant.TranslationConstants.*; import static com.minecolonies.core.MineColonies.getConfig; +import static com.minecolonies.core.util.TeamUtils.checkOrCreateTeam; /** * This class describes a colony and contains all the data and methods for manipulating a Colony. @@ -638,28 +639,6 @@ public PlayerTeam getTeam() return checkOrCreateTeam(world, getTeamName()); } - /** - * Check or create a team. - * - * @param level the level to create the team in. - * @param name the team name. - */ - @Nullable - public static PlayerTeam checkOrCreateTeam(@Nullable Level level, String name) - { - if (level == null) - { - return null; - } - - PlayerTeam team = level.getScoreboard().getPlayerTeam(name); - if (team == null) - { - team = level.getScoreboard().addPlayerTeam(name); - } - return team; - } - /** * Set up the colony color for team handling for pvp. * diff --git a/src/main/java/com/minecolonies/core/util/TeamUtils.java b/src/main/java/com/minecolonies/core/util/TeamUtils.java new file mode 100644 index 00000000000..851316f82d3 --- /dev/null +++ b/src/main/java/com/minecolonies/core/util/TeamUtils.java @@ -0,0 +1,33 @@ +package com.minecolonies.core.util; + +import net.minecraft.world.level.Level; +import net.minecraft.world.scores.PlayerTeam; +import org.jetbrains.annotations.Nullable; + +/** + * Utility class for working with {@link net.minecraft.world.scores.Team instances}. + */ +public class TeamUtils +{ + /** + * Check or create a team. + * + * @param level the level to create the team in. + * @param name the team name. + */ + @Nullable + public static PlayerTeam checkOrCreateTeam(@Nullable Level level, String name) + { + if (level == null) + { + return null; + } + + PlayerTeam team = level.getScoreboard().getPlayerTeam(name); + if (team == null) + { + team = level.getScoreboard().addPlayerTeam(name); + } + return team; + } +} From 67dea1829745be794c85841402070b1300fd54b9 Mon Sep 17 00:00:00 2001 From: Thom van den Akker Date: Fri, 1 Nov 2024 18:39:49 +0100 Subject: [PATCH 4/4] Fix friendly fire, undo colony manager and events class --- .../entity/mobs/AbstractEntityRaiderMob.java | 5 -- .../minecolonies/api/events/ColonyEvents.java | 38 +++++++++++ .../com/minecolonies/core/colony/Colony.java | 4 +- .../core/colony/ColonyManager.java | 66 ++++++------------- .../com/minecolonies/core/util/TeamUtils.java | 17 ++++- 5 files changed, 77 insertions(+), 53 deletions(-) create mode 100644 src/main/java/com/minecolonies/api/events/ColonyEvents.java diff --git a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java index b45042f6776..6cce739ffdc 100644 --- a/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java +++ b/src/main/java/com/minecolonies/api/entity/mobs/AbstractEntityRaiderMob.java @@ -59,11 +59,6 @@ */ public abstract class AbstractEntityRaiderMob extends AbstractFastMinecoloniesEntity implements IThreatTableEntity, Enemy { - /** - * Difficulty at which raiders team up - */ - private static final double TEAM_DIFFICULTY = 2.0d; - /** * The percent of life taken per damage modifier */ diff --git a/src/main/java/com/minecolonies/api/events/ColonyEvents.java b/src/main/java/com/minecolonies/api/events/ColonyEvents.java new file mode 100644 index 00000000000..aef3f6d7b4c --- /dev/null +++ b/src/main/java/com/minecolonies/api/events/ColonyEvents.java @@ -0,0 +1,38 @@ +package com.minecolonies.api.events; + +import com.minecolonies.api.colony.IColony; +import com.minecolonies.api.colony.event.ColonyDeletedEvent; +import com.minecolonies.api.util.Log; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.Event; + +/** + * Event manager for all forge events. + */ +public class ColonyEvents +{ + /** + * Event triggered when a colony is being deleted. + * + * @param colony the colony in question. + */ + public static void deleteColony(final IColony colony) + { + sendEventSafe(new ColonyDeletedEvent(colony)); + } + + /** + * Underlying logic for transmitting an event. + */ + private static void sendEventSafe(final Event event) + { + try + { + MinecraftForge.EVENT_BUS.post(event); + } + catch (final Exception e) + { + Log.getLogger().atError().withThrowable(e).log("Exception occurred during {} event", event.getClass().getName()); + } + } +} diff --git a/src/main/java/com/minecolonies/core/colony/Colony.java b/src/main/java/com/minecolonies/core/colony/Colony.java index 59710df8423..644603f86ec 100644 --- a/src/main/java/com/minecolonies/core/colony/Colony.java +++ b/src/main/java/com/minecolonies/core/colony/Colony.java @@ -367,7 +367,7 @@ protected Colony(final int id, @Nullable final Level world) { this.dimensionId = world.dimension(); onWorldLoad(world); - checkOrCreateTeam(world, getTeamName()); + checkOrCreateTeam(world, getTeamName(), false); } this.permissions = new Permissions(this); researchManager = new ResearchManager(this); @@ -636,7 +636,7 @@ public void updateAttackingPlayers() public PlayerTeam getTeam() { // This getter will create the team if it doesn't exist. Could do something different though in the future. - return checkOrCreateTeam(world, getTeamName()); + return checkOrCreateTeam(world, getTeamName(), false); } /** diff --git a/src/main/java/com/minecolonies/core/colony/ColonyManager.java b/src/main/java/com/minecolonies/core/colony/ColonyManager.java index d315237be53..b11c9cbed41 100755 --- a/src/main/java/com/minecolonies/core/colony/ColonyManager.java +++ b/src/main/java/com/minecolonies/core/colony/ColonyManager.java @@ -1,13 +1,9 @@ package com.minecolonies.core.colony; import com.minecolonies.api.blocks.AbstractBlockHut; -import com.minecolonies.api.colony.ICitizenData; -import com.minecolonies.api.colony.IColony; -import com.minecolonies.api.colony.IColonyManager; -import com.minecolonies.api.colony.IColonyView; +import com.minecolonies.api.colony.*; import com.minecolonies.api.colony.buildings.IBuilding; import com.minecolonies.api.colony.buildings.views.IBuildingView; -import com.minecolonies.api.colony.event.ColonyDeletedEvent; import com.minecolonies.api.colony.event.ColonyViewUpdatedEvent; import com.minecolonies.api.colony.managers.events.ColonyManagerLoadedEvent; import com.minecolonies.api.colony.managers.events.ColonyManagerUnloadedEvent; @@ -15,6 +11,7 @@ import com.minecolonies.api.compatibility.CompatibilityManager; import com.minecolonies.api.compatibility.ICompatibilityManager; import com.minecolonies.api.crafting.IRecipeManager; +import com.minecolonies.api.events.ColonyEvents; import com.minecolonies.api.sounds.SoundManager; import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.ColonyUtils; @@ -36,7 +33,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.scores.PlayerTeam; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.TickEvent; import net.minecraftforge.server.ServerLifecycleHooks; @@ -64,7 +60,7 @@ public final class ColonyManager implements IColonyManager private final Map, ColonyList> colonyViews = new HashMap<>(); /** - * Recipe manager of this server. + * Recipemanager of this server. */ private final IRecipeManager recipeManager = new StandardRecipeManager(); @@ -107,7 +103,7 @@ public IColony createColony(@NotNull final Level w, final BlockPos pos, @NotNull colony.getPackageManager().addImportantColonyPlayer((ServerPlayer) player); colony.getPackageManager().addCloseSubscriber((ServerPlayer) player); - Log.getLogger().info("New Colony Id: {} by {}", colony.getID(), player.getName().getString()); + Log.getLogger().info(String.format("New Colony Id: %d by %s", colony.getID(), player.getName().getString())); if (colony.getWorld() == null) { @@ -139,46 +135,38 @@ public void deleteColonyByDimension(final int id, final boolean canDestroy, fina */ private void deleteColony(@Nullable final IColony iColony, final boolean canDestroy) { - if (!(iColony instanceof final Colony colony)) + if (!(iColony instanceof Colony)) { return; } + final Colony colony = (Colony) iColony; final int id = colony.getID(); final Level world = colony.getWorld(); if (world == null) { - Log.getLogger().warn("Deleting Colony {} errored: World is Null", id); - return; - } - - final IColonyManagerCapability cap = world.getCapability(COLONY_MANAGER_CAP, null).resolve().orElse(null); - if (cap == null) - { - Log.getLogger().warn(MISSING_WORLD_CAP_MESSAGE); + Log.getLogger().warn("Deleting Colony " + id + " errored: World is Null"); return; } try { - Log.getLogger().info("Removing claimed area for {}", id); ChunkDataHelper.claimColonyChunks(world, false, id, colony.getCenter()); - - Log.getLogger().info("Removing citizens for {}", id); + Log.getLogger().info("Removing citizens for " + id); for (final ICitizenData citizenData : new ArrayList<>(colony.getCitizenManager().getCitizens())) { - Log.getLogger().info("Kill Citizen {}", citizenData.getName()); + Log.getLogger().info("Kill Citizen " + citizenData.getName()); citizenData.getEntity().ifPresent(entityCitizen -> entityCitizen.die(world.damageSources().source(DamageSourceKeys.CONSOLE))); } - Log.getLogger().info("Removing buildings for {}", id); + Log.getLogger().info("Removing buildings for " + id); for (final IBuilding building : new ArrayList<>(colony.getBuildingManager().getBuildings().values())) { try { final BlockPos location = building.getPosition(); - Log.getLogger().info("Delete Building at {}", location); + Log.getLogger().info("Delete Building at " + location); if (canDestroy) { building.deconstruct(); @@ -186,7 +174,7 @@ private void deleteColony(@Nullable final IColony iColony, final boolean canDest building.destroy(); if (world.getBlockState(location).getBlock() instanceof AbstractBlockHut) { - Log.getLogger().info("Found Block, deleting {}", world.getBlockState(location).getBlock()); + Log.getLogger().info("Found Block, deleting " + world.getBlockState(location).getBlock()); world.removeBlock(location, false); } } @@ -198,7 +186,6 @@ private void deleteColony(@Nullable final IColony iColony, final boolean canDest try { - Log.getLogger().info("Unregistering event handlers for {}", id); MinecraftForge.EVENT_BUS.unregister(colony.getEventHandler()); } catch (final NullPointerException e) @@ -206,36 +193,25 @@ private void deleteColony(@Nullable final IColony iColony, final boolean canDest Log.getLogger().warn("Can't unregister the event handler twice"); } - // Delete the colony - Log.getLogger().info("Deleting colony {}", colony.getID()); - cap.deleteColony(id); + Log.getLogger().info("Deleting colony: " + colony.getID()); - // Delete the colony team - Log.getLogger().info("Deleting team for colony {}", id); - final PlayerTeam team = colony.getTeam(); - if (team != null) + final IColonyManagerCapability cap = world.getCapability(COLONY_MANAGER_CAP, null).resolve().orElse(null); + if (cap == null) { - world.getScoreboard().removePlayerTeam(team); - } - - // Send the deletion event - try - { - MinecraftForge.EVENT_BUS.post(new ColonyDeletedEvent(colony)); - } - catch (final Exception e) - { - Log.getLogger().error("Error during ColonyDeletedEvent", e); + Log.getLogger().warn(MISSING_WORLD_CAP_MESSAGE); + return; } + ColonyEvents.deleteColony(colony); + cap.deleteColony(id); BackUpHelper.markColonyDeleted(colony.getID(), colony.getDimension()); colony.getImportantMessageEntityPlayers() .forEach(player -> Network.getNetwork().sendToPlayer(new ColonyViewRemoveMessage(colony.getID(), colony.getDimension()), (ServerPlayer) player)); - Log.getLogger().info("Successfully deleted colony {}", id); + Log.getLogger().info("Successfully deleted colony: " + id); } catch (final RuntimeException e) { - Log.getLogger().warn("Deleting Colony {} errored:", id, e); + Log.getLogger().warn("Deleting Colony " + id + " errored:", e); } } diff --git a/src/main/java/com/minecolonies/core/util/TeamUtils.java b/src/main/java/com/minecolonies/core/util/TeamUtils.java index 851316f82d3..88c7a9b3509 100644 --- a/src/main/java/com/minecolonies/core/util/TeamUtils.java +++ b/src/main/java/com/minecolonies/core/util/TeamUtils.java @@ -9,6 +9,7 @@ */ public class TeamUtils { + /** * Check or create a team. * @@ -16,7 +17,20 @@ public class TeamUtils * @param name the team name. */ @Nullable - public static PlayerTeam checkOrCreateTeam(@Nullable Level level, String name) + public static PlayerTeam checkOrCreateTeam(@Nullable final Level level, final String name) + { + return checkOrCreateTeam(level, name, true); + } + + /** + * Check or create a team. + * + * @param level the level to create the team in. + * @param name the team name. + * @param allowFriendlyFire whether this team allows friendly fire or not. + */ + @Nullable + public static PlayerTeam checkOrCreateTeam(@Nullable final Level level, final String name, boolean allowFriendlyFire) { if (level == null) { @@ -28,6 +42,7 @@ public static PlayerTeam checkOrCreateTeam(@Nullable Level level, String name) { team = level.getScoreboard().addPlayerTeam(name); } + team.setAllowFriendlyFire(allowFriendlyFire); return team; } }