Version 2.12.0

Updated for MC 1.16.4.
master
blablubbabc 2020-11-03 22:37:52 +01:00
parent b776ac4163
commit a72b1bf657
7 changed files with 253 additions and 4 deletions

View File

@ -1,9 +1,14 @@
# Changelog
Date format: (YYYY-MM-DD)
## v2.11.1 (TBA)
### Supported MC versions: 1.16.2, 1.16.1, 1.15.2, 1.14.4
## v2.12.1 (TBA)
### Supported MC versions: 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.15.2, 1.14.4
## v2.12.0 (2020-11-04)
### Supported MC versions: 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.15.2, 1.14.4
* Updated for MC 1.16.4.
* Bumped Towny dependency to 0.96.2.0 and using Jitpack repository for it now.
* Fixed: Creating shopkeepers via Citizens trait failed previously if the block at the spawn location is not passable (eg. when the Citizens NPC stands on a non-full block such as carpet).
* Minor changes to handling failures when trying to create a shopkeeper via Citizens trait. We always inform the player (if there is one), log a warning and delete the trait again now.
@ -24,7 +29,7 @@ Internal:
* Editor UIs are setup lazily now, only when required for the first time.
## v2.11.0 (2020-08-13)
### Supported MC versions: 1.16.2, 1.16.1, 1.15.2, 1.14.4
### Supported MC versions: 1.16.3, 1.16.2, 1.16.1, 1.15.2, 1.14.4
Update for MC 1.16.2:
* Config: Added piglin brute to the by default enabled mob types. If you are updating, you will have to manually enable this yourself.

View File

@ -6,3 +6,4 @@ if [ ! -f "$HOME/.m2/repository/org/bukkit/craftbukkit/1.14.4-R0.1-SNAPSHOT/craf
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
if [ ! -f "$HOME/.m2/repository/org/bukkit/craftbukkit/1.16.2-R0.1-SNAPSHOT/craftbukkit-1.16.2-R0.1-SNAPSHOT.jar" ]; then ./installSpigot.sh 1.16.2 ; else echo "Not compiling Spigot 1.16.2 because it is already in our Maven repo" ; fi
if [ ! -f "$HOME/.m2/repository/org/bukkit/craftbukkit/1.16.4-R0.1-SNAPSHOT/craftbukkit-1.16.4-R0.1-SNAPSHOT.jar" ]; then ./installSpigot.sh 1.16.4 ; else echo "Not compiling Spigot 1.16.4 because it is already in our Maven repo" ; fi

View File

@ -115,6 +115,13 @@
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>sk-v1_16_R3</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.11.1-SNAPSHOT</revision>
<revision>2.12.0</revision>
<root.relativePath>../..</root.relativePath>
<shopkeepers.version>${project.version}</shopkeepers.version>
<shopkeepers.dbo.url>https://dev.bukkit.org/projects/shopkeepers/</shopkeepers.dbo.url>

25
modules/v1_16_R3/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_R3</artifactId>
<packaging>jar</packaging>
<name>SK for v1_16_R3</name>
<properties>
<craftbukkit.version>1.16.4-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_R3;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftAbstractVillager;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftVillager;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchant;
import org.bukkit.craftbukkit.v1_16_R3.util.CraftMagicNumbers;
import org.bukkit.entity.AbstractVillager;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.PiglinAbstract;
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_R3.Entity;
import net.minecraft.server.v1_16_R3.EntityHuman;
import net.minecraft.server.v1_16_R3.EntityInsentient;
import net.minecraft.server.v1_16_R3.EntityLiving;
import net.minecraft.server.v1_16_R3.EntityPlayer;
import net.minecraft.server.v1_16_R3.GameProfileSerializer;
import net.minecraft.server.v1_16_R3.IMerchant;
import net.minecraft.server.v1_16_R3.MerchantRecipeList;
import net.minecraft.server.v1_16_R3.NBTTagCompound;
import net.minecraft.server.v1_16_R3.PathfinderGoalFloat;
import net.minecraft.server.v1_16_R3.PathfinderGoalLookAtPlayer;
import net.minecraft.server.v1_16_R3.PathfinderGoalSelector;
public final class NMSHandler implements NMSCallProvider {
@Override
public String getVersionId() {
return "1_16_R3";
}
@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.setOnGround(onGround);
}
@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 PiglinAbstract) {
((PiglinAbstract) 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_R3.ItemStack nmsProvided = CraftItemStack.asNMSCopy(provided);
net.minecraft.server.v1_16_R3.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_R3.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_R3.Item nmsItem = CraftMagicNumbers.getItem(material);
if (nmsItem == null) return null;
return nmsItem.getName();
}
}

View File

@ -65,6 +65,7 @@
<module>modules/v1_15_R1</module>
<module>modules/v1_16_R1</module>
<module>modules/v1_16_R2</module>
<module>modules/v1_16_R3</module>
<module>modules/dist</module>
</modules>