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
parent
ae14c09ff1
commit
186711941b
|
@ -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
|
||||
|
|
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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();
|
||||
}
|
||||
}
|
1
pom.xml
1
pom.xml
|
@ -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>
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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>
|
||||
*/
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue