Initial 1.20 update

This commit is contained in:
fullwall 2023-06-08 22:37:50 +08:00
parent f164494cde
commit 9facad1b2a
172 changed files with 30208 additions and 60 deletions

9
dist/pom.xml vendored
View File

@ -5,7 +5,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens</artifactId>
<packaging>pom</packaging>
@ -92,5 +92,12 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>citizens-v1_20_R1</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-main</artifactId>
<properties>
@ -131,13 +131,13 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.11.0</version>
<version>4.14.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.1.2</version>
<version>4.3.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -305,28 +305,28 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
lib.loadLibrary(Library.builder().groupId("net{}sf{}trove4j").artifactId("trove4j").version("3.0.3")
.relocate("gnu{}trove", "clib{}trove").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-text-minimessage")
.version("4.12.0").relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-bukkit").version("4.2.0")
.version("4.14.0").relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-bukkit").version("4.3.0")
.relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-api").version("4.2.0")
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-api").version("4.3.0")
.relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-facet").version("4.2.0")
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-facet").version("4.3.0")
.relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-viaversion")
.version("4.2.0").relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-api").version("4.12.0")
.version("4.3.0").relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-api").version("4.14.0")
.relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-text-serializer-bungeecord")
.version("4.2.0").relocate("net{}kyori", "clib{}net{}kyori").build());
.version("4.3.0").relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-text-serializer-legacy")
.version("4.12.0").relocate("net{}kyori", "clib{}net{}kyori").build());
.version("4.13.0").relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-text-serializer-gson")
.version("4.12.0").relocate("net{}kyori", "clib{}net{}kyori").build());
.version("4.13.0").relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-text-serializer-gson-legacy-impl")
.version("4.12.0").relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-nbt").version("4.12.0")
.version("4.13.0").relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-nbt").version("4.13.0")
.relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-key").version("4.12.0")
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-key").version("4.14.0")
.relocate("net{}kyori", "clib{}net{}kyori").build());
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("examination-api").version("1.3.0")
.relocate("net{}kyori", "clib{}net{}kyori").build());

View File

@ -141,7 +141,7 @@ public class Settings {
"npc.pathfinding.straight-line-targeting-distance", 5),
DEFAULT_STUCK_ACTION(
"The default action to perform when NPCs are unable to find a path or are stuck in the same block for too long. Supported options are: 'teleport to destination' or 'none'",
"npc.pathfinding.default-stuck-action", "teleport to destination"),
"npc.pathfinding.default-stuck-action", "none"),
DEFAULT_TALK_CLOSE("npc.default.talk-close.enabled", false),
DEFAULT_TALK_CLOSE_RANGE("Default talk close range in blocks", "npc.default.talk-close.range", 5),
DEFAULT_TEXT("npc.default.talk-close.text.0", "Hi, I'm <npc>!") {

View File

@ -133,6 +133,7 @@ import net.citizensnpcs.trait.ScriptTrait;
import net.citizensnpcs.trait.SheepTrait;
import net.citizensnpcs.trait.ShopTrait;
import net.citizensnpcs.trait.ShopTrait.NPCShop;
import net.citizensnpcs.trait.SitTrait;
import net.citizensnpcs.trait.SkinLayers;
import net.citizensnpcs.trait.SkinLayers.Layer;
import net.citizensnpcs.trait.SkinTrait;
@ -2647,6 +2648,31 @@ public class NPCCommands {
}
}
@Command(
aliases = { "npc" },
usage = "sitting (--explicit [true|false]) (--at [at])",
desc = "Sets the NPC sitting",
modifiers = { "sitting" },
min = 1,
max = 2,
permission = "citizens.npc.sitting")
@Requirements(selected = true, ownership = true)
public void sitting(CommandContext args, CommandSender sender, NPC npc, @Flag("explicit") Boolean explicit,
@Flag("at") Location at) {
SitTrait trait = npc.getOrAddTrait(SitTrait.class);
boolean toSit = explicit != null ? explicit : !trait.isSitting();
if (!toSit) {
trait.setSitting(null);
Messaging.sendTr(sender, Messages.SITTING_UNSET, npc.getName());
return;
}
if (at == null) {
at = npc.getStoredLocation();
}
trait.setSitting(at);
Messaging.sendTr(sender, Messages.SITTING_SET, npc.getName(), at);
}
@Command(
aliases = { "npc" },
usage = "skin (-c(lear) -l(atest)) [name] (or --url [url] --file [file] (-s(lim)) or -t [uuid/name] [data] [signature])",

View File

@ -301,6 +301,7 @@ public class CitizensNPC extends AbstractNPC {
getOrAddTrait(CurrentLocation.class).setLocation(at);
entityController.create(at.clone(), this);
getEntity().setMetadata("NPC", new FixedMetadataValue(CitizensAPI.getPlugin(), true));
getEntity().setMetadata("NPC-ID", new FixedMetadataValue(CitizensAPI.getPlugin(), getId()));
if (getEntity() instanceof SkinnableEntity && !hasTrait(SkinLayers.class)) {
((SkinnableEntity) getEntity()).setSkinFlags(EnumSet.allOf(SkinLayers.Layer.class));

View File

@ -97,7 +97,6 @@ public class FollowTrait extends Trait {
if (entity == null)
return;
}
if (!isActive())
return;
@ -107,6 +106,7 @@ public class FollowTrait extends Trait {
}
return;
}
if (!npc.getNavigator().isNavigating()) {
npc.getNavigator().setTarget(entity, false);
} else {

View File

@ -44,6 +44,8 @@ public class HologramTrait extends Trait {
private BiFunction<String, Player, String> customHologramSupplier;
@Persist
private HologramDirection direction = HologramDirection.BOTTOM_UP;
@Persist(reify = true)
private HologramFilter filter;
private double lastEntityHeight = 0;
private boolean lastNameplateVisible;
@Persist
@ -417,6 +419,17 @@ public class HologramTrait extends Trait {
TOP_DOWN;
}
public static class HologramFilter {
private HologramFilter() {
}
public static class Builder {
public HologramFilter build() {
return new HologramFilter();
}
}
}
private class HologramLine implements Function<Player, String> {
NPC hologram;
double mb, mt;

View File

@ -361,6 +361,8 @@ public class Messages {
public static final String SHEEP_COLOR_SET = "citizens.commands.npc.sheep.color-set";
public static final String SHULKER_COLOR_SET = "citizens.commands.npc.shulker.color-set";
public static final String SHULKER_PEEK_SET = "citizens.commands.npc.shulker.peek-set";
public static final String SITTING_SET = "citizens.commands.npc.sitting.set";
public static final String SITTING_UNSET = "citizens.commands.npc.sitting.unset";
public static final String SIZE_DESCRIPTION = "citizens.commands.npc.size.description";
public static final String SIZE_SET = "citizens.commands.npc.size.set";
public static final String SKELETON_TYPE_SET = "citizens.commands.npc.skeletontype.set";

View File

@ -9,7 +9,7 @@ import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@ -60,20 +60,26 @@ public class Util {
}
}
public static void callPossiblyAsyncEvent(Event event, boolean sync) {
public static boolean callEventPossiblySync(Event event, boolean sync) {
if (!sync) {
try {
Bukkit.getPluginManager().callEvent(event);
return false;
} catch (IllegalStateException ex) {
// sync method called
}
}
try {
Callable<Void> callable = () -> {
Bukkit.getScheduler().callSyncMethod(CitizensAPI.getPlugin(), () -> {
Bukkit.getPluginManager().callEvent(event);
return null;
};
if (sync) {
Bukkit.getScheduler().callSyncMethod(CitizensAPI.getPlugin(), callable).get();
} else {
callable.call();
}
} catch (Exception e) {
}).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return true;
}
public static Vector callPushEvent(NPC npc, double x, double y, double z) {

View File

@ -278,12 +278,14 @@ citizens.commands.npc.script.current-scripts=[[{0}]]''s current scripts are [[{1
citizens.commands.npc.shulker.peek-set=[[{0}]]''s peek amount set to [[{1}]].
citizens.commands.npc.shulker.color-set=[[{0}]]''s color set to [[{1}]].
citizens.commands.npc.shulker.invalid-color=Invalid shulker color given. Valid colors are: [[{0}]].
citizens.commands.npc.sitting.set=[[{0}]] is now sitting at [[{1}]].
citizens.commands.npc.sitting.unset=[[{0}]] is no longer sitting.
citizens.commands.npc.skin.error-setting-url=Error downloading skin texture from [[{0}]]. Are you sure the URL is valid?
citizens.commands.npc.skin.skin-url-set=Downloaded [[{0}]]''s skin from [[{1}]].
citizens.commands.npc.skin.set=[[{0}]]''s skin name set to [[{1}]].
citizens.commands.npc.skin.missing-skin=A skin name is required.
citizens.commands.npc.skin.fetching=Attempting to generate skin using https://mineskin.org
citizens.commands.npc.skin.invalid-file=Skin file [[{0}]] not found. Must be a file under plugins/Citizens2/skins/<file.png>
citizens.commands.npc.skin.invalid-file=Skin file [[{0}]] not found. Must be a file under plugins/Citizens/skins/<file.png>
citizens.commands.npc.skin.cleared=[[{0}]]''s skin name was cleared.
citizens.commands.npc.skin.layers-set=[[{0}]]''s skin layers: cape - [[{1}]], hat - [[{2}]], jacket - [[{3}]], sleeves - [[{4}]], pants - [[{5}]].
citizens.commands.npc.size.description=[[{0}]]''s size is [[{1}]].

View File

@ -4,10 +4,10 @@
<packaging>pom</packaging>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
<properties>
<BUILD_NUMBER>Unknown</BUILD_NUMBER>
<CITIZENS_VERSION>2.0.31</CITIZENS_VERSION>
<CITIZENS_VERSION>2.0.32</CITIZENS_VERSION>
<maven-javadoc-plugin.version>3.5.0</maven-javadoc-plugin.version>
<maven-assembly-plugin.version>3.5.0</maven-assembly-plugin.version>
<maven-deploy-plugin.version>3.1.1</maven-deploy-plugin.version>
@ -37,6 +37,7 @@
<module>v1_16_R3</module>
<module>v1_18_R2</module>
<module>v1_19_R3</module>
<module>v1_20_R1</module>
<module>dist</module>
</modules>
</project>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_10_R1</artifactId>
<properties>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_11_R1</artifactId>
<properties>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_12_R1</artifactId>
<properties>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_13_R2</artifactId>
<properties>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_14_R1</artifactId>
<properties>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_15_R1</artifactId>
<properties>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_16_R3</artifactId>
<properties>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_17_R1</artifactId>
<properties>

View File

@ -480,6 +480,5 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
private static final float EPSILON = 0.003F;
private static final MethodHandle GAMEMODE_SETTING = NMS.getFirstMethodHandle(ServerPlayerGameMode.class, true,
GameType.class, GameType.class);
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
}

View File

@ -54,11 +54,8 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
public void updatePlayer(final ServerPlayer entityplayer) {
if (tracker instanceof NPCHolder) {
NPC npc = ((NPCHolder) tracker).getNPC();
if (REQUIRES_SYNC == null) {
REQUIRES_SYNC = !Bukkit.isPrimaryThread();
}
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
Util.callPossiblyAsyncEvent(event, REQUIRES_SYNC);
REQUIRES_SYNC = Util.callEventPossiblySync(event, REQUIRES_SYNC);
if (event.isCancelled())
return;
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
@ -117,9 +114,8 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
}
private static final MethodHandle E = NMS.getGetter(ServerEntity.class, "e");
private static final MethodHandle F = NMS.getGetter(ServerEntity.class, "f");
private static Boolean REQUIRES_SYNC;
private static boolean REQUIRES_SYNC;
private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class);
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);

View File

@ -6,7 +6,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_18_R2</artifactId>
<properties>

View File

@ -54,11 +54,8 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
public void updatePlayer(final ServerPlayer entityplayer) {
if (tracker instanceof NPCHolder) {
NPC npc = ((NPCHolder) tracker).getNPC();
if (REQUIRES_SYNC == null) {
REQUIRES_SYNC = !Bukkit.isPrimaryThread();
}
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
Util.callPossiblyAsyncEvent(event, REQUIRES_SYNC);
REQUIRES_SYNC = Util.callEventPossiblySync(event, REQUIRES_SYNC);
if (event.isCancelled())
return;
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
@ -117,9 +114,8 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
}
private static final MethodHandle E = NMS.getGetter(ServerEntity.class, "e");
private static final MethodHandle F = NMS.getGetter(ServerEntity.class, "f");
private static Boolean REQUIRES_SYNC;
private static boolean REQUIRES_SYNC;
private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class);
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);

View File

@ -4,7 +4,7 @@
<parent>
<groupId>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.31-SNAPSHOT</version>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_19_R3</artifactId>
<properties>

View File

@ -81,11 +81,8 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
if (tracker instanceof NPCHolder) {
NPC npc = ((NPCHolder) tracker).getNPC();
if (REQUIRES_SYNC == null) {
REQUIRES_SYNC = !Bukkit.isPrimaryThread();
}
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
Util.callPossiblyAsyncEvent(event, REQUIRES_SYNC);
REQUIRES_SYNC = Util.callEventPossiblySync(event, REQUIRES_SYNC);
if (event.isCancelled())
return;
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
@ -141,7 +138,7 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
private static final MethodHandle E = NMS.getGetter(ServerEntity.class, "e");
private static final MethodHandle F = NMS.getGetter(ServerEntity.class, "f");
private static Boolean REQUIRES_SYNC;
private static boolean REQUIRES_SYNC = false;
private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class);
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);

112
v1_20_R1/pom.xml Normal file
View File

@ -0,0 +1,112 @@
<!-- Citizens build file -->
<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>net.citizensnpcs</groupId>
<artifactId>citizens-parent</artifactId>
<version>2.0.32-SNAPSHOT</version>
</parent>
<artifactId>citizens-v1_20_R1</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<craftbukkit.version>1.20-R0.1-SNAPSHOT</craftbukkit.version>
</properties>
<repositories>
<repository>
<id>viaversion-repo</id>
<url>https://repo.viaversion.com</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>citizens-main</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>${craftbukkit.version}</version>
<classifier>remapped-mojang</classifier>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean package install</defaultGoal>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
<executions>
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.md-5</groupId>
<artifactId>specialsource-maven-plugin</artifactId>
<version>1.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>remap</goal>
</goals>
<id>remap-obf</id>
<configuration>
<srgIn>org.spigotmc:minecraft-server:${craftbukkit.version}:txt:maps-mojang</srgIn>
<reverse>true</reverse>
<remappedDependencies>org.spigotmc:spigot:${craftbukkit.version}:jar:remapped-mojang</remappedDependencies>
<remappedArtifactAttached>true</remappedArtifactAttached>
<remappedClassifierName>remapped-obf</remappedClassifierName>
</configuration>
</execution>
<execution>
<phase>package</phase>
<goals>
<goal>remap</goal>
</goals>
<id>remap-spigot</id>
<configuration>
<inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile>
<srgIn>org.spigotmc:minecraft-server:${craftbukkit.version}:csrg:maps-spigot</srgIn>
<remappedDependencies>org.spigotmc:spigot:${craftbukkit.version}:jar:remapped-obf</remappedDependencies>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,242 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftAllay;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.animal.allay.Allay;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class AllayController extends MobEntityController {
public AllayController() {
super(EntityAllayNPC.class);
}
@Override
public org.bukkit.entity.Allay getBukkitEntity() {
return (org.bukkit.entity.Allay) super.getBukkitEntity();
}
public static class AllayNPC extends CraftAllay implements ForwardingNPCHolder {
public AllayNPC(EntityAllayNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityAllayNPC extends Allay implements NPCHolder {
private final CitizensNPC npc;
private int taskId = -1;
public EntityAllayNPC(EntityType<? extends Allay> types, Level level) {
this(types, level, null);
}
public EntityAllayNPC(EntityType<? extends Allay> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new AllayNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
protected InteractionResult mobInteract(Player var0, InteractionHand var1) {
if (npc != null && npc.isProtected()) {
// prevent clientside prediction
if (taskId == -1) {
taskId = Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMSImpl.sendPacket((org.bukkit.entity.Player) var0.getBukkitEntity(),
new ClientboundSetEquipmentPacket(getId(),
Lists.newArrayList(
Pair.of(EquipmentSlot.OFFHAND,
this.getItemInHand(InteractionHand.OFF_HAND)),
Pair.of(EquipmentSlot.MAINHAND,
this.getItemInHand(InteractionHand.MAIN_HAND)))));
((org.bukkit.entity.Player) var0.getBukkitEntity()).updateInventory();
taskId = -1;
}, 2);
}
return InteractionResult.FAIL;
}
return super.mobInteract(var0, var1);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,150 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftArmorStand;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.MobAI;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_20_R1.util.MobAI.ForwardingMobAI;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.decoration.ArmorStand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class ArmorStandController extends MobEntityController {
public ArmorStandController() {
super(EntityArmorStandNPC.class);
}
@Override
public org.bukkit.entity.ArmorStand getBukkitEntity() {
return (org.bukkit.entity.ArmorStand) super.getBukkitEntity();
}
public static class ArmorStandNPC extends CraftArmorStand implements ForwardingNPCHolder {
public ArmorStandNPC(EntityArmorStandNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityArmorStandNPC extends ArmorStand implements NPCHolder, ForwardingMobAI {
private MobAI ai;
private final CitizensNPC npc;
public EntityArmorStandNPC(EntityType<? extends ArmorStand> types, Level level) {
this(types, level, null);
}
public EntityArmorStandNPC(EntityType<? extends ArmorStand> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
ai = new BasicMobAI(this);
}
}
@Override
public MobAI getAI() {
return ai;
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new ArmorStandNPC(this));
}
return super.getBukkitEntity();
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public InteractionResult interactAt(Player entityhuman, Vec3 vec3d, InteractionHand enumhand) {
if (npc == null) {
return super.interactAt(entityhuman, vec3d, enumhand);
}
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(
(org.bukkit.entity.Player) entityhuman.getBukkitEntity(), getBukkitEntity());
Bukkit.getPluginManager().callEvent(event);
return event.isCancelled() ? InteractionResult.FAIL : InteractionResult.SUCCESS;
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void tick() {
super.tick();
if (npc != null) {
npc.update();
ai.tickAI();
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,256 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftAxolotl;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import com.mojang.serialization.Dynamic;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.animal.axolotl.Axolotl;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class AxolotlController extends MobEntityController {
public AxolotlController() {
super(EntityAxolotlNPC.class);
}
@Override
public org.bukkit.entity.Axolotl getBukkitEntity() {
return (org.bukkit.entity.Axolotl) super.getBukkitEntity();
}
public static class AxolotlNPC extends CraftAxolotl implements ForwardingNPCHolder {
public AxolotlNPC(EntityAxolotlNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityAxolotlNPC extends Axolotl implements NPCHolder {
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityAxolotlNPC(EntityType<? extends Axolotl> types, Level level) {
this(types, level, null);
}
public EntityAxolotlNPC(EntityType<? extends Axolotl> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
this.oldMoveController = this.moveControl;
this.moveControl = new MoveControl(this);
this.getAttribute(Attributes.MOVEMENT_SPEED)
.setBaseValue(this.getAttribute(Attributes.MOVEMENT_SPEED).getBaseValue() / 10);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new AxolotlNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
protected Brain<?> makeBrain(Dynamic<?> dynamic) {
if (npc == null || npc.useMinecraftAI()) {
return super.makeBrain(dynamic);
}
return brainProvider().makeBrain(dynamic);
}
@Override
public InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc == null || !npc.isProtected())
return super.mobInteract(entityhuman, enumhand);
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.getItem() == Items.BUCKET || itemstack.getItem() == Items.WATER_BUCKET) {
return InteractionResult.FAIL;
}
return super.mobInteract(entityhuman, enumhand);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void tick() {
super.tick();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new MoveControl(this);
}
npc.update();
}
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
if (!NMSImpl.moveFish(npc, this, vec3d)) {
super.travel(vec3d);
}
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,185 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftBat;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ambient.Bat;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
public class BatController extends MobEntityController {
public BatController() {
super(EntityBatNPC.class);
}
@Override
public org.bukkit.entity.Bat getBukkitEntity() {
return (org.bukkit.entity.Bat) super.getBukkitEntity();
}
public static class BatNPC extends CraftBat implements ForwardingNPCHolder {
public BatNPC(EntityBatNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityBatNPC extends Bat implements NPCHolder {
private final CitizensNPC npc;
public EntityBatNPC(EntityType<? extends Bat> types, Level level) {
this(types, level, null);
}
public EntityBatNPC(EntityType<? extends Bat> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
setFlying(false);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
public void customServerAiStep() {
if (npc == null) {
super.customServerAiStep();
} else {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI()) {
super.customServerAiStep();
}
npc.update();
}
}
@Override
public SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new BatNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(net.minecraft.world.entity.Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
public void setFlying(boolean flying) {
setResting(flying);
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,180 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftBee;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Bee;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
public class BeeController extends MobEntityController {
public BeeController() {
super(EntityBeeNPC.class);
}
@Override
public org.bukkit.entity.Bee getBukkitEntity() {
return (org.bukkit.entity.Bee) super.getBukkitEntity();
}
public static class BeeNPC extends CraftBee implements ForwardingNPCHolder {
public BeeNPC(EntityBeeNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityBeeNPC extends Bee implements NPCHolder {
private final CitizensNPC npc;
public EntityBeeNPC(EntityType<? extends Bee> types, Level level) {
this(types, level, null);
}
public EntityBeeNPC(EntityType<? extends Bee> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
public void customServerAiStep() {
if (npc == null) {
super.customServerAiStep();
} else {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI()) {
super.customServerAiStep();
}
npc.update();
}
}
@Override
public SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new BeeNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,175 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftBlaze;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Blaze;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
public class BlazeController extends MobEntityController {
public BlazeController() {
super(EntityBlazeNPC.class);
}
@Override
public org.bukkit.entity.Blaze getBukkitEntity() {
return (org.bukkit.entity.Blaze) super.getBukkitEntity();
}
public static class BlazeNPC extends CraftBlaze implements ForwardingNPCHolder {
public BlazeNPC(EntityBlazeNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityBlazeNPC extends Blaze implements NPCHolder {
private final CitizensNPC npc;
public EntityBlazeNPC(EntityType<? extends Blaze> types, Level level) {
this(types, level, null);
}
public EntityBlazeNPC(EntityType<? extends Blaze> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new BlazeNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,239 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftCamel;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.camel.Camel;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class CamelController extends MobEntityController {
public CamelController() {
super(EntityCamelNPC.class);
}
@Override
public void create(Location at, NPC npc) {
npc.getOrAddTrait(HorseModifiers.class);
super.create(at, npc);
}
@Override
public org.bukkit.entity.Camel getBukkitEntity() {
return (org.bukkit.entity.Camel) super.getBukkitEntity();
}
public static class CamelNPC extends CraftCamel implements ForwardingNPCHolder {
public CamelNPC(EntityCamelNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityCamelNPC extends Camel implements NPCHolder {
private final CitizensNPC npc;
public EntityCamelNPC(EntityType<? extends Camel> types, Level level) {
this(types, level, null);
}
public EntityCamelNPC(EntityType<? extends Camel> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
((org.bukkit.entity.Camel) getBukkitEntity())
.setDomestication(((org.bukkit.entity.Camel) getBukkitEntity()).getMaxDomestication());
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc == null) {
super.customServerAiStep();
} else {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI()) {
super.customServerAiStep();
}
NMS.setStepHeight(getBukkitEntity(), 1);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new CamelNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,222 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftCat;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Cat;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class CatController extends MobEntityController {
public CatController() {
super(EntityCatNPC.class);
}
@Override
public org.bukkit.entity.Cat getBukkitEntity() {
return (org.bukkit.entity.Cat) super.getBukkitEntity();
}
public static class CatNPC extends CraftCat implements ForwardingNPCHolder {
public CatNPC(EntityCatNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityCatNPC extends Cat implements NPCHolder {
private final CitizensNPC npc;
public EntityCatNPC(EntityType<? extends Cat> types, Level level) {
this(types, level, null);
}
public EntityCatNPC(EntityType<? extends Cat> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new CatNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,221 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftCaveSpider;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.CaveSpider;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class CaveSpiderController extends MobEntityController {
public CaveSpiderController() {
super(EntityCaveSpiderNPC.class);
}
@Override
public org.bukkit.entity.CaveSpider getBukkitEntity() {
return (org.bukkit.entity.CaveSpider) super.getBukkitEntity();
}
public static class CaveSpiderNPC extends CraftCaveSpider implements ForwardingNPCHolder {
public CaveSpiderNPC(EntityCaveSpiderNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityCaveSpiderNPC extends CaveSpider implements NPCHolder {
private final CitizensNPC npc;
public EntityCaveSpiderNPC(EntityType<? extends CaveSpider> types, Level level) {
this(types, level, null);
}
public EntityCaveSpiderNPC(EntityType<? extends CaveSpider> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new CaveSpiderNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,230 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftChicken;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Chicken;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class ChickenController extends MobEntityController {
public ChickenController() {
super(EntityChickenNPC.class);
}
@Override
public org.bukkit.entity.Chicken getBukkitEntity() {
return (org.bukkit.entity.Chicken) super.getBukkitEntity();
}
public static class ChickenNPC extends CraftChicken implements ForwardingNPCHolder {
public ChickenNPC(EntityChickenNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityChickenNPC extends Chicken implements NPCHolder {
private final CitizensNPC npc;
public EntityChickenNPC(EntityType<? extends Chicken> types, Level level) {
this(types, level, null);
}
public EntityChickenNPC(EntityType<? extends Chicken> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
public void aiStep() {
if (npc != null) {
this.eggTime = 100;
}
super.aiStep();
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new ChickenNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,261 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftCod;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.EntityMoveControl;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.animal.Cod;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class CodController extends MobEntityController {
public CodController() {
super(EntityCodNPC.class);
}
@Override
public org.bukkit.entity.Cod getBukkitEntity() {
return (org.bukkit.entity.Cod) super.getBukkitEntity();
}
public static class CodNPC extends CraftCod implements ForwardingNPCHolder {
public CodNPC(EntityCodNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityCodNPC extends Cod implements NPCHolder {
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityCodNPC(EntityType<? extends Cod> types, Level level) {
this(types, level, null);
}
public EntityCodNPC(EntityType<? extends Cod> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
this.oldMoveController = this.moveControl;
this.moveControl = new MoveControl(this);
}
}
@Override
public void aiStep() {
boolean lastInWater = this.verticalCollision;
if (npc != null) {
this.verticalCollision = false;
}
super.aiStep();
if (npc != null) {
this.verticalCollision = lastInWater;
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
if (!npc.useMinecraftAI()) {
NMSImpl.setNotInSchool(this);
}
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new EntityMoveControl(this);
}
}
super.customServerAiStep();
if (npc != null) {
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new CodNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
protected InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc == null || !npc.isProtected())
return super.mobInteract(entityhuman, enumhand);
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.getItem() == Items.WATER_BUCKET && isAlive()) {
return InteractionResult.FAIL;
}
return super.mobInteract(entityhuman, enumhand);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
if (!NMSImpl.moveFish(npc, this, vec3d)) {
super.travel(vec3d);
}
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,238 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftCow;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Cow;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class CowController extends MobEntityController {
public CowController() {
super(EntityCowNPC.class);
}
@Override
public org.bukkit.entity.Cow getBukkitEntity() {
return (org.bukkit.entity.Cow) super.getBukkitEntity();
}
public static class CowNPC extends CraftCow implements ForwardingNPCHolder {
public CowNPC(EntityCowNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityCowNPC extends Cow implements NPCHolder {
private final CitizensNPC npc;
public EntityCowNPC(EntityType<? extends Cow> types, Level level) {
this(types, level, null);
}
public EntityCowNPC(EntityType<? extends Cow> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new CowNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc == null || !npc.isProtected())
return super.mobInteract(entityhuman, enumhand);
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.getItem() == Items.BUCKET && !entityhuman.getAbilities().instabuild && !this.isBaby()) {
return InteractionResult.FAIL;
}
return super.mobInteract(entityhuman, enumhand);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,241 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftCreeper;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LightningBolt;
import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class CreeperController extends MobEntityController {
public CreeperController() {
super(EntityCreeperNPC.class);
}
@Override
public org.bukkit.entity.Creeper getBukkitEntity() {
return (org.bukkit.entity.Creeper) super.getBukkitEntity();
}
public static class CreeperNPC extends CraftCreeper implements ForwardingNPCHolder {
public CreeperNPC(EntityCreeperNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityCreeperNPC extends Creeper implements NPCHolder {
private boolean allowPowered;
private final CitizensNPC npc;
public EntityCreeperNPC(EntityType<? extends Creeper> types, Level level) {
this(types, level, null);
}
public EntityCreeperNPC(EntityType<? extends Creeper> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new CreeperNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public void ignite() {
if (npc == null || !npc.isProtected()) {
super.ignite();
}
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
public void setAllowPowered(boolean allowPowered) {
this.allowPowered = allowPowered;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void thunderHit(ServerLevel worldserver, LightningBolt entitylightning) {
if (npc == null || allowPowered) {
super.thunderHit(worldserver, entitylightning);
}
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,240 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDolphin;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.animal.Dolphin;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class DolphinController extends MobEntityController {
public DolphinController() {
super(EntityDolphinNPC.class);
}
@Override
public org.bukkit.entity.Dolphin getBukkitEntity() {
return (org.bukkit.entity.Dolphin) super.getBukkitEntity();
}
public static class DolphinNPC extends CraftDolphin implements ForwardingNPCHolder {
public DolphinNPC(EntityDolphinNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityDolphinNPC extends Dolphin implements NPCHolder {
private boolean inProtectedTick;
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityDolphinNPC(EntityType<? extends Dolphin> types, Level level) {
this(types, level, null);
}
public EntityDolphinNPC(EntityType<? extends Dolphin> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
this.oldMoveController = this.moveControl;
this.moveControl = new MoveControl(this);
this.getAttribute(Attributes.MOVEMENT_SPEED)
.setBaseValue(this.getAttribute(Attributes.MOVEMENT_SPEED).getBaseValue() / 10);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new DolphinNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isInWaterRainOrBubble() {
return inProtectedTick ? true : super.isInWaterRainOrBubble();
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void tick() {
if (npc != null && npc.isProtected()) {
inProtectedTick = true;
}
super.tick();
inProtectedTick = false;
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new MoveControl(this);
}
npc.update();
}
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
if (!NMSImpl.moveFish(npc, this, vec3d)) {
super.travel(vec3d);
}
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,211 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDrowned;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Drowned;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class DrownedController extends MobEntityController {
public DrownedController() {
super(EntityDrownedNPC.class);
}
@Override
public org.bukkit.entity.Drowned getBukkitEntity() {
return (org.bukkit.entity.Drowned) super.getBukkitEntity();
}
public static class DrownedNPC extends CraftDrowned implements ForwardingNPCHolder {
public DrownedNPC(EntityDrownedNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityDrownedNPC extends Drowned implements NPCHolder {
private final CitizensNPC npc;
public EntityDrownedNPC(EntityType<? extends Drowned> types, Level level) {
this(types, level, null);
}
public EntityDrownedNPC(EntityType<? extends Drowned> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new DrownedNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,274 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import java.lang.invoke.MethodHandle;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEnderDragon;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.versioned.EnderDragonTrait;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySelector;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
import net.minecraft.world.entity.boss.enderdragon.phases.EnderDragonPhase;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class EnderDragonController extends MobEntityController {
public EnderDragonController() {
super(EntityEnderDragonNPC.class);
}
@Override
public org.bukkit.entity.EnderDragon getBukkitEntity() {
return (org.bukkit.entity.EnderDragon) super.getBukkitEntity();
}
public static class EnderDragonNPC extends CraftEnderDragon implements ForwardingNPCHolder {
public EnderDragonNPC(EntityEnderDragonNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityEnderDragonNPC extends EnderDragon implements NPCHolder {
private final CitizensNPC npc;
public EntityEnderDragonNPC(EntityType<? extends EnderDragon> types, Level level) {
this(types, level, null);
}
public EntityEnderDragonNPC(EntityType<? extends EnderDragon> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
public void aiStep() {
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
if (npc != null && !npc.useMinecraftAI()) {
if (isDeadOrDying()) {
setHealth(0F);
return;
}
if (this.posPointer < 0) {
for (int i = 0; i < this.positions.length; ++i) {
this.positions[i][0] = this.getYRot();
this.positions[i][1] = this.getY();
}
}
if (++this.posPointer == this.positions.length) {
this.posPointer = 0;
}
this.positions[this.posPointer][0] = this.getYRot();
this.positions[this.posPointer][1] = this.getY();
float[][] pos = NMS.calculateDragonPositions(getYRot(),
new double[][] { getLatencyPos(0, 1F), getLatencyPos(5, 1F), getLatencyPos(10, 1F),
getLatencyPos(12, 1F), getLatencyPos(14, 1F), getLatencyPos(16, 1F) });
for (int j = 0; j < subEntities.length; ++j) {
Vec3 vec3 = new Vec3(this.subEntities[j].getX(), this.subEntities[j].getY(),
this.subEntities[j].getZ());
subEntities[j].setPos(this.getX() + pos[j][0], this.getY() + pos[j][1], this.getZ() + pos[j][2]);
subEntities[j].xo = subEntities[j].xOld = vec3.x;
subEntities[j].yo = subEntities[j].yOld = vec3.y;
subEntities[j].zo = subEntities[j].zOld = vec3.z;
}
if (getFirstPassenger() != null) {
setYRot(getFirstPassenger().getBukkitYaw() - 180);
}
Vec3 mot = getDeltaMovement();
if (mot.x != 0 || mot.y != 0 || mot.z != 0) {
mot = mot.multiply(0.98, 0.91, 0.98);
if (getFirstPassenger() == null) {
setYRot(Util.getDragonYaw(getBukkitEntity(), mot.x, mot.z));
}
setPos(getX() + mot.x, getY() + mot.y, getZ() + mot.z);
setDeltaMovement(mot);
}
if (npc.hasTrait(EnderDragonTrait.class) && npc.getOrAddTrait(EnderDragonTrait.class).isDestroyWalls()
&& NMSImpl.ENDERDRAGON_CHECK_WALLS != null) {
for (int i = 0; i < 3; i++) {
try {
this.inWall |= (boolean) NMSImpl.ENDERDRAGON_CHECK_WALLS.invoke(this,
subEntities[i].getBoundingBox());
} catch (Throwable e) {
e.printStackTrace();
}
}
}
if (npc.data().get(NPC.Metadata.COLLIDABLE, false)) {
try {
KNOCKBACK.invoke(this,
this.level().getEntities(this,
subEntities[6].getBoundingBox().inflate(4.0, 2.0, 4.0).move(0.0, -2.0, 0.0),
EntitySelector.NO_CREATIVE_OR_SPECTATOR));
KNOCKBACK.invoke(this,
this.level().getEntities(this,
subEntities[7].getBoundingBox().inflate(4.0, 2.0, 4.0).move(0.0, -2.0, 0.0),
EntitySelector.NO_CREATIVE_OR_SPECTATOR));
HURT.invoke(this, this.level().getEntities(this, subEntities[0].getBoundingBox().inflate(1.0),
EntitySelector.NO_CREATIVE_OR_SPECTATOR));
HURT.invoke(this, this.level().getEntities(this, subEntities[1].getBoundingBox().inflate(1.0),
EntitySelector.NO_CREATIVE_OR_SPECTATOR));
} catch (Throwable t) {
t.printStackTrace();
}
}
} else {
super.aiStep();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new EnderDragonNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
protected boolean reallyHurt(DamageSource source, float f) {
if (npc == null)
return super.reallyHurt(source, f);
Vec3 old = getDeltaMovement();
boolean res = super.reallyHurt(source, f);
if (getPhaseManager().getCurrentPhase().getPhase() == EnderDragonPhase.HOVERING) {
setDeltaMovement(old);
}
return res;
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
private static final MethodHandle HURT = NMS.getMethodHandle(EnderDragon.class, "c", true, List.class);
private static final MethodHandle KNOCKBACK = NMS.getMethodHandle(EnderDragon.class, "b", true, List.class);
}
}

View File

@ -0,0 +1,232 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEnderman;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.EnderMan;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class EndermanController extends MobEntityController {
public EndermanController() {
super(EntityEndermanNPC.class);
}
@Override
public org.bukkit.entity.Enderman getBukkitEntity() {
return (org.bukkit.entity.Enderman) super.getBukkitEntity();
}
public static class EndermanNPC extends CraftEnderman implements ForwardingNPCHolder {
public EndermanNPC(EntityEndermanNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityEndermanNPC extends EnderMan implements NPCHolder {
private final CitizensNPC npc;
public EntityEndermanNPC(EntityType<? extends EnderMan> types, Level level) {
this(types, level, null);
}
public EntityEndermanNPC(EntityType<? extends EnderMan> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new EndermanNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public Optional<Boolean> randomTeleport(double d0, double d1, double d2, boolean flag,
PlayerTeleportEvent.TeleportCause cause) {
if (npc == null) {
return super.randomTeleport(d0, d1, d2, flag, cause);
}
return Optional.of(false);
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEndermite;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Endermite;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class EndermiteController extends MobEntityController {
public EndermiteController() {
super(EntityEndermiteNPC.class);
}
@Override
public org.bukkit.entity.Endermite getBukkitEntity() {
return (org.bukkit.entity.Endermite) super.getBukkitEntity();
}
public static class EndermiteNPC extends CraftEndermite implements ForwardingNPCHolder {
public EndermiteNPC(EntityEndermiteNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
public static class EntityEndermiteNPC extends Endermite implements NPCHolder {
private final CitizensNPC npc;
public EntityEndermiteNPC(EntityType<? extends Endermite> types, Level level) {
this(types, level, null);
}
public EntityEndermiteNPC(EntityType<? extends Endermite> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new EndermiteNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
}

View File

@ -0,0 +1,494 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.net.Socket;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import com.mojang.authlib.GameProfile;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCKnockbackEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPC.NPCUpdate;
import net.citizensnpcs.api.trait.trait.Inventory;
import net.citizensnpcs.api.util.SpigotUtil;
import net.citizensnpcs.nms.v1_20_R1.network.EmptyNetHandler;
import net.citizensnpcs.nms.v1_20_R1.network.EmptyNetworkManager;
import net.citizensnpcs.nms.v1_20_R1.util.EmptyAdvancementDataPlayer;
import net.citizensnpcs.nms.v1_20_R1.util.EmptyServerStatsCounter;
import net.citizensnpcs.nms.v1_20_R1.util.MobAI;
import net.citizensnpcs.nms.v1_20_R1.util.MobAI.ForwardingMobAI;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.npc.skin.SkinPacketTracker;
import net.citizensnpcs.npc.skin.SkinnableEntity;
import net.citizensnpcs.trait.Gravity;
import net.citizensnpcs.trait.SkinTrait;
import net.citizensnpcs.util.EmptySocket;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.contents.LiteralContents;
import net.minecraft.network.protocol.PacketFlow;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.ServerPlayerGameMode;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.stats.ServerStatsCounter;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class EntityHumanNPC extends ServerPlayer implements NPCHolder, SkinnableEntity, ForwardingMobAI {
private MobAI ai;
private int jumpTicks = 0;
private final CitizensNPC npc;
private boolean setBukkitEntity;
private final SkinPacketTracker skinTracker;
private EmptyServerStatsCounter statsCache;
public EntityHumanNPC(MinecraftServer minecraftServer, ServerLevel world, GameProfile gameProfile, NPC npc) {
super(minecraftServer, world, gameProfile);
this.npc = (CitizensNPC) npc;
if (npc != null) {
ai = new BasicMobAI(this);
skinTracker = new SkinPacketTracker(this);
try {
GAMEMODE_SETTING.invoke(gameMode, GameType.SURVIVAL, null);
} catch (Throwable e) {
e.printStackTrace();
}
initialise(minecraftServer);
} else {
skinTracker = null;
}
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void die(DamageSource damagesource) {
// players that die are not normally removed from the world. when the
// NPC dies, we are done with the instance and it should be removed.
if (dead) {
return;
}
super.die(damagesource);
Bukkit.getScheduler().runTaskLater(CitizensAPI.getPlugin(), () -> {
((ServerLevel) level()).removePlayerImmediately(EntityHumanNPC.this, RemovalReason.KILLED);
((ServerLevel) level()).getChunkSource().removeEntity(EntityHumanNPC.this);
}, 15); // give enough time for death and smoke animation
}
@Override
public void doTick() {
if (npc == null) {
super.doTick();
return;
}
super.baseTick();
boolean navigating = npc.getNavigator().isNavigating() || ai.getMoveControl().hasWanted();
if (!navigating && getBukkitEntity() != null
&& (!npc.hasTrait(Gravity.class) || npc.getOrAddTrait(Gravity.class).hasGravity())
&& Util.isLoaded(getBukkitEntity().getLocation(LOADED_LOCATION))
&& SpigotUtil.checkYSafe(getY(), getBukkitEntity().getWorld())) {
moveWithFallDamage(Vec3.ZERO);
}
Vec3 mot = getDeltaMovement();
if (Math.abs(mot.x) < EPSILON && Math.abs(mot.y) < EPSILON && Math.abs(mot.z) < EPSILON) {
setDeltaMovement(Vec3.ZERO);
}
if (navigating) {
if (!ai.getNavigation().isDone()) {
ai.getNavigation().tick();
}
moveOnCurrentHeading();
}
tickAI();
detectEquipmentUpdates();
noPhysics = isSpectator();
if (isSpectator()) {
this.onGround = false;
}
pushEntities();
if (npc.data().get(NPC.Metadata.PICKUP_ITEMS, false)) {
AABB axisalignedbb;
if (this.isPassenger() && !this.getVehicle().isRemoved()) {
axisalignedbb = this.getBoundingBox().minmax(this.getVehicle().getBoundingBox()).inflate(1.0, 0.0, 1.0);
} else {
axisalignedbb = this.getBoundingBox().inflate(1.0, 0.5, 1.0);
}
for (Entity entity : level().getEntities(this, axisalignedbb)) {
entity.playerTouch(this);
}
}
}
@Override
public MobAI getAI() {
return ai;
}
@Override
public CraftPlayer getBukkitEntity() {
if (npc != null && !setBukkitEntity) {
NMSImpl.setBukkitEntity(this, new PlayerNPC(this));
setBukkitEntity = true;
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public GameProfile getProfile() {
return super.getGameProfile();
}
@Override
public String getSkinName() {
String skinName = npc.getOrAddTrait(SkinTrait.class).getSkinName();
if (skinName == null) {
skinName = npc.getName();
}
return skinName.toLowerCase();
}
@Override
public SkinPacketTracker getSkinTracker() {
return skinTracker;
}
@Override
public ServerStatsCounter getStats() {
return this.statsCache == null ? statsCache = new EmptyServerStatsCounter() : statsCache;
}
@Override
public Component getTabListDisplayName() {
if (Setting.DISABLE_TABLIST.asBoolean()) {
return MutableComponent.create(new LiteralContents(""));
}
return super.getTabListDisplayName();
}
@Override
public boolean hurt(DamageSource damagesource, float f) {
// knock back velocity is cancelled and sent to client for handling when
// the entity is a player. there is no client so make this happen
// manually.
boolean damaged = super.hurt(damagesource, f);
if (damaged && hurtMarked) {
hurtMarked = false;
Bukkit.getScheduler().runTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
EntityHumanNPC.this.hurtMarked = true;
}
});
}
return damaged;
}
private void initialise(MinecraftServer minecraftServer) {
Socket socket = new EmptySocket();
EmptyNetworkManager conn = null;
try {
conn = new EmptyNetworkManager(PacketFlow.CLIENTBOUND);
connection = new EmptyNetHandler(minecraftServer, conn, this);
conn.setListener(connection);
socket.close();
} catch (IOException e) {
// swallow
}
this.invulnerableTime = 0;
NMS.setStepHeight(getBukkitEntity(), 1); // the default (0) breaks step climbing
setSkinFlags((byte) 0xFF);
EmptyAdvancementDataPlayer.clear(this.getAdvancements());
NMSImpl.setAdvancement(this.getBukkitEntity(),
new EmptyAdvancementDataPlayer(minecraftServer.getFixerUpper(), minecraftServer.getPlayerList(),
minecraftServer.getAdvancements(), CitizensAPI.getDataFolder().getParentFile(), this));
}
@Override
public boolean isInWall() {
if (npc == null || noPhysics || isSleeping()) {
return super.isInWall();
}
return Util.inBlock(getBukkitEntity());
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable() : npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NPCKnockbackEvent event = new NPCKnockbackEvent(npc, strength, dx, dz);
Bukkit.getPluginManager().callEvent(event);
Vector kb = event.getKnockbackVector();
if (!event.isCancelled()) {
super.knockback(event.getStrength(), kb.getX(), kb.getZ());
}
}
private void moveOnCurrentHeading() {
if (jumping) {
if (onGround && jumpTicks == 0) {
jumpFromGround();
jumpTicks = 10;
}
} else {
jumpTicks = 0;
}
xxa *= 0.98F;
zza *= 0.98F;
moveWithFallDamage(new Vec3(this.xxa, this.yya, this.zza));
NMS.setHeadYaw(getBukkitEntity(), getYRot());
if (jumpTicks > 0) {
jumpTicks--;
}
}
private void moveWithFallDamage(Vec3 vec) {
double x = getX();
double y = getY();
double z = getZ();
travel(vec);
if (!npc.isProtected()) {
doCheckFallDamage(getX() - x, getY() - y, getZ() - z, onGround);
}
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public void remove(RemovalReason reason) {
super.remove(reason);
getAdvancements().save();
}
@Override
public void setSkinFlags(byte flags) {
getEntityData().set(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION, flags);
}
@Override
public void setSkinName(String name) {
npc.getOrAddTrait(SkinTrait.class).setSkinName(name);
}
@Override
public void setSkinName(String name, boolean forceUpdate) {
npc.getOrAddTrait(SkinTrait.class).setSkinName(name, forceUpdate);
}
@Override
public void setSkinPersistent(String skinName, String signature, String data) {
npc.getOrAddTrait(SkinTrait.class).setSkinPersistent(skinName, signature, data);
}
@Override
public void tick() {
super.tick();
if (npc == null)
return;
Bukkit.getServer().getPluginManager().unsubscribeFromPermission("bukkit.broadcast.user", getBukkitEntity());
updatePackets(npc.getNavigator().isNavigating());
npc.update();
}
@Override
public void tickAI() {
ai.getMoveControl().tick();
ai.getJumpControl().tick();
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
Vec3 old = getDeltaMovement().add(0, 0, 0);
boolean res = super.updateFluidHeightAndDoFluidPushing(tagkey, d0);
if (!npc.isPushableByFluids()) {
setDeltaMovement(old);
}
return res;
}
private void updatePackets(boolean navigating) {
if (!npc.isUpdating(NPCUpdate.PACKET))
return;
effectsDirty = true;
}
public static class PlayerNPC extends CraftPlayer implements NPCHolder, SkinnableEntity {
private final CitizensNPC npc;
private PlayerNPC(EntityHumanNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
this.npc = entity.npc;
npc.getOrAddTrait(Inventory.class);
}
@Override
public boolean canSee(org.bukkit.entity.Entity entity) {
if (entity != null && entity.getType().name().contains("ITEM_FRAME")) {
return false; // optimise for large maps in item frames
}
return super.canSee(entity);
}
@Override
public Player getBukkitEntity() {
return this;
}
@Override
public EntityHumanNPC getHandle() {
return (EntityHumanNPC) this.entity;
}
@Override
public List<MetadataValue> getMetadata(String metadataKey) {
return ((CraftServer) Bukkit.getServer()).getEntityMetadata().getMetadata(this, metadataKey);
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public String getSkinName() {
return ((SkinnableEntity) this.entity).getSkinName();
}
@Override
public SkinPacketTracker getSkinTracker() {
return ((SkinnableEntity) this.entity).getSkinTracker();
}
@Override
public boolean hasMetadata(String metadataKey) {
return ((CraftServer) Bukkit.getServer()).getEntityMetadata().hasMetadata(this, metadataKey);
}
@Override
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
((CraftServer) Bukkit.getServer()).getEntityMetadata().removeMetadata(this, metadataKey, owningPlugin);
}
@Override
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
((CraftServer) Bukkit.getServer()).getEntityMetadata().setMetadata(this, metadataKey, newMetadataValue);
}
@Override
public void setSkinFlags(byte flags) {
((SkinnableEntity) this.entity).setSkinFlags(flags);
}
@Override
public void setSkinName(String name) {
((SkinnableEntity) this.entity).setSkinName(name);
}
@Override
public void setSkinName(String skinName, boolean forceUpdate) {
((SkinnableEntity) this.entity).setSkinName(skinName, forceUpdate);
}
@Override
public void setSkinPersistent(String skinName, String signature, String data) {
((SkinnableEntity) this.entity).setSkinPersistent(skinName, signature, data);
}
}
private static final float EPSILON = 0.003F;
private static final MethodHandle GAMEMODE_SETTING = NMS.getFirstMethodHandle(ServerPlayerGameMode.class, true,
GameType.class, GameType.class);
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
}

View File

@ -0,0 +1,212 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEvoker;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Evoker;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class EvokerController extends MobEntityController {
public EvokerController() {
super(EntityEvokerNPC.class);
}
@Override
public org.bukkit.entity.Evoker getBukkitEntity() {
return (org.bukkit.entity.Evoker) super.getBukkitEntity();
}
public static class EntityEvokerNPC extends Evoker implements NPCHolder {
private final CitizensNPC npc;
public EntityEvokerNPC(EntityType<? extends Evoker> types, Level level) {
this(types, level, null);
}
public EntityEvokerNPC(EntityType<? extends Evoker> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new EvokerNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class EvokerNPC extends CraftEvoker implements ForwardingNPCHolder {
public EvokerNPC(EntityEvokerNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,222 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftFox;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Fox;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class FoxController extends MobEntityController {
public FoxController() {
super(EntityFoxNPC.class);
}
@Override
public org.bukkit.entity.Fox getBukkitEntity() {
return (org.bukkit.entity.Fox) super.getBukkitEntity();
}
public static class EntityFoxNPC extends Fox implements NPCHolder {
private final CitizensNPC npc;
public EntityFoxNPC(EntityType<? extends Fox> types, Level level) {
this(types, level, null);
}
public EntityFoxNPC(EntityType<? extends Fox> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new FoxNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class FoxNPC extends CraftFox implements ForwardingNPCHolder {
public FoxNPC(EntityFoxNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,225 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftFrog;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.frog.Frog;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class FrogController extends MobEntityController {
public FrogController() {
super(EntityFrogNPC.class);
}
@Override
public org.bukkit.entity.Frog getBukkitEntity() {
return (org.bukkit.entity.Frog) super.getBukkitEntity();
}
public static class EntityFrogNPC extends Frog implements NPCHolder {
private final CitizensNPC npc;
public EntityFrogNPC(EntityType<? extends Frog> types, Level level) {
this(types, level, null);
}
public EntityFrogNPC(EntityType<? extends Frog> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
croakAnimationState.start(1);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new FrogNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class FrogNPC extends CraftFrog implements ForwardingNPCHolder {
public FrogNPC(EntityFrogNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,181 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftGhast;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Ghast;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
public class GhastController extends MobEntityController {
public GhastController() {
super(EntityGhastNPC.class);
}
@Override
public org.bukkit.entity.Ghast getBukkitEntity() {
return (org.bukkit.entity.Ghast) super.getBukkitEntity();
}
public static class EntityGhastNPC extends Ghast implements NPCHolder {
private final CitizensNPC npc;
public EntityGhastNPC(EntityType<? extends Ghast> types, Level level) {
this(types, level, null);
}
public EntityGhastNPC(EntityType<? extends Ghast> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
npc.update();
NMSImpl.updateMinecraftAIState(npc, this);
}
super.customServerAiStep();
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new GhastNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isAutoSpinAttack() {
return npc != null;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class GhastNPC extends CraftGhast implements ForwardingNPCHolder {
public GhastNPC(EntityGhastNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftGiant;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Giant;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class GiantController extends MobEntityController {
public GiantController() {
super(EntityGiantNPC.class);
}
@Override
public org.bukkit.entity.Giant getBukkitEntity() {
return (org.bukkit.entity.Giant) super.getBukkitEntity();
}
public static class EntityGiantNPC extends Giant implements NPCHolder {
private final CitizensNPC npc;
public EntityGiantNPC(EntityType<? extends Giant> types, Level level) {
this(types, level, null);
}
public EntityGiantNPC(EntityType<? extends Giant> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new GiantNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class GiantNPC extends CraftGiant implements ForwardingNPCHolder {
public GiantNPC(EntityGiantNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftGlowSquid;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.GlowSquid;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class GlowSquidController extends MobEntityController {
public GlowSquidController() {
super(EntityGlowSquidNPC.class);
}
@Override
public org.bukkit.entity.GlowSquid getBukkitEntity() {
return (org.bukkit.entity.GlowSquid) super.getBukkitEntity();
}
public static class EntityGlowSquidNPC extends GlowSquid implements NPCHolder {
private final CitizensNPC npc;
public EntityGlowSquidNPC(EntityType<? extends GlowSquid> types, Level level) {
this(types, level, null);
}
public EntityGlowSquidNPC(EntityType<? extends GlowSquid> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new GlowSquidNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class GlowSquidNPC extends CraftGlowSquid implements ForwardingNPCHolder {
public GlowSquidNPC(EntityGlowSquidNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,222 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftGoat;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.goat.Goat;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class GoatController extends MobEntityController {
public GoatController() {
super(EntityGoatNPC.class);
}
@Override
public org.bukkit.entity.Goat getBukkitEntity() {
return (org.bukkit.entity.Goat) super.getBukkitEntity();
}
public static class EntityGoatNPC extends Goat implements NPCHolder {
private final CitizensNPC npc;
public EntityGoatNPC(EntityType<? extends Goat> types, Level level) {
this(types, level, null);
}
public EntityGoatNPC(EntityType<? extends Goat> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new GoatNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class GoatNPC extends CraftGoat implements ForwardingNPCHolder {
public GoatNPC(EntityGoatNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,227 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftGuardian;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Guardian;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class GuardianController extends MobEntityController {
public GuardianController() {
super(EntityGuardianNPC.class);
}
@Override
public org.bukkit.entity.Guardian getBukkitEntity() {
return (org.bukkit.entity.Guardian) super.getBukkitEntity();
}
public static class EntityGuardianNPC extends Guardian implements NPCHolder {
private final CitizensNPC npc;
public EntityGuardianNPC(EntityType<? extends Guardian> types, Level level) {
this(types, level, null);
}
public EntityGuardianNPC(EntityType<? extends Guardian> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
public void aiStep() {
if (npc == null) {
super.aiStep();
} else {
NMSImpl.updateMinecraftAIState(npc, this);
if (!npc.useMinecraftAI()) {
NMSImpl.updateAI(this);
} else {
super.aiStep();
}
npc.update();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new GuardianNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class GuardianNPC extends CraftGuardian implements ForwardingNPCHolder {
public GuardianNPC(EntityGuardianNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,227 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftElderGuardian;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.ElderGuardian;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class GuardianElderController extends MobEntityController {
public GuardianElderController() {
super(EntityGuardianElderNPC.class);
}
@Override
public org.bukkit.entity.ElderGuardian getBukkitEntity() {
return (org.bukkit.entity.ElderGuardian) super.getBukkitEntity();
}
public static class EntityGuardianElderNPC extends ElderGuardian implements NPCHolder {
private final CitizensNPC npc;
public EntityGuardianElderNPC(EntityType<? extends ElderGuardian> types, Level level) {
this(types, level, null);
}
public EntityGuardianElderNPC(EntityType<? extends ElderGuardian> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
public void aiStep() {
if (npc == null) {
super.aiStep();
} else {
NMSImpl.updateMinecraftAIState(npc, this);
if (!npc.useMinecraftAI()) {
NMSImpl.updateAI(this);
} else {
super.aiStep();
}
npc.update();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new GuardianElderNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class GuardianElderNPC extends CraftElderGuardian implements ForwardingNPCHolder {
public GuardianElderNPC(EntityGuardianElderNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,215 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftHoglin;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.hoglin.Hoglin;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class HoglinController extends MobEntityController {
public HoglinController() {
super(EntityHoglinNPC.class);
}
@Override
public org.bukkit.entity.Hoglin getBukkitEntity() {
return (org.bukkit.entity.Hoglin) super.getBukkitEntity();
}
public static class EntityHoglinNPC extends Hoglin implements NPCHolder {
private final CitizensNPC npc;
public EntityHoglinNPC(EntityType<? extends Hoglin> types, Level level) {
this(types, level, null);
}
public EntityHoglinNPC(EntityType<? extends Hoglin> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
NMSImpl.clearGoals(npc, goalSelector, targetSelector);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
setImmuneToZombification(true);
}
super.customServerAiStep();
if (npc != null) {
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new HoglinNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class HoglinNPC extends CraftHoglin implements ForwardingNPCHolder {
public HoglinNPC(EntityHoglinNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,268 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftHorse;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.animal.horse.Horse;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class HorseController extends MobEntityController {
public HorseController() {
super(EntityHorseNPC.class);
}
@Override
public void create(Location at, NPC npc) {
npc.getOrAddTrait(HorseModifiers.class);
super.create(at, npc);
}
@Override
public org.bukkit.entity.Horse getBukkitEntity() {
return (org.bukkit.entity.Horse) super.getBukkitEntity();
}
public static class EntityHorseNPC extends Horse implements NPCHolder {
private double baseMovementSpeed;
private final CitizensNPC npc;
private boolean riding;
public EntityHorseNPC(EntityType<? extends Horse> types, Level level) {
this(types, level, null);
}
public EntityHorseNPC(EntityType<? extends Horse> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
org.bukkit.entity.Horse horse = (org.bukkit.entity.Horse) getBukkitEntity();
horse.setDomestication(horse.getMaxDomestication());
baseMovementSpeed = this.getAttribute(Attributes.MOVEMENT_SPEED).getValue();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc == null)
return;
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.hasTrait(Controllable.class) && npc.getOrAddTrait(Controllable.class).isEnabled()) {
riding = getBukkitEntity().getPassengers().size() > 0;
getAttribute(Attributes.MOVEMENT_SPEED)
.setBaseValue(baseMovementSpeed * npc.getNavigator().getDefaultParameters().speedModifier());
} else {
riding = false;
}
if (riding) {
if (npc.getNavigator().isNavigating()) {
org.bukkit.entity.Entity basePassenger = passengers.get(0).getBukkitEntity();
NMS.look(basePassenger, getYRot(), getXRot());
}
setFlag(4, true); // datawatcher method
}
NMS.setStepHeight(getBukkitEntity(), 1);
npc.update();
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new HorseNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isControlledByLocalInstance() {
if (npc != null && riding) {
return true;
}
return super.isControlledByLocalInstance();
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public boolean isVehicle() {
return npc != null && npc.getNavigator().isNavigating() ? false : super.isVehicle();
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class HorseNPC extends CraftHorse implements ForwardingNPCHolder {
public HorseNPC(EntityHorseNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,268 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDonkey;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.animal.horse.Donkey;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class HorseDonkeyController extends MobEntityController {
public HorseDonkeyController() {
super(EntityHorseDonkeyNPC.class);
}
@Override
public void create(Location at, NPC npc) {
npc.addTrait(HorseModifiers.class);
super.create(at, npc);
}
@Override
public org.bukkit.entity.Donkey getBukkitEntity() {
return (org.bukkit.entity.Donkey) super.getBukkitEntity();
}
public static class EntityHorseDonkeyNPC extends Donkey implements NPCHolder {
private double baseMovementSpeed;
private final CitizensNPC npc;
private boolean riding;
public EntityHorseDonkeyNPC(EntityType<? extends Donkey> types, Level level) {
this(types, level, null);
}
public EntityHorseDonkeyNPC(EntityType<? extends Donkey> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
((org.bukkit.entity.Donkey) getBukkitEntity())
.setDomestication(((org.bukkit.entity.Donkey) getBukkitEntity()).getMaxDomestication());
baseMovementSpeed = this.getAttribute(Attributes.MOVEMENT_SPEED).getValue();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.hasTrait(Controllable.class) && npc.getOrAddTrait(Controllable.class).isEnabled()) {
riding = getBukkitEntity().getPassengers().size() > 0;
getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(
baseMovementSpeed * npc.getNavigator().getDefaultParameters().speedModifier());
} else {
riding = false;
}
if (riding) {
if (npc.getNavigator().isNavigating()) {
org.bukkit.entity.Entity basePassenger = passengers.get(0).getBukkitEntity();
NMS.look(basePassenger, getYRot(), getXRot());
}
setFlag(4, true); // datawatcher method
}
NMS.setStepHeight(getBukkitEntity(), 1);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new HorseDonkeyNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isControlledByLocalInstance() {
if (npc != null && riding) {
return true;
}
return super.isControlledByLocalInstance();
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public boolean isVehicle() {
return npc != null && npc.getNavigator().isNavigating() ? false : super.isVehicle();
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class HorseDonkeyNPC extends CraftDonkey implements ForwardingNPCHolder {
public HorseDonkeyNPC(EntityHorseDonkeyNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,268 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftMule;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.animal.horse.Mule;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class HorseMuleController extends MobEntityController {
public HorseMuleController() {
super(EntityHorseMuleNPC.class);
}
@Override
public void create(Location at, NPC npc) {
npc.getOrAddTrait(HorseModifiers.class);
super.create(at, npc);
}
@Override
public org.bukkit.entity.Mule getBukkitEntity() {
return (org.bukkit.entity.Mule) super.getBukkitEntity();
}
public static class EntityHorseMuleNPC extends Mule implements NPCHolder {
private double baseMovementSpeed;
private final CitizensNPC npc;
private boolean riding;
public EntityHorseMuleNPC(EntityType<? extends Mule> types, Level level) {
this(types, level, null);
}
public EntityHorseMuleNPC(EntityType<? extends Mule> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
((org.bukkit.entity.Mule) getBukkitEntity())
.setDomestication(((org.bukkit.entity.Mule) getBukkitEntity()).getMaxDomestication());
baseMovementSpeed = this.getAttribute(Attributes.MOVEMENT_SPEED).getValue();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.hasTrait(Controllable.class) && npc.getOrAddTrait(Controllable.class).isEnabled()) {
riding = getBukkitEntity().getPassengers().size() > 0;
getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(
baseMovementSpeed * npc.getNavigator().getDefaultParameters().speedModifier());
} else {
riding = false;
}
if (riding) {
if (npc.getNavigator().isNavigating()) {
org.bukkit.entity.Entity basePassenger = passengers.get(0).getBukkitEntity();
NMS.look(basePassenger, getYRot(), getXRot());
}
setFlag(4, true); // datawatcher method
}
NMS.setStepHeight(getBukkitEntity(), 1);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new HorseMuleNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isControlledByLocalInstance() {
if (npc != null && riding) {
return true;
}
return super.isControlledByLocalInstance();
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public boolean isVehicle() {
return npc != null && npc.getNavigator().isNavigating() ? false : super.isVehicle();
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class HorseMuleNPC extends CraftMule implements ForwardingNPCHolder {
public HorseMuleNPC(EntityHorseMuleNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,268 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSkeletonHorse;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.animal.horse.SkeletonHorse;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class HorseSkeletonController extends MobEntityController {
public HorseSkeletonController() {
super(EntityHorseSkeletonNPC.class);
}
@Override
public void create(Location at, NPC npc) {
npc.getOrAddTrait(HorseModifiers.class);
super.create(at, npc);
}
@Override
public org.bukkit.entity.SkeletonHorse getBukkitEntity() {
return (org.bukkit.entity.SkeletonHorse) super.getBukkitEntity();
}
public static class EntityHorseSkeletonNPC extends SkeletonHorse implements NPCHolder {
private double baseMovementSpeed;
private final CitizensNPC npc;
private boolean riding;
public EntityHorseSkeletonNPC(EntityType<? extends SkeletonHorse> types, Level level) {
this(types, level, null);
}
public EntityHorseSkeletonNPC(EntityType<? extends SkeletonHorse> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
((org.bukkit.entity.SkeletonHorse) getBukkitEntity())
.setDomestication(((org.bukkit.entity.SkeletonHorse) getBukkitEntity()).getMaxDomestication());
baseMovementSpeed = this.getAttribute(Attributes.MOVEMENT_SPEED).getValue();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.hasTrait(Controllable.class) && npc.getOrAddTrait(Controllable.class).isEnabled()) {
riding = getBukkitEntity().getPassengers().size() > 0;
getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(
baseMovementSpeed * npc.getNavigator().getDefaultParameters().speedModifier());
} else {
riding = false;
}
if (riding) {
if (npc.getNavigator().isNavigating()) {
org.bukkit.entity.Entity basePassenger = passengers.get(0).getBukkitEntity();
NMS.look(basePassenger, getYRot(), getXRot());
}
setFlag(4, true); // datawatcher method
}
NMS.setStepHeight(getBukkitEntity(), 1);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new HorseSkeletonNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isControlledByLocalInstance() {
if (npc != null && riding) {
return true;
}
return super.isControlledByLocalInstance();
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public boolean isVehicle() {
return npc != null && npc.getNavigator().isNavigating() ? false : super.isVehicle();
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class HorseSkeletonNPC extends CraftSkeletonHorse implements ForwardingNPCHolder {
public HorseSkeletonNPC(EntityHorseSkeletonNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,268 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftZombieHorse;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.animal.horse.ZombieHorse;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class HorseZombieController extends MobEntityController {
public HorseZombieController() {
super(EntityHorseZombieNPC.class);
}
@Override
public void create(Location at, NPC npc) {
npc.getOrAddTrait(HorseModifiers.class);
super.create(at, npc);
}
@Override
public org.bukkit.entity.ZombieHorse getBukkitEntity() {
return (org.bukkit.entity.ZombieHorse) super.getBukkitEntity();
}
public static class EntityHorseZombieNPC extends ZombieHorse implements NPCHolder {
private double baseMovementSpeed;
private final CitizensNPC npc;
private boolean riding;
public EntityHorseZombieNPC(EntityType<? extends ZombieHorse> types, Level level) {
this(types, level, null);
}
public EntityHorseZombieNPC(EntityType<? extends ZombieHorse> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
((org.bukkit.entity.ZombieHorse) getBukkitEntity())
.setDomestication(((org.bukkit.entity.ZombieHorse) getBukkitEntity()).getMaxDomestication());
baseMovementSpeed = this.getAttribute(Attributes.MOVEMENT_SPEED).getValue();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.hasTrait(Controllable.class) && npc.getOrAddTrait(Controllable.class).isEnabled()) {
riding = getBukkitEntity().getPassengers().size() > 0;
getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(
baseMovementSpeed * npc.getNavigator().getDefaultParameters().speedModifier());
} else {
riding = false;
}
if (riding) {
if (npc.getNavigator().isNavigating()) {
org.bukkit.entity.Entity basePassenger = passengers.get(0).getBukkitEntity();
NMS.look(basePassenger, getYRot(), getXRot());
}
setFlag(4, true); // datawatcher method
}
NMS.setStepHeight(getBukkitEntity(), 1);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new HorseZombieNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isControlledByLocalInstance() {
if (npc != null && riding) {
return true;
}
return super.isControlledByLocalInstance();
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public boolean isVehicle() {
return npc != null && npc.getNavigator().isNavigating() ? false : super.isVehicle();
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class HorseZombieNPC extends CraftZombieHorse implements ForwardingNPCHolder {
public HorseZombieNPC(EntityHorseZombieNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,70 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import com.mojang.authlib.GameProfile;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.npc.AbstractEntityController;
import net.citizensnpcs.npc.skin.Skin;
import net.citizensnpcs.trait.ScoreboardTrait;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
public class HumanController extends AbstractEntityController {
public HumanController() {
super();
}
@Override
protected Entity createEntity(final Location at, final NPC npc) {
final ServerLevel nmsWorld = ((CraftWorld) at.getWorld()).getHandle();
String coloredName = npc.getFullName();
String name = coloredName.length() > 16 ? coloredName.substring(0, 16) : coloredName;
UUID uuid = npc.getUniqueId();
if (uuid.version() == 4) { // set version to 2
long msb = uuid.getMostSignificantBits();
msb &= ~0x0000000000004000L;
msb |= 0x0000000000002000L;
uuid = new UUID(msb, uuid.getLeastSignificantBits());
}
String teamName = Util.getTeamName(uuid);
if (npc.requiresNameHologram()) {
name = teamName;
}
if (Setting.USE_SCOREBOARD_TEAMS.asBoolean()) {
npc.getOrAddTrait(ScoreboardTrait.class).createTeam(name);
}
final GameProfile profile = new GameProfile(uuid, name);
final EntityHumanNPC handle = new EntityHumanNPC(MinecraftServer.getServer(), nmsWorld, profile, npc);
Skin skin = handle.getSkinTracker().getSkin();
if (skin != null) {
skin.apply(handle);
}
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
if (getBukkitEntity() == null || !getBukkitEntity().isValid()
|| getBukkitEntity() != handle.getBukkitEntity())
return;
boolean removeFromPlayerList = npc.data().get(NPC.Metadata.REMOVE_FROM_PLAYERLIST,
Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean());
NMS.addOrRemoveFromPlayerList(getBukkitEntity(), removeFromPlayerList);
}, 20);
handle.getBukkitEntity().setSleepingIgnored(true);
return handle.getBukkitEntity();
}
@Override
public Player getBukkitEntity() {
return (Player) super.getBukkitEntity();
}
}

View File

@ -0,0 +1,212 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftIllusioner;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Illusioner;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class IllusionerController extends MobEntityController {
public IllusionerController() {
super(EntityIllusionerNPC.class);
}
@Override
public org.bukkit.entity.Illusioner getBukkitEntity() {
return (org.bukkit.entity.Illusioner) super.getBukkitEntity();
}
public static class EntityIllusionerNPC extends Illusioner implements NPCHolder {
private final CitizensNPC npc;
public EntityIllusionerNPC(EntityType<? extends Illusioner> types, Level level) {
this(types, level, null);
}
public EntityIllusionerNPC(EntityType<? extends Illusioner> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new IllusionerNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class IllusionerNPC extends CraftIllusioner implements ForwardingNPCHolder {
public IllusionerNPC(EntityIllusionerNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftIronGolem;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.IronGolem;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class IronGolemController extends MobEntityController {
public IronGolemController() {
super(EntityIronGolemNPC.class);
}
@Override
public org.bukkit.entity.IronGolem getBukkitEntity() {
return (org.bukkit.entity.IronGolem) super.getBukkitEntity();
}
public static class EntityIronGolemNPC extends IronGolem implements NPCHolder {
private final CitizensNPC npc;
public EntityIronGolemNPC(EntityType<? extends IronGolem> types, Level level) {
this(types, level, null);
}
public EntityIronGolemNPC(EntityType<? extends IronGolem> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new IronGolemNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class IronGolemNPC extends CraftIronGolem implements ForwardingNPCHolder {
public IronGolemNPC(EntityIronGolemNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,239 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftLlama;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.horse.Llama;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class LlamaController extends MobEntityController {
public LlamaController() {
super(EntityLlamaNPC.class);
}
@Override
public void create(Location at, NPC npc) {
npc.getOrAddTrait(HorseModifiers.class);
super.create(at, npc);
}
@Override
public org.bukkit.entity.Llama getBukkitEntity() {
return (org.bukkit.entity.Llama) super.getBukkitEntity();
}
public static class EntityLlamaNPC extends Llama implements NPCHolder {
private final CitizensNPC npc;
public EntityLlamaNPC(EntityType<? extends Llama> types, Level level) {
this(types, level, null);
}
public EntityLlamaNPC(EntityType<? extends Llama> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
((org.bukkit.entity.Llama) getBukkitEntity())
.setDomestication(((org.bukkit.entity.Llama) getBukkitEntity()).getMaxDomestication());
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc == null) {
super.customServerAiStep();
} else {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI()) {
super.customServerAiStep();
}
NMS.setStepHeight(getBukkitEntity(), 1);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new LlamaNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class LlamaNPC extends CraftLlama implements ForwardingNPCHolder {
public LlamaNPC(EntityLlamaNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,243 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftMagmaCube;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.EntityMoveControl;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.monster.MagmaCube;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class MagmaCubeController extends MobEntityController {
public MagmaCubeController() {
super(EntityMagmaCubeNPC.class);
}
@Override
public org.bukkit.entity.MagmaCube getBukkitEntity() {
return (org.bukkit.entity.MagmaCube) super.getBukkitEntity();
}
public static class EntityMagmaCubeNPC extends MagmaCube implements NPCHolder {
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityMagmaCubeNPC(EntityType<? extends MagmaCube> types, Level level) {
this(types, level, null);
}
public EntityMagmaCubeNPC(EntityType<? extends MagmaCube> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
setSize(3, true);
this.oldMoveController = this.moveControl;
this.moveControl = new EntityMoveControl(this);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new MagmaCubeNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void playerTouch(Player human) {
if (npc == null) {
super.playerTouch(human);
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void tick() {
super.tick();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new EntityMoveControl(this);
}
npc.update();
}
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class MagmaCubeNPC extends CraftMagmaCube implements ForwardingNPCHolder {
public MagmaCubeNPC(EntityMagmaCubeNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,82 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.WeakHashMap;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
import org.bukkit.entity.Entity;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.nms.v1_20_R1.util.PitchableLookControl;
import net.citizensnpcs.npc.AbstractEntityController;
import net.citizensnpcs.trait.ScoreboardTrait;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.control.LookControl;
import net.minecraft.world.level.Level;
public abstract class MobEntityController extends AbstractEntityController {
private final Class<?> clazz;
protected MobEntityController(Class<?> clazz) {
super(clazz);
this.clazz = clazz;
}
@Override
protected Entity createEntity(Location at, NPC npc) {
EntityType<?> type = NMSImpl.getEntityType(clazz);
net.minecraft.world.entity.Entity entity = createEntityFromClass(type, ((CraftWorld) at.getWorld()).getHandle(),
npc);
if (entity instanceof Mob) {
NMSImpl.clearGoals(npc, ((Mob) entity).goalSelector, ((Mob) entity).targetSelector);
Mob mob = (Mob) entity;
if (mob.getLookControl().getClass() == LookControl.class) {
NMSImpl.setLookControl(mob, new PitchableLookControl(mob));
}
}
entity.absMoveTo(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
if (npc != null) {
// entity.onGround isn't updated right away - we approximate here so
// that things like pathfinding still work *immediately* after spawn.
org.bukkit.Material beneath = at.getBlock().getRelative(BlockFace.DOWN).getType();
if (beneath.isSolid()) {
entity.setOnGround(true);
}
entity.setUUID(npc.getUniqueId());
if (Setting.USE_SCOREBOARD_TEAMS.asBoolean()) {
npc.getOrAddTrait(ScoreboardTrait.class).createTeam(npc.getUniqueId().toString());
}
}
return entity.getBukkitEntity();
}
private net.minecraft.world.entity.Entity createEntityFromClass(Object... args) {
try {
return (net.minecraft.world.entity.Entity) getConstructor(clazz).newInstance(args);
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
private static Constructor<?> getConstructor(Class<?> clazz) {
Constructor<?> constructor = CONSTRUCTOR_CACHE.get(clazz);
if (constructor != null)
return constructor;
try {
CONSTRUCTOR_CACHE.put(clazz, constructor = clazz.getConstructor(EntityType.class, Level.class, NPC.class));
return constructor;
} catch (Exception ex) {
throw new IllegalStateException("unable to find an entity constructor");
}
}
private static final Map<Class<?>, Constructor<?>> CONSTRUCTOR_CACHE = new WeakHashMap<Class<?>, Constructor<?>>();
}

View File

@ -0,0 +1,231 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftMushroomCow;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.MushroomCow;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class MushroomCowController extends MobEntityController {
public MushroomCowController() {
super(EntityMushroomCowNPC.class);
}
@Override
public org.bukkit.entity.MushroomCow getBukkitEntity() {
return (org.bukkit.entity.MushroomCow) super.getBukkitEntity();
}
public static class EntityMushroomCowNPC extends MushroomCow implements NPCHolder {
private final CitizensNPC npc;
public EntityMushroomCowNPC(EntityType<? extends MushroomCow> types, Level level) {
this(types, level, null);
}
public EntityMushroomCowNPC(EntityType<? extends MushroomCow> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new MushroomCowNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc == null || !npc.isProtected())
return super.mobInteract(entityhuman, enumhand);
return InteractionResult.FAIL;
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class MushroomCowNPC extends CraftMushroomCow implements ForwardingNPCHolder {
public MushroomCowNPC(EntityMushroomCowNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,228 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftOcelot;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.animal.Ocelot;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class OcelotController extends MobEntityController {
public OcelotController() {
super(EntityOcelotNPC.class);
}
@Override
public org.bukkit.entity.Ocelot getBukkitEntity() {
return (org.bukkit.entity.Ocelot) super.getBukkitEntity();
}
public static class EntityOcelotNPC extends Ocelot implements NPCHolder {
private final CitizensNPC npc;
public EntityOcelotNPC(EntityType<? extends Ocelot> types, Level level) {
this(types, level, null);
}
public EntityOcelotNPC(EntityType<? extends Ocelot> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
Pose old = this.getPose();
boolean restorePose = !this.getMoveControl().hasWanted();
super.customServerAiStep();
if (restorePose) {
this.setPose(old);
}
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new OcelotNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class OcelotNPC extends CraftOcelot implements ForwardingNPCHolder {
public OcelotNPC(EntityOcelotNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,222 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPanda;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Panda;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class PandaController extends MobEntityController {
public PandaController() {
super(EntityPandaNPC.class);
}
@Override
public org.bukkit.entity.Panda getBukkitEntity() {
return (org.bukkit.entity.Panda) super.getBukkitEntity();
}
public static class EntityPandaNPC extends Panda implements NPCHolder {
private final CitizensNPC npc;
public EntityPandaNPC(EntityType<? extends Panda> types, Level level) {
this(types, level, null);
}
public EntityPandaNPC(EntityType<? extends Panda> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new PandaNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class PandaNPC extends CraftPanda implements ForwardingNPCHolder {
public PandaNPC(EntityPandaNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,190 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftParrot;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Parrot;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
public class ParrotController extends MobEntityController {
public ParrotController() {
super(EntityParrotNPC.class);
}
@Override
public org.bukkit.entity.Parrot getBukkitEntity() {
return (org.bukkit.entity.Parrot) super.getBukkitEntity();
}
public static class EntityParrotNPC extends Parrot implements NPCHolder {
private final CitizensNPC npc;
public EntityParrotNPC(EntityType<? extends Parrot> types, Level level) {
this(types, level, null);
}
public EntityParrotNPC(EntityType<? extends Parrot> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
public void customServerAiStep() {
if (npc == null) {
super.customServerAiStep();
} else {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI()) {
super.customServerAiStep();
}
npc.update();
}
}
@Override
public SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new ParrotNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
// block feeding
if (npc == null || !npc.isProtected()) {
return super.mobInteract(entityhuman, enumhand);
}
return InteractionResult.FAIL;
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class ParrotNPC extends CraftParrot implements ForwardingNPCHolder {
public ParrotNPC(EntityParrotNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,257 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPhantom;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.EntityMoveControl;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.control.LookControl;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.monster.Phantom;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class PhantomController extends MobEntityController {
public PhantomController() {
super(EntityPhantomNPC.class);
}
@Override
public org.bukkit.entity.Phantom getBukkitEntity() {
return (org.bukkit.entity.Phantom) super.getBukkitEntity();
}
public static class EntityPhantomNPC extends Phantom implements NPCHolder {
private final CitizensNPC npc;
private LookControl oldLookController;
private MoveControl oldMoveController;
public EntityPhantomNPC(EntityType<? extends Phantom> types, Level level) {
this(types, level, null);
}
public EntityPhantomNPC(EntityType<? extends Phantom> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
this.oldMoveController = this.moveControl;
this.oldLookController = this.lookControl;
this.moveControl = new MoveControl(this);
this.lookControl = new LookControl(this);
// TODO: phantom pitch reversed
}
}
@Override
public void aiStep() {
super.aiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
this.lookControl = this.oldLookController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new EntityMoveControl(this);
this.lookControl = new LookControl(this);
}
if (npc.isProtected()) {
setSecondsOnFire(0);
}
npc.update();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new PhantomNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public boolean isSunBurnTick() {
if (npc == null || !npc.isProtected())
return super.isSunBurnTick();
return false;
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
protected boolean shouldDespawnInPeaceful() {
return npc != null ? false : super.shouldDespawnInPeaceful();
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class PhantomNPC extends CraftPhantom implements ForwardingNPCHolder {
public PhantomNPC(EntityPhantomNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,236 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPig;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LightningBolt;
import net.minecraft.world.entity.animal.Pig;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class PigController extends MobEntityController {
public PigController() {
super(EntityPigNPC.class);
}
@Override
public org.bukkit.entity.Pig getBukkitEntity() {
return (org.bukkit.entity.Pig) super.getBukkitEntity();
}
public static class EntityPigNPC extends Pig implements NPCHolder {
private final CitizensNPC npc;
public EntityPigNPC(EntityType<? extends Pig> types, Level level) {
this(types, level, null);
}
public EntityPigNPC(EntityType<? extends Pig> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new PigNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public boolean isVehicle() {
// block carrot-on-a-stick behaviour
return npc == null ? super.isVehicle() : false;
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void thunderHit(ServerLevel worldserver, LightningBolt entitylightning) {
if (npc == null) {
super.thunderHit(worldserver, entitylightning);
}
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class PigNPC extends CraftPig implements ForwardingNPCHolder {
public PigNPC(EntityPigNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,211 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPigZombie;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.ZombifiedPiglin;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class PigZombieController extends MobEntityController {
public PigZombieController() {
super(EntityPigZombieNPC.class);
}
@Override
public org.bukkit.entity.PigZombie getBukkitEntity() {
return (org.bukkit.entity.PigZombie) super.getBukkitEntity();
}
public static class EntityPigZombieNPC extends ZombifiedPiglin implements NPCHolder {
private final CitizensNPC npc;
public EntityPigZombieNPC(EntityType<? extends ZombifiedPiglin> types, Level level) {
this(types, level, null);
}
public EntityPigZombieNPC(EntityType<? extends ZombifiedPiglin> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new PigZombieNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class PigZombieNPC extends CraftPigZombie implements ForwardingNPCHolder {
public PigZombieNPC(EntityPigZombieNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,214 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPiglinBrute;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.piglin.PiglinBrute;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class PiglinBruteController extends MobEntityController {
public PiglinBruteController() {
super(EntityPiglinBruteNPC.class);
}
@Override
public org.bukkit.entity.PiglinBrute getBukkitEntity() {
return (org.bukkit.entity.PiglinBrute) super.getBukkitEntity();
}
public static class EntityPiglinBruteNPC extends PiglinBrute implements NPCHolder {
private final CitizensNPC npc;
public EntityPiglinBruteNPC(EntityType<? extends PiglinBrute> types, Level level) {
this(types, level, null);
}
public EntityPiglinBruteNPC(EntityType<? extends PiglinBrute> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
setImmuneToZombification(true);
}
super.customServerAiStep();
if (npc != null) {
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new PiglinBruteNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class PiglinBruteNPC extends CraftPiglinBrute implements ForwardingNPCHolder {
public PiglinBruteNPC(EntityPiglinBruteNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,214 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPiglin;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.piglin.Piglin;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class PiglinController extends MobEntityController {
public PiglinController() {
super(EntityPiglinNPC.class);
}
@Override
public org.bukkit.entity.Piglin getBukkitEntity() {
return (org.bukkit.entity.Piglin) super.getBukkitEntity();
}
public static class EntityPiglinNPC extends Piglin implements NPCHolder {
private final CitizensNPC npc;
public EntityPiglinNPC(EntityType<? extends Piglin> types, Level level) {
this(types, level, null);
}
public EntityPiglinNPC(EntityType<? extends Piglin> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
setImmuneToZombification(true);
}
super.customServerAiStep();
if (npc != null) {
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new PiglinNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class PiglinNPC extends CraftPiglin implements ForwardingNPCHolder {
public PiglinNPC(EntityPiglinNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,222 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPillager;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Pillager;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class PillagerController extends MobEntityController {
public PillagerController() {
super(EntityPillagerNPC.class);
}
@Override
public org.bukkit.entity.Pillager getBukkitEntity() {
return (org.bukkit.entity.Pillager) super.getBukkitEntity();
}
public static class EntityPillagerNPC extends Pillager implements NPCHolder {
private final CitizensNPC npc;
public EntityPillagerNPC(EntityType<? extends Pillager> types, Level level) {
this(types, level, null);
}
public EntityPillagerNPC(EntityType<? extends Pillager> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new PillagerNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class PillagerNPC extends CraftPillager implements ForwardingNPCHolder {
public PillagerNPC(EntityPillagerNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,186 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPolarBear;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.PolarBear;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
public class PolarBearController extends MobEntityController {
public PolarBearController() {
super(EntityPolarBearNPC.class);
}
@Override
public org.bukkit.entity.PolarBear getBukkitEntity() {
return (org.bukkit.entity.PolarBear) super.getBukkitEntity();
}
public static class EntityPolarBearNPC extends PolarBear implements NPCHolder {
private final CitizensNPC npc;
public EntityPolarBearNPC(EntityType<? extends PolarBear> types, Level level) {
this(types, level, null);
}
public EntityPolarBearNPC(EntityType<? extends PolarBear> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new PolarBearNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class PolarBearNPC extends CraftPolarBear implements ForwardingNPCHolder {
public PolarBearNPC(EntityPolarBearNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,293 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPufferFish;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.EntityMoveControl;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.versioned.PufferFishTrait;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.animal.Pufferfish;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class PufferFishController extends MobEntityController {
public PufferFishController() {
super(EntityPufferFishNPC.class);
}
@Override
public org.bukkit.entity.PufferFish getBukkitEntity() {
return (org.bukkit.entity.PufferFish) super.getBukkitEntity();
}
public static class EntityPufferFishNPC extends Pufferfish implements NPCHolder {
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityPufferFishNPC(EntityType<? extends Pufferfish> types, Level level) {
this(types, level, null);
}
public EntityPufferFishNPC(EntityType<? extends Pufferfish> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
this.oldMoveController = this.moveControl;
this.moveControl = new MoveControl(this);
}
}
@Override
public void aiStep() {
boolean lastInWater = this.verticalCollision;
int lastPuffState = getPuffState();
if (npc != null) {
this.verticalCollision = false;
setPuffState(0);
}
super.aiStep();
if (npc != null) {
this.verticalCollision = lastInWater;
setPuffState(lastPuffState);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new EntityMoveControl(this);
}
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new PufferFishNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
public EntityDimensions getDimensions(Pose entitypose) {
if (npc == null) {
return super.getDimensions(entitypose);
}
return super.getDimensions(entitypose).scale(1 / s(getPuffState())).scale(0.5F);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
protected InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc == null || !npc.isProtected())
return super.mobInteract(entityhuman, enumhand);
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.getItem() == Items.WATER_BUCKET && isAlive()) {
return InteractionResult.FAIL;
}
return super.mobInteract(entityhuman, enumhand);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void tick() {
if (npc != null) {
NMSImpl.resetPuffTicks(this);
}
super.tick();
PufferFishTrait trait = null;
if (npc != null && (trait = npc.getTraitNullable(PufferFishTrait.class)) != null) {
setPuffState(trait.getPuffState());
}
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
if (!NMSImpl.moveFish(npc, this, vec3d)) {
super.travel(vec3d);
}
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
private static float s(int i) {
switch (i) {
case 0:
return 0.5F;
case 1:
return 0.7F;
default:
return 1.0F;
}
}
}
public static class PufferFishNPC extends CraftPufferFish implements ForwardingNPCHolder {
public PufferFishNPC(EntityPufferFishNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,242 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftRabbit;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.animal.Rabbit;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class RabbitController extends MobEntityController {
public RabbitController() {
super(EntityRabbitNPC.class);
}
@Override
public org.bukkit.entity.Rabbit getBukkitEntity() {
return (org.bukkit.entity.Rabbit) super.getBukkitEntity();
}
public static class EntityRabbitNPC extends Rabbit implements NPCHolder {
private final CitizensNPC npc;
public EntityRabbitNPC(EntityType<? extends Rabbit> types, Level level) {
this(types, level, null);
}
public EntityRabbitNPC(EntityType<? extends Rabbit> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.getNavigator().isNavigating()) {
NMS.setShouldJump(getBukkitEntity());
}
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new RabbitNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public LivingEntity getTarget() {
return npc != null ? null : super.getTarget();
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public void setVariant(Variant variant) {
if (npc != null) {
if (NMSImpl.getRabbitTypeField() == null)
return;
this.entityData.set(NMSImpl.getRabbitTypeField(), variant.id());
return;
}
super.setVariant(variant);
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class RabbitNPC extends CraftRabbit implements ForwardingNPCHolder {
public RabbitNPC(EntityRabbitNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,227 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftRavager;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Ravager;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class RavagerController extends MobEntityController {
public RavagerController() {
super(EntityRavagerNPC.class);
}
@Override
public org.bukkit.entity.Ravager getBukkitEntity() {
return (org.bukkit.entity.Ravager) super.getBukkitEntity();
}
public static class EntityRavagerNPC extends Ravager implements NPCHolder {
private final CitizensNPC npc;
public EntityRavagerNPC(EntityType<? extends Ravager> types, Level level) {
this(types, level, null);
}
public EntityRavagerNPC(EntityType<? extends Ravager> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new RavagerNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public boolean isVehicle() {
return (npc == null || npc.useMinecraftAI()) ? super.isVehicle() : false;
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class RavagerNPC extends CraftRavager implements ForwardingNPCHolder {
public RavagerNPC(EntityRavagerNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,258 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSalmon;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.EntityMoveControl;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.animal.Salmon;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SalmonController extends MobEntityController {
public SalmonController() {
super(EntitySalmonNPC.class);
}
@Override
public org.bukkit.entity.Salmon getBukkitEntity() {
return (org.bukkit.entity.Salmon) super.getBukkitEntity();
}
public static class EntitySalmonNPC extends Salmon implements NPCHolder {
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntitySalmonNPC(EntityType<? extends Salmon> types, Level level) {
this(types, level, null);
}
public EntitySalmonNPC(EntityType<? extends Salmon> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
this.oldMoveController = this.moveControl;
this.moveControl = new MoveControl(this);
}
}
@Override
public void aiStep() {
boolean lastInWater = this.verticalCollision;
if (npc != null) {
this.verticalCollision = false;
}
super.aiStep();
if (npc != null) {
this.verticalCollision = lastInWater;
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
NMSImpl.setNotInSchool(this);
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new EntityMoveControl(this);
}
}
super.customServerAiStep();
if (npc != null) {
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SalmonNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
protected InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc == null || !npc.isProtected())
return super.mobInteract(entityhuman, enumhand);
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.getItem() == Items.WATER_BUCKET && isAlive()) {
return InteractionResult.FAIL;
}
return super.mobInteract(entityhuman, enumhand);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
if (!NMSImpl.moveFish(npc, this, vec3d)) {
super.travel(vec3d);
}
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SalmonNPC extends CraftSalmon implements ForwardingNPCHolder {
public SalmonNPC(EntitySalmonNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,221 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSheep;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Sheep;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SheepController extends MobEntityController {
public SheepController() {
super(EntitySheepNPC.class);
}
@Override
public org.bukkit.entity.Sheep getBukkitEntity() {
return (org.bukkit.entity.Sheep) super.getBukkitEntity();
}
public static class EntitySheepNPC extends Sheep implements NPCHolder {
private final CitizensNPC npc;
public EntitySheepNPC(EntityType<? extends Sheep> types, Level level) {
this(types, level, null);
}
public EntitySheepNPC(EntityType<? extends Sheep> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SheepNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SheepNPC extends CraftSheep implements ForwardingNPCHolder {
public SheepNPC(EntitySheepNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,237 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftShulker;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.control.BodyRotationControl;
import net.minecraft.world.entity.monster.Shulker;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class ShulkerController extends MobEntityController {
public ShulkerController() {
super(EntityShulkerNPC.class);
}
@Override
public org.bukkit.entity.Shulker getBukkitEntity() {
return (org.bukkit.entity.Shulker) super.getBukkitEntity();
}
public static class EntityShulkerNPC extends Shulker implements NPCHolder {
private final CitizensNPC npc;
public EntityShulkerNPC(EntityType<? extends Shulker> types, Level level) {
this(types, level, null);
}
public EntityShulkerNPC(EntityType<? extends Shulker> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
public void aiStep() {
if (npc == null || npc.useMinecraftAI()) {
super.aiStep();
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
protected BodyRotationControl createBodyControl() {
return new BodyRotationControl(this);
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new ShulkerNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void tick() {
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI()) {
super.tick();
}
npc.update();
} else {
super.tick();
}
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class ShulkerNPC extends CraftShulker implements ForwardingNPCHolder {
public ShulkerNPC(EntityShulkerNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,221 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSilverfish;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Silverfish;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SilverfishController extends MobEntityController {
public SilverfishController() {
super(EntitySilverfishNPC.class);
}
@Override
public org.bukkit.entity.Silverfish getBukkitEntity() {
return (org.bukkit.entity.Silverfish) super.getBukkitEntity();
}
public static class EntitySilverfishNPC extends Silverfish implements NPCHolder {
private final CitizensNPC npc;
public EntitySilverfishNPC(EntityType<? extends Silverfish> types, Level level) {
this(types, level, null);
}
public EntitySilverfishNPC(EntityType<? extends Silverfish> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SilverfishNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SilverfishNPC extends CraftSilverfish implements ForwardingNPCHolder {
public SilverfishNPC(EntitySilverfishNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSkeleton;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Skeleton;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SkeletonController extends MobEntityController {
public SkeletonController() {
super(EntitySkeletonNPC.class);
}
@Override
public org.bukkit.entity.Skeleton getBukkitEntity() {
return (org.bukkit.entity.Skeleton) super.getBukkitEntity();
}
public static class EntitySkeletonNPC extends Skeleton implements NPCHolder {
private final CitizensNPC npc;
public EntitySkeletonNPC(EntityType<? extends Skeleton> types, Level level) {
this(types, level, null);
}
public EntitySkeletonNPC(EntityType<? extends Skeleton> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SkeletonNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SkeletonNPC extends CraftSkeleton implements ForwardingNPCHolder {
public SkeletonNPC(EntitySkeletonNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftStray;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Stray;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SkeletonStrayController extends MobEntityController {
public SkeletonStrayController() {
super(EntityStrayNPC.class);
}
@Override
public org.bukkit.entity.Stray getBukkitEntity() {
return (org.bukkit.entity.Stray) super.getBukkitEntity();
}
public static class EntityStrayNPC extends Stray implements NPCHolder {
private final CitizensNPC npc;
public EntityStrayNPC(EntityType<? extends Stray> types, Level level) {
this(types, level, null);
}
public EntityStrayNPC(EntityType<? extends Stray> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new StrayNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class StrayNPC extends CraftStray implements ForwardingNPCHolder {
public StrayNPC(EntityStrayNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftWitherSkeleton;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.WitherSkeleton;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SkeletonWitherController extends MobEntityController {
public SkeletonWitherController() {
super(EntitySkeletonWitherNPC.class);
}
@Override
public org.bukkit.entity.WitherSkeleton getBukkitEntity() {
return (org.bukkit.entity.WitherSkeleton) super.getBukkitEntity();
}
public static class EntitySkeletonWitherNPC extends WitherSkeleton implements NPCHolder {
private final CitizensNPC npc;
public EntitySkeletonWitherNPC(EntityType<? extends WitherSkeleton> types, Level level) {
this(types, level, null);
}
public EntitySkeletonWitherNPC(EntityType<? extends WitherSkeleton> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SkeletonWitherNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SkeletonWitherNPC extends CraftWitherSkeleton implements ForwardingNPCHolder {
public SkeletonWitherNPC(EntitySkeletonWitherNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,244 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSlime;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.EntityMoveControl;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.monster.Slime;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SlimeController extends MobEntityController {
public SlimeController() {
super(EntitySlimeNPC.class);
}
@Override
public org.bukkit.entity.Slime getBukkitEntity() {
return (org.bukkit.entity.Slime) super.getBukkitEntity();
}
public static class EntitySlimeNPC extends Slime implements NPCHolder {
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntitySlimeNPC(EntityType<? extends Slime> types, Level level) {
this(types, level, null);
}
public EntitySlimeNPC(EntityType<? extends Slime> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
setSize(3, true);
this.oldMoveController = this.moveControl;
this.moveControl = new EntityMoveControl(this);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SlimeNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void playerTouch(Player human) {
if (npc == null) {
super.playerTouch(human);
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void tick() {
super.tick();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new EntityMoveControl(this);
}
npc.update();
}
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SlimeNPC extends CraftSlime implements ForwardingNPCHolder {
public SlimeNPC(EntitySlimeNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,236 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSniffer;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.sniffer.Sniffer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SnifferController extends MobEntityController {
public SnifferController() {
super(EntitySnifferNPC.class);
}
@Override
public org.bukkit.entity.Sniffer getBukkitEntity() {
return (org.bukkit.entity.Sniffer) super.getBukkitEntity();
}
public static class EntitySnifferNPC extends Sniffer implements NPCHolder {
private final CitizensNPC npc;
public EntitySnifferNPC(EntityType<? extends Sniffer> types, Level level) {
this(types, level, null);
}
public EntitySnifferNPC(EntityType<? extends Sniffer> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SnifferNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc == null || !npc.isProtected())
return super.mobInteract(entityhuman, enumhand);
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.getItem() == Items.BUCKET && !entityhuman.getAbilities().instabuild && !this.isBaby()) {
return InteractionResult.FAIL;
}
return super.mobInteract(entityhuman, enumhand);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SnifferNPC extends CraftSniffer implements ForwardingNPCHolder {
public SnifferNPC(EntitySnifferNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSnowman;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.SnowGolem;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SnowmanController extends MobEntityController {
public SnowmanController() {
super(EntitySnowmanNPC.class);
}
@Override
public org.bukkit.entity.Snowman getBukkitEntity() {
return (org.bukkit.entity.Snowman) super.getBukkitEntity();
}
public static class EntitySnowmanNPC extends SnowGolem implements NPCHolder {
private final CitizensNPC npc;
public EntitySnowmanNPC(EntityType<? extends SnowGolem> types, Level level) {
this(types, level, null);
}
public EntitySnowmanNPC(EntityType<? extends SnowGolem> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SnowmanNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SnowmanNPC extends CraftSnowman implements ForwardingNPCHolder {
public SnowmanNPC(EntitySnowmanNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSpider;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Spider;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SpiderController extends MobEntityController {
public SpiderController() {
super(EntitySpiderNPC.class);
}
@Override
public org.bukkit.entity.Spider getBukkitEntity() {
return (org.bukkit.entity.Spider) super.getBukkitEntity();
}
public static class EntitySpiderNPC extends Spider implements NPCHolder {
private final CitizensNPC npc;
public EntitySpiderNPC(EntityType<? extends Spider> types, Level level) {
this(types, level, null);
}
public EntitySpiderNPC(EntityType<? extends Spider> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SpiderNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SpiderNPC extends CraftSpider implements ForwardingNPCHolder {
public SpiderNPC(EntitySpiderNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,220 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftSquid;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.Squid;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class SquidController extends MobEntityController {
public SquidController() {
super(EntitySquidNPC.class);
}
@Override
public org.bukkit.entity.Squid getBukkitEntity() {
return (org.bukkit.entity.Squid) super.getBukkitEntity();
}
public static class EntitySquidNPC extends Squid implements NPCHolder {
private final CitizensNPC npc;
public EntitySquidNPC(EntityType<? extends Squid> types, Level level) {
this(types, level, null);
}
public EntitySquidNPC(EntityType<? extends Squid> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new SquidNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public void refreshDimensions() {
if (npc == null) {
super.refreshDimensions();
} else {
NMSImpl.setSize(this, firstTick);
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class SquidNPC extends CraftSquid implements ForwardingNPCHolder {
public SquidNPC(EntitySquidNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,211 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftStrider;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Strider;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class StriderController extends MobEntityController {
public StriderController() {
super(EntityStriderNPC.class);
}
@Override
public org.bukkit.entity.Strider getBukkitEntity() {
return (org.bukkit.entity.Strider) super.getBukkitEntity();
}
public static class EntityStriderNPC extends Strider implements NPCHolder {
private final CitizensNPC npc;
public EntityStriderNPC(EntityType<? extends Strider> types, Level level) {
this(types, level, null);
}
public EntityStriderNPC(EntityType<? extends Strider> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new StriderNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class StriderNPC extends CraftStrider implements ForwardingNPCHolder {
public StriderNPC(EntityStriderNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,258 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftTadpole;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.EntityMoveControl;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.animal.frog.Frog;
import net.minecraft.world.entity.animal.frog.Tadpole;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class TadpoleController extends MobEntityController {
public TadpoleController() {
super(EntityTadpoleNPC.class);
}
@Override
public org.bukkit.entity.Tadpole getBukkitEntity() {
return (org.bukkit.entity.Tadpole) super.getBukkitEntity();
}
public static class EntityTadpoleNPC extends Tadpole implements NPCHolder {
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityTadpoleNPC(EntityType<? extends Tadpole> types, Level level) {
this(types, level, null);
}
public EntityTadpoleNPC(EntityType<? extends Tadpole> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
this.oldMoveController = this.moveControl;
this.moveControl = new MoveControl(this);
}
}
@Override
public void aiStep() {
boolean lastInWater = this.verticalCollision;
if (npc != null) {
this.verticalCollision = false;
}
super.aiStep();
if (npc != null) {
this.verticalCollision = lastInWater;
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new EntityMoveControl(this);
}
}
super.customServerAiStep();
if (npc != null) {
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new TadpoleNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc == null || !npc.isProtected())
return super.mobInteract(entityhuman, enumhand);
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if ((Frog.TEMPTATION_ITEM.test(itemstack) || itemstack.getItem() == Items.WATER_BUCKET) && isAlive()) {
return InteractionResult.FAIL;
}
return super.mobInteract(entityhuman, enumhand);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
if (!NMSImpl.moveFish(npc, this, vec3d)) {
super.travel(vec3d);
}
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class TadpoleNPC extends CraftTadpole implements ForwardingNPCHolder {
public TadpoleNPC(EntityTadpoleNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,240 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftTraderLlama;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.trait.HorseModifiers;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.animal.horse.TraderLlama;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class TraderLlamaController extends MobEntityController {
public TraderLlamaController() {
super(EntityTraderLlamaNPC.class);
}
@Override
public void create(Location at, NPC npc) {
npc.getOrAddTrait(HorseModifiers.class);
super.create(at, npc);
}
@Override
public org.bukkit.entity.TraderLlama getBukkitEntity() {
return (org.bukkit.entity.TraderLlama) super.getBukkitEntity();
}
public static class EntityTraderLlamaNPC extends TraderLlama implements NPCHolder {
private final CitizensNPC npc;
public EntityTraderLlamaNPC(EntityType<? extends TraderLlama> types, Level level) {
this(types, level, null);
}
public EntityTraderLlamaNPC(EntityType<? extends TraderLlama> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
((org.bukkit.entity.TraderLlama) getBukkitEntity())
.setDomestication(((org.bukkit.entity.TraderLlama) getBukkitEntity()).getMaxDomestication());
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc == null) {
super.customServerAiStep();
} else {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI()) {
super.customServerAiStep();
}
setDespawnDelay(10);
NMS.setStepHeight(getBukkitEntity(), 1);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new TraderLlamaNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class TraderLlamaNPC extends CraftTraderLlama implements ForwardingNPCHolder {
public TraderLlamaNPC(EntityTraderLlamaNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,260 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftTropicalFish;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.EntityMoveControl;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.animal.TropicalFish;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class TropicalFishController extends MobEntityController {
public TropicalFishController() {
super(EntityTropicalFishNPC.class);
}
@Override
public org.bukkit.entity.TropicalFish getBukkitEntity() {
return (org.bukkit.entity.TropicalFish) super.getBukkitEntity();
}
public static class EntityTropicalFishNPC extends TropicalFish implements NPCHolder {
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityTropicalFishNPC(EntityType<? extends TropicalFish> types, Level level) {
this(types, level, null);
}
public EntityTropicalFishNPC(EntityType<? extends TropicalFish> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
this.oldMoveController = this.moveControl;
this.moveControl = new MoveControl(this);
}
}
@Override
public void aiStep() {
boolean lastInWater = this.verticalCollision;
if (npc != null) {
this.verticalCollision = false;
}
super.aiStep();
if (npc != null) {
this.verticalCollision = lastInWater;
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
if (!npc.useMinecraftAI()) {
NMSImpl.setNotInSchool(this);
}
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new EntityMoveControl(this);
}
}
super.customServerAiStep();
if (npc != null) {
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new TropicalFishNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
protected InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc == null || !npc.isProtected())
return super.mobInteract(entityhuman, enumhand);
ItemStack itemstack = entityhuman.getItemInHand(enumhand);
if (itemstack.getItem() == Items.WATER_BUCKET && isAlive()) {
return InteractionResult.FAIL;
}
return super.mobInteract(entityhuman, enumhand);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null)
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
if (!NMSImpl.moveFish(npc, this, vec3d)) {
super.travel(vec3d);
}
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class TropicalFishNPC extends CraftTropicalFish implements ForwardingNPCHolder {
public TropicalFishNPC(EntityTropicalFishNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,246 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftTurtle;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.EntityMoveControl;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.control.JumpControl;
import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.animal.Turtle;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class TurtleController extends MobEntityController {
public TurtleController() {
super(EntityTurtleNPC.class);
}
@Override
public org.bukkit.entity.Turtle getBukkitEntity() {
return (org.bukkit.entity.Turtle) super.getBukkitEntity();
}
public static class EntityTurtleNPC extends Turtle implements NPCHolder {
private final CitizensNPC npc;
private JumpControl oldJumpController;
private MoveControl oldMoveController;
public EntityTurtleNPC(EntityType<? extends Turtle> types, Level level) {
this(types, level, null);
}
public EntityTurtleNPC(EntityType<? extends Turtle> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
this.oldMoveController = this.moveControl;
this.oldJumpController = this.jumpControl;
this.moveControl = new MoveControl(this);
this.jumpControl = new EmptyControllerJump(this);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {
this.moveControl = this.oldMoveController;
this.jumpControl = this.oldJumpController;
}
if (!npc.useMinecraftAI() && this.moveControl == this.oldMoveController) {
this.moveControl = new EntityMoveControl(this);
this.jumpControl = new EmptyControllerJump(this);
}
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new TurtleNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
if (!NMSImpl.moveFish(npc, this, vec3d)) {
super.travel(vec3d);
}
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
static class EmptyControllerJump extends JumpControl {
public EmptyControllerJump(Mob var1) {
super(var1);
}
@Override
public void jump() {
this.jump = false;
}
}
}
public static class TurtleNPC extends CraftTurtle implements ForwardingNPCHolder {
public TurtleNPC(EntityTurtleNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,179 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftVex;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Vex;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
public class VexController extends MobEntityController {
public VexController() {
super(EntityVexNPC.class);
}
@Override
public org.bukkit.entity.Vex getBukkitEntity() {
return (org.bukkit.entity.Vex) super.getBukkitEntity();
}
public static class EntityVexNPC extends Vex implements NPCHolder {
private final CitizensNPC npc;
public EntityVexNPC(EntityType<? extends Vex> types, Level level) {
this(types, level, null);
}
public EntityVexNPC(EntityType<? extends Vex> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
setNoGravity(true);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
public void customServerAiStep() {
super.customServerAiStep();
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
npc.update();
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new VexNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class VexNPC extends CraftVex implements ForwardingNPCHolder {
public VexNPC(EntityVexNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

View File

@ -0,0 +1,263 @@
package net.citizensnpcs.nms.v1_20_R1.entity;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftVillager;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_20_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_20_R1.util.NMSBoundingBox;
import net.citizensnpcs.nms.v1_20_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LightningBolt;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.trading.MerchantOffers;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class VillagerController extends MobEntityController {
public VillagerController() {
super(EntityVillagerNPC.class);
}
@Override
public org.bukkit.entity.Villager getBukkitEntity() {
return (org.bukkit.entity.Villager) super.getBukkitEntity();
}
public static class EntityVillagerNPC extends Villager implements NPCHolder {
private boolean blockingATrade;
private final CitizensNPC npc;
public EntityVillagerNPC(EntityType<? extends Villager> types, Level level) {
this(types, level, null);
}
public EntityVillagerNPC(EntityType<? extends Villager> types, Level level, NPC npc) {
super(types, level);
this.npc = (CitizensNPC) npc;
if (npc != null) {
getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.3);
}
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
return !npc.isProtected();
}
return super.canRide(entity);
}
@Override
public boolean causeFallDamage(float f, float f1, DamageSource damagesource) {
if (npc == null || !npc.isFlyable()) {
return super.causeFallDamage(f, f1, damagesource);
}
return false;
}
@Override
public void checkDespawn() {
if (npc == null) {
super.checkDespawn();
}
}
@Override
protected void checkFallDamage(double d0, boolean flag, BlockState iblockdata, BlockPos blockposition) {
if (npc == null || !npc.isFlyable()) {
super.checkFallDamage(d0, flag, iblockdata, blockposition);
}
}
@Override
public void customServerAiStep() {
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
}
super.customServerAiStep();
if (npc != null) {
npc.update();
if (npc.data().get(NPC.Metadata.RESET_PITCH_ON_TICK, true)) {
NMS.setPitch(getBukkitEntity(), 0);
}
}
}
@Override
protected SoundEvent getAmbientSound() {
return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND);
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new VillagerNPC(this));
}
return super.getBukkitEntity();
}
@Override
protected SoundEvent getDeathSound() {
return NMSImpl.getSoundEffect(npc, super.getDeathSound(), NPC.Metadata.DEATH_SOUND);
}
@Override
protected SoundEvent getHurtSound(DamageSource damagesource) {
return NMSImpl.getSoundEffect(npc, super.getHurtSound(damagesource), NPC.Metadata.HURT_SOUND);
}
@Override
public int getMaxFallDistance() {
return NMS.getFallDistance(npc, super.getMaxFallDistance());
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(npc, super::isLeashed, this);
}
@Override
public boolean isPushable() {
return npc == null ? super.isPushable()
: npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected());
}
@Override
public boolean isTrading() {
if (blockingATrade) {
blockingATrade = false;
return true;
}
return super.isTrading();
}
@Override
public void knockback(double strength, double dx, double dz) {
NMS.callKnockbackEvent(npc, (float) strength, dx, dz, (evt) -> super.knockback((float) evt.getStrength(),
evt.getKnockbackVector().getX(), evt.getKnockbackVector().getZ()));
}
@Override
protected AABB makeBoundingBox() {
return NMSBoundingBox.makeBB(npc, super.makeBoundingBox());
}
@Override
public InteractionResult mobInteract(Player entityhuman, InteractionHand enumhand) {
if (npc != null && npc.data().get(NPC.Metadata.VILLAGER_BLOCK_TRADES, true)) {
blockingATrade = true;
MerchantOffers list = getOffers();
if (list != null) {
list.clear();
}
}
return super.mobInteract(entityhuman, enumhand);
}
@Override
public boolean onClimbable() {
if (npc == null || !npc.isFlyable()) {
return super.onClimbable();
} else {
return false;
}
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> datawatcherobject) {
if (npc == null) {
super.onSyncedDataUpdated(datawatcherobject);
return;
}
NMSImpl.checkAndUpdateHeight(this, datawatcherobject, super::onSyncedDataUpdated);
}
@Override
public void push(double x, double y, double z) {
Vector vector = Util.callPushEvent(npc, x, y, z);
if (vector != null) {
super.push(vector.getX(), vector.getY(), vector.getZ());
}
}
@Override
public void push(Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.push(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean save(CompoundTag save) {
return npc == null ? super.save(save) : false;
}
@Override
public Entity teleportTo(ServerLevel worldserver, PositionImpl location) {
if (npc == null)
return super.teleportTo(worldserver, location);
return NMSImpl.teleportAcrossWorld(this, worldserver, location);
}
@Override
public void thunderHit(ServerLevel worldserver, LightningBolt entitylightning) {
if (npc == null) {
super.thunderHit(worldserver, entitylightning);
}
}
@Override
public void travel(Vec3 vec3d) {
if (npc == null || !npc.isFlyable()) {
super.travel(vec3d);
} else {
NMSImpl.flyingMoveLogic(this, vec3d);
}
}
@Override
public boolean updateFluidHeightAndDoFluidPushing(TagKey<Fluid> tagkey, double d0) {
return NMSImpl.fluidPush(npc, this, () -> super.updateFluidHeightAndDoFluidPushing(tagkey, d0));
}
}
public static class VillagerNPC extends CraftVillager implements ForwardingNPCHolder {
public VillagerNPC(EntityVillagerNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
}
}
}

Some files were not shown because too many files have changed in this diff Show More