mirror of
https://github.com/Dreeam-qwq/Gale.git
synced 2025-12-19 14:59:29 +00:00
327 lines
19 KiB
Diff
327 lines
19 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Martijn Muijsers <martijnmuijsers@live.nl>
|
|
Date: Sun, 25 Dec 2022 11:20:37 +0100
|
|
Subject: [PATCH] Optimize villager data storage
|
|
|
|
License: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
|
Gale - https://galemc.org
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/Container.java b/src/main/java/net/minecraft/world/Container.java
|
|
index 0d22bce549c46d686ab3402a1cad87307d0e1c00..35d7737b195b3207e45a670636aed977d5d6c4a6 100644
|
|
--- a/src/main/java/net/minecraft/world/Container.java
|
|
+++ b/src/main/java/net/minecraft/world/Container.java
|
|
@@ -126,6 +126,20 @@ public interface Container extends Clearable {
|
|
});
|
|
}
|
|
|
|
+ // Gale start - optimize villager data storage
|
|
+ default boolean hasAnyOf(Item[] items) {
|
|
+ for (int i = 0; i < this.getContainerSize(); ++i) {
|
|
+ ItemStack itemstack = this.getItem(i);
|
|
+ for (Item item : items) {
|
|
+ if (itemstack.is(item)) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+ // Gale end - optimize villager data storage
|
|
+
|
|
default boolean hasAnyMatching(Predicate<ItemStack> predicate) {
|
|
for (int i = 0; i < this.getContainerSize(); ++i) {
|
|
ItemStack itemstack = this.getItem(i);
|
|
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
|
|
index 3af715e2f3f3949af614a8fcebbc4a835d48ca49..94fb9bcf601832ee934331c0376de8707b5043c5 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/TradeWithVillager.java
|
|
@@ -1,9 +1,8 @@
|
|
package net.minecraft.world.entity.ai.behavior;
|
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
-import com.google.common.collect.ImmutableSet;
|
|
-import java.util.Set;
|
|
-import java.util.stream.Collectors;
|
|
+
|
|
+import java.util.Arrays;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.world.SimpleContainer;
|
|
import net.minecraft.world.entity.EntityType;
|
|
@@ -15,11 +14,16 @@ import net.minecraft.world.entity.npc.VillagerProfession;
|
|
import net.minecraft.world.item.Item;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.Items;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
|
|
public class TradeWithVillager extends Behavior<Villager> {
|
|
private static final int INTERACT_DIST_SQR = 5;
|
|
private static final float SPEED_MODIFIER = 0.5F;
|
|
- private Set<Item> trades = ImmutableSet.of();
|
|
+ // Gale start - optimize villager data storage
|
|
+ private static final Item[] WHEAT_SINGLETON_ARRAY = {Items.WHEAT};
|
|
+ private @NotNull Item @Nullable [] trades = null;
|
|
+ // Gale end - optimize villager data storage
|
|
|
|
public TradeWithVillager() {
|
|
super(ImmutableMap.of(MemoryModuleType.INTERACTION_TARGET, MemoryStatus.VALUE_PRESENT, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryStatus.VALUE_PRESENT));
|
|
@@ -49,15 +53,17 @@ public class TradeWithVillager extends Behavior<Villager> {
|
|
BehaviorUtils.lockGazeAndWalkToEachOther(entity, villager, 0.5F);
|
|
entity.gossip(world, villager, time);
|
|
if (entity.hasExcessFood() && (entity.getVillagerData().getProfession() == VillagerProfession.FARMER || villager.wantsMoreFood())) {
|
|
- throwHalfStack(entity, Villager.FOOD_POINTS.keySet(), villager);
|
|
+ throwHalfStack(entity, Villager.FOOD_POINTS_KEY_ARRAY, villager); // Gale - optimize villager data storage
|
|
}
|
|
|
|
if (villager.getVillagerData().getProfession() == VillagerProfession.FARMER && entity.getInventory().countItem(Items.WHEAT) > Items.WHEAT.getMaxStackSize() / 2) {
|
|
- throwHalfStack(entity, ImmutableSet.of(Items.WHEAT), villager);
|
|
+ throwHalfStack(entity, WHEAT_SINGLETON_ARRAY, villager); // Gale - optimize villager data storage
|
|
}
|
|
|
|
- if (!this.trades.isEmpty() && entity.getInventory().hasAnyOf(this.trades)) {
|
|
+ // Gale start - optimize villager data storage
|
|
+ if (this.trades != null && entity.getInventory().hasAnyOf(this.trades)) {
|
|
throwHalfStack(entity, this.trades, villager);
|
|
+ // Gale end - optimize villager data storage
|
|
}
|
|
|
|
}
|
|
@@ -68,15 +74,35 @@ public class TradeWithVillager extends Behavior<Villager> {
|
|
villager.getBrain().eraseMemory(MemoryModuleType.INTERACTION_TARGET);
|
|
}
|
|
|
|
- private static Set<Item> figureOutWhatIAmWillingToTrade(Villager entity, Villager target) {
|
|
- ImmutableSet<Item> immutableSet = target.getVillagerData().getProfession().requestedItems();
|
|
- ImmutableSet<Item> immutableSet2 = entity.getVillagerData().getProfession().requestedItems();
|
|
- return immutableSet.stream().filter((item) -> {
|
|
- return !immutableSet2.contains(item);
|
|
- }).collect(Collectors.toSet());
|
|
+ // Gale start - optimize villager data storage
|
|
+ private static @NotNull Item @Nullable [] figureOutWhatIAmWillingToTrade(Villager entity, Villager target) {
|
|
+ @NotNull Item @Nullable [] immutableSet = target.getVillagerData().getProfession().requestedItems();
|
|
+ if (immutableSet == null) {
|
|
+ return null;
|
|
+ }
|
|
+ @NotNull Item @Nullable [] immutableSet2 = entity.getVillagerData().getProfession().requestedItems();
|
|
+ if (immutableSet2 == null) {
|
|
+ return immutableSet;
|
|
+ }
|
|
+ if (immutableSet == immutableSet2) {
|
|
+ return null;
|
|
+ }
|
|
+ Item[] willingToTrade = new Item[immutableSet.length];
|
|
+ int willingToTradeSize = 0;
|
|
+ forImmutableSet: for (Item item : immutableSet) {
|
|
+ for (Item item2 : immutableSet2) {
|
|
+ if (item == item2) {
|
|
+ continue forImmutableSet;
|
|
+ }
|
|
+ }
|
|
+ willingToTrade[willingToTradeSize] = item;
|
|
+ willingToTradeSize++;
|
|
+ }
|
|
+ return Arrays.copyOf(willingToTrade, willingToTradeSize);
|
|
+ // Gale end - optimize villager data storage
|
|
}
|
|
|
|
- private static void throwHalfStack(Villager villager, Set<Item> validItems, LivingEntity target) {
|
|
+ private static void throwHalfStack(Villager villager, @NotNull Item @NotNull [] validItems, LivingEntity target) { // Gale - optimize villager data storage
|
|
SimpleContainer simpleContainer = villager.getInventory();
|
|
ItemStack itemStack = ItemStack.EMPTY;
|
|
int i = 0;
|
|
@@ -89,7 +115,16 @@ public class TradeWithVillager extends Behavior<Villager> {
|
|
itemStack2 = simpleContainer.getItem(i);
|
|
if (!itemStack2.isEmpty()) {
|
|
item = itemStack2.getItem();
|
|
- if (validItems.contains(item)) {
|
|
+ // Gale start - optimize villager data storage
|
|
+ boolean inValidItems = false;
|
|
+ for (Item validItem : validItems) {
|
|
+ if (validItem == item) {
|
|
+ inValidItems = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (inValidItems) {
|
|
+ // Gale end - optimize villager data storage
|
|
if (itemStack2.getCount() > itemStack2.getMaxStackSize() / 2) {
|
|
j = itemStack2.getCount() / 2;
|
|
break label28;
|
|
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
|
|
index 75dc06a3041bfdfb08c914eb50cfa282ae9eb2fe..53b0519bbc5d52490040eaf0fe449648f021d0c2 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java
|
|
@@ -2,7 +2,8 @@ package net.minecraft.world.entity.ai.sensing;
|
|
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.common.collect.Lists;
|
|
-import java.util.List;
|
|
+
|
|
+import java.util.ArrayList;
|
|
import java.util.Set;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.GlobalPos;
|
|
@@ -12,6 +13,7 @@ import net.minecraft.world.entity.ai.Brain;
|
|
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
|
|
import net.minecraft.world.entity.npc.Villager;
|
|
import net.minecraft.world.level.Level;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
|
|
public class SecondaryPoiSensor extends Sensor<Villager> {
|
|
private static final int SCAN_RATE = 40;
|
|
@@ -24,21 +26,26 @@ public class SecondaryPoiSensor extends Sensor<Villager> {
|
|
protected void doTick(ServerLevel world, Villager entity) {
|
|
// Gale start - Lithium - skip secondary POI sensor if absent
|
|
var secondaryPoi = entity.getVillagerData().getProfession().secondaryPoi();
|
|
- if (secondaryPoi.isEmpty()) {
|
|
+ if (secondaryPoi == null) { // Gale - optimize villager data storage
|
|
entity.getBrain().eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE);
|
|
return;
|
|
}
|
|
// Gale end - Lithium - skip secondary POI sensor if absent
|
|
ResourceKey<Level> resourceKey = world.dimension();
|
|
BlockPos blockPos = entity.blockPosition();
|
|
- List<GlobalPos> list = Lists.newArrayList();
|
|
+ @Nullable ArrayList<GlobalPos> list = null; // Gale - optimize villager data storage
|
|
int i = 4;
|
|
|
|
for(int j = -4; j <= 4; ++j) {
|
|
for(int k = -2; k <= 2; ++k) {
|
|
for(int l = -4; l <= 4; ++l) {
|
|
BlockPos blockPos2 = blockPos.offset(j, k, l);
|
|
- if (entity.getVillagerData().getProfession().secondaryPoi().contains(world.getBlockState(blockPos2).getBlock())) {
|
|
+ // Gale start - optimize villager data storage
|
|
+ if (secondaryPoi == world.getBlockState(blockPos2).getBlock()) {
|
|
+ if (list == null) {
|
|
+ list = Lists.newArrayList();
|
|
+ }
|
|
+ // Gale end - optimize villager data storage
|
|
list.add(GlobalPos.of(resourceKey, blockPos2));
|
|
}
|
|
}
|
|
@@ -46,7 +53,10 @@ public class SecondaryPoiSensor extends Sensor<Villager> {
|
|
}
|
|
|
|
Brain<?> brain = entity.getBrain();
|
|
- if (!list.isEmpty()) {
|
|
+ // Gale start - optimize villager data storage
|
|
+ if (list != null) {
|
|
+ list.trimToSize();
|
|
+ // Gale end - optimize villager data storage
|
|
brain.setMemory(MemoryModuleType.SECONDARY_JOB_SITE, list);
|
|
} else {
|
|
brain.eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE);
|
|
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
|
index 10749bebb1c94ec1a74bacdce3b9b7903d8c4322..ae3628efe7628427c53bb7d0f7fc6e457a511b94 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
|
@@ -89,6 +89,7 @@ import net.minecraft.world.item.trading.MerchantOffers;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.ServerLevelAccessor;
|
|
import net.minecraft.world.phys.AABB;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
import org.slf4j.Logger;
|
|
|
|
// CraftBukkit start
|
|
@@ -104,8 +105,9 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
|
private static final EntityDataAccessor<VillagerData> DATA_VILLAGER_DATA = SynchedEntityData.defineId(Villager.class, EntityDataSerializers.VILLAGER_DATA);
|
|
public static final int BREEDING_FOOD_THRESHOLD = 12;
|
|
public static final Map<Item, Integer> FOOD_POINTS = ImmutableMap.of(Items.BREAD, 4, Items.POTATO, 1, Items.CARROT, 1, Items.BEETROOT, 1);
|
|
+ public static final Item[] FOOD_POINTS_KEY_ARRAY = FOOD_POINTS.keySet().toArray(Item[]::new); // Gale - optimize villager data storage
|
|
private static final int TRADES_PER_LEVEL = 2;
|
|
- private static final Set<Item> WANTED_ITEMS = ImmutableSet.of(Items.BREAD, Items.POTATO, Items.CARROT, Items.WHEAT, Items.WHEAT_SEEDS, Items.BEETROOT, new Item[]{Items.BEETROOT_SEEDS, Items.TORCHFLOWER_SEEDS, Items.PITCHER_POD});
|
|
+ private static final Item[] WANTED_ITEMS = {Items.BREAD, Items.POTATO, Items.CARROT, Items.WHEAT, Items.WHEAT_SEEDS, Items.BEETROOT, Items.BEETROOT_SEEDS, Items.TORCHFLOWER_SEEDS, Items.PITCHER_POD}; // Gale - optimize villager data storage
|
|
private static final int MAX_GOSSIP_TOPICS = 10;
|
|
private static final int GOSSIP_COOLDOWN = 1200;
|
|
private static final int GOSSIP_DECAY_INTERVAL = 24000;
|
|
@@ -914,7 +916,28 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
|
public boolean wantsToPickUp(ItemStack stack) {
|
|
Item item = stack.getItem();
|
|
|
|
- return (Villager.WANTED_ITEMS.contains(item) || this.getVillagerData().getProfession().requestedItems().contains(item)) && this.getInventory().canAddItem(stack);
|
|
+ // Gale start - optimize villager data storage
|
|
+ boolean isDesired = false;
|
|
+ for (Item wantedItem : WANTED_ITEMS) {
|
|
+ if (wantedItem == item) {
|
|
+ isDesired = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (!isDesired) {
|
|
+ var requestedItems = this.getVillagerData().getProfession().requestedItems();
|
|
+ if (requestedItems == null) {
|
|
+ return false;
|
|
+ }
|
|
+ for (Item requestedItem : requestedItems) {
|
|
+ if (requestedItem == item) {
|
|
+ isDesired = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return isDesired && this.getInventory().canAddItem(stack);
|
|
+ // Gale end - optimize villager data storage
|
|
}
|
|
|
|
public boolean hasExcessFood() {
|
|
diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java
|
|
index ac70c2c03241e73943bd517a8c69dd05e0873634..95197b601d93c30a7645d67c89c7608fc00a8de6 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/npc/VillagerProfession.java
|
|
@@ -1,8 +1,6 @@
|
|
package net.minecraft.world.entity.npc;
|
|
|
|
-import com.google.common.collect.ImmutableSet;
|
|
import java.util.function.Predicate;
|
|
-import javax.annotation.Nullable;
|
|
import net.minecraft.core.Holder;
|
|
import net.minecraft.core.Registry;
|
|
import net.minecraft.core.registries.BuiltInRegistries;
|
|
@@ -17,8 +15,10 @@ import net.minecraft.world.item.Item;
|
|
import net.minecraft.world.item.Items;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.Blocks;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
|
|
-public record VillagerProfession(String name, Predicate<Holder<PoiType>> heldJobSite, Predicate<Holder<PoiType>> acquirableJobSite, ImmutableSet<Item> requestedItems, ImmutableSet<Block> secondaryPoi, @Nullable SoundEvent workSound) {
|
|
+public record VillagerProfession(String name, Predicate<Holder<PoiType>> heldJobSite, Predicate<Holder<PoiType>> acquirableJobSite, @NotNull Item @Nullable [] requestedItems, @Nullable Block secondaryPoi, @Nullable SoundEvent workSound) { // Gale - optimize villager data storage
|
|
public static final Predicate<Holder<PoiType>> ALL_ACQUIRABLE_JOBS = (poiType) -> {
|
|
return poiType.is(PoiTypeTags.ACQUIRABLE_JOB_SITE);
|
|
};
|
|
@@ -27,7 +27,7 @@ public record VillagerProfession(String name, Predicate<Holder<PoiType>> heldJob
|
|
public static final VillagerProfession BUTCHER = register("butcher", PoiTypes.BUTCHER, SoundEvents.VILLAGER_WORK_BUTCHER);
|
|
public static final VillagerProfession CARTOGRAPHER = register("cartographer", PoiTypes.CARTOGRAPHER, SoundEvents.VILLAGER_WORK_CARTOGRAPHER);
|
|
public static final VillagerProfession CLERIC = register("cleric", PoiTypes.CLERIC, SoundEvents.VILLAGER_WORK_CLERIC);
|
|
- public static final VillagerProfession FARMER = register("farmer", PoiTypes.FARMER, ImmutableSet.of(Items.WHEAT, Items.WHEAT_SEEDS, Items.BEETROOT_SEEDS, Items.BONE_MEAL), ImmutableSet.of(Blocks.FARMLAND), SoundEvents.VILLAGER_WORK_FARMER);
|
|
+ public static final VillagerProfession FARMER = register("farmer", PoiTypes.FARMER, new Item[] {Items.WHEAT, Items.WHEAT_SEEDS, Items.BEETROOT_SEEDS, Items.BONE_MEAL}, Blocks.FARMLAND, SoundEvents.VILLAGER_WORK_FARMER); // Gale - optimize villager data storage
|
|
public static final VillagerProfession FISHERMAN = register("fisherman", PoiTypes.FISHERMAN, SoundEvents.VILLAGER_WORK_FISHERMAN);
|
|
public static final VillagerProfession FLETCHER = register("fletcher", PoiTypes.FLETCHER, SoundEvents.VILLAGER_WORK_FLETCHER);
|
|
public static final VillagerProfession LEATHERWORKER = register("leatherworker", PoiTypes.LEATHERWORKER, SoundEvents.VILLAGER_WORK_LEATHERWORKER);
|
|
@@ -52,18 +52,20 @@ public record VillagerProfession(String name, Predicate<Holder<PoiType>> heldJob
|
|
}
|
|
|
|
private static VillagerProfession register(String id, Predicate<Holder<PoiType>> heldWorkstation, Predicate<Holder<PoiType>> acquirableWorkstation, @Nullable SoundEvent workSound) {
|
|
- return register(id, heldWorkstation, acquirableWorkstation, ImmutableSet.of(), ImmutableSet.of(), workSound);
|
|
+ return register(id, heldWorkstation, acquirableWorkstation, null, null, workSound); // Gale - optimize villager data storage
|
|
}
|
|
|
|
- private static VillagerProfession register(String id, ResourceKey<PoiType> heldWorkstation, ImmutableSet<Item> gatherableItems, ImmutableSet<Block> secondaryJobSites, @Nullable SoundEvent workSound) {
|
|
+ private static VillagerProfession register(String id, ResourceKey<PoiType> heldWorkstation, @NotNull Item @Nullable [] gatherableItems, @Nullable Block secondaryJobSite, @Nullable SoundEvent workSound) { // Gale - optimize villager data storage
|
|
return register(id, (entry) -> {
|
|
return entry.is(heldWorkstation);
|
|
}, (entry) -> {
|
|
return entry.is(heldWorkstation);
|
|
- }, gatherableItems, secondaryJobSites, workSound);
|
|
+ }, gatherableItems, secondaryJobSite, workSound); // Gale - optimize villager data storage
|
|
}
|
|
|
|
- private static VillagerProfession register(String id, Predicate<Holder<PoiType>> heldWorkstation, Predicate<Holder<PoiType>> acquirableWorkstation, ImmutableSet<Item> gatherableItems, ImmutableSet<Block> secondaryJobSites, @Nullable SoundEvent workSound) {
|
|
- return Registry.register(BuiltInRegistries.VILLAGER_PROFESSION, new ResourceLocation(id), new VillagerProfession(id, heldWorkstation, acquirableWorkstation, gatherableItems, secondaryJobSites, workSound));
|
|
+ // Gale start - optimize villager data storage
|
|
+ private static VillagerProfession register(String id, Predicate<Holder<PoiType>> heldWorkstation, Predicate<Holder<PoiType>> acquirableWorkstation, @NotNull Item @Nullable [] gatherableItems, @Nullable Block secondaryJobSite, @Nullable SoundEvent workSound) {
|
|
+ return Registry.register(BuiltInRegistries.VILLAGER_PROFESSION, new ResourceLocation(id), new VillagerProfession(id, heldWorkstation, acquirableWorkstation, gatherableItems != null && gatherableItems.length == 0 ? null : gatherableItems, secondaryJobSite, workSound));
|
|
+ // Gale end - optimize villager data storage
|
|
}
|
|
}
|