Yatopia/patches/server/0008-Per-entity-type-collision-settings.patch
Ivan Pekov 58e66daeb4
Updated Upstream and Sidestream(s) (Tuinity/Origami/Purpur/AirplaneLite)
Upstream/An Sidestream has released updates that appears to apply and compile correctly
This update has NOT been tested by YatopiaMC and as with ANY update, please do your own testing.

Tuinity Changes:
a405b1b Merge branch 'master' of https://github.com/Spottedleaf/Tuinity into ver/1.16.4
f06591a Updated Upstream (Paper)
48d3556 Prevent light queue overfill when no players are online

Origami Changes:
78f4af0 Require Java 11
b70595f Fix patch rebuilding for MojangAPI module
34170a7 Update Paper

Purpur Changes:
3d455ff Updated Upstream (Paper & Tuinity)
7152b72 [ci-skip] Use shadowJar output as input for paperclip
822a35a [ci-skip] Publish shadowJar as server artifact
f142481 Resolves #125 - Full netherite armor grants fire resistance
5e269e1 Updated Upstream (Paper)

AirplaneLite Changes:
9326301 Update upstream, fix utf8
2020-12-28 11:34:56 +02:00

225 lines
11 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrIvanPlays <ivan@mrivanplays.com>
Date: Thu, 13 Aug 2020 15:14:36 +0300
Subject: [PATCH] Per entity (type) collision settings
Base patch was the only player collisions patch, the original author of was tr7zw <tr7zw@live.de>
but pretty much the whole implementation changed.
This patch implements per entity (type) collision settings with 100% compatibility with bukkit api and
vanilla.
The whole code is based around 1 class, the EntityFilter class. Whole filtering logic is there.
Co-authored-by: tr7zw <tr7zw@live.de>
diff --git a/src/main/java/de/minebench/origami/OrigamiConfig.java b/src/main/java/de/minebench/origami/OrigamiConfig.java
index 537456a7427cddd6783f5b5d8ee2d655668c4c53..004184a7c3da4f72f68a5fd9b4dd5abd0b8f871d 100644
--- a/src/main/java/de/minebench/origami/OrigamiConfig.java
+++ b/src/main/java/de/minebench/origami/OrigamiConfig.java
@@ -134,6 +134,39 @@ public final class OrigamiConfig {
private void observerClock() {
disableObserverClocks = getBoolean("disable-observer-clocks", disableObserverClocks);
}
+
+ // Yatopia start
+ public boolean playerCollisions = true;
+ public boolean animalCollisions = true;
+ public boolean ambientCollisions = true;
+ public boolean monsterCollisions = true;
+ public boolean villagerCollisions = true;
+ public boolean pillagerCollisions = true;
+ public boolean ironGolemCollisions = true;
+ public boolean miscCollisions = true;
+ public boolean itemCollisions = true;
+ public boolean waterCreatureCollisions = true;
+ public boolean waterAmbientCollisions = true;
+ public boolean allCollisionsEnabled = false;
+ private void specificCollisionSettings() {
+ playerCollisions = getBoolean("collisions.players", playerCollisions);
+ animalCollisions = getBoolean("collisions.animals", animalCollisions);
+ ambientCollisions = getBoolean("collisions.ambient", ambientCollisions);
+ monsterCollisions = getBoolean("collisions.monsters", monsterCollisions);
+ villagerCollisions = getBoolean("collisions.villagers", villagerCollisions);
+ pillagerCollisions = getBoolean("collisions.pillagers", pillagerCollisions);
+ ironGolemCollisions = getBoolean("collisions.iron-golems", ironGolemCollisions);
+ miscCollisions = getBoolean("collisions.misc", miscCollisions);
+ itemCollisions = getBoolean("collisions.items", itemCollisions);
+ waterCreatureCollisions = getBoolean("collisions.water-creature", waterCreatureCollisions);
+ waterAmbientCollisions = getBoolean("collisions.water-ambient", waterAmbientCollisions);
+
+ allCollisionsEnabled =
+ playerCollisions && animalCollisions && ambientCollisions && monsterCollisions && villagerCollisions
+ && pillagerCollisions && ironGolemCollisions && miscCollisions && itemCollisions
+ && waterCreatureCollisions && waterAmbientCollisions;
+ }
+ // Yatopia end
}
}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index b1fa51050ca3deb9a7cfc732d5415010d753ada4..2f0e9e3fc184d803aa81b2d4d0b52927f575f69b 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -2870,7 +2870,7 @@ public abstract class EntityLiving extends Entity {
// Paper - end don't run getEntities if we're not going to use its result
// Tuinity start - reduce memory allocation from collideNearby
List<Entity> list = com.tuinity.tuinity.util.CachedLists.getTempGetEntitiesList();
- this.world.getEntities(this, this.getBoundingBox(), IEntitySelector.pushable(this, world.paperConfig.fixClimbingBypassingCrammingRule), list); // Paper - fix climbing bypassing cramming rule
+ this.world.getEntities(this, this.getBoundingBox(), org.yatopiamc.yatopia.server.EntityFilter.getFilter(this, world.paperConfig.fixClimbingBypassingCrammingRule), list); // Paper - fix climbing bypassing cramming rule // Yatopia
try {
// Tuinity end - reduce memory allocation from collideNearby
diff --git a/src/main/java/org/yatopiamc/yatopia/server/EntityFilter.java b/src/main/java/org/yatopiamc/yatopia/server/EntityFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..cb6bab603dcb20521868a482c872f65dd5733c15
--- /dev/null
+++ b/src/main/java/org/yatopiamc/yatopia/server/EntityFilter.java
@@ -0,0 +1,145 @@
+package org.yatopiamc.yatopia.server;
+
+import de.minebench.origami.OrigamiConfig;
+import java.util.function.Predicate;
+import net.minecraft.server.Entity;
+import net.minecraft.server.EntityTypes;
+import net.minecraft.server.EnumCreatureType;
+import net.minecraft.server.IEntitySelector;
+import net.minecraft.server.ScoreboardTeamBase;
+
+public class EntityFilter {
+
+ public static Predicate<Entity> getFilter(Entity entity, boolean ignoreClimbing) {
+ OrigamiConfig.WorldConfig config = entity.world.origamiConfig;
+ if (config.allCollisionsEnabled) {
+ return IEntitySelector.pushable(entity, ignoreClimbing);
+ }
+
+ ScoreboardTeamBase entityTeam = entity.getScoreboardTeam();
+ ScoreboardTeamBase.EnumTeamPush entityTeamPush =
+ entityTeam == null ?
+ ScoreboardTeamBase.EnumTeamPush.ALWAYS :
+ entityTeam.getCollisionRule();
+
+ if (entityTeamPush == ScoreboardTeamBase.EnumTeamPush.NEVER || entity.world.isClientSide
+ || entity.isSpectator()) {
+ return tested -> false;
+ }
+
+ Predicate<Entity> ret = (tested) -> {
+ if (!tested.isCollidable(ignoreClimbing) || !tested.canCollideWith(entity) || !entity.canCollideWith(tested)) {
+ return false;
+ }
+ ScoreboardTeamBase testedTeam = tested.getScoreboardTeam();
+ ScoreboardTeamBase.EnumTeamPush testedPush =
+ testedTeam == null ?
+ ScoreboardTeamBase.EnumTeamPush.ALWAYS :
+ testedTeam.getCollisionRule();
+
+ if (testedPush == ScoreboardTeamBase.EnumTeamPush.NEVER) {
+ return false;
+ }
+ if (testedTeam != null && entityTeam != null) {
+ // see IEntitySelector#a(Entity)
+ // copied from there, although for me this logic doesn't seem quite right
+ boolean ally = entityTeam.isAlly(testedTeam);
+
+ if ((entityTeamPush == ScoreboardTeamBase.EnumTeamPush.PUSH_OWN_TEAM ||
+ testedPush == ScoreboardTeamBase.EnumTeamPush.PUSH_OWN_TEAM) && ally) {
+ return false;
+ }
+ return (entityTeamPush != ScoreboardTeamBase.EnumTeamPush.PUSH_OTHER_TEAMS
+ && testedPush != ScoreboardTeamBase.EnumTeamPush.PUSH_OTHER_TEAMS) || ally;
+ } else {
+ return testedPush == ScoreboardTeamBase.EnumTeamPush.ALWAYS &&
+ entityTeamPush == ScoreboardTeamBase.EnumTeamPush.ALWAYS;
+ }
+ };
+
+ ret = ret.and((tested) -> {
+ if (tested.getEntityType() == EntityTypes.PLAYER && config.playerCollisions) {
+ return true;
+ }
+ if (tested.getEntityType().getEnumCreatureType() == EnumCreatureType.CREATURE && config.animalCollisions) {
+ return true;
+ }
+ if (tested.getEntityType().getEnumCreatureType() == EnumCreatureType.AMBIENT && config.ambientCollisions) {
+ return true;
+ }
+ if (tested.getEntityType().getEnumCreatureType() == EnumCreatureType.MONSTER) {
+ if (config.monsterCollisions) {
+ if (config.pillagerCollisions) {
+ return true;
+ } else {
+ return tested.getEntityType() != EntityTypes.PILLAGER;
+ }
+ } else {
+ if (config.pillagerCollisions) {
+ return tested.getEntityType() == EntityTypes.PILLAGER;
+ } else {
+ return false;
+ }
+ }
+ }
+ if (tested.getEntityType().getEnumCreatureType() == EnumCreatureType.MISC) {
+ if (config.miscCollisions) {
+ if (config.villagerCollisions && config.ironGolemCollisions && config.itemCollisions) {
+ return true;
+ }
+ if (!config.villagerCollisions) {
+ if (tested.getEntityType() == EntityTypes.VILLAGER) {
+ return false;
+ }
+ }
+ if (!config.ironGolemCollisions) {
+ if (tested.getEntityType() == EntityTypes.IRON_GOLEM) {
+ return false;
+ }
+ }
+ if (!config.itemCollisions) {
+ if (tested.getEntityType() == EntityTypes.ITEM) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ if (config.villagerCollisions && config.ironGolemCollisions && config.itemCollisions) {
+ if (tested.getEntityType() == EntityTypes.VILLAGER) {
+ return true;
+ }
+ if (tested.getEntityType() == EntityTypes.IRON_GOLEM) {
+ return true;
+ }
+ if (tested.getEntityType() == EntityTypes.ITEM) {
+ return true;
+ }
+ }
+ if (config.villagerCollisions && config.ironGolemCollisions) {
+ if (tested.getEntityType() == EntityTypes.VILLAGER) {
+ return true;
+ }
+ if (tested.getEntityType() == EntityTypes.IRON_GOLEM) {
+ return true;
+ }
+ }
+ if (config.villagerCollisions) {
+ if (tested.getEntityType() == EntityTypes.VILLAGER) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ if (tested.getEntityType().getEnumCreatureType() == EnumCreatureType.WATER_CREATURE && config.waterCreatureCollisions) {
+ return true;
+ }
+ if (tested.getEntityType().getEnumCreatureType() == EnumCreatureType.WATER_AMBIENT && config.waterAmbientCollisions) {
+ return true;
+ }
+ return false;
+ });
+
+ return ret;
+ }
+}