9
0
mirror of https://github.com/Dreeam-qwq/Gale.git synced 2025-12-21 07:49:22 +00:00
Files
Gale/patches/server/0083-Optimize-villager-data-storage.patch

351 lines
18 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 5db5ba026462ca642dcee718af732f80fadabef5..cd380ceb40d38acc7eef289ded11259388becabd 100644
--- a/src/main/java/net/minecraft/world/Container.java
+++ b/src/main/java/net/minecraft/world/Container.java
@@ -71,6 +71,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 8508ac7de8cda3127b73e11ff4aee62502e65ead..3232f40ef11f59091cec469f0dd40c60ee2a16e9 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,9 +14,14 @@ 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 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(
@@ -51,16 +55,18 @@ public class TradeWithVillager extends Behavior<Villager> {
BehaviorUtils.lockGazeAndWalkToEachOther(entity, villager, 0.5F, 2);
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.getDefaultMaxStackSize() / 2) {
- throwHalfStack(entity, ImmutableSet.of(Items.WHEAT), villager);
+ throwHalfStack(entity, Villager.FOOD_POINTS_KEY_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
}
}
}
@@ -70,13 +76,36 @@ 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 -> !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 +118,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 1595568f3140a62b0f2236644ac2da11db12af05..ce8851c2cacfd3145b1e2c11443140a0759a1b07 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 ba49442ed0b7c05c50dbc2a640f5759e391902f2..71a3eadd2f1e00fa066dbfe9918d749d43435a18 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -90,6 +90,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
@@ -106,8 +107,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;
@@ -910,7 +912,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 8734ab1bd8299bbf43906d81a349c2a13e0981a7..018b577aecf612e4a4e98cbd7d9292955d04693c 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,13 +15,15 @@ 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,
+ @NotNull Item @Nullable [] requestedItems, // Gale - optimize villager data storage
+ @Nullable Block secondaryPoi, // Gale - optimize villager data storage
@Nullable SoundEvent workSound
) {
public static final Predicate<Holder<PoiType>> ALL_ACQUIRABLE_JOBS = poiType -> poiType.is(PoiTypeTags.ACQUIRABLE_JOB_SITE);
@@ -35,8 +35,8 @@ public record VillagerProfession(
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),
+ new Item[] {Items.WHEAT, Items.WHEAT_SEEDS, Items.BEETROOT_SEEDS, Items.BONE_MEAL}, // Gale - optimize villager data storage
+ Blocks.FARMLAND, // Gale - optimize villager data storage
SoundEvents.VILLAGER_WORK_FARMER
);
public static final VillagerProfession FISHERMAN = register("fisherman", PoiTypes.FISHERMAN, SoundEvents.VILLAGER_WORK_FISHERMAN);
@@ -58,34 +58,36 @@ public record VillagerProfession(
return register(id, entry -> entry.is(heldWorkstation), entry -> entry.is(heldWorkstation), workSound);
}
+ // Gale start - optimize villager data storage
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);
}
private static VillagerProfession register(
String id,
ResourceKey<PoiType> heldWorkstation,
- ImmutableSet<Item> gatherableItems,
- ImmutableSet<Block> secondaryJobSites,
+ @NotNull Item @Nullable [] gatherableItems,
+ @Nullable Block secondaryJobSite,
@Nullable SoundEvent workSound
) {
- return register(id, entry -> entry.is(heldWorkstation), entry -> entry.is(heldWorkstation), gatherableItems, secondaryJobSites, workSound);
+ return register(id, entry -> entry.is(heldWorkstation), entry -> entry.is(heldWorkstation), gatherableItems, secondaryJobSite, workSound);
}
private static VillagerProfession register(
String id,
Predicate<Holder<PoiType>> heldWorkstation,
Predicate<Holder<PoiType>> acquirableWorkstation,
- ImmutableSet<Item> gatherableItems,
- ImmutableSet<Block> secondaryJobSites,
+ @NotNull Item @Nullable [] gatherableItems,
+ @Nullable Block secondaryJobSite,
@Nullable SoundEvent workSound
) {
return Registry.register(
BuiltInRegistries.VILLAGER_PROFESSION,
ResourceLocation.withDefaultNamespace(id),
- new VillagerProfession(id, heldWorkstation, acquirableWorkstation, gatherableItems, secondaryJobSites, workSound)
+ new VillagerProfession(id, heldWorkstation, acquirableWorkstation, gatherableItems != null && gatherableItems.length == 0 ? null : gatherableItems, secondaryJobSite, workSound)
);
+ // Gale end - optimize villager data storage
}
}