1515import net .minecraft .text .Text ;
1616import net .minecraft .util .math .BlockPos ;
1717import net .minecraft .util .math .MathHelper ;
18+ import net .minecraft .util .registry .Registry ;
1819import net .minecraft .world .GameRules ;
1920import net .minecraft .world .Heightmap ;
2021import net .minecraft .world .SpawnHelper ;
2526import net .minecraft .world .poi .PointOfInterestType ;
2627import org .apache .logging .log4j .Level ;
2728
28- import java .util .HashMap ;
29- import java .util .Iterator ;
30- import java .util .Optional ;
31- import java .util .Random ;
29+ import java .util .*;
3230
3331public class TradesmenManager implements WorldTickCallback {
3432 public static final TradesmenManager INSTANCE = new TradesmenManager ();
@@ -50,9 +48,8 @@ private class WorldTradesmenManager {
5048 public WorldTradesmenManager (ServerWorld world ) {
5149 this .world = world ;
5250 this .tickCount = 1200 ;
53- //LevelProperties levelProperties = world.getLevelProperties();
54- this .spawnDelay = Tradesmen .getConfig ().spawnDelay ;//levelProperties.getWanderingTraderSpawnDelay();
55- this .spawnChance = Tradesmen .getConfig ().spawnChance ;//levelProperties.getWanderingTraderSpawnChance();
51+ this .spawnDelay = Tradesmen .getConfig ().spawnDelay ;
52+ this .spawnChance = Tradesmen .getConfig ().spawnChance ;
5653 if (this .spawnDelay == 0 && this .spawnChance == 0 ) {
5754 this .spawnDelay = Tradesmen .getConfig ().spawnDelay ;
5855 this .spawnChance = Tradesmen .getConfig ().spawnChance ;
@@ -69,7 +66,7 @@ public void tick() {
6966 this .spawnDelay = Tradesmen .getConfig ().spawnDelay ;
7067 if (this .world .getGameRules ().getBoolean (GameRules .DO_MOB_SPAWNING )) {
7168 int i = this .spawnChance ;
72- this .spawnChance = MathHelper .clamp (this .spawnChance + 25 , 25 , 75 );
69+ this .spawnChance = MathHelper .clamp (this .spawnChance , 0 , 100 );
7370 if (this .random .nextInt (100 ) <= i ) {
7471 if (this .spawnRoamingTrader ()) {
7572 this .spawnChance = Tradesmen .getConfig ().spawnChance ;
@@ -87,32 +84,44 @@ private boolean spawnRoamingTrader() {
8784 if (playerEntity == null ) {
8885 return true ;
8986 } else {
87+ List <String > allowedTraderTypes = new ArrayList <>();
88+ Traders .forEach ((id ,trader )->{
89+ if ( !id .equals ("default:default_trader" ) &&
90+ (trader .allowedWorlds .contains ("*" ) ||
91+ trader .allowedWorlds .contains (Registry .DIMENSION_TYPE .getId (world .dimension .getType ()).toString ()))) {
92+ allowedTraderTypes .add (id );
93+ }
94+
95+ });
96+ if (allowedTraderTypes .size () < 1 ) {
97+ return true ;
98+ }
9099 BlockPos blockPos = playerEntity .getBlockPos ();
91- //int i = true;
100+
101+ // spawn a distance from the player or from a meeting POI type
102+ // currently only village bells
92103 PointOfInterestStorage pointOfInterestStorage = this .world .getPointOfInterestStorage ();
93104 Optional <BlockPos > optional = pointOfInterestStorage .getPosition (PointOfInterestType .MEETING .getCompletionCondition (), (blockPosx ) -> {
94105 return true ;
95106 }, blockPos , 48 , PointOfInterestStorage .OccupationStatus .ANY );
96107 BlockPos blockPos2 = (BlockPos )optional .orElse (blockPos );
97- BlockPos blockPos3 = this .getPosDistanceFrom (blockPos2 , 48 );
98- if (blockPos3 != null && this . method_23279 ( blockPos3 ) ) {
108+ BlockPos blockPos3 = this .getPosDistanceFrom (blockPos2 , 25 );
109+ if (blockPos3 != null ) {
99110 if (this .world .getBiome (blockPos3 ) == Biomes .THE_VOID ) {
100111 return false ;
101112 }
102113
103114 TradesmenEntity traderEntity = (TradesmenEntity ) InitEntities .TRADESMEN_ENTITY_TYPE .spawn (this .world , (CompoundTag )null , (Text )null , (PlayerEntity )null , blockPos3 , SpawnType .EVENT , false , false );
104115 if (traderEntity != null ) {
105- if (Traders .size () > 1 ) {
106- traderEntity .setTraderType (
107- Traders .keySet ().stream ().filter (id -> !("default:default_trader" .equalsIgnoreCase (id ))).toArray ()[world .random .nextInt (Traders .size ()-1 )].toString ()
108- );
116+ traderEntity .setTraderType (allowedTraderTypes .get (world .random .nextInt (allowedTraderTypes .size ())));
117+ for (int i =0 ;i <getTraderById (traderEntity .getTraderType ()).animalCount ; i ++) {
118+ this .SpawnAnimal (traderEntity .getTraderAnimal (),traderEntity , 4 );
109119 }
110- this .SpawnAnimal (traderEntity .getTraderAnimal (),traderEntity , 4 );
111120
112- //this.world.getLevelProperties().setWanderingTraderId(wanderingTraderEntity.getUuid());
113121 traderEntity .setDespawnDelay ((int )(Tradesmen .getConfig ().spawnDelay *0.75F ));
114122 traderEntity .setWanderTarget (blockPos2 );
115123 traderEntity .setPositionTarget (blockPos2 , 16 );
124+ traderEntity .setInvulnerable (getTraderById (traderEntity .getTraderType ()).godMode );
116125 return true ;
117126 }
118127 }
@@ -121,32 +130,47 @@ private boolean spawnRoamingTrader() {
121130 }
122131 }
123132 private void SpawnAnimal (String AnimalId , TradesmenEntity ownerTrader , int distance ) {
133+ if (AnimalId .isEmpty ())
134+ return ;
124135 BlockPos blockPos = this .getPosDistanceFrom (new BlockPos (ownerTrader ), distance );
125136 if (blockPos != null ) {
126137 MobEntity traderAnimalEntity = (MobEntity )(EntityType .get (AnimalId ).orElse (EntityType .TRADER_LLAMA )).spawn (this .world , (CompoundTag )null , (Text )null , (PlayerEntity )null , blockPos , SpawnType .EVENT , false , false );
127138 if (traderAnimalEntity != null ) {
128139 traderAnimalEntity .attachLeash (ownerTrader , true );
129- ownerTrader .setAnimalUUID (traderAnimalEntity .getUuidAsString ());
140+ ownerTrader .addAnimalUUID (traderAnimalEntity .getUuidAsString ());
130141 }
131142 }
132143 }
133144 @ Nullable
145+ private BlockPos getSpawnableHeight (BlockPos pos , int vDistance ) {
146+ for (int y = 0 ; y < vDistance ; y ++) {
147+ if (SpawnHelper .canSpawn (SpawnRestriction .Location .ON_GROUND , this .world , pos .add (0 ,y ,0 ), InitEntities .TRADESMEN_ENTITY_TYPE )) {
148+ return pos .add (0 ,y ,0 );
149+ }
150+ }
151+ for (int y = -1 ; y > -vDistance ; y --) {
152+ if (SpawnHelper .canSpawn (SpawnRestriction .Location .ON_GROUND , this .world , pos .add (0 ,y ,0 ), InitEntities .TRADESMEN_ENTITY_TYPE )) {
153+ return pos .add (0 ,y ,0 );
154+ }
155+ }
156+ return null ;
157+ }
158+ @ Nullable
134159 private BlockPos getPosDistanceFrom (BlockPos blockPos , int distance ) {
135160 BlockPos blockPos2 = null ;
136161
137162 for (int j = 0 ; j < 10 ; ++j ) {
138163 int k = blockPos .getX () + this .random .nextInt (distance * 2 ) - distance ;
139164 int l = blockPos .getZ () + this .random .nextInt (distance * 2 ) - distance ;
140- int m = this .world .getTopY (Heightmap .Type .WORLD_SURFACE , k , l );
141- BlockPos blockPos3 = new BlockPos (k , m , l );
142- if (SpawnHelper .canSpawn (SpawnRestriction .Location .ON_GROUND , this .world , blockPos3 , InitEntities .TRADESMEN_ENTITY_TYPE )) {
143- blockPos2 = blockPos3 ;
165+ blockPos2 = getSpawnableHeight (new BlockPos (k ,blockPos .getY (),l ),distance );
166+ if (blockPos2 != null ) {
144167 break ;
145168 }
146169 }
147170
148171 return blockPos2 ;
149172 }
173+
150174 private boolean method_23279 (BlockPos blockPos ) {
151175 Iterator var2 = BlockPos .iterate (blockPos , blockPos .add (1 , 2 , 1 )).iterator ();
152176
@@ -170,12 +194,10 @@ public void tick(World world) {
170194 return ;
171195 }
172196 ServerWorld sWorld = (ServerWorld )world ;
173- if (sWorld .dimension .getType () == DimensionType .OVERWORLD ) {
174- if (!WorldManagers .containsKey (sWorld )) {
175- WorldManagers .put (world , new WorldTradesmenManager (sWorld ));
176- }
177- WorldManagers .get (sWorld ).tick ();
197+ if (!WorldManagers .containsKey (sWorld )) {
198+ WorldManagers .put (world , new WorldTradesmenManager (sWorld ));
178199 }
200+ WorldManagers .get (sWorld ).tick ();
179201 }
180202
181203}
0 commit comments