Update for API changes, add /npc scaledmaxhealth, use new API

This commit is contained in:
fullwall 2024-11-02 13:50:19 +08:00
parent 7f400dc672
commit f31d986c27
14 changed files with 119 additions and 37 deletions

View File

@ -4,7 +4,6 @@ import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import net.citizensnpcs.trait.TargetableTrait;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@ -116,7 +115,7 @@ import net.citizensnpcs.trait.CommandTrait;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.CurrentLocation;
import net.citizensnpcs.trait.HologramTrait.HologramRenderer;
import net.citizensnpcs.trait.ShopTrait;
import net.citizensnpcs.trait.TargetableTrait;
import net.citizensnpcs.trait.versioned.SnowmanTrait;
import net.citizensnpcs.util.ChunkCoord;
import net.citizensnpcs.util.Messages;
@ -373,9 +372,9 @@ public class EventListen implements Listener {
}
NPCLeftClickEvent leftClickEvent = new NPCLeftClickEvent(npc, damager);
Bukkit.getPluginManager().callEvent(leftClickEvent);
if (leftClickEvent.isCancelled()) {
if (leftClickEvent.isCancelled())
return;
}
if (npc.hasTrait(CommandTrait.class)) {
npc.getTraitNullable(CommandTrait.class).dispatch(damager, CommandTrait.Hand.LEFT);
}
@ -657,10 +656,6 @@ public class EventListen implements Listener {
npc.getTraitNullable(CommandTrait.class).dispatch(player, CommandTrait.Hand.RIGHT);
rightClickEvent.setDelayedCancellation(true);
}
if (npc.hasTrait(ShopTrait.class)) {
npc.getTraitNullable(ShopTrait.class).onRightClick(player);
rightClickEvent.setDelayedCancellation(true);
}
if (rightClickEvent.isDelayedCancellation()) {
event.setCancelled(true);
}

View File

@ -7,6 +7,7 @@ import org.bukkit.event.Listener;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.event.PlayerCreateNPCEvent;
import net.citizensnpcs.api.trait.TraitEventHandler;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.util.Messages;
import net.milkbowl.vault.economy.Economy;
@ -20,7 +21,7 @@ public class PaymentListener implements Listener {
this.provider = provider;
}
@EventHandler(ignoreCancelled = true)
@TraitEventHandler(@EventHandler(ignoreCancelled = true))
public void onPlayerCreateNPC(PlayerCreateNPCEvent event) {
if (!provider.hasAccount(event.getCreator()) || event.getCreator().hasPermission("citizens.npc.ignore-cost"))
return;

View File

@ -156,6 +156,7 @@ import net.citizensnpcs.trait.Poses;
import net.citizensnpcs.trait.Powered;
import net.citizensnpcs.trait.RabbitType;
import net.citizensnpcs.trait.RotationTrait;
import net.citizensnpcs.trait.ScaledMaxHealthTrait;
import net.citizensnpcs.trait.ScoreboardTrait;
import net.citizensnpcs.trait.SheepTrait;
import net.citizensnpcs.trait.ShopTrait;
@ -2207,7 +2208,7 @@ public class NPCCommands {
PaintingTrait trait = npc.getOrAddTrait(PaintingTrait.class);
if (art != null) {
trait.setArt(art);
Messaging.sendTr(sender, Messages.PAINTING_ART_SET, npc.getName(), Util.prettyEnum(art));
Messaging.sendTr(sender, Messages.PAINTING_ART_SET, npc.getName(), art);
return;
}
throw new CommandUsageException();
@ -2794,6 +2795,19 @@ public class NPCCommands {
}
}
@Command(
aliases = { "npc" },
usage = "scaledmaxhealth [health]",
desc = "",
modifiers = { "scaledmaxhealth" },
min = 1,
max = 2,
permission = "citizens.npc.scaledmaxhealth")
public void scaledhealth(CommandContext args, CommandSender sender, NPC npc, @Arg(1) Double scaled) {
npc.getOrAddTrait(ScaledMaxHealthTrait.class).setMaxHealth(scaled);
Messaging.sendTr(sender, Messages.SCALED_MAX_HEALTH_SET, scaled);
}
@Command(
aliases = { "npc" },
usage = "select|sel [id|name] (--range range) (--registry [name])",

View File

@ -10,6 +10,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.citizensnpcs.Citizens;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitFactory;
@ -54,6 +55,7 @@ import net.citizensnpcs.trait.Powered;
import net.citizensnpcs.trait.RabbitType;
import net.citizensnpcs.trait.RotationTrait;
import net.citizensnpcs.trait.Saddle;
import net.citizensnpcs.trait.ScaledMaxHealthTrait;
import net.citizensnpcs.trait.ScoreboardTrait;
import net.citizensnpcs.trait.SheepTrait;
import net.citizensnpcs.trait.ShopTrait;
@ -81,7 +83,7 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(Age.class));
registerTrait(TraitInfo.create(ArmorStandTrait.class));
registerTrait(TraitInfo.create(AttributeTrait.class));
registerTrait(TraitInfo.create(Anchors.class));
registerTrait(TraitInfo.create(Anchors.class).optInToStats());
registerTrait(TraitInfo.create(BatTrait.class));
registerTrait(TraitInfo.create(BoundingBoxTrait.class));
registerTrait(TraitInfo.create(ClickRedirectTrait.class));
@ -99,10 +101,10 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(Gravity.class));
registerTrait(TraitInfo.create(HomeTrait.class).optInToStats());
registerTrait(TraitInfo.create(HorseModifiers.class));
registerTrait(TraitInfo.create(HologramTrait.class));
registerTrait(TraitInfo.create(HologramTrait.class).optInToStats());
registerTrait(TraitInfo.create(Inventory.class));
registerTrait(TraitInfo.create(ItemFrameTrait.class));
registerTrait(TraitInfo.create(LookClose.class));
registerTrait(TraitInfo.create(LookClose.class).optInToStats());
registerTrait(TraitInfo.create(PaintingTrait.class));
registerTrait(TraitInfo.create(MirrorTrait.class).optInToStats());
registerTrait(TraitInfo.create(MountTrait.class));
@ -128,6 +130,7 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(RabbitType.class));
registerTrait(TraitInfo.create(RotationTrait.class));
registerTrait(TraitInfo.create(Saddle.class));
registerTrait(TraitInfo.create(ScaledMaxHealthTrait.class));
registerTrait(TraitInfo.create(ScoreboardTrait.class));
registerTrait(TraitInfo.create(SitTrait.class).optInToStats());
registerTrait(
@ -139,7 +142,7 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(SneakTrait.class));
registerTrait(TraitInfo.create(SlimeSize.class));
registerTrait(TraitInfo.create(Spawned.class));
registerTrait(TraitInfo.create(Text.class));
registerTrait(TraitInfo.create(Text.class).optInToStats());
registerTrait(TraitInfo.create(TargetableTrait.class));
registerTrait(TraitInfo.create(Waypoints.class).optInToStats());
registerTrait(TraitInfo.create(WitherTrait.class));
@ -204,9 +207,10 @@ public class CitizensTraitFactory implements TraitFactory {
if (info.isDefaultTrait()) {
defaultTraits.add(info);
}
info.registerListener(CitizensAPI.getPlugin());
}
public boolean trackStats(Trait trait) {
return registered.get(trait.getName()).trackStats();
return registered.get(trait.getName()).shouldTrackStats();
}
}

View File

@ -20,6 +20,7 @@ import net.citizensnpcs.api.event.NPCRightClickEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitEventHandler;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.util.NMS;
@ -98,9 +99,9 @@ public class Controllable extends Trait {
}
}
@EventHandler
@TraitEventHandler(@EventHandler)
private void onRightClick(NPCRightClickEvent event) {
if (!enabled || !npc.isSpawned() || !event.getNPC().equals(npc))
if (!enabled || !npc.isSpawned())
return;
controller.rightClickEntity(event);
event.setDelayedCancellation(true);

View File

@ -25,6 +25,7 @@ import net.citizensnpcs.api.gui.MenuContext;
import net.citizensnpcs.api.gui.PercentageSlotHandler;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitEventHandler;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.util.Util;
@ -41,11 +42,8 @@ public class DropsTrait extends Trait {
InventoryMenu.createSelfRegistered(new DropsGUI(this)).present(sender);
}
@EventHandler
@TraitEventHandler(@EventHandler)
public void onNPCDeath(NPCDeathEvent event) {
if (!event.getNPC().equals(npc))
return;
Random random = Util.getFastRandom();
for (ItemDrop drop : drops) {
if (random.nextDouble() < drop.chance) {

View File

@ -7,6 +7,7 @@ import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCRightClickEvent;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitEventHandler;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.util.NMS;
@ -39,9 +40,9 @@ public class PausePathfindingTrait extends Trait {
return playerRange;
}
@EventHandler(ignoreCancelled = true)
@TraitEventHandler(@EventHandler(ignoreCancelled = true))
public void onInteract(NPCRightClickEvent event) {
if (lockoutDuration > t || !rightclick || event.getNPC() != npc)
if (lockoutDuration > t || !rightclick)
return;
pause();
event.setDelayedCancellation(true);

View File

@ -0,0 +1,65 @@
package net.citizensnpcs.trait;
import java.math.BigDecimal;
import org.bukkit.Registry;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import net.citizensnpcs.api.event.NPCDamageEvent;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitEventHandler;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.util.SpigotUtil;
@TraitName("scaledhealthtrait")
public class ScaledMaxHealthTrait extends Trait {
@Persist
private Double maxHealth;
public ScaledMaxHealthTrait() {
super("scaledhealthtrait");
}
public Double getMaxHealth() {
return maxHealth;
}
@TraitEventHandler(@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true))
public void onDamage(NPCDamageEvent event) {
if (maxHealth == null || (npc.getEntity() instanceof LivingEntity))
return;
event.setCancelled(true);
LivingEntity entity = (LivingEntity) npc.getEntity();
entity.setHealth(new BigDecimal(entity.getHealth() - (Math.min(maxHealth, MAX_VALUE) / event.getDamage()))
.setScale(0, java.math.RoundingMode.HALF_DOWN).doubleValue());
}
@Override
public void onSpawn() {
if (maxHealth != null && npc.getEntity() instanceof LivingEntity) {
if (SUPPORTS_ATTRIBUTES) {
((LivingEntity) npc.getEntity()).getAttribute(Registry.ATTRIBUTE.get(SpigotUtil.getKey("max_health")))
.setBaseValue(Math.min(MAX_VALUE, maxHealth));
} else {
((LivingEntity) npc.getEntity()).setMaxHealth(maxHealth);
}
}
}
public void setMaxHealth(Double maxHealth) {
this.maxHealth = maxHealth;
}
private static int MAX_VALUE = 2048;
private static boolean SUPPORTS_ATTRIBUTES = true;
static {
try {
Class.forName("org.bukkit.attribute.Attribute");
} catch (ClassNotFoundException e) {
SUPPORTS_ATTRIBUTES = false;
}
}
}

View File

@ -37,6 +37,7 @@ import com.google.common.collect.Maps;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCRightClickEvent;
import net.citizensnpcs.api.gui.CitizensInventoryClickEvent;
import net.citizensnpcs.api.gui.ClickHandler;
import net.citizensnpcs.api.gui.InputMenus;
@ -53,6 +54,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.persistence.Persistable;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitEventHandler;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.api.util.DataKey;
@ -109,9 +111,12 @@ public class ShopTrait extends Trait {
shops.deleteShop(getDefaultShop());
}
public void onRightClick(Player player) {
@TraitEventHandler(@EventHandler)
public void onRightClick(NPCRightClickEvent event) {
if (rightClickShop == null || rightClickShop.isEmpty())
return;
Player player = event.getClicker();
event.setDelayedCancellation(true);
String globalViewPermission = Setting.SHOP_GLOBAL_VIEW_PERMISSION.asString();
if (!globalViewPermission.isEmpty() && !player.hasPermission(globalViewPermission))

View File

@ -31,9 +31,9 @@ public class TargetableTrait extends Trait {
}
public void clearTargeters() {
if (targeters == null) {
if (targeters == null)
return;
}
if (SUPPORTS_GET_ENTITY) {
for (UUID entityUUID : targeters) {
final Entity entity = Bukkit.getEntity(entityUUID);
@ -48,10 +48,7 @@ public class TargetableTrait extends Trait {
}
public boolean isTargetable() {
if (targetable == null) {
return !npc.isProtected();
}
return targetable;
return targetable == null ? !npc.isProtected() : targetable;
}
@Override
@ -67,7 +64,7 @@ public class TargetableTrait extends Trait {
}
public void setTargetable(boolean targetable) {
if (this.targetable == targetable)
if (Boolean.valueOf(targetable).equals(this.targetable))
return;
this.targetable = targetable;
if (!targetable) {

View File

@ -5,7 +5,6 @@ import org.bukkit.entity.Sheep;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.SheepDyeWoolEvent;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
@ -40,9 +39,7 @@ public class WoolColor extends Trait {
@EventHandler
private void onSheepDyeWool(SheepDyeWoolEvent event) {
if (npc.equals(CitizensAPI.getNPCRegistry().getNPC(event.getEntity()))) {
event.setCancelled(true);
}
event.setCancelled(true);
}
@Override

View File

@ -22,6 +22,7 @@ import net.citizensnpcs.api.ai.speech.SpeechContext;
import net.citizensnpcs.api.event.NPCRightClickEvent;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitEventHandler;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging;
@ -142,9 +143,9 @@ public class Text extends Trait implements Runnable, Listener {
range = key.getDouble("range", Setting.DEFAULT_TALK_CLOSE_RANGE.asDouble());
}
@EventHandler
@TraitEventHandler(@EventHandler)
private void onRightClick(NPCRightClickEvent event) {
if (!event.getNPC().equals(npc) || text.size() == 0)
if (text.size() == 0)
return;
String localPattern = "default".equals(itemInHandPattern) ? Setting.TALK_ITEM.asString() : itemInHandPattern;
if (Util.matchesItemInHand(event.getClicker(), localPattern) && !shouldTalkClose()) {

View File

@ -374,6 +374,7 @@ public class Messages {
public static final String REMOVED_FROM_PLAYERLIST = "citizens.commands.npc.playerlist.removed";
public static final String RESPAWN_DELAY_DESCRIBE = "citizens.commands.npc.respawn.describe";
public static final String RESPAWN_DELAY_SET = "citizens.commands.npc.respawn.delay-set";
public static final String SCALED_MAX_HEALTH_SET = "citizens.commands.npc.scaledmaxhealth.set";
public static final String SELECTION_PROMPT = "citizens.editors.selection.start-prompt";
public static final String SELECTION_PROMPT_INVALID_CHOICE = "citizens.conversations.selection.invalid-choice";
public static final String SHEARED_SET = "citizens.editors.equipment.sheared-set";

View File

@ -234,6 +234,8 @@
"citizens.commands.npc.guardian.elder-unset" : "[[{0}]] is no longer an elder guardian.",
"citizens.commands.npc.help" : "",
"citizens.commands.npc.hitbox.description" : "Sets the NPC hitbox",
"citizens.commands.npc.scaledmaxhealth.set" : "Max health set to [[{0}]].",
"citizens.commands.npc.scaledmaxhealth.description" : "Controls the max health of an NPC, can use large numbers.",
"citizens.commands.npc.hitbox.help" : "",
"citizens.commands.npc.hitbox.set" : "Hitbox set to [[{0}]].",
"citizens.commands.npc.hologram.cleared" : "Hologram lines cleared.",