Initial 1.20 update
This commit is contained in:
parent
f164494cde
commit
9facad1b2a
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens</artifactId>
|
<artifactId>citizens</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
@ -92,5 +92,12 @@
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>citizens-v1_20_R1</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-main</artifactId>
|
<artifactId>citizens-main</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -131,13 +131,13 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>adventure-text-minimessage</artifactId>
|
<artifactId>adventure-text-minimessage</artifactId>
|
||||||
<version>4.11.0</version>
|
<version>4.14.0</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>adventure-platform-bukkit</artifactId>
|
<artifactId>adventure-platform-bukkit</artifactId>
|
||||||
<version>4.1.2</version>
|
<version>4.3.0</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
@ -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")
|
lib.loadLibrary(Library.builder().groupId("net{}sf{}trove4j").artifactId("trove4j").version("3.0.3")
|
||||||
.relocate("gnu{}trove", "clib{}trove").build());
|
.relocate("gnu{}trove", "clib{}trove").build());
|
||||||
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-text-minimessage")
|
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-text-minimessage")
|
||||||
.version("4.12.0").relocate("net{}kyori", "clib{}net{}kyori").build());
|
.version("4.14.0").relocate("net{}kyori", "clib{}net{}kyori").build());
|
||||||
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-bukkit").version("4.2.0")
|
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-bukkit").version("4.3.0")
|
||||||
.relocate("net{}kyori", "clib{}net{}kyori").build());
|
.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());
|
.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());
|
.relocate("net{}kyori", "clib{}net{}kyori").build());
|
||||||
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-viaversion")
|
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-platform-viaversion")
|
||||||
.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-api").version("4.12.0")
|
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-api").version("4.14.0")
|
||||||
.relocate("net{}kyori", "clib{}net{}kyori").build());
|
.relocate("net{}kyori", "clib{}net{}kyori").build());
|
||||||
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-text-serializer-bungeecord")
|
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")
|
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")
|
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")
|
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());
|
.version("4.13.0").relocate("net{}kyori", "clib{}net{}kyori").build());
|
||||||
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-nbt").version("4.12.0")
|
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("adventure-nbt").version("4.13.0")
|
||||||
.relocate("net{}kyori", "clib{}net{}kyori").build());
|
.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());
|
.relocate("net{}kyori", "clib{}net{}kyori").build());
|
||||||
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("examination-api").version("1.3.0")
|
lib.loadLibrary(Library.builder().groupId("net{}kyori").artifactId("examination-api").version("1.3.0")
|
||||||
.relocate("net{}kyori", "clib{}net{}kyori").build());
|
.relocate("net{}kyori", "clib{}net{}kyori").build());
|
||||||
|
|
|
@ -141,7 +141,7 @@ public class Settings {
|
||||||
"npc.pathfinding.straight-line-targeting-distance", 5),
|
"npc.pathfinding.straight-line-targeting-distance", 5),
|
||||||
DEFAULT_STUCK_ACTION(
|
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'",
|
"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("npc.default.talk-close.enabled", false),
|
||||||
DEFAULT_TALK_CLOSE_RANGE("Default talk close range in blocks", "npc.default.talk-close.range", 5),
|
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>!") {
|
DEFAULT_TEXT("npc.default.talk-close.text.0", "Hi, I'm <npc>!") {
|
||||||
|
|
|
@ -133,6 +133,7 @@ import net.citizensnpcs.trait.ScriptTrait;
|
||||||
import net.citizensnpcs.trait.SheepTrait;
|
import net.citizensnpcs.trait.SheepTrait;
|
||||||
import net.citizensnpcs.trait.ShopTrait;
|
import net.citizensnpcs.trait.ShopTrait;
|
||||||
import net.citizensnpcs.trait.ShopTrait.NPCShop;
|
import net.citizensnpcs.trait.ShopTrait.NPCShop;
|
||||||
|
import net.citizensnpcs.trait.SitTrait;
|
||||||
import net.citizensnpcs.trait.SkinLayers;
|
import net.citizensnpcs.trait.SkinLayers;
|
||||||
import net.citizensnpcs.trait.SkinLayers.Layer;
|
import net.citizensnpcs.trait.SkinLayers.Layer;
|
||||||
import net.citizensnpcs.trait.SkinTrait;
|
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(
|
@Command(
|
||||||
aliases = { "npc" },
|
aliases = { "npc" },
|
||||||
usage = "skin (-c(lear) -l(atest)) [name] (or --url [url] --file [file] (-s(lim)) or -t [uuid/name] [data] [signature])",
|
usage = "skin (-c(lear) -l(atest)) [name] (or --url [url] --file [file] (-s(lim)) or -t [uuid/name] [data] [signature])",
|
||||||
|
|
|
@ -301,6 +301,7 @@ public class CitizensNPC extends AbstractNPC {
|
||||||
getOrAddTrait(CurrentLocation.class).setLocation(at);
|
getOrAddTrait(CurrentLocation.class).setLocation(at);
|
||||||
entityController.create(at.clone(), this);
|
entityController.create(at.clone(), this);
|
||||||
getEntity().setMetadata("NPC", new FixedMetadataValue(CitizensAPI.getPlugin(), true));
|
getEntity().setMetadata("NPC", new FixedMetadataValue(CitizensAPI.getPlugin(), true));
|
||||||
|
getEntity().setMetadata("NPC-ID", new FixedMetadataValue(CitizensAPI.getPlugin(), getId()));
|
||||||
|
|
||||||
if (getEntity() instanceof SkinnableEntity && !hasTrait(SkinLayers.class)) {
|
if (getEntity() instanceof SkinnableEntity && !hasTrait(SkinLayers.class)) {
|
||||||
((SkinnableEntity) getEntity()).setSkinFlags(EnumSet.allOf(SkinLayers.Layer.class));
|
((SkinnableEntity) getEntity()).setSkinFlags(EnumSet.allOf(SkinLayers.Layer.class));
|
||||||
|
|
|
@ -97,7 +97,6 @@ public class FollowTrait extends Trait {
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isActive())
|
if (!isActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -107,6 +106,7 @@ public class FollowTrait extends Trait {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!npc.getNavigator().isNavigating()) {
|
if (!npc.getNavigator().isNavigating()) {
|
||||||
npc.getNavigator().setTarget(entity, false);
|
npc.getNavigator().setTarget(entity, false);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -44,6 +44,8 @@ public class HologramTrait extends Trait {
|
||||||
private BiFunction<String, Player, String> customHologramSupplier;
|
private BiFunction<String, Player, String> customHologramSupplier;
|
||||||
@Persist
|
@Persist
|
||||||
private HologramDirection direction = HologramDirection.BOTTOM_UP;
|
private HologramDirection direction = HologramDirection.BOTTOM_UP;
|
||||||
|
@Persist(reify = true)
|
||||||
|
private HologramFilter filter;
|
||||||
private double lastEntityHeight = 0;
|
private double lastEntityHeight = 0;
|
||||||
private boolean lastNameplateVisible;
|
private boolean lastNameplateVisible;
|
||||||
@Persist
|
@Persist
|
||||||
|
@ -417,6 +419,17 @@ public class HologramTrait extends Trait {
|
||||||
TOP_DOWN;
|
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> {
|
private class HologramLine implements Function<Player, String> {
|
||||||
NPC hologram;
|
NPC hologram;
|
||||||
double mb, mt;
|
double mb, mt;
|
||||||
|
|
|
@ -361,6 +361,8 @@ public class Messages {
|
||||||
public static final String SHEEP_COLOR_SET = "citizens.commands.npc.sheep.color-set";
|
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_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 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_DESCRIPTION = "citizens.commands.npc.size.description";
|
||||||
public static final String SIZE_SET = "citizens.commands.npc.size.set";
|
public static final String SIZE_SET = "citizens.commands.npc.size.set";
|
||||||
public static final String SKELETON_TYPE_SET = "citizens.commands.npc.skeletontype.set";
|
public static final String SKELETON_TYPE_SET = "citizens.commands.npc.skeletontype.set";
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Function;
|
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 {
|
try {
|
||||||
Callable<Void> callable = () -> {
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
return false;
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
// sync method called
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Bukkit.getScheduler().callSyncMethod(CitizensAPI.getPlugin(), () -> {
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
return null;
|
return null;
|
||||||
};
|
}).get();
|
||||||
if (sync) {
|
} catch (InterruptedException e) {
|
||||||
Bukkit.getScheduler().callSyncMethod(CitizensAPI.getPlugin(), callable).get();
|
e.printStackTrace();
|
||||||
} else {
|
} catch (ExecutionException e) {
|
||||||
callable.call();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector callPushEvent(NPC npc, double x, double y, double z) {
|
public static Vector callPushEvent(NPC npc, double x, double y, double z) {
|
||||||
|
|
|
@ -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.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.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.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.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.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.set=[[{0}]]''s skin name set to [[{1}]].
|
||||||
citizens.commands.npc.skin.missing-skin=A skin name is required.
|
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.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.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.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}]].
|
citizens.commands.npc.size.description=[[{0}]]''s size is [[{1}]].
|
||||||
|
|
5
pom.xml
5
pom.xml
|
@ -4,10 +4,10 @@
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
<properties>
|
<properties>
|
||||||
<BUILD_NUMBER>Unknown</BUILD_NUMBER>
|
<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-javadoc-plugin.version>3.5.0</maven-javadoc-plugin.version>
|
||||||
<maven-assembly-plugin.version>3.5.0</maven-assembly-plugin.version>
|
<maven-assembly-plugin.version>3.5.0</maven-assembly-plugin.version>
|
||||||
<maven-deploy-plugin.version>3.1.1</maven-deploy-plugin.version>
|
<maven-deploy-plugin.version>3.1.1</maven-deploy-plugin.version>
|
||||||
|
@ -37,6 +37,7 @@
|
||||||
<module>v1_16_R3</module>
|
<module>v1_16_R3</module>
|
||||||
<module>v1_18_R2</module>
|
<module>v1_18_R2</module>
|
||||||
<module>v1_19_R3</module>
|
<module>v1_19_R3</module>
|
||||||
|
<module>v1_20_R1</module>
|
||||||
<module>dist</module>
|
<module>dist</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_10_R1</artifactId>
|
<artifactId>citizens-v1_10_R1</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_11_R1</artifactId>
|
<artifactId>citizens-v1_11_R1</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_12_R1</artifactId>
|
<artifactId>citizens-v1_12_R1</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_13_R2</artifactId>
|
<artifactId>citizens-v1_13_R2</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_14_R1</artifactId>
|
<artifactId>citizens-v1_14_R1</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_15_R1</artifactId>
|
<artifactId>citizens-v1_15_R1</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_16_R3</artifactId>
|
<artifactId>citizens-v1_16_R3</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_17_R1</artifactId>
|
<artifactId>citizens-v1_17_R1</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -480,6 +480,5 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
|
||||||
private static final float EPSILON = 0.003F;
|
private static final float EPSILON = 0.003F;
|
||||||
private static final MethodHandle GAMEMODE_SETTING = NMS.getFirstMethodHandle(ServerPlayerGameMode.class, true,
|
private static final MethodHandle GAMEMODE_SETTING = NMS.getFirstMethodHandle(ServerPlayerGameMode.class, true,
|
||||||
GameType.class, GameType.class);
|
GameType.class, GameType.class);
|
||||||
|
|
||||||
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
|
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,11 +54,8 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
|
||||||
public void updatePlayer(final ServerPlayer entityplayer) {
|
public void updatePlayer(final ServerPlayer entityplayer) {
|
||||||
if (tracker instanceof NPCHolder) {
|
if (tracker instanceof NPCHolder) {
|
||||||
NPC npc = ((NPCHolder) tracker).getNPC();
|
NPC npc = ((NPCHolder) tracker).getNPC();
|
||||||
if (REQUIRES_SYNC == null) {
|
|
||||||
REQUIRES_SYNC = !Bukkit.isPrimaryThread();
|
|
||||||
}
|
|
||||||
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
|
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
|
||||||
Util.callPossiblyAsyncEvent(event, REQUIRES_SYNC);
|
REQUIRES_SYNC = Util.callEventPossiblySync(event, REQUIRES_SYNC);
|
||||||
if (event.isCancelled())
|
if (event.isCancelled())
|
||||||
return;
|
return;
|
||||||
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
|
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 E = NMS.getGetter(ServerEntity.class, "e");
|
||||||
|
|
||||||
private static final MethodHandle F = NMS.getGetter(ServerEntity.class, "f");
|
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 = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
|
||||||
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.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);
|
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_18_R2</artifactId>
|
<artifactId>citizens-v1_18_R2</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -54,11 +54,8 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity {
|
||||||
public void updatePlayer(final ServerPlayer entityplayer) {
|
public void updatePlayer(final ServerPlayer entityplayer) {
|
||||||
if (tracker instanceof NPCHolder) {
|
if (tracker instanceof NPCHolder) {
|
||||||
NPC npc = ((NPCHolder) tracker).getNPC();
|
NPC npc = ((NPCHolder) tracker).getNPC();
|
||||||
if (REQUIRES_SYNC == null) {
|
|
||||||
REQUIRES_SYNC = !Bukkit.isPrimaryThread();
|
|
||||||
}
|
|
||||||
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
|
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
|
||||||
Util.callPossiblyAsyncEvent(event, REQUIRES_SYNC);
|
REQUIRES_SYNC = Util.callEventPossiblySync(event, REQUIRES_SYNC);
|
||||||
if (event.isCancelled())
|
if (event.isCancelled())
|
||||||
return;
|
return;
|
||||||
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
|
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 E = NMS.getGetter(ServerEntity.class, "e");
|
||||||
|
|
||||||
private static final MethodHandle F = NMS.getGetter(ServerEntity.class, "f");
|
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 = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
|
||||||
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.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);
|
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.citizensnpcs</groupId>
|
<groupId>net.citizensnpcs</groupId>
|
||||||
<artifactId>citizens-parent</artifactId>
|
<artifactId>citizens-parent</artifactId>
|
||||||
<version>2.0.31-SNAPSHOT</version>
|
<version>2.0.32-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>citizens-v1_19_R3</artifactId>
|
<artifactId>citizens-v1_19_R3</artifactId>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -81,11 +81,8 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
|
||||||
|
|
||||||
if (tracker instanceof NPCHolder) {
|
if (tracker instanceof NPCHolder) {
|
||||||
NPC npc = ((NPCHolder) tracker).getNPC();
|
NPC npc = ((NPCHolder) tracker).getNPC();
|
||||||
if (REQUIRES_SYNC == null) {
|
|
||||||
REQUIRES_SYNC = !Bukkit.isPrimaryThread();
|
|
||||||
}
|
|
||||||
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
|
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
|
||||||
Util.callPossiblyAsyncEvent(event, REQUIRES_SYNC);
|
REQUIRES_SYNC = Util.callEventPossiblySync(event, REQUIRES_SYNC);
|
||||||
if (event.isCancelled())
|
if (event.isCancelled())
|
||||||
return;
|
return;
|
||||||
Integer trackingRange = npc.data().<Integer> get(NPC.Metadata.TRACKING_RANGE);
|
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 E = NMS.getGetter(ServerEntity.class, "e");
|
||||||
private static final MethodHandle F = NMS.getGetter(ServerEntity.class, "f");
|
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 = NMS.getFirstGetter(TrackedEntity.class, Entity.class);
|
||||||
private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.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);
|
private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class);
|
||||||
|
|
|
@ -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>
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<?>>();
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
Loading…
Reference in New Issue