SPIGOT-5784, SPIGOT-6858, #1527: Add villager reputation API
This commit is contained in:
parent
c905a715e9
commit
fa10c5029f
@ -0,0 +1,221 @@
|
|||||||
|
--- a/net/minecraft/world/entity/ai/gossip/Reputation.java
|
||||||
|
+++ b/net/minecraft/world/entity/ai/gossip/Reputation.java
|
||||||
|
@@ -30,13 +30,27 @@
|
||||||
|
import net.minecraft.util.VisibleForDebug;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
+// CraftBukkit start
|
||||||
|
+import net.minecraft.world.entity.npc.EntityVillager;
|
||||||
|
+import org.bukkit.craftbukkit.entity.CraftVillager.CraftReputationType;
|
||||||
|
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
|
+import org.bukkit.entity.Villager;
|
||||||
|
+import org.bukkit.event.entity.VillagerReputationChangeEvent;
|
||||||
|
+// CraftBukkit end
|
||||||
|
+
|
||||||
|
public class Reputation {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
|
public static final int DISCARD_THRESHOLD = 2;
|
||||||
|
private final Map<UUID, Reputation.a> gossips = Maps.newHashMap();
|
||||||
|
|
||||||
|
- public Reputation() {}
|
||||||
|
+ // CraftBukkit start - store reference to villager entity
|
||||||
|
+ private final EntityVillager villager;
|
||||||
|
+
|
||||||
|
+ public Reputation(EntityVillager villager) {
|
||||||
|
+ this.villager = villager;
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
|
||||||
|
@VisibleForDebug
|
||||||
|
public Map<UUID, Object2IntMap<ReputationType>> getGossipEntries() {
|
||||||
|
@@ -51,15 +65,17 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public void decay() {
|
||||||
|
- Iterator<Reputation.a> iterator = this.gossips.values().iterator();
|
||||||
|
+ Iterator<Map.Entry<UUID, Reputation.a>> iterator = this.gossips.entrySet().iterator(); // CraftBukkit - iterate over entries instead of values to access entity UUID
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
- Reputation.a reputation_a = (Reputation.a) iterator.next();
|
||||||
|
+ // CraftBukkit start - pass villager and entity UUID to decay method
|
||||||
|
+ Map.Entry<UUID, Reputation.a> reputation_a = iterator.next();
|
||||||
|
|
||||||
|
- reputation_a.decay();
|
||||||
|
- if (reputation_a.isEmpty()) {
|
||||||
|
+ reputation_a.getValue().decay(villager, reputation_a.getKey());
|
||||||
|
+ if (reputation_a.getValue().isEmpty()) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
+ // CraftBukkit end
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -112,16 +128,27 @@
|
||||||
|
int j = reputation_b.value - reputation_b.type.decayPerTransfer;
|
||||||
|
|
||||||
|
if (j >= 2) {
|
||||||
|
- this.getOrCreate(reputation_b.target).entries.mergeInt(reputation_b.type, j, Reputation::mergeValuesForTransfer);
|
||||||
|
+ // CraftBukkit start - redirect to a method which fires an event before setting value
|
||||||
|
+ this.set(reputation_b.target, reputation_b.type, Reputation.mergeValuesForTransfer(getReputation(reputation_b.target, Predicate.isEqual(reputation_b.type), false), j), Villager.ReputationEvent.GOSSIP);
|
||||||
|
+ //this.getOrCreate(reputation_b.target).entries.mergeInt(reputation_b.type, j, Reputation::mergeValuesForTransfer);
|
||||||
|
+ // CraftBukkit end
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getReputation(UUID uuid, Predicate<ReputationType> predicate) {
|
||||||
|
+ // CraftBukkit start - add getReputation overload with additional parameter
|
||||||
|
+ return getReputation(uuid, predicate, true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public int getReputation(UUID uuid, Predicate<ReputationType> predicate, boolean weighted) {
|
||||||
|
+ // CraftBukkit end
|
||||||
|
Reputation.a reputation_a = (Reputation.a) this.gossips.get(uuid);
|
||||||
|
|
||||||
|
- return reputation_a != null ? reputation_a.weightedValue(predicate) : 0;
|
||||||
|
+ // CraftBukkit start - handle weighted parameter
|
||||||
|
+ return reputation_a != null ? (weighted ? reputation_a.weightedValue(predicate) : reputation_a.unweightedValue(predicate)) : 0;
|
||||||
|
+ // CraftBukkit end
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCountForType(ReputationType reputationtype, DoublePredicate doublepredicate) {
|
||||||
|
@@ -131,27 +158,58 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(UUID uuid, ReputationType reputationtype, int i) {
|
||||||
|
+ // CraftBukkit start - add change reason parameter
|
||||||
|
+ add(uuid, reputationtype, i, Villager.ReputationEvent.UNSPECIFIED);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void add(UUID uuid, ReputationType reputationtype, int i, Villager.ReputationEvent changeReason) {
|
||||||
|
+ // CraftBukkit end
|
||||||
|
Reputation.a reputation_a = this.getOrCreate(uuid);
|
||||||
|
|
||||||
|
+ int oldValue = reputation_a.entries.getInt(reputationtype); // CraftBukkit - store old value
|
||||||
|
reputation_a.entries.mergeInt(reputationtype, i, (j, k) -> {
|
||||||
|
return this.mergeValuesForAddition(reputationtype, j, k);
|
||||||
|
});
|
||||||
|
- reputation_a.makeSureValueIsntTooLowOrTooHigh(reputationtype);
|
||||||
|
+ // CraftBukkit start - fire reputation change event
|
||||||
|
+ int newValue = reputation_a.entries.getInt(reputationtype);
|
||||||
|
+ newValue = Math.max(0, Math.min(newValue, reputationtype.max));
|
||||||
|
+ reputation_a.entries.replace(reputationtype, oldValue); // restore old value until the event completed processing
|
||||||
|
+ VillagerReputationChangeEvent event = CraftEventFactory.callVillagerReputationChangeEvent((Villager) villager.getBukkitEntity(), uuid, changeReason, CraftReputationType.minecraftToBukkit(reputationtype), oldValue, newValue, reputationtype.max);
|
||||||
|
+ if (!event.isCancelled()) {
|
||||||
|
+ reputation_a.entries.replace(reputationtype, event.getNewValue());
|
||||||
|
+ reputation_a.makeSureValueIsntTooLowOrTooHigh(reputationtype);
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
if (reputation_a.isEmpty()) {
|
||||||
|
this.gossips.remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- public void remove(UUID uuid, ReputationType reputationtype, int i) {
|
||||||
|
- this.add(uuid, reputationtype, -i);
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ public void set(UUID uuid, ReputationType reputationType, int i, Villager.ReputationEvent changeReason) {
|
||||||
|
+ int addAmount = i - getReputation(uuid, Predicate.isEqual(reputationType), false);
|
||||||
|
+ if (addAmount == 0) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ this.add(uuid, reputationType, addAmount, changeReason);
|
||||||
|
}
|
||||||
|
+ // CraftBukkit end
|
||||||
|
|
||||||
|
- public void remove(UUID uuid, ReputationType reputationtype) {
|
||||||
|
+ // CraftBukkit start - add change reason parameter
|
||||||
|
+ public void remove(UUID uuid, ReputationType reputationtype, int i, Villager.ReputationEvent changeReason) {
|
||||||
|
+ this.add(uuid, reputationtype, -i, changeReason);
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
+
|
||||||
|
+ public void remove(UUID uuid, ReputationType reputationtype, Villager.ReputationEvent changeReason) { // CraftBukkit - add change reason parameter
|
||||||
|
Reputation.a reputation_a = (Reputation.a) this.gossips.get(uuid);
|
||||||
|
|
||||||
|
if (reputation_a != null) {
|
||||||
|
- reputation_a.remove(reputationtype);
|
||||||
|
+ // CraftBukkit start - redirect - set to 0 instead
|
||||||
|
+ set(uuid, reputationtype, 0, changeReason);
|
||||||
|
+ //reputation_a.remove(reputationtype);
|
||||||
|
+ // CraftBukkit end
|
||||||
|
if (reputation_a.isEmpty()) {
|
||||||
|
this.gossips.remove(uuid);
|
||||||
|
}
|
||||||
|
@@ -159,7 +217,16 @@
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- public void remove(ReputationType reputationtype) {
|
||||||
|
+ public void remove(ReputationType reputationtype, Villager.ReputationEvent changeReason) { // CraftBukkit - add change reason parameter
|
||||||
|
+ // CraftBukkit start - replace the logic to call the other remove instead
|
||||||
|
+ Set<UUID> uuids = Sets.newHashSet(this.gossips.keySet());
|
||||||
|
+ for (UUID uuid : uuids) {
|
||||||
|
+ remove(uuid, reputationtype, changeReason);
|
||||||
|
+ }
|
||||||
|
+ if (true) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
Iterator<Reputation.a> iterator = this.gossips.values().iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
@@ -174,7 +241,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T store(DynamicOps<T> dynamicops) {
|
||||||
|
- Optional optional = Reputation.b.LIST_CODEC.encodeStart(dynamicops, this.unpack().toList()).resultOrPartial((s) -> {
|
||||||
|
+ Optional<T> optional = Reputation.b.LIST_CODEC.encodeStart(dynamicops, this.unpack().toList()).resultOrPartial((s) -> { // CraftBukkit - missing generic parameter after decompile
|
||||||
|
Reputation.LOGGER.warn("Failed to serialize gossips: {}", s);
|
||||||
|
});
|
||||||
|
|
||||||
|
@@ -186,7 +253,7 @@
|
||||||
|
Reputation.b.LIST_CODEC.decode(dynamic).resultOrPartial((s) -> {
|
||||||
|
Reputation.LOGGER.warn("Failed to deserialize gossips: {}", s);
|
||||||
|
}).stream().flatMap((pair) -> {
|
||||||
|
- return ((List) pair.getFirst()).stream();
|
||||||
|
+ return ((List<Reputation.b>) pair.getFirst()).stream(); // CraftBukkit - missing generic parameter after decompile
|
||||||
|
}).forEach((reputation_b) -> {
|
||||||
|
this.getOrCreate(reputation_b.target).entries.put(reputation_b.type, reputation_b.value);
|
||||||
|
});
|
||||||
|
@@ -216,18 +283,36 @@
|
||||||
|
}).sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ public int unweightedValue(Predicate<ReputationType> predicate) {
|
||||||
|
+ return this.entries.object2IntEntrySet().stream().filter((entry) -> {
|
||||||
|
+ return predicate.test((ReputationType) entry.getKey());
|
||||||
|
+ }).mapToInt((entry) -> {
|
||||||
|
+ return entry.getIntValue();
|
||||||
|
+ }).sum();
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
+
|
||||||
|
public Stream<Reputation.b> unpack(UUID uuid) {
|
||||||
|
return this.entries.object2IntEntrySet().stream().map((entry) -> {
|
||||||
|
return new Reputation.b(uuid, (ReputationType) entry.getKey(), entry.getIntValue());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- public void decay() {
|
||||||
|
+ public void decay(EntityVillager villager, UUID uuid) { // CraftBukkit - add villager and entity uuid parameters
|
||||||
|
ObjectIterator<Entry<ReputationType>> objectiterator = this.entries.object2IntEntrySet().iterator();
|
||||||
|
|
||||||
|
while (objectiterator.hasNext()) {
|
||||||
|
Entry<ReputationType> entry = (Entry) objectiterator.next();
|
||||||
|
int i = entry.getIntValue() - ((ReputationType) entry.getKey()).decayPerDay;
|
||||||
|
+ // CraftBukkit start - fire event
|
||||||
|
+ VillagerReputationChangeEvent event = CraftEventFactory.callVillagerReputationChangeEvent((Villager) villager.getBukkitEntity(), uuid, Villager.ReputationEvent.DECAY, CraftReputationType.minecraftToBukkit(entry.getKey()), entry.getIntValue(), i, entry.getKey().max);
|
||||||
|
+ if (event.isCancelled()) {
|
||||||
|
+ continue;
|
||||||
|
+ } else {
|
||||||
|
+ i = event.getNewValue();
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
|
||||||
|
if (i < 2) {
|
||||||
|
objectiterator.remove();
|
@ -0,0 +1,29 @@
|
|||||||
|
--- a/net/minecraft/world/entity/ai/village/ReputationEvent.java
|
||||||
|
+++ b/net/minecraft/world/entity/ai/village/ReputationEvent.java
|
||||||
|
@@ -2,14 +2,26 @@
|
||||||
|
|
||||||
|
public interface ReputationEvent {
|
||||||
|
|
||||||
|
+ java.util.Map<String, ReputationEvent> BY_ID = com.google.common.collect.Maps.newHashMap(); // CraftBukkit - map with all values
|
||||||
|
ReputationEvent ZOMBIE_VILLAGER_CURED = register("zombie_villager_cured");
|
||||||
|
ReputationEvent GOLEM_KILLED = register("golem_killed");
|
||||||
|
ReputationEvent VILLAGER_HURT = register("villager_hurt");
|
||||||
|
ReputationEvent VILLAGER_KILLED = register("villager_killed");
|
||||||
|
ReputationEvent TRADE = register("trade");
|
||||||
|
+ // CraftBukkit start - additional events added in the API
|
||||||
|
+ ReputationEvent GOSSIP = register("bukkit_gossip");
|
||||||
|
+ ReputationEvent DECAY = register("bukkit_decay");
|
||||||
|
+ ReputationEvent UNSPECIFIED = register("bukkit_unspecified");
|
||||||
|
+ // CraftBukkit end
|
||||||
|
|
||||||
|
static ReputationEvent register(final String s) {
|
||||||
|
return new ReputationEvent() {
|
||||||
|
+ // CraftBukkit start - add new value to map
|
||||||
|
+ {
|
||||||
|
+ BY_ID.put(s, this);
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
+
|
||||||
|
public String toString() {
|
||||||
|
return s;
|
||||||
|
}
|
@ -16,7 +16,28 @@
|
|||||||
public class EntityVillager extends EntityVillagerAbstract implements ReputationHandler, VillagerDataHolder {
|
public class EntityVillager extends EntityVillagerAbstract implements ReputationHandler, VillagerDataHolder {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogUtils.getLogger();
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
@@ -150,7 +159,7 @@
|
@@ -133,6 +142,9 @@
|
||||||
|
}, MemoryModuleType.MEETING_POINT, (entityvillager, holder) -> {
|
||||||
|
return holder.is(PoiTypes.MEETING);
|
||||||
|
});
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ public long gossipDecayInterval = GOSSIP_DECAY_INTERVAL;
|
||||||
|
+ // CraftBukkit end
|
||||||
|
|
||||||
|
public EntityVillager(EntityTypes<? extends EntityVillager> entitytypes, World world) {
|
||||||
|
this(entitytypes, world, VillagerType.PLAINS);
|
||||||
|
@@ -140,7 +152,9 @@
|
||||||
|
|
||||||
|
public EntityVillager(EntityTypes<? extends EntityVillager> entitytypes, World world, VillagerType villagertype) {
|
||||||
|
super(entitytypes, world);
|
||||||
|
- this.gossips = new Reputation();
|
||||||
|
+ // CraftBukkit start - add constructor parameter in Reputation
|
||||||
|
+ this.gossips = new Reputation(this);
|
||||||
|
+ // CraftBukkit end
|
||||||
|
((Navigation) this.getNavigation()).setCanOpenDoors(true);
|
||||||
|
this.getNavigation().setCanFloat(true);
|
||||||
|
this.getNavigation().setRequiredPathLength(48.0F);
|
||||||
|
@@ -150,7 +164,7 @@
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BehaviorController<EntityVillager> getBrain() {
|
public BehaviorController<EntityVillager> getBrain() {
|
||||||
@ -25,7 +46,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -235,7 +244,7 @@
|
@@ -235,7 +249,7 @@
|
||||||
this.increaseProfessionLevelOnUpdate = false;
|
this.increaseProfessionLevelOnUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,7 +55,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +369,13 @@
|
@@ -360,7 +374,13 @@
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next();
|
MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next();
|
||||||
|
|
||||||
@ -49,7 +70,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.resendOffersToTradingPlayer();
|
this.resendOffersToTradingPlayer();
|
||||||
@@ -429,7 +444,13 @@
|
@@ -429,7 +449,13 @@
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next();
|
MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next();
|
||||||
|
|
||||||
@ -64,7 +85,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +510,7 @@
|
@@ -489,7 +515,7 @@
|
||||||
@Override
|
@Override
|
||||||
public void addAdditionalSaveData(NBTTagCompound nbttagcompound) {
|
public void addAdditionalSaveData(NBTTagCompound nbttagcompound) {
|
||||||
super.addAdditionalSaveData(nbttagcompound);
|
super.addAdditionalSaveData(nbttagcompound);
|
||||||
@ -73,7 +94,7 @@
|
|||||||
Logger logger = EntityVillager.LOGGER;
|
Logger logger = EntityVillager.LOGGER;
|
||||||
|
|
||||||
Objects.requireNonNull(logger);
|
Objects.requireNonNull(logger);
|
||||||
@@ -512,7 +533,7 @@
|
@@ -512,7 +538,7 @@
|
||||||
public void readAdditionalSaveData(NBTTagCompound nbttagcompound) {
|
public void readAdditionalSaveData(NBTTagCompound nbttagcompound) {
|
||||||
super.readAdditionalSaveData(nbttagcompound);
|
super.readAdditionalSaveData(nbttagcompound);
|
||||||
if (nbttagcompound.contains("VillagerData", 10)) {
|
if (nbttagcompound.contains("VillagerData", 10)) {
|
||||||
@ -82,7 +103,7 @@
|
|||||||
Logger logger = EntityVillager.LOGGER;
|
Logger logger = EntityVillager.LOGGER;
|
||||||
|
|
||||||
Objects.requireNonNull(logger);
|
Objects.requireNonNull(logger);
|
||||||
@@ -808,7 +829,7 @@
|
@@ -808,7 +834,7 @@
|
||||||
entitywitch1.finalizeSpawn(worldserver, worldserver.getCurrentDifficultyAt(entitywitch1.blockPosition()), EntitySpawnReason.CONVERSION, (GroupDataEntity) null);
|
entitywitch1.finalizeSpawn(worldserver, worldserver.getCurrentDifficultyAt(entitywitch1.blockPosition()), EntitySpawnReason.CONVERSION, (GroupDataEntity) null);
|
||||||
entitywitch1.setPersistenceRequired();
|
entitywitch1.setPersistenceRequired();
|
||||||
this.releaseAllPois();
|
this.releaseAllPois();
|
||||||
@ -91,7 +112,16 @@
|
|||||||
|
|
||||||
if (entitywitch == null) {
|
if (entitywitch == null) {
|
||||||
super.thunderHit(worldserver, entitylightning);
|
super.thunderHit(worldserver, entitylightning);
|
||||||
@@ -906,7 +927,7 @@
|
@@ -891,7 +917,7 @@
|
||||||
|
|
||||||
|
if (this.lastGossipDecayTime == 0L) {
|
||||||
|
this.lastGossipDecayTime = i;
|
||||||
|
- } else if (i >= this.lastGossipDecayTime + 24000L) {
|
||||||
|
+ } else if (i >= this.lastGossipDecayTime + gossipDecayInterval) { // CraftBukkit - use variable for decay interval
|
||||||
|
this.gossips.decay();
|
||||||
|
this.lastGossipDecayTime = i;
|
||||||
|
}
|
||||||
|
@@ -906,7 +932,7 @@
|
||||||
}).limit(5L).toList();
|
}).limit(5L).toList();
|
||||||
|
|
||||||
if (list1.size() >= j) {
|
if (list1.size() >= j) {
|
||||||
@ -100,7 +130,31 @@
|
|||||||
list.forEach(SensorGolemLastSeen::golemDetected);
|
list.forEach(SensorGolemLastSeen::golemDetected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -963,7 +984,7 @@
|
@@ -919,15 +945,18 @@
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReputationEventFrom(ReputationEvent reputationevent, Entity entity) {
|
||||||
|
+ Villager.ReputationEvent bukkitReputationEvent = org.bukkit.craftbukkit.entity.CraftVillager.CraftReputationEvent.minecraftToBukkit(reputationevent); // CraftBukkit - convert event to bukkit
|
||||||
|
if (reputationevent == ReputationEvent.ZOMBIE_VILLAGER_CURED) {
|
||||||
|
- this.gossips.add(entity.getUUID(), ReputationType.MAJOR_POSITIVE, 20);
|
||||||
|
- this.gossips.add(entity.getUUID(), ReputationType.MINOR_POSITIVE, 25);
|
||||||
|
+ // CraftBukkit start - add change reason parameter
|
||||||
|
+ this.gossips.add(entity.getUUID(), ReputationType.MAJOR_POSITIVE, 20, bukkitReputationEvent);
|
||||||
|
+ this.gossips.add(entity.getUUID(), ReputationType.MINOR_POSITIVE, 25, bukkitReputationEvent);
|
||||||
|
+ // CraftBukkit end
|
||||||
|
} else if (reputationevent == ReputationEvent.TRADE) {
|
||||||
|
- this.gossips.add(entity.getUUID(), ReputationType.TRADING, 2);
|
||||||
|
+ this.gossips.add(entity.getUUID(), ReputationType.TRADING, 2, bukkitReputationEvent); // CraftBukkit - add change reason parameter
|
||||||
|
} else if (reputationevent == ReputationEvent.VILLAGER_HURT) {
|
||||||
|
- this.gossips.add(entity.getUUID(), ReputationType.MINOR_NEGATIVE, 25);
|
||||||
|
+ this.gossips.add(entity.getUUID(), ReputationType.MINOR_NEGATIVE, 25, bukkitReputationEvent); // CraftBukkit - add change reason parameter
|
||||||
|
} else if (reputationevent == ReputationEvent.VILLAGER_KILLED) {
|
||||||
|
- this.gossips.add(entity.getUUID(), ReputationType.MAJOR_NEGATIVE, 25);
|
||||||
|
+ this.gossips.add(entity.getUUID(), ReputationType.MAJOR_NEGATIVE, 25, bukkitReputationEvent); // CraftBukkit - add change reason parameter
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -963,7 +992,7 @@
|
||||||
@Override
|
@Override
|
||||||
public void startSleeping(BlockPosition blockposition) {
|
public void startSleeping(BlockPosition blockposition) {
|
||||||
super.startSleeping(blockposition);
|
super.startSleeping(blockposition);
|
||||||
@ -109,7 +163,7 @@
|
|||||||
this.brain.eraseMemory(MemoryModuleType.WALK_TARGET);
|
this.brain.eraseMemory(MemoryModuleType.WALK_TARGET);
|
||||||
this.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
|
this.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
|
||||||
}
|
}
|
||||||
@@ -971,7 +992,7 @@
|
@@ -971,7 +1000,7 @@
|
||||||
@Override
|
@Override
|
||||||
public void stopSleeping() {
|
public void stopSleeping() {
|
||||||
super.stopSleeping();
|
super.stopSleeping();
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
package org.bukkit.craftbukkit.entity;
|
package org.bukkit.craftbukkit.entity;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import net.minecraft.core.BlockPosition;
|
import net.minecraft.core.BlockPosition;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.world.entity.ai.gossip.ReputationType;
|
||||||
import net.minecraft.world.entity.monster.EntityZombie;
|
import net.minecraft.world.entity.monster.EntityZombie;
|
||||||
import net.minecraft.world.entity.monster.EntityZombieVillager;
|
import net.minecraft.world.entity.monster.EntityZombieVillager;
|
||||||
import net.minecraft.world.entity.npc.EntityVillager;
|
import net.minecraft.world.entity.npc.EntityVillager;
|
||||||
@ -128,6 +135,79 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
|
|||||||
return (entityzombievillager != null) ? (ZombieVillager) entityzombievillager.getBukkitEntity() : null;
|
return (entityzombievillager != null) ? (ZombieVillager) entityzombievillager.getBukkitEntity() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getReputation(UUID uuid, ReputationType reputationType) {
|
||||||
|
Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||||
|
Preconditions.checkArgument(reputationType != null, "Reputation type cannot be null");
|
||||||
|
return getHandle().getGossips().getReputation(uuid,
|
||||||
|
Predicate.isEqual(CraftReputationType.bukkitToMinecraft(reputationType)),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWeightedReputation(UUID uuid, ReputationType reputationType) {
|
||||||
|
Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||||
|
Preconditions.checkArgument(reputationType != null, "Reputation type cannot be null");
|
||||||
|
return getHandle().getGossips().getReputation(uuid,
|
||||||
|
Predicate.isEqual(CraftReputationType.bukkitToMinecraft(reputationType)),
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getReputation(UUID uuid) {
|
||||||
|
Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||||
|
return getHandle().getGossips().getReputation(uuid, reputationType -> true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addReputation(UUID uuid, ReputationType reputationType, int amount) {
|
||||||
|
addReputation(uuid, reputationType, amount, ReputationEvent.UNSPECIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addReputation(UUID uuid, ReputationType reputationType, int amount, ReputationEvent changeReason) {
|
||||||
|
Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||||
|
Preconditions.checkArgument(reputationType != null, "Reputation type cannot be null");
|
||||||
|
Preconditions.checkArgument(changeReason != null, "Change reason cannot be null");
|
||||||
|
getHandle().getGossips().add(uuid, CraftReputationType.bukkitToMinecraft(reputationType), amount, changeReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeReputation(UUID uuid, ReputationType reputationType, int amount) {
|
||||||
|
removeReputation(uuid, reputationType, amount, ReputationEvent.UNSPECIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeReputation(UUID uuid, ReputationType reputationType, int amount, ReputationEvent changeReason) {
|
||||||
|
Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||||
|
Preconditions.checkArgument(reputationType != null, "Reputation type cannot be null");
|
||||||
|
Preconditions.checkArgument(changeReason != null, "Change reason cannot be null");
|
||||||
|
getHandle().getGossips().remove(uuid, CraftReputationType.bukkitToMinecraft(reputationType), amount, changeReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReputation(UUID uuid, ReputationType reputationType, int amount) {
|
||||||
|
setReputation(uuid, reputationType, amount, ReputationEvent.UNSPECIFIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReputation(UUID uuid, ReputationType reputationType, int amount, ReputationEvent changeReason) {
|
||||||
|
Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||||
|
Preconditions.checkArgument(reputationType != null, "Reputation type cannot be null");
|
||||||
|
Preconditions.checkArgument(changeReason != null, "Change reason cannot be null");
|
||||||
|
getHandle().getGossips().set(uuid, CraftReputationType.bukkitToMinecraft(reputationType), amount, changeReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setGossipDecayTime(long ticks) {
|
||||||
|
getHandle().gossipDecayInterval = ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getGossipDecayTime() {
|
||||||
|
return getHandle().gossipDecayInterval;
|
||||||
|
}
|
||||||
|
|
||||||
public static class CraftType implements Type, Handleable<VillagerType> {
|
public static class CraftType implements Type, Handleable<VillagerType> {
|
||||||
private static int count = 0;
|
private static int count = 0;
|
||||||
|
|
||||||
@ -289,4 +369,78 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
|
|||||||
return getKey().hashCode();
|
return getKey().hashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class CraftReputationType implements ReputationType, Handleable<net.minecraft.world.entity.ai.gossip.ReputationType> {
|
||||||
|
|
||||||
|
public static final Map<String, CraftReputationType> BY_ID = Stream
|
||||||
|
.of(net.minecraft.world.entity.ai.gossip.ReputationType.values())
|
||||||
|
.collect(Collectors.toMap(reputationType -> reputationType.id, CraftReputationType::new));
|
||||||
|
private final net.minecraft.world.entity.ai.gossip.ReputationType handle;
|
||||||
|
|
||||||
|
public CraftReputationType(net.minecraft.world.entity.ai.gossip.ReputationType handle) {
|
||||||
|
this.handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.entity.ai.gossip.ReputationType getHandle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxValue() {
|
||||||
|
return handle.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWeight() {
|
||||||
|
return handle.weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static net.minecraft.world.entity.ai.gossip.ReputationType bukkitToMinecraft(ReputationType bukkit) {
|
||||||
|
Preconditions.checkArgument(bukkit != null);
|
||||||
|
|
||||||
|
return ((CraftReputationType) bukkit).getHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReputationType minecraftToBukkit(net.minecraft.world.entity.ai.gossip.ReputationType minecraft) {
|
||||||
|
Preconditions.checkArgument(minecraft != null);
|
||||||
|
|
||||||
|
return switch (minecraft) {
|
||||||
|
case MAJOR_NEGATIVE -> ReputationType.MAJOR_NEGATIVE;
|
||||||
|
case MINOR_NEGATIVE -> ReputationType.MINOR_NEGATIVE;
|
||||||
|
case MINOR_POSITIVE -> ReputationType.MINOR_POSITIVE;
|
||||||
|
case MAJOR_POSITIVE -> ReputationType.MAJOR_POSITIVE;
|
||||||
|
case TRADING -> ReputationType.TRADING;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CraftReputationEvent implements ReputationEvent, Handleable<net.minecraft.world.entity.ai.village.ReputationEvent> {
|
||||||
|
|
||||||
|
private static final Map<String, ReputationEvent> ALL = Maps.newHashMap();
|
||||||
|
private final net.minecraft.world.entity.ai.village.ReputationEvent handle;
|
||||||
|
|
||||||
|
public CraftReputationEvent(net.minecraft.world.entity.ai.village.ReputationEvent handle) {
|
||||||
|
this.handle = handle;
|
||||||
|
ALL.put(handle.toString(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.entity.ai.village.ReputationEvent getHandle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static net.minecraft.world.entity.ai.village.ReputationEvent bukkitToMinecraft(ReputationEvent bukkit) {
|
||||||
|
Preconditions.checkArgument(bukkit != null);
|
||||||
|
|
||||||
|
return ((CraftReputationEvent) bukkit).getHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReputationEvent minecraftToBukkit(net.minecraft.world.entity.ai.village.ReputationEvent minecraft) {
|
||||||
|
Preconditions.checkArgument(minecraft != null);
|
||||||
|
|
||||||
|
ReputationEvent bukkit = ALL.get(minecraft.toString());
|
||||||
|
return bukkit == null ? new CraftReputationEvent(minecraft) : bukkit;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import java.util.Collections;
|
|||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -220,6 +221,7 @@ import org.bukkit.event.entity.SpawnerSpawnEvent;
|
|||||||
import org.bukkit.event.entity.StriderTemperatureChangeEvent;
|
import org.bukkit.event.entity.StriderTemperatureChangeEvent;
|
||||||
import org.bukkit.event.entity.TrialSpawnerSpawnEvent;
|
import org.bukkit.event.entity.TrialSpawnerSpawnEvent;
|
||||||
import org.bukkit.event.entity.VillagerCareerChangeEvent;
|
import org.bukkit.event.entity.VillagerCareerChangeEvent;
|
||||||
|
import org.bukkit.event.entity.VillagerReputationChangeEvent;
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||||
import org.bukkit.event.inventory.InventoryOpenEvent;
|
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||||
import org.bukkit.event.inventory.PrepareAnvilEvent;
|
import org.bukkit.event.inventory.PrepareAnvilEvent;
|
||||||
@ -1928,4 +1930,11 @@ public class CraftEventFactory {
|
|||||||
|
|
||||||
Bukkit.getPluginManager().callEvent(new EntityRemoveEvent(entity.getBukkitEntity(), cause));
|
Bukkit.getPluginManager().callEvent(new EntityRemoveEvent(entity.getBukkitEntity(), cause));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static VillagerReputationChangeEvent callVillagerReputationChangeEvent(Villager villager, UUID targetUuid, Villager.ReputationEvent reason, Villager.ReputationType reputationType, int oldValue, int newValue, int maxValue) {
|
||||||
|
VillagerReputationChangeEvent event = new VillagerReputationChangeEvent(villager, targetUuid, reason, reputationType, oldValue, newValue, maxValue);
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import java.io.IOException;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
@ -32,6 +33,7 @@ import net.minecraft.server.MinecraftServer;
|
|||||||
import net.minecraft.util.datafix.DataConverterRegistry;
|
import net.minecraft.util.datafix.DataConverterRegistry;
|
||||||
import net.minecraft.util.datafix.fixes.DataConverterTypes;
|
import net.minecraft.util.datafix.fixes.DataConverterTypes;
|
||||||
import net.minecraft.world.entity.EntityTypes;
|
import net.minecraft.world.entity.EntityTypes;
|
||||||
|
import net.minecraft.world.entity.ai.village.ReputationEvent;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.alchemy.PotionRegistry;
|
import net.minecraft.world.item.alchemy.PotionRegistry;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
@ -56,6 +58,7 @@ import org.bukkit.craftbukkit.block.CraftBiome;
|
|||||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.damage.CraftDamageEffect;
|
import org.bukkit.craftbukkit.damage.CraftDamageEffect;
|
||||||
import org.bukkit.craftbukkit.damage.CraftDamageSourceBuilder;
|
import org.bukkit.craftbukkit.damage.CraftDamageSourceBuilder;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftVillager;
|
||||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.craftbukkit.legacy.CraftLegacy;
|
import org.bukkit.craftbukkit.legacy.CraftLegacy;
|
||||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||||
@ -65,6 +68,7 @@ import org.bukkit.damage.DamageSource;
|
|||||||
import org.bukkit.damage.DamageType;
|
import org.bukkit.damage.DamageType;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Villager;
|
||||||
import org.bukkit.inventory.CreativeCategory;
|
import org.bukkit.inventory.CreativeCategory;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@ -422,6 +426,18 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
|||||||
return customBiome;
|
return customBiome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Villager.ReputationType createReputationType(String key) {
|
||||||
|
return Optional.ofNullable(CraftVillager.CraftReputationType.BY_ID.get(key))
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Invalid ReputationType key: " + key));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Villager.ReputationEvent createReputationEvent(String key) {
|
||||||
|
return Optional.ofNullable(ReputationEvent.BY_ID.get(key)).map(CraftVillager.CraftReputationEvent::new)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Invalid ReputationEvent key: " + key));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This helper class represents the different NBT Tags.
|
* This helper class represents the different NBT Tags.
|
||||||
* <p>
|
* <p>
|
||||||
|
52
src/test/java/org/bukkit/entity/ReputationEventTest.java
Normal file
52
src/test/java/org/bukkit/entity/ReputationEventTest.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package org.bukkit.entity;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import net.minecraft.world.entity.ai.village.ReputationEvent;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftVillager;
|
||||||
|
import org.bukkit.support.environment.Normal;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@Normal
|
||||||
|
public class ReputationEventTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toBukkit() throws IllegalAccessException {
|
||||||
|
List<ReputationEvent> reputationEvents = getConstants(ReputationEvent.class);
|
||||||
|
List<Villager.ReputationEvent> bukkitReputationEvents = getConstants(Villager.ReputationEvent.class);
|
||||||
|
for (ReputationEvent reputationEvent : reputationEvents) {
|
||||||
|
Villager.ReputationEvent bukkit = CraftVillager.CraftReputationEvent.minecraftToBukkit(reputationEvent);
|
||||||
|
assertNotNull(bukkit, "Reputation event " + reputationEvent.toString() + " should have a Bukkit equivalent");
|
||||||
|
assertTrue(bukkitReputationEvents.contains(bukkit), "Reputation event " + reputationEvent.toString() + " should have a Bukkit equivalent");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toMinecraft() throws IllegalAccessException {
|
||||||
|
List<ReputationEvent> reputationEvents = getConstants(ReputationEvent.class);
|
||||||
|
List<Villager.ReputationEvent> bukkitReputationEvents = getConstants(Villager.ReputationEvent.class);
|
||||||
|
for (Villager.ReputationEvent reputationEvent : bukkitReputationEvents) {
|
||||||
|
ReputationEvent minecraft = CraftVillager.CraftReputationEvent.bukkitToMinecraft(reputationEvent);
|
||||||
|
assertNotNull(minecraft, "Reputation event " + reputationEvent.toString() + " should have a Minecraft equivalent");
|
||||||
|
assertTrue(reputationEvents.contains(minecraft), "Reputation event " + reputationEvent + " should have a Minecraft equivalent");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isPublicStaticFinal(Field field) {
|
||||||
|
return Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers()) && Modifier.isFinal(field.getModifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> List<T> getConstants(Class<T> clazz) throws IllegalAccessException {
|
||||||
|
List<T> list = new ArrayList<>();
|
||||||
|
for (Field field : clazz.getFields()) {
|
||||||
|
if (isPublicStaticFinal(field) && clazz.isAssignableFrom(field.getType())) {
|
||||||
|
list.add((T) field.get(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
43
src/test/java/org/bukkit/entity/ReputationTypeTest.java
Normal file
43
src/test/java/org/bukkit/entity/ReputationTypeTest.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package org.bukkit.entity;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import net.minecraft.world.entity.ai.gossip.ReputationType;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftVillager;
|
||||||
|
import org.bukkit.support.environment.Normal;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@Normal
|
||||||
|
public class ReputationTypeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toBukkit() {
|
||||||
|
for (ReputationType reputationType : ReputationType.values()) {
|
||||||
|
assertNotNull(CraftVillager.CraftReputationType.minecraftToBukkit(reputationType), "ReputationType." + reputationType.name() + ".toBukkit() should not be null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromBukkit() throws IllegalAccessException {
|
||||||
|
for (Villager.ReputationType reputationType : getConstants(Villager.ReputationType.class)) {
|
||||||
|
assertNotNull(CraftVillager.CraftReputationType.bukkitToMinecraft(reputationType), "ReputationType.fromBukkit(Villager.ReputationType) should not be null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isPublicStaticFinal(Field field) {
|
||||||
|
return Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers()) && Modifier.isFinal(field.getModifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> List<T> getConstants(Class<T> clazz) throws IllegalAccessException {
|
||||||
|
List<T> list = new ArrayList<>();
|
||||||
|
for (Field field : clazz.getFields()) {
|
||||||
|
if (isPublicStaticFinal(field) && clazz.isAssignableFrom(field.getType())) {
|
||||||
|
list.add((T) field.get(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
107
src/test/java/org/bukkit/entity/VillagerTest.java
Normal file
107
src/test/java/org/bukkit/entity/VillagerTest.java
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package org.bukkit.entity;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
import java.util.UUID;
|
||||||
|
import net.minecraft.server.level.WorldServer;
|
||||||
|
import net.minecraft.world.entity.ai.gossip.Reputation;
|
||||||
|
import net.minecraft.world.entity.ai.gossip.ReputationType;
|
||||||
|
import net.minecraft.world.entity.npc.EntityVillager;
|
||||||
|
import net.minecraft.world.flag.FeatureFlags;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftEntityTypes;
|
||||||
|
import org.bukkit.support.environment.AllFeatures;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@AllFeatures
|
||||||
|
public class VillagerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getReputation() {
|
||||||
|
Villager villager = createVillager();
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, 20);
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, 10);
|
||||||
|
assertEquals(20, villager.getReputation(uuid, Villager.ReputationType.MINOR_POSITIVE), "getReputation should return correct value for a single reputation type");
|
||||||
|
assertEquals(10, villager.getReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE), "getReputation should return correct value for a single reputation type");
|
||||||
|
assertEquals(10, villager.getReputation(uuid), "getReputation should return correct value for total weighted reputation");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getWeightedReputation() {
|
||||||
|
Villager villager = createVillager();
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, 20);
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, 10);
|
||||||
|
assertEquals(20, villager.getWeightedReputation(uuid, Villager.ReputationType.MINOR_POSITIVE), "getWeightedReputation should return correct value for a single reputation type");
|
||||||
|
assertEquals(-10, villager.getWeightedReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE), "getWeightedReputation should return correct value for a single reputation type");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addReputation() {
|
||||||
|
Villager villager = createVillager();
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, 20);
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, 10);
|
||||||
|
villager.addReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, 3);
|
||||||
|
villager.addReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, 20);
|
||||||
|
assertEquals(23, villager.getReputation(uuid, Villager.ReputationType.MINOR_POSITIVE), "addReputation should increase value by given amount");
|
||||||
|
assertEquals(30, villager.getReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE), "addReputation should increase value by given amount");
|
||||||
|
|
||||||
|
villager.addReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, ReputationType.MINOR_POSITIVE.max);
|
||||||
|
villager.addReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, ReputationType.MINOR_NEGATIVE.max);
|
||||||
|
assertEquals(ReputationType.MINOR_POSITIVE.max, villager.getReputation(uuid, Villager.ReputationType.MINOR_POSITIVE), "addReputation should not exceed maximum value");
|
||||||
|
assertEquals(ReputationType.MINOR_NEGATIVE.max, villager.getReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE), "addReputation should not exceed maximum value");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void removeReputation() {
|
||||||
|
Villager villager = createVillager();
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, 20);
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, 10);
|
||||||
|
villager.removeReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, 5);
|
||||||
|
villager.removeReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, 2);
|
||||||
|
assertEquals(15, villager.getReputation(uuid, Villager.ReputationType.MINOR_POSITIVE), "removeReputation should decrease value by given amount");
|
||||||
|
assertEquals(8, villager.getReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE), "removeReputation should decrease value by given amount");
|
||||||
|
|
||||||
|
villager.removeReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, 15 - Reputation.DISCARD_THRESHOLD + 1);
|
||||||
|
villager.removeReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, Integer.MAX_VALUE);
|
||||||
|
assertEquals(0, villager.getReputation(uuid, Villager.ReputationType.MINOR_POSITIVE), "removeReputation should cause reputation removal if value drops below discard threshold");
|
||||||
|
assertEquals(0, villager.getReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE), "removeReputation should cause reputation removal if value drops below discard threshold");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setReputation() {
|
||||||
|
Villager villager = createVillager();
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, 20);
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, 10);
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, 5);
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, 2);
|
||||||
|
assertEquals(5, villager.getReputation(uuid, Villager.ReputationType.MINOR_POSITIVE), "setReputation should set value to given amount");
|
||||||
|
assertEquals(2, villager.getReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE), "setReputation should set value to given amount");
|
||||||
|
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, Reputation.DISCARD_THRESHOLD - 1);
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, Integer.MIN_VALUE);
|
||||||
|
assertEquals(0, villager.getReputation(uuid, Villager.ReputationType.MINOR_POSITIVE), "setReputation should cause reputation removal if value drops below discard threshold");
|
||||||
|
assertEquals(0, villager.getReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE), "setReputation should cause reputation removal if value drops below discard threshold");
|
||||||
|
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_POSITIVE, ReputationType.MINOR_POSITIVE.max + 1);
|
||||||
|
villager.setReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE, Integer.MAX_VALUE);
|
||||||
|
assertEquals(ReputationType.MINOR_POSITIVE.max, villager.getReputation(uuid, Villager.ReputationType.MINOR_POSITIVE), "setReputation should be clamped to reputation type maximum value");
|
||||||
|
assertEquals(ReputationType.MINOR_NEGATIVE.max, villager.getReputation(uuid, Villager.ReputationType.MINOR_NEGATIVE), "setReputation should be clamped to reputation type maximum value");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Villager createVillager() {
|
||||||
|
World world = mock(withSettings().stubOnly());
|
||||||
|
WorldServer worldServer = mock(withSettings().stubOnly());
|
||||||
|
when(worldServer.getMinecraftWorld()).thenReturn(worldServer);
|
||||||
|
when(worldServer.enabledFeatures()).thenReturn(FeatureFlags.VANILLA_SET);
|
||||||
|
Location location = new Location(world, 0, 0, 0, 0, 0);
|
||||||
|
CraftEntityTypes.SpawnData spawnData = new CraftEntityTypes.SpawnData(worldServer, location, false, false);
|
||||||
|
EntityVillager entityVillager = (EntityVillager) CraftEntityTypes.getEntityTypeData(EntityType.VILLAGER).spawnFunction().apply(spawnData);
|
||||||
|
return (Villager) entityVillager.getBukkitEntity();
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import org.bukkit.Keyed;
|
|||||||
import org.bukkit.Registry;
|
import org.bukkit.Registry;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.craftbukkit.CraftRegistry;
|
import org.bukkit.craftbukkit.CraftRegistry;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.support.DummyServerHelper;
|
import org.bukkit.support.DummyServerHelper;
|
||||||
import org.bukkit.support.RegistryHelper;
|
import org.bukkit.support.RegistryHelper;
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
@ -56,6 +57,9 @@ public class AllFeaturesExtension extends BaseExtension {
|
|||||||
return spy;
|
return spy;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PluginManager pluginManager = mock(withSettings().stubOnly());
|
||||||
|
when(server.getPluginManager()).thenReturn(pluginManager);
|
||||||
|
|
||||||
CraftRegistry.setMinecraftRegistry(RegistryHelper.getRegistry());
|
CraftRegistry.setMinecraftRegistry(RegistryHelper.getRegistry());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user