Update for MC 1.16.1

* Bumped version to 2.10.0-SNAPSHOT.
* Added zombified piglin, piglin, hoglin, zoglin and strider to the by default enabled mob types. If you are updating, you will have to manually add these to your config's 'enabled-living-shops' setting.
* During my quick initial testing I did not encounter any major issues with these new mobs, but there are some oddities you might want to be aware of:
  * We don't support changing the baby property of piglin and zoglin shopkeepers yet. However, we at least ensure that they always spawn as adult.
  * The zombified piglin, hoglin and strider already support changing the baby property.
  * The strider constantly shakes when being spawned outside the nether and randomly spawns with saddle.
* The pig zombie mob type has been removed from the by default enabled mob types. If you are updating to MC 1.16, it will get automatically removed from your config. To prevent your config from losing its comments and formatting during this small migration, consider manually removing this mob type before your update.
* If you are updating to MC 1.16, your pig zombie shopkeepers get automatically converted to zombified pigman shopkeepers.
* Internal: Any internal references to the pig zombie mob type have been removed to prevent any kind of binary problems to arise.

Other changes:
* Improved/Fixed: Some mobs randomly spawn with passengers. We remove those passengers now.
master
blablubbabc 2020-06-26 13:01:42 +02:00
parent ae14c09ff1
commit 186711941b
15 changed files with 353 additions and 11 deletions

View File

@ -18,6 +18,7 @@ cache:
before_install:
- if [ ! -f "$HOME/.m2/repository/org/bukkit/craftbukkit/1.14.4-R0.1-SNAPSHOT/craftbukkit-1.14.4-R0.1-SNAPSHOT.jar" ]; then ./installSpigot.sh 1.14.4 ; else echo "Not compiling Spigot 1.14.4 because it is already in our maven repo" ; fi
- if [ ! -f "$HOME/.m2/repository/org/bukkit/craftbukkit/1.15.2-R0.1-SNAPSHOT/craftbukkit-1.15.2-R0.1-SNAPSHOT.jar" ]; then ./installSpigot.sh 1.15.2 ; else echo "Not compiling Spigot 1.15.2 because it is already in our maven repo" ; fi
- if [ ! -f "$HOME/.m2/repository/org/bukkit/craftbukkit/1.16.1-R0.1-SNAPSHOT/craftbukkit-1.16.1-R0.1-SNAPSHOT.jar" ]; then ./installSpigot.sh 1.16.1 ; else echo "Not compiling Spigot 1.16.1 because it is already in our maven repo" ; fi
install: true
script: mvn clean install

View File

@ -1,10 +1,27 @@
# Changelog
Date format: (YYYY-MM-DD)
## v2.9.4 (TBA)
### Supported MC versions: 1.15.2, 1.14.4
## v2.10.1 (TBA)
### Supported MC versions: 1.16.1, 1.15.2, 1.14.4
## v2.10.0 (2020-06-26)
### Supported MC versions: 1.16.1, 1.15.2, 1.14.4
**Update for MC 1.16.1:**
* Added zombified piglin, piglin, hoglin, zoglin and strider to the by default enabled mob types. If you are updating, you will have to manually add these to your config's 'enabled-living-shops' setting.
* During my quick initial testing I did not encounter any major issues with these new mobs, but there are some oddities you might want to be aware of:
* We don't support changing the baby property of piglin and zoglin shopkeepers yet. However, we at least ensure that they always spawn as adult.
* The zombified piglin, hoglin and strider already support changing the baby property.
* The strider constantly shakes when being spawned outside the nether and randomly spawns with saddle.
* The pig zombie mob type has been removed from the by default enabled mob types. If you are updating to MC 1.16, it will get automatically removed from your config. To prevent your config from losing its comments and formatting during this small migration, consider manually removing this mob type before your update.
* If you are updating to MC 1.16, your pig zombie shopkeepers get automatically converted to zombified pigman shopkeepers.
* Internal: Any internal references to the pig zombie mob type have been removed to prevent any kind of binary problems to arise.
**Other migration notes:**
* Removed: We no longer migrate items inside the config from legacy (pre MC 1.13) item types, data values and spawn eggs to corresponding item types in MC 1.13. Instead any unknown item types get migrated to their default now.
**Other changes:**
* Improved/Fixed: Some mobs randomly spawn with passengers. We remove those passengers now.
* Fixed: The random equipment of certain mobs gets properly cleared now. For instance, this resolves the issues of foxes randomly carrying items inside their mouth.
* Fixed: When a Citizens NPC, created without the 'shopkeeper' trait, is deleted, we immediately delete any corresponding shopkeeper now. Previously the corresponding shopkeeper would not get deleted right away, but only during the next plugin startup (when checking whether the corresponding NPC still exists). Any chest used by the shopkeeper would remain locked until then.
* Improved: In order to determine the player who is setting up a shopkeeper via the 'shopkeeper' trait, we previously only took players into account which are adding the trait via the Citizens trait command (NPCTraitCommandAttachEvent). However, players are also able to add traits during NPC creation. We now also react to player's creating NPCs (PlayerCreateNPCEvent) and then (heuristically) assume that any directly following trait additions for the same NPC within one tick are caused by this player. This player will then be able to receive feedback message about the shopkeeper creation.

View File

@ -101,6 +101,13 @@
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>sk-v1_16_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<!-- Includes the API -->
<dependency>
<groupId>${project.groupId}</groupId>

View File

@ -11,7 +11,7 @@
<properties>
<!-- Shopkeepers version -->
<revision>2.9.4-SNAPSHOT</revision>
<revision>2.10.0-SNAPSHOT</revision>
<root.relativePath>../..</root.relativePath>
<shopkeepers.version>${project.version}</shopkeepers.version>
<shopkeepers.dbo.url>https://dev.bukkit.org/projects/shopkeepers/</shopkeepers.dbo.url>

View File

@ -9,11 +9,11 @@ import org.bukkit.craftbukkit.v1_14_R1.entity.CraftAbstractVillager;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftRaider;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftVillager;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftMerchant;
import org.bukkit.craftbukkit.v1_14_R1.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftRaider;
import org.bukkit.entity.AbstractVillager;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -32,6 +32,7 @@ import net.minecraft.server.v1_14_R1.EntityHuman;
import net.minecraft.server.v1_14_R1.EntityInsentient;
import net.minecraft.server.v1_14_R1.EntityLiving;
import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.EntityRaider;
import net.minecraft.server.v1_14_R1.GameProfileSerializer;
import net.minecraft.server.v1_14_R1.IMerchant;
import net.minecraft.server.v1_14_R1.MerchantRecipeList;
@ -39,7 +40,6 @@ import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.PathfinderGoalFloat;
import net.minecraft.server.v1_14_R1.PathfinderGoalLookAtPlayer;
import net.minecraft.server.v1_14_R1.PathfinderGoalSelector;
import net.minecraft.server.v1_14_R1.EntityRaider;
public final class NMSHandler implements NMSCallProvider {

25
modules/v1_16_R1/pom.xml Normal file
View File

@ -0,0 +1,25 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.nisovin.shopkeepers</groupId>
<artifactId>sk-nms-parent</artifactId>
<version>${revision}</version>
<relativePath>../nms-parent/</relativePath>
</parent>
<artifactId>sk-v1_16_R1</artifactId>
<packaging>jar</packaging>
<name>SK for v1_16_R1</name>
<properties>
<craftbukkit.version>1.16.1-R0.1-SNAPSHOT</craftbukkit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,210 @@
package com.nisovin.shopkeepers.compat.v1_16_R1;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftAbstractVillager;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftVillager;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftMerchant;
import org.bukkit.craftbukkit.v1_16_R1.util.CraftMagicNumbers;
import org.bukkit.entity.AbstractVillager;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Piglin;
import org.bukkit.entity.Player;
import org.bukkit.entity.Raider;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Zoglin;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.MerchantInventory;
import com.nisovin.shopkeepers.compat.api.NMSCallProvider;
import com.nisovin.shopkeepers.util.ItemUtils;
import net.minecraft.server.v1_16_R1.Entity;
import net.minecraft.server.v1_16_R1.EntityHuman;
import net.minecraft.server.v1_16_R1.EntityInsentient;
import net.minecraft.server.v1_16_R1.EntityLiving;
import net.minecraft.server.v1_16_R1.EntityPlayer;
import net.minecraft.server.v1_16_R1.GameProfileSerializer;
import net.minecraft.server.v1_16_R1.IMerchant;
import net.minecraft.server.v1_16_R1.MerchantRecipeList;
import net.minecraft.server.v1_16_R1.NBTTagCompound;
import net.minecraft.server.v1_16_R1.PathfinderGoalFloat;
import net.minecraft.server.v1_16_R1.PathfinderGoalLookAtPlayer;
import net.minecraft.server.v1_16_R1.PathfinderGoalSelector;
public final class NMSHandler implements NMSCallProvider {
@Override
public String getVersionId() {
return "1_16_R1";
}
@Override
public void overwriteLivingEntityAI(LivingEntity entity) {
try {
EntityLiving mcLivingEntity = ((CraftLivingEntity) entity).getHandle();
// example: armor stands are living, but not insentient
if (!(mcLivingEntity instanceof EntityInsentient)) return;
// make goal selector items accessible:
Field cField = PathfinderGoalSelector.class.getDeclaredField("c"); // active goals
cField.setAccessible(true);
Field dField = PathfinderGoalSelector.class.getDeclaredField("d"); // registered goals
dField.setAccessible(true);
// overwrite goal selector:
Field goalsField = EntityInsentient.class.getDeclaredField("goalSelector");
goalsField.setAccessible(true);
PathfinderGoalSelector goals = (PathfinderGoalSelector) goalsField.get(mcLivingEntity);
// clear old goals:
Map<?, ?> goals_c = (Map<?, ?>) cField.get(goals);
goals_c.clear();
Set<?> goals_d = (Set<?>) dField.get(goals);
goals_d.clear();
// add new goals:
goals.a(0, new PathfinderGoalFloat((EntityInsentient) mcLivingEntity));
goals.a(1, new PathfinderGoalLookAtPlayer((EntityInsentient) mcLivingEntity, EntityHuman.class, 12.0F, 1.0F));
// overwrite target selector:
Field targetsField = EntityInsentient.class.getDeclaredField("targetSelector");
targetsField.setAccessible(true);
PathfinderGoalSelector targets = (PathfinderGoalSelector) targetsField.get(mcLivingEntity);
// clear old target goals:
Map<?, ?> targets_c = (Map<?, ?>) cField.get(targets);
targets_c.clear();
Set<?> targets_d = (Set<?>) dField.get(targets);
targets_d.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void tickAI(LivingEntity entity) {
EntityLiving mcLivingEntity = ((CraftLivingEntity) entity).getHandle();
// example: armor stands are living, but not insentient
if (!(mcLivingEntity instanceof EntityInsentient)) return;
EntityInsentient mcInsentientEntity = ((EntityInsentient) mcLivingEntity);
mcInsentientEntity.getEntitySenses().a(); // clear sensing cache
mcInsentientEntity.goalSelector.doTick();
mcInsentientEntity.getControllerLook().a(); // tick look controller
mcInsentientEntity.getEntitySenses().a(); // clear sensing cache
}
@Override
public void setOnGround(org.bukkit.entity.Entity entity, boolean onGround) {
Entity mcEntity = ((CraftEntity) entity).getHandle();
mcEntity.c(onGround); // setOnGround
}
@Override
public boolean isNoAIDisablingGravity() {
return true;
}
@Override
public void setNoclip(org.bukkit.entity.Entity entity) {
// when gravity gets disabled, we are able to also disable collisions/pushing of mobs via the noclip flag:
// this might not properly work for Vec, since those disable noclip again after their movement:
Entity mcEntity = ((CraftEntity) entity).getHandle();
mcEntity.noclip = true;
}
@Override
public void setCanJoinRaid(Raider raider, boolean canJoinRaid) {
// only works in the latest versions of 1.15.1 and upwards:
raider.setCanJoinRaid(canJoinRaid);
}
@Override
public void setExclusiveAdult(LivingEntity entity) {
if (entity instanceof Piglin) {
((Piglin) entity).setBaby(false);
} else if (entity instanceof Zoglin) {
((Zoglin) entity).setBaby(false);
}
}
@Override
public boolean matches(ItemStack provided, ItemStack required) {
if (provided == required) return true;
// if the required item is empty, then the provided item has to be empty as well:
if (ItemUtils.isEmpty(required)) return ItemUtils.isEmpty(provided);
else if (ItemUtils.isEmpty(provided)) return false;
if (provided.getType() != required.getType()) return false;
net.minecraft.server.v1_16_R1.ItemStack nmsProvided = CraftItemStack.asNMSCopy(provided);
net.minecraft.server.v1_16_R1.ItemStack nmsRequired = CraftItemStack.asNMSCopy(required);
NBTTagCompound providedTag = nmsProvided.getTag();
NBTTagCompound requiredTag = nmsRequired.getTag();
return GameProfileSerializer.a(requiredTag, providedTag, false); // compare tags
}
@Override
public void updateTrades(Player player) {
Inventory openInventory = player.getOpenInventory().getTopInventory();
if (!(openInventory instanceof MerchantInventory)) {
return;
}
MerchantInventory merchantInventory = (MerchantInventory) openInventory;
// update merchant inventory on the server (updates the result item, etc.):
merchantInventory.setItem(0, merchantInventory.getItem(0));
Merchant merchant = merchantInventory.getMerchant();
IMerchant nmsMerchant;
boolean regularVillager = false;
boolean canRestock = false;
// note: when using the 'is-regular-villager'-flag, using level 0 allows hiding the level name suffix
int merchantLevel = 1;
int merchantExperience = 0;
if (merchant instanceof Villager) {
nmsMerchant = ((CraftVillager) merchant).getHandle();
Villager villager = (Villager) merchant;
regularVillager = true;
canRestock = true;
merchantLevel = villager.getVillagerLevel();
merchantExperience = villager.getVillagerExperience();
} else if (merchant instanceof AbstractVillager) {
nmsMerchant = ((CraftAbstractVillager) merchant).getHandle();
} else {
nmsMerchant = ((CraftMerchant) merchant).getMerchant();
merchantLevel = 0; // hide name suffix
}
MerchantRecipeList merchantRecipeList = nmsMerchant.getOffers();
if (merchantRecipeList == null) merchantRecipeList = new MerchantRecipeList(); // just in case
// send PacketPlayOutOpenWindowMerchant packet: window id, recipe list, merchant level (1: Novice, .., 5:
// Master), merchant total experience, is-regular-villager flag (false: hides some gui elements), can-restock
// flag (false: hides restock message if out of stock)
EntityPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
nmsPlayer.openTrade(nmsPlayer.activeContainer.windowId, merchantRecipeList, merchantLevel, merchantExperience, regularVillager, canRestock);
}
@Override
public String getItemSNBT(ItemStack itemStack) {
if (itemStack == null) return null;
net.minecraft.server.v1_16_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound itemNBT = nmsItem.save(new NBTTagCompound());
return itemNBT.toString();
}
@Override
public String getItemTypeTranslationKey(Material material) {
if (material == null) return null;
net.minecraft.server.v1_16_R1.Item nmsItem = CraftMagicNumbers.getItem(material);
if (nmsItem == null) return null;
return nmsItem.getName();
}
}

View File

@ -63,6 +63,7 @@
<module>modules/main</module>
<module>modules/v1_14_R1</module>
<module>modules/v1_15_R1</module>
<module>modules/v1_16_R1</module>
<module>modules/dist</module>
</modules>

View File

@ -7,6 +7,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
@ -164,7 +165,6 @@ public class Settings {
EntityType.ENDERMAN.name(),
EntityType.ZOMBIE.name(),
EntityType.ZOMBIE_VILLAGER.name(), // MC 1.11
EntityType.PIG_ZOMBIE.name(),
EntityType.HUSK.name(), // MC 1.11
EntityType.GIANT.name(),
EntityType.GHAST.name(),
@ -197,7 +197,12 @@ public class Settings {
EntityType.TRADER_LLAMA.name(), // MC 1.14
EntityType.WANDERING_TRADER.name(), // MC 1.14
EntityType.FOX.name(), // MC 1.14
"BEE" // MC 1.15
"BEE", // MC 1.15
"ZOMBIFIED_PIGLIN", // MC 1.16, replaced PIG_ZOMBIE
"PIGLIN", // MC 1.16
"HOGLIN", // MC 1.16
"ZOGLIN", // MC 1.16
"STRIDER" // MC 1.16
);
public static boolean useLegacyMobBehavior = false;
@ -580,13 +585,25 @@ public class Settings {
// validation:
boolean foundInvalidEntityType = false;
boolean removePigZombie = false;
for (String entityTypeId : enabledLivingShops) {
EntityType entityType = matchEntityType(entityTypeId);
if (entityType == null || !entityType.isAlive() || !entityType.isSpawnable()) {
foundInvalidEntityType = true;
Log.warning("Config: Invalid living entity type name in 'enabled-living-shops': " + entityTypeId);
if ("PIG_ZOMBIE".equals(entityTypeId)) {
removePigZombie = true;
} else {
Log.warning("Config: Invalid living entity type name in 'enabled-living-shops': " + entityTypeId);
}
}
}
// Migration for MC 1.16 TODO remove this again at some point
if (removePigZombie) {
Log.warning("Config: The mob type 'PIG_ZOMBIE' no longer exist since MC 1.16 and has therefore been removed from the 'enabled-living-shops'. Consider replacing it with 'ZOMBIFIED_PIGLIN'.");
enabledLivingShops.removeIf(e -> Objects.equals(e, "PIG_ZOMBIE"));
config.set(toConfigKey("enabledLivingShops"), enabledLivingShops);
configChanged = true;
}
if (foundInvalidEntityType) {
Log.warning("Config: All existing entity type names can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/EntityType.html");
}

View File

@ -0,0 +1,29 @@
package com.nisovin.shopkeepers.compat;
import java.util.Optional;
import org.bukkit.entity.EntityType;
import com.nisovin.shopkeepers.util.Log;
// TODO This can be removed once we only support Bukkit 1.16.1 upwards.
public class MC_1_16_Utils {
private static Optional<EntityType> zombifiedPiglin = null;
private MC_1_16_Utils() {
}
public static EntityType getZombifiedPiglin() {
if (zombifiedPiglin == null) {
try {
zombifiedPiglin = Optional.of(EntityType.valueOf("ZOMBIFIED_PIGLIN"));
Log.debug("Server knows EntityType 'ZOMBIFIED_PIGLIN'.");
} catch (IllegalArgumentException e) {
zombifiedPiglin = Optional.empty();
Log.debug("Server does not know EntityType 'ZOMBIFIED_PIGLIN'.");
}
}
return zombifiedPiglin.orElse(null);
}
}

View File

@ -32,6 +32,14 @@ public interface NMSCallProvider {
// TODO replace this once only the latest versions of 1.15.1 and upwards are supported
public void setCanJoinRaid(Raider raider, boolean canJoinRaid);
// Sets the entity as adult for mob types for which we don't support the baby property yet, i.e. because they are
// exclusive to the specific MC version:
// TODO Remove this once there are no exclusive mobs anymore to which this applies (currently, once we only support
// MC 1.16.1 upwards)
public default void setExclusiveAdult(LivingEntity entity) {
// no exclusive mobs by default
}
/**
* Checks if the <code>provided</code> itemstack fulfills the requirements of a trading recipe requiring the given
* <code>required</code> itemstack.

View File

@ -28,6 +28,7 @@ import com.nisovin.shopkeepers.api.storage.ShopkeeperStorage;
import com.nisovin.shopkeepers.api.ui.DefaultUITypes;
import com.nisovin.shopkeepers.api.ui.UIType;
import com.nisovin.shopkeepers.api.util.ChunkCoords;
import com.nisovin.shopkeepers.compat.MC_1_16_Utils;
import com.nisovin.shopkeepers.shopobjects.AbstractShopObject;
import com.nisovin.shopkeepers.shopobjects.AbstractShopObjectType;
import com.nisovin.shopkeepers.shopobjects.living.types.CatShop;
@ -259,6 +260,14 @@ public abstract class AbstractShopkeeper implements Shopkeeper {
}
} // else: stays ocelot
}
// MC 1.16:
// Convert pig-zombie to zombified-piglin (but only if we run on MC 1.16 or above):
if (MC_1_16_Utils.getZombifiedPiglin() != null && objectTypeId.equals("pig-zombie")) {
objectTypeId = "zombified-piglin";
Log.warning("Migrated object type of shopkeeper '" + id + "' from 'pig-zombie' to 'zombified-piglin'.");
this.markDirty();
}
}
AbstractShopObjectType<?> objectType = SKShopkeepersPlugin.getInstance().getShopObjectTypeRegistry().get(objectTypeId);

View File

@ -5,6 +5,7 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Raider;
@ -195,6 +196,10 @@ public class SKLivingShopObject<E extends LivingEntity> extends AbstractEntitySh
if (this.isActive()) {
// further setup entity after it was successfully spawned:
// Some entities randomly spawn with passengers:
for (Entity passenger : entity.getPassengers()) {
passenger.remove();
}
entity.eject(); // some entities might automatically mount on nearby entities (like baby zombies on chicken)
entity.setRemoveWhenFarAway(false);
entity.setCanPickupItems(false);
@ -207,6 +212,9 @@ public class SKLivingShopObject<E extends LivingEntity> extends AbstractEntitySh
ageable.setAgeLock(true);
}
// Set the entity to an adult if we don't support its baby property yet:
NMSManager.getProvider().setExclusiveAdult(entity);
// remove potion effects:
for (PotionEffect potionEffect : entity.getActivePotionEffects()) {
entity.removePotionEffect(potionEffect.getType());

View File

@ -62,7 +62,7 @@ public class SKLivingShopObjectTypes implements LivingShopObjectTypes {
* <li> MUSHROOM_COW: okay
* <li> OCELOT: okay
* <li> PIG: okay
* <li> PIG_ZOMBIE: okay, spawns randomly as baby
* <li> PIG_ZOMBIE: okay; replaced by ZOMBIFIED_PIGLIN in MC 1.16
* <li> SHEEP: okay
* <li> SILVERFISH: experimental, strange movement when the player is standing behind it -> NoAI for now
* <li> SKELETON: okay
@ -95,7 +95,7 @@ public class SKLivingShopObjectTypes implements LivingShopObjectTypes {
* <li> DONKEY: same issues as horse
* <li> MULE: same issues as horse
* <li> EVOKER: okay
* <li> VEX: starts gliding into the ground once spawned and occasionally,other than that it seems to work fine
* <li> VEX: starts gliding into the ground once spawned and occasionally, other than that it seems to work fine
* <li> VINDICATOR: okay
* <li> LLAMA: okay
* # 1.12
@ -120,6 +120,12 @@ public class SKLivingShopObjectTypes implements LivingShopObjectTypes {
* <li> FOX: okay, randomly spawns with an item in its mouth (gets cleared)
* # 1.15
* <li> BEE: okay, turning towards nearby players is jerky (body rotation instead of head rotation), occasionally starts flapping its wings
* # 1.16
* <li> ZOMBIFIED_PIGLIN: okay, replaces PIG_ZOMBIE
* <li> PIGLIN: okay, spawns with random gear (gets cleared), TODO add baby property
* <li> HOGLIN: okay
* <li> ZOGLIN: okay, TODO add baby property
* <li> STRIDER: okay, shakes outside the nether, randomly spawns with passenger (gets cleared), randomly spawns with saddle (TODO; clearing the passengers during entity preparation doesn't help with this)
* </ul>
*/

View File

@ -154,7 +154,6 @@ enabled-living-shops:
- ENDERMAN
- ZOMBIE
- ZOMBIE_VILLAGER
- PIG_ZOMBIE
- HUSK
- GIANT
- GHAST
@ -188,6 +187,11 @@ enabled-living-shops:
- WANDERING_TRADER
- FOX
- BEE
- ZOMBIFIED_PIGLIN
- PIGLIN
- HOGLIN
- ZOGLIN
- STRIDER
# With the old behavior the mobs can be pushed around and their AI and gravity
# is handled by minecraft itself. With the new behavior all their vanilla AI is