Skip to content

Commit

Permalink
Raid fixes (#10509)
Browse files Browse the repository at this point in the history
Rework raid messages for raid ending, they now got an individual finished message followed by a general victory message for the whole raid
Fix campfires getting spawned incorrectly, due to not loading a chunk when required to
Reworked North/South directions util, it is now split into 8 sections a 45° to give proper ranges for North/Northeast etc
Fix door break speed, research no longer strengthens normal doors and doors break slightly faster with more raiders hitting it.
Improved despawn of few remaining raiders to not stall raids for longer than needed
Full raid end is now handled by the raid manager
Added more message variants to raid end messages
Removed attackspeed scaling from archers, as those already scale in attack damage
  • Loading branch information
someaddons authored Dec 8, 2024
1 parent eb4fd95 commit 0896b9d
Show file tree
Hide file tree
Showing 13 changed files with 191 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,4 @@ default boolean isRaidActive()
{
return getStatus() == EventStatus.PROGRESSING ||getStatus() == EventStatus.PREPARING;
}

/**
* Set the raid event to mercy.
*/
void setMercyEnd();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.minecolonies.api.colony.managers.interfaces;

import com.minecolonies.api.colony.ICitizenData;
import com.minecolonies.api.colony.colonyEvents.IColonyRaidEvent;
import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
Expand Down Expand Up @@ -206,7 +207,7 @@ default RaidSpawnResult raiderEvent(String raidType, final boolean overrideConfi
/**
* Gets the amount of citizens lost in a raid.
*
* @return weighted amount of list citizen
* @return amount
*/
int getLostCitizen();

Expand All @@ -217,6 +218,8 @@ default RaidSpawnResult raiderEvent(String raidType, final boolean overrideConfi
*/
void onRaiderDeath(AbstractEntityRaiderMob entity);

void onRaidEventFinished(IColonyRaidEvent event);

/**
* Notify raid manager of a passing through raid.
*/
Expand Down
79 changes: 54 additions & 25 deletions src/main/java/com/minecolonies/api/util/BlockPosUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,27 @@ public static BlockPos getRandomPosAround(final BlockPos center, final int dista
* @return the BlockPos.
*/
public static BlockPos getRandomPosition(final Level world, final BlockPos currentPosition, final BlockPos def, final int minDist, final int maxDist)
{
return getRandomPosition(world, currentPosition, def, minDist, maxDist, false);
}

/**
* Gets a random position within a certain range for wandering around.
*
* @param world the world.
* @param currentPosition the current position.
* @param def the default position if none was found.
* @param minDist the minimum distance of the pos.
* @param maxDist the maximum distance.
* @param load whether chunks should get loaded if needed
* @return the BlockPos.
*/
public static BlockPos getRandomPosition(final Level world, final BlockPos currentPosition, final BlockPos def, final int minDist, final int maxDist, final boolean load)
{
int tries = 0;
BlockPos pos = null;
while (pos == null
|| !WorldUtil.isEntityBlockLoaded(world, pos)
|| !load && !WorldUtil.isEntityBlockLoaded(world, pos)
|| world.getBlockState(pos).liquid()
|| !BlockUtils.isAnySolid(world.getBlockState(pos.below()))
|| (!world.isEmptyBlock(pos) || !world.isEmptyBlock(pos.above())))
Expand Down Expand Up @@ -889,46 +905,59 @@ public static DirectionResult calcDirection(@NotNull final BlockPos building, @N
{
if (pos.getY() > building.getY())
{
direction = DirectionResult.UP;
return DirectionResult.UP;
}
else if (pos.getY() < building.getY())
{
direction = DirectionResult.DOWN;
return DirectionResult.DOWN;
}
else
{
return DirectionResult.SAME;
}
}

// If a building is greater or smaller in the Z direction, either return north or south
if (pos.getZ() > building.getZ())
final int xDiff = building.getX() - pos.getX();
final int zDiff = building.getZ() - pos.getZ();
int degree = (int) (Math.atan2(xDiff, zDiff) * 180 / Math.PI);
if (degree < 0)
{
direction = DirectionResult.SOUTH;
degree += 360;
}
else if (pos.getZ() < building.getZ())

if (degree <= 22 || degree >= 338)
{
direction = DirectionResult.NORTH;
}

// If a building is greater or smaller in the X direction, either return west or east
// If previously already north or south was selected, create a compound direction (north/east etc)
if (pos.getX() > building.getX())
else if (degree > 22 && degree < 67)
{
direction = DirectionResult.NORTH_WEST;
}
else if (degree >= 67 && degree <= 112)
{
direction = DirectionResult.WEST;
}
else if (degree > 112 && degree < 157)
{
direction = switch (direction)
{
case NORTH -> DirectionResult.NORTH_EAST;
case SOUTH -> DirectionResult.SOUTH_EAST;
default -> DirectionResult.EAST;
};
direction = DirectionResult.SOUTH_WEST;
}
else if (pos.getX() < building.getX())
else if (degree >= 157 && degree <= 202)
{
direction = DirectionResult.SOUTH;
}
else if (degree > 202 && degree < 247)
{
direction = DirectionResult.SOUTH_EAST;
}
else if (degree >= 247 && degree <= 292)
{
direction = DirectionResult.EAST;
}
else
{
direction = switch (direction)
{
case NORTH -> DirectionResult.NORTH_WEST;
case SOUTH -> DirectionResult.SOUTH_WEST;
default -> DirectionResult.WEST;
};
direction = DirectionResult.NORTH_EAST;
}

// In case that none of the checks pass (XYZ fully identical to the building), return a component saying the positions are identical
return direction;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,14 @@ public final class TranslationConstants
@NonNls
public static final String RAID_NORSEMEN = "com.minecolonies.coremod.raid.norsemen.name";
@NonNls
public static final String ONLY_X_BARBARIANS_LEFT_MESSAGE = "com.minecolonies.coremod.barbarians.left";
public static final String ONLY_X_BARBARIANS_LEFT_MESSAGE = "com.minecolonies.coremod.barbarians.left";
@NonNls
public static final String ALL_BARBARIANS_KILLED_MESSAGE = "com.minecolonies.coremod.barbarians.killed";
public static final String INDIVIDUAL_RAID_FINISH = "com.minecolonies.coremod.raid.end";
@NonNls
public static final String ALL_BARBARIANS_MERCY_MESSAGE = "com.minecolonies.core.barbarians.mercy";
public static final String RAID_END_MERCY = "com.minecolonies.core.barbarians.mercy";
public static final String RAID_END = "com.minecolonies.coremod.barbarians.killed";
@NonNls
public static final String CANT_PLACE_COLONY_TOO_CLOSE_TO_SPAWN = "com.minecolonies.core.founding.tooclosetospawn";
public static final String CANT_PLACE_COLONY_TOO_CLOSE_TO_SPAWN = "com.minecolonies.core.founding.tooclosetospawn";
@NonNls
public static final String CANT_PLACE_COLONY_TOO_FAR_FROM_SPAWN = "com.minecolonies.core.founding.toofarfromspawn";
@NonNls
Expand Down Expand Up @@ -262,9 +263,7 @@ public final class TranslationConstants
@NonNls
public static final String CMC_GUI_TOWNHALL_BUILDING_LEVEL = "com.minecolonies.coremod.gui.townhall.buildinglevel";
@NonNls
public static final String PIRATES_SAILING_OFF_MESSAGE = "com.minecolonies.coremod.pirates.sailing.away";
@NonNls
public static final String DROWNED_PIRATES_SAILING_OFF_MESSAGE = "com.minecolonies.core.drowned_pirates.sailing.away";
public static final String PIRATES_SAILING_OFF_MESSAGE = "com.minecolonies.coremod.raid.sailing.away";
@NonNls
public static final String STRUCTURE_SPAWNER_BREAKS = "com.minecolonies.core.raidevent.spawnerbreaks";
@NonNls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ public static void init(final IForgeRegistry<Block> registry)
ModBlocks.blockCompostedDirt = new BlockCompostedDirt().registerBlock(registry);
ModBlocks.blockColonyBanner = new BlockColonyFlagBanner().registerBlock(registry);
ModBlocks.blockColonyWallBanner = new BlockColonyFlagWallBanner().registerBlock(registry);
ModBlocks.blockIronGate = new BlockGate(IRON_GATE, 5f, 6, 8).registerBlock(registry);
ModBlocks.blockWoodenGate = new BlockGate(WOODEN_GATE, 4f, 6, 5).registerBlock(registry);
ModBlocks.blockIronGate = new BlockGate(IRON_GATE, 10f, 6, 8).registerBlock(registry);
ModBlocks.blockWoodenGate = new BlockGate(WOODEN_GATE, 7f, 6, 5).registerBlock(registry);
ModBlocks.farmland = new MinecoloniesFarmland(FARMLAND, false, 15.0).registerBlock(registry);
ModBlocks.floodedFarmland = new MinecoloniesFarmland(FLOODED_FARMLAND, true, 13.0).registerBlock(registry);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.minecolonies.api.util.MessageUtils.MessagePriority;
import com.minecolonies.api.util.Tuple;
import com.minecolonies.api.util.WorldUtil;
import com.minecolonies.api.util.constant.ColonyConstants;
import com.minecolonies.core.colony.events.raid.pirateEvent.ShipBasedRaiderUtils;
import com.minecolonies.core.colony.events.raid.pirateEvent.ShipSize;
import com.minecolonies.core.entity.pathfinding.pathresults.PathResult;
Expand Down Expand Up @@ -311,16 +312,10 @@ public boolean isUnderWater()
return false;
}

@Override
public void setMercyEnd()
{
// Noop, the sailing away message is fine.
}

@Override
public void onFinish()
{
MessageUtils.format(PIRATES_SAILING_OFF_MESSAGE, BlockPosUtil.calcDirection(colony.getCenter(), spawnPoint).getLongText(), colony.getName())
MessageUtils.format(PIRATES_SAILING_OFF_MESSAGE, BlockPosUtil.calcDirection(colony.getCenter(), spawnPoint).getLongText())
.sendTo(colony).forManagers();
for (final Entity entity : raiders.keySet())
{
Expand All @@ -339,12 +334,22 @@ public void onTileEntityBreak(final BlockEntity te)
spawners.remove(te.getBlockPos());

raidBar.setProgress((float) spawners.size() / maxSpawners);
// remove at nightfall after spawners are killed.
if (spawners.isEmpty())
{
daysToGo = 2;
MessageUtils.format(ALL_PIRATE_SPAWNERS_DESTROYED_MESSAGE, colony.getName()).sendTo(colony).forManagers();
}
checkRaidEnd();
}
}

/**
* Checks if the raid got defeated, announces it and sets the remaining days for the ship
*/
private void checkRaidEnd()
{
if (raiders.isEmpty() && spawners.isEmpty())
{
status = EventStatus.WAITING;
colony.getRaiderManager().onRaidEventFinished(this);
daysToGo = 1;
MessageUtils.format(INDIVIDUAL_RAID_FINISH + "." + this.getEventTypeID().getPath() + ColonyConstants.rand.nextInt(3),
BlockPosUtil.calcDirection(colony.getCenter(), spawnPoint).getLongText()).sendTo(colony, true).forManagers();
}
}

Expand All @@ -361,26 +366,17 @@ public void onNightFall()
@Override
public void onEntityDeath(final LivingEntity entity)
{
raiders.remove(entity);
if (raiders.isEmpty() && spawners.isEmpty())
{
status = EventStatus.WAITING;
MessageUtils.format(ALL_PIRATES_KILLED_MESSAGE, colony.getName()).sendTo(colony).forManagers();
}
spawnerThresholdKillTracker++;

if (!spawners.isEmpty() && spawnerThresholdKillTracker > maxRaiderCount/maxSpawners)
{
MessageUtils.format(STRUCTURE_SPAWNER_BREAKS, colony.getName()).sendTo(colony).forManagers();
colony.getWorld().removeBlock(spawners.remove(0), false);
raidBar.setProgress((float) spawners.size() / maxSpawners);
spawnerThresholdKillTracker = 0;
if (spawners.isEmpty())
{
daysToGo = 1;
MessageUtils.format(ALL_PIRATE_SPAWNERS_DESTROYED_MESSAGE, colony.getName()).sendTo(colony).forManagers();
}
}

raiders.remove(entity);
checkRaidEnd();
}

@Override
Expand Down
Loading

0 comments on commit 0896b9d

Please sign in to comment.