Skip to content

Commit 04bff3a

Browse files
authored
Merge pull request #10 from jamesgreen26/1.20
Ships generate pre-assembled
2 parents cb59b41 + ba4ed22 commit 04bff3a

22 files changed

+243
-28
lines changed

src/main/java/ace/actually/pirates/blocks/CrewSpawnerBlock.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import ace.actually.pirates.Pirates;
44
import ace.actually.pirates.blocks.entity.CrewSpawnerBlockEntity;
5-
import ace.actually.pirates.util.ModProperties;
5+
import ace.actually.pirates.util.CrewTypes;
66
import net.minecraft.block.*;
77
import net.minecraft.block.entity.BlockEntity;
88
import net.minecraft.block.entity.BlockEntityTicker;
@@ -30,7 +30,7 @@ public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
3030

3131
@Override
3232
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
33-
builder.add(Properties.CONDITIONAL).add(ModProperties.CREW_SPAWN_TYPE);
33+
builder.add(Properties.CONDITIONAL).add(CrewTypes.CREW_SPAWN_TYPE);
3434
}
3535

3636
@Nullable

src/main/java/ace/actually/pirates/blocks/entity/CrewSpawnerBlockEntity.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
import ace.actually.pirates.entities.pirate_default.PirateEntity;
55
import ace.actually.pirates.entities.pirate_skeleton.SkeletonPirateEntity;
66
import ace.actually.pirates.util.CrewSpawnType;
7-
import ace.actually.pirates.util.ModProperties;
7+
import ace.actually.pirates.util.CrewTypes;
88
import net.minecraft.block.BlockState;
99
import net.minecraft.block.entity.BlockEntity;
1010
import net.minecraft.enchantment.Enchantments;
1111
import net.minecraft.entity.Entity;
1212
import net.minecraft.entity.EntityType;
1313
import net.minecraft.entity.EquipmentSlot;
14-
import net.minecraft.entity.mob.MobEntity;
1514
import net.minecraft.entity.passive.VillagerEntity;
1615
import net.minecraft.item.ItemStack;
1716
import net.minecraft.item.Items;
@@ -97,12 +96,12 @@ private static BlockPos checkForBlocksToCrew (World world, BlockPos origin) {
9796

9897
private static Entity getEntityFromState(World world, BlockEntity be) {
9998
Entity crew = null;
100-
if (be.getCachedState().get(ModProperties.CREW_SPAWN_TYPE) == CrewSpawnType.PIRATE) {
99+
if (be.getCachedState().get(CrewTypes.CREW_SPAWN_TYPE) == CrewSpawnType.PIRATE) {
101100
crew = new PirateEntity(world, checkForBlocksToCrew(world, be.getPos()));
102101
crew.equipStack(EquipmentSlot.MAINHAND, new ItemStack(Items.BOW));
103-
} else if (be.getCachedState().get(ModProperties.CREW_SPAWN_TYPE) == CrewSpawnType.VILLAGER) {
102+
} else if (be.getCachedState().get(CrewTypes.CREW_SPAWN_TYPE) == CrewSpawnType.VILLAGER) {
104103
crew = new VillagerEntity(EntityType.VILLAGER, world, VillagerType.forBiome(world.getBiome(be.getPos())));
105-
} else if (be.getCachedState().get(ModProperties.CREW_SPAWN_TYPE) == CrewSpawnType.SKELETON_PIRATE) {
104+
} else if (be.getCachedState().get(CrewTypes.CREW_SPAWN_TYPE) == CrewSpawnType.SKELETON_PIRATE) {
106105
BlockPos blockToCrew = checkForBlocksToCrew(world, be.getPos());
107106
crew = new SkeletonPirateEntity(world, blockToCrew);
108107
ItemStack itemStack = new ItemStack(Items.BOW);

src/main/java/ace/actually/pirates/blocks/entity/MotionInvokingBlockEntity.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public static void tick(World world, BlockPos pos, BlockState state, MotionInvok
8787

8888
}
8989
} else {
90-
be.buildShipRec((ServerWorld) world, pos);
90+
//be.buildShipRec((ServerWorld) world, pos);
9191
}
9292
}
9393

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package ace.actually.pirates.mixin;
2+
3+
import ace.actually.pirates.util.ShipStructurePlacementHelper;
4+
import kotlin.Triple;
5+
import net.minecraft.server.world.ServerWorld;
6+
import net.minecraft.structure.StructureTemplate;
7+
import net.minecraft.util.math.BlockPos;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.injection.At;
10+
import org.spongepowered.asm.mixin.injection.Inject;
11+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
12+
13+
import java.util.function.BooleanSupplier;
14+
15+
import static ace.actually.pirates.util.ShipStructurePlacementHelper.shipQueue;
16+
17+
@Mixin(ServerWorld.class)
18+
public abstract class ServerWorldMixin {
19+
20+
@Inject(method = "tick", at = @At("HEAD"))
21+
protected void tickMixin(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
22+
if (!shipQueue.isEmpty()) {
23+
Triple<StructureTemplate, ServerWorld, BlockPos> structureData = shipQueue.poll();
24+
assert structureData != null;
25+
ShipStructurePlacementHelper.createShip(structureData.getFirst(), structureData.getSecond(), structureData.getThird());
26+
}
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package ace.actually.pirates.mixin;
2+
3+
import ace.actually.pirates.util.CanRemoveTemplate;
4+
import net.minecraft.structure.StructureTemplate;
5+
import net.minecraft.structure.StructureTemplateManager;
6+
import net.minecraft.util.Identifier;
7+
import org.spongepowered.asm.mixin.*;
8+
import org.spongepowered.asm.mixin.injection.At;
9+
import org.spongepowered.asm.mixin.injection.Inject;
10+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
11+
12+
import java.util.Map;
13+
import java.util.Optional;
14+
15+
@Mixin(value = StructureTemplateManager.class)
16+
public abstract class StructureTemplateManagerMixin implements CanRemoveTemplate {
17+
18+
@Final
19+
@Shadow
20+
private Map<Identifier, Optional<StructureTemplate>> templates;
21+
22+
@Shadow
23+
protected abstract Optional<StructureTemplate> loadTemplate(Identifier identifier);
24+
25+
@Shadow public abstract void unloadTemplate(Identifier id);
26+
27+
@Inject(method = "getTemplate", at = @At("HEAD"), cancellable = true)
28+
public void getTemplateMixin(Identifier id, CallbackInfoReturnable<Optional<StructureTemplate>> cir) {
29+
30+
Optional<StructureTemplate> template = this.templates.computeIfAbsent(id, this::loadTemplate);
31+
32+
if (template.isPresent() && !template.get().getAuthor().equals("dirty") && id.getNamespace().equals("pirates") && id.getPath().startsWith("ship/")) {
33+
template.get().setAuthor("pirate-ship");
34+
}
35+
36+
cir.setReturnValue(template);
37+
}
38+
39+
@Override
40+
public boolean pirates$unload(StructureTemplate template) {
41+
Optional<Identifier> key = templates.entrySet().stream()
42+
.filter(entry -> entry.getValue().isPresent() && entry.getValue().get().equals(template))
43+
.map(Map.Entry::getKey)
44+
.findFirst();
45+
46+
key.ifPresent(this::unloadTemplate);
47+
return key.isPresent();
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package ace.actually.pirates.mixin;
2+
3+
import ace.actually.pirates.Pirates;
4+
import ace.actually.pirates.util.CanRemoveTemplate;
5+
import ace.actually.pirates.util.ShipStructurePlacementHelper;
6+
import net.minecraft.client.render.entity.SpiderEntityRenderer;
7+
import net.minecraft.structure.StructurePlacementData;
8+
import net.minecraft.structure.StructureTemplate;
9+
import net.minecraft.structure.StructureTemplateManager;
10+
import net.minecraft.util.BlockMirror;
11+
import net.minecraft.util.BlockRotation;
12+
import net.minecraft.util.math.*;
13+
import net.minecraft.util.math.random.Random;
14+
import net.minecraft.world.ServerWorldAccess;
15+
import org.spongepowered.asm.mixin.Mixin;
16+
import org.spongepowered.asm.mixin.Shadow;
17+
import org.spongepowered.asm.mixin.injection.At;
18+
import org.spongepowered.asm.mixin.injection.Inject;
19+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
20+
import org.valkyrienskies.mod.common.VSGameUtilsKt;
21+
22+
import java.util.Objects;
23+
24+
25+
@Mixin(value = StructureTemplate.class)
26+
public abstract class StructureTemplateMixin {
27+
28+
@Shadow private String author;
29+
30+
@Shadow public abstract void setAuthor(String author);
31+
32+
@Inject(method = "place", at = @At("HEAD"), cancellable = true)
33+
public void placeMixin(ServerWorldAccess world, BlockPos pos, BlockPos pivot, StructurePlacementData placementData, Random random, int flags, CallbackInfoReturnable<Boolean> cir) {
34+
if (VSGameUtilsKt.isBlockInShipyard(world.toServerWorld(), pos)) return;
35+
36+
boolean placed;
37+
if (this.author.equals("pirate-ship")) {
38+
if (placementData.getBoundingBox() != null) {
39+
ShipStructurePlacementHelper.placeShipTemplate(
40+
(StructureTemplate) (Object) this,
41+
world.toServerWorld(),
42+
placementData.getBoundingBox().getCenter());
43+
placed = true;
44+
} else {
45+
ShipStructurePlacementHelper.placeShipTemplate(
46+
(StructureTemplate) (Object) this,
47+
world.toServerWorld(),
48+
pos);
49+
Pirates.LOGGER.info("Template generated with null bounding box");
50+
placed = true;
51+
}
52+
this.setAuthor("dirty");
53+
cir.setReturnValue(placed);
54+
cir.cancel();
55+
} else if (this.author.equals("dirty")) {
56+
cir.setReturnValue(false);
57+
cir.cancel();
58+
}
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package ace.actually.pirates.util;
2+
3+
import net.minecraft.structure.StructureTemplate;
4+
5+
public interface CanRemoveTemplate {
6+
boolean pirates$unload(StructureTemplate template);
7+
}

src/main/java/ace/actually/pirates/util/ModProperties.java src/main/java/ace/actually/pirates/util/CrewTypes.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
import net.minecraft.state.property.EnumProperty;
44

5-
public interface ModProperties {
5+
public interface CrewTypes {
66
EnumProperty<CrewSpawnType> CREW_SPAWN_TYPE = EnumProperty.of("crew_spawn_type", CrewSpawnType.class);
77
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package ace.actually.pirates.util;
2+
3+
import ace.actually.pirates.Pirates;
4+
import kotlin.Triple;
5+
6+
import net.minecraft.server.world.ServerWorld;
7+
import net.minecraft.structure.StructurePlacementData;
8+
import net.minecraft.structure.StructureTemplate;
9+
import net.minecraft.structure.StructureTemplateManager;
10+
import net.minecraft.util.math.BlockPos;
11+
import net.minecraft.util.math.random.Random;
12+
import org.joml.Vector3i;
13+
import org.valkyrienskies.core.api.ships.ServerShip;
14+
import org.valkyrienskies.mod.common.VSGameUtilsKt;
15+
import org.valkyrienskies.mod.common.util.VectorConversionsMCKt;
16+
17+
import java.util.*;
18+
import java.util.concurrent.ArrayBlockingQueue;
19+
20+
21+
public class ShipStructurePlacementHelper {
22+
23+
public static final Queue<Triple<StructureTemplate, ServerWorld, BlockPos>> shipQueue = new ArrayBlockingQueue<>(12,false);
24+
25+
26+
27+
public static void placeShipTemplate(StructureTemplate structureTemplate, ServerWorld world, BlockPos centrePos) {
28+
shipQueue.add(new Triple<>(structureTemplate, world, centrePos));
29+
Pirates.LOGGER.info("enqueuing template at {}", centrePos.toString());
30+
}
31+
32+
public static void createShip (StructureTemplate structureTemplate, ServerWorld world, BlockPos blockPos) {
33+
34+
ServerShip newShip = VSGameUtilsKt.getShipObjectWorld(world).createNewShipAtBlock(
35+
VectorConversionsMCKt.toJOML(withOceanYLevel(world, blockPos)),
36+
false,
37+
1.0,
38+
VSGameUtilsKt.getDimensionId(world));
39+
40+
newShip.setStatic(true);
41+
42+
BlockPos centerPos = VectorConversionsMCKt.toBlockPos(newShip.getChunkClaim().getCenterBlockCoordinates(VSGameUtilsKt.getYRange(world), new Vector3i()));
43+
44+
StructurePlacementData structurePlacementData = new StructurePlacementData();
45+
boolean success = structureTemplate.place(world, withOceanYLevel(world, centerPos), centerPos, structurePlacementData, Random.create(), 2);
46+
47+
Pirates.LOGGER.info("new ship id: {} mass: {}", newShip.getId(), newShip.getInertiaData().getMass());
48+
Pirates.LOGGER.info("Template claims to have generated successfully? {}", success);
49+
if (newShip.getInertiaData().getMass() < 0.1) {
50+
System.out.println("deleting ship");
51+
VSGameUtilsKt.getShipObjectWorld(world).deleteShip(newShip);
52+
} else {
53+
Pirates.LOGGER.info("ship created successfully.");
54+
StructureTemplateManager manager = Objects.requireNonNull(world.getServer()).getStructureTemplateManager();
55+
if(((CanRemoveTemplate) manager).pirates$unload(structureTemplate)) {
56+
Pirates.LOGGER.info("templates cleaned.");
57+
} else {
58+
Pirates.LOGGER.info("template cleanup failed.");
59+
}
60+
61+
newShip.setStatic(false);
62+
}
63+
64+
}
65+
66+
private static BlockPos withOceanYLevel(ServerWorld world, BlockPos source) {
67+
return new BlockPos(source.getX(), world.getSeaLevel(), source.getZ());
68+
}
69+
}

src/main/resources/data/pirates/worldgen/template_pool/ship.json

+11-11
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"element": {
88
"element_type": "minecraft:single_pool_element",
99
"projection": "rigid",
10-
"location": "pirates:deep-sea-moray",
10+
"location": "pirates:ship/deep-sea-moray",
1111
"processors": "minecraft:empty"
1212
}
1313
},
@@ -16,7 +16,7 @@
1616
"element": {
1717
"element_type": "minecraft:single_pool_element",
1818
"projection": "rigid",
19-
"location": "pirates:barnacle-hopper",
19+
"location": "pirates:ship/barnacle-hopper",
2020
"processors": "minecraft:empty"
2121
}
2222
},
@@ -25,7 +25,7 @@
2525
"element": {
2626
"element_type": "minecraft:single_pool_element",
2727
"projection": "rigid",
28-
"location": "pirates:midnight-barracuda",
28+
"location": "pirates:ship/midnight-barracuda",
2929
"processors": "minecraft:empty"
3030
}
3131
},
@@ -34,7 +34,7 @@
3434
"element": {
3535
"element_type": "minecraft:single_pool_element",
3636
"projection": "rigid",
37-
"location": "pirates:eye-of-horus",
37+
"location": "pirates:ship/eye-of-horus",
3838
"processors": "minecraft:empty"
3939
}
4040
},
@@ -43,7 +43,7 @@
4343
"element": {
4444
"element_type": "minecraft:single_pool_element",
4545
"projection": "rigid",
46-
"location": "pirates:antelope",
46+
"location": "pirates:ship/antelope",
4747
"processors": "minecraft:empty"
4848
}
4949
},
@@ -52,7 +52,7 @@
5252
"element": {
5353
"element_type": "minecraft:single_pool_element",
5454
"projection": "rigid",
55-
"location": "pirates:anetum-contatum",
55+
"location": "pirates:ship/anetum-contatum",
5656
"processors": "minecraft:empty"
5757
}
5858
},
@@ -61,7 +61,7 @@
6161
"element": {
6262
"element_type": "minecraft:single_pool_element",
6363
"projection": "rigid",
64-
"location": "pirates:the-heart-attack",
64+
"location": "pirates:ship/the-heart-attack",
6565
"processors": "minecraft:empty"
6666
}
6767
},
@@ -70,7 +70,7 @@
7070
"element": {
7171
"element_type": "minecraft:single_pool_element",
7272
"projection": "rigid",
73-
"location": "pirates:whydah",
73+
"location": "pirates:ship/whydah",
7474
"processors": "minecraft:empty"
7575
}
7676
},
@@ -79,7 +79,7 @@
7979
"element": {
8080
"element_type": "minecraft:single_pool_element",
8181
"projection": "rigid",
82-
"location": "pirates:whydah_ghost",
82+
"location": "pirates:ship/whydah_ghost",
8383
"processors": "minecraft:empty"
8484
}
8585
},
@@ -88,7 +88,7 @@
8888
"element": {
8989
"element_type": "minecraft:single_pool_element",
9090
"projection": "rigid",
91-
"location": "pirates:revenge",
91+
"location": "pirates:ship/revenge",
9292
"processors": "minecraft:empty"
9393
}
9494
},
@@ -97,7 +97,7 @@
9797
"element": {
9898
"element_type": "minecraft:single_pool_element",
9999
"projection": "rigid",
100-
"location": "pirates:the-phantom-leviathan",
100+
"location": "pirates:ship/the-phantom-leviathan",
101101
"processors": "minecraft:empty"
102102
}
103103
}

0 commit comments

Comments
 (0)