Skip to content

Commit 20a8b62

Browse files
committed
add ammo assembler
1 parent 63a616d commit 20a8b62

30 files changed

+1444
-40
lines changed

buildSrc/src/main/groovy/multiloader-common.gradle

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ repositories {
182182
url = 'https://mvn.devos.one/releases'
183183
}
184184
}
185+
forRepository {
186+
maven {
187+
name = 'Create 0.5 Backup'
188+
url = 'https://modmaven.dev/'
189+
}
190+
}
185191
filter {
186192
includeGroup('com.jozufozu.flywheel')
187193
includeGroup('com.simibubi.create')
@@ -205,11 +211,6 @@ repositories {
205211
}
206212
}
207213

208-
maven {
209-
name = 'BlameJared'
210-
url = 'https://maven.blamejared.com'
211-
}
212-
213214
exclusiveContent {
214215
forRepository {
215216
maven {
@@ -222,6 +223,11 @@ repositories {
222223
includeGroup('org.squiddev')
223224
}
224225
}
226+
227+
maven {
228+
name = 'BlameJared'
229+
url = 'https://maven.blamejared.com'
230+
}
225231
}
226232

227233
dependencies {

common/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ dependencies {
3737
implementation "org.valkyrienskies.core:util:${vs_core_version}"
3838
implementation "org.valkyrienskies.core:impl:${vs_core_version}"
3939

40-
compileOnly "cc.tweaked:cc-tweaked-${minecraft_version}-common:${cc_tweaked}"
40+
compileOnly "cc.tweaked:cc-tweaked-${minecraft_version}-common:${cct_version}"
41+
42+
modCompileOnly "com.simibubi.create:create-fabric-${minecraft_version}:${create_fabric_version}"
4143
}
4244

4345
configurations {

common/src/main/java/com/github/litermc/vschunkloader/VSCApi.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.litermc.vschunkloader;
22

33
import com.github.litermc.vschunkloader.attachment.ForceLoadAttachment;
4+
import com.github.litermc.vschunkloader.config.Config;
45

56
import net.minecraft.resources.ResourceLocation;
67
import net.minecraft.server.MinecraftServer;
@@ -14,6 +15,11 @@
1415

1516
public final class VSCApi {
1617
private static final VSCApi INSTANCE = new VSCApi();
18+
/**
19+
* Reusable ship slug prefix.
20+
* Ship will not be force loaded with this prefix when {@link Config.forceLoadAllShips} is {@code true}.
21+
*/
22+
public static final String REUSABLE_SHIP_SLUG_PREFIX = "+reuse+";
1723

1824
private VSCApi() {}
1925

common/src/main/java/com/github/litermc/vschunkloader/VSCListeners.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ public static void onServerLevelUnload(final ServerLevel level) {
2727
public static void preServerTick(final MinecraftServer server) {
2828
final ServerShipWorld shipWorld = VSGameUtilsKt.getShipObjectWorld(server);
2929
for (final ServerShip ship : shipWorld.getAllShips()) {
30-
if (!Config.forceLoadAllShips && !VSCApi.isForceLoaded(server, ship.getId())) {
30+
if (!Config.forceLoadAllShips) {
31+
final String slug = ship.getSlug();
32+
if (slug != null && slug.startsWith(VSCApi.REUSABLE_SHIP_SLUG_PREFIX)) {
33+
continue;
34+
}
35+
} else if (!VSCApi.isForceLoaded(server, ship.getId())) {
3136
continue;
3237
}
3338
final ServerLevel level = Utils.getLevel(ship.getChunkClaimDimension());

common/src/main/java/com/github/litermc/vschunkloader/VSCRegistry.java

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
import com.github.litermc.vschunkloader.block.ChunkLoaderBlockEntity;
99
import com.github.litermc.vschunkloader.block.ChunkLoaderWeakBlock;
1010
import com.github.litermc.vschunkloader.block.ChunkLoaderWeakBlockEntity;
11+
import com.github.litermc.vschunkloader.block.ammo.AmmoAssemblerBlock;
12+
import com.github.litermc.vschunkloader.block.ammo.AmmoAssemblerBlockEntity;
13+
import com.github.litermc.vschunkloader.block.ammo.AmmoManagerBlock;
14+
import com.github.litermc.vschunkloader.block.ammo.AmmoManagerBlockEntity;
1115
import com.github.litermc.vschunkloader.platform.PlatformHelper;
1216
import com.github.litermc.vschunkloader.platform.RegistrationHelper;
1317
import com.github.litermc.vschunkloader.platform.RegistryEntry;
@@ -28,6 +32,8 @@
2832
import net.minecraft.world.level.block.state.BlockState;
2933
import net.minecraft.world.level.material.PushReaction;
3034

35+
import java.util.ArrayList;
36+
import java.util.List;
3137
import java.util.function.BiFunction;
3238

3339
public final class VSCRegistry {
@@ -43,7 +49,25 @@ public static void register() {
4349
public static final class Blocks {
4450
private static final RegistrationHelper<Block> REGISTRY = PlatformHelper.get().createRegistrationHelper(Registries.BLOCK);
4551

46-
public static final RegistryEntry<Block> CHUNK_LOADER =
52+
public static final RegistryEntry<AmmoAssemblerBlock> AMMO_ASSEMBLER =
53+
REGISTRY.register("ammo_assembler", () -> new AmmoAssemblerBlock(
54+
BlockBehaviour.Properties.of()
55+
.strength(5f)
56+
.sound(SoundType.ANVIL)
57+
.pushReaction(PushReaction.IGNORE)
58+
.isRedstoneConductor((state, level, pos) -> false)
59+
.requiresCorrectToolForDrops()));
60+
61+
public static final RegistryEntry<AmmoManagerBlock> AMMO_MANAGER =
62+
REGISTRY.register("ammo_manager", () -> new AmmoManagerBlock(
63+
BlockBehaviour.Properties.of()
64+
.strength(10f)
65+
.sound(SoundType.COPPER)
66+
.pushReaction(PushReaction.IGNORE)
67+
.isRedstoneConductor((state, level, pos) -> false)
68+
.requiresCorrectToolForDrops()));
69+
70+
public static final RegistryEntry<ChunkLoaderBlock> CHUNK_LOADER =
4771
REGISTRY.register("chunk_loader", () -> new ChunkLoaderBlock(
4872
BlockBehaviour.Properties.of()
4973
.strength(5f)
@@ -53,7 +77,7 @@ public static final class Blocks {
5377
.isRedstoneConductor((state, level, pos) -> false)
5478
.requiresCorrectToolForDrops()));
5579

56-
public static final RegistryEntry<Block> CHUNK_LOADER_WEAK =
80+
public static final RegistryEntry<ChunkLoaderWeakBlock> CHUNK_LOADER_WEAK =
5781
REGISTRY.register("chunk_loader_weak", () -> new ChunkLoaderWeakBlock(
5882
BlockBehaviour.Properties.of()
5983
.strength(3f)
@@ -73,6 +97,12 @@ private static <T extends BlockEntity> RegistryEntry<BlockEntityType<T>> ofBlock
7397
return REGISTRY.register(block.id().getPath(), () -> PlatformHelper.get().createBlockEntityType(factory, block.get()));
7498
}
7599

100+
public static final RegistryEntry<BlockEntityType<AmmoAssemblerBlockEntity>> AMMO_ASSEMBLER =
101+
ofBlock(Blocks.AMMO_ASSEMBLER, AmmoAssemblerBlockEntity::new);
102+
103+
public static final RegistryEntry<BlockEntityType<AmmoManagerBlockEntity>> AMMO_MANAGER =
104+
ofBlock(Blocks.AMMO_MANAGER, AmmoManagerBlockEntity::new);
105+
76106
public static final RegistryEntry<BlockEntityType<ChunkLoaderBlockEntity>> CHUNK_LOADER =
77107
ofBlock(Blocks.CHUNK_LOADER, ChunkLoaderBlockEntity::new);
78108

@@ -84,15 +114,28 @@ private BlockEntities() {}
84114

85115
public static final class Items {
86116
private static final RegistrationHelper<Item> REGISTRY = PlatformHelper.get().createRegistrationHelper(Registries.ITEM);
117+
private static final List<RegistryEntry<? extends Item>> TAB_ITEMS = new ArrayList<>();
87118

88119
private static Item.Properties properties() {
89120
return new Item.Properties();
90121
}
91122

92123
private static <B extends Block, I extends Item> RegistryEntry<I> ofBlock(RegistryEntry<B> block, BiFunction<B, Item.Properties, I> supplier) {
93-
return REGISTRY.register(block.id().getPath(), () -> supplier.apply(block.get(), properties()));
124+
final RegistryEntry<I> entry = REGISTRY.register(block.id().getPath(), () -> supplier.apply(block.get(), properties()));
125+
TAB_ITEMS.add(entry);
126+
return entry;
94127
}
95128

129+
public static final RegistryEntry<BlockItem> AMMO_ASSEMBLER = ofBlock(
130+
Blocks.AMMO_ASSEMBLER,
131+
(block, props) -> new BlockItem(block, props.rarity(Rarity.UNCOMMON).stacksTo(64))
132+
);
133+
134+
public static final RegistryEntry<BlockItem> AMMO_MANAGER = ofBlock(
135+
Blocks.AMMO_MANAGER,
136+
(block, props) -> new BlockItem(block, props.rarity(Rarity.RARE).stacksTo(1))
137+
);
138+
96139
public static final RegistryEntry<BlockItem> CHUNK_LOADER = ofBlock(
97140
Blocks.CHUNK_LOADER,
98141
(block, props) -> new BlockItem(block, props.rarity(Rarity.EPIC).stacksTo(1))
@@ -109,13 +152,15 @@ private Items() {}
109152
static class CreativeTabs {
110153
static final RegistrationHelper<CreativeModeTab> REGISTRY = PlatformHelper.get().createRegistrationHelper(Registries.CREATIVE_MODE_TAB);
111154

112-
private static final RegistryEntry<CreativeModeTab> TAB = REGISTRY.register("tab", () -> PlatformHelper.get().newCreativeModeTab()
113-
.icon(() -> new ItemStack(Items.CHUNK_LOADER.get()))
114-
.title(Component.translatable("itemGroup.vschunkloader"))
115-
.displayItems((context, out) -> {
116-
out.accept(Items.CHUNK_LOADER.get());
117-
out.accept(Items.CHUNK_LOADER_WEAK.get());
118-
})
119-
.build());
155+
private static final RegistryEntry<CreativeModeTab> TAB = REGISTRY.register(
156+
"tab",
157+
() -> PlatformHelper.get().newCreativeModeTab()
158+
.icon(() -> new ItemStack(Items.CHUNK_LOADER.get()))
159+
.title(Component.translatable("itemGroup.vschunkloader"))
160+
.displayItems((context, out) -> {
161+
Items.TAB_ITEMS.stream().map(RegistryEntry::get).forEach(out::accept);
162+
})
163+
.build()
164+
);
120165
}
121166
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package com.github.litermc.vschunkloader.attachment;
2+
3+
import com.github.litermc.vschunkloader.Constants;
4+
import com.github.litermc.vschunkloader.VSCApi;
5+
import com.github.litermc.vschunkloader.config.Config;
6+
import com.github.litermc.vschunkloader.platform.PlatformHelper;
7+
import com.github.litermc.vschunkloader.util.ShipAllocator;
8+
import com.github.litermc.vschunkloader.util.Utils;
9+
10+
import net.minecraft.resources.ResourceLocation;
11+
import net.minecraft.server.MinecraftServer;
12+
import net.minecraft.server.level.ServerLevel;
13+
14+
import com.fasterxml.jackson.annotation.JsonAutoDetect;
15+
import com.fasterxml.jackson.annotation.JsonGetter;
16+
import com.fasterxml.jackson.annotation.JsonSetter;
17+
import org.valkyrienskies.core.api.ships.LoadedServerShip;
18+
import org.valkyrienskies.core.api.ships.ServerShip;
19+
import org.valkyrienskies.core.api.ships.ServerTickListener;
20+
import org.valkyrienskies.core.apigame.world.ServerShipWorldCore;
21+
import org.valkyrienskies.mod.common.VSGameUtilsKt;
22+
23+
import java.util.Collection;
24+
import java.util.Collections;
25+
import java.util.HashSet;
26+
import java.util.Set;
27+
28+
@JsonAutoDetect(
29+
fieldVisibility = JsonAutoDetect.Visibility.NONE,
30+
isGetterVisibility = JsonAutoDetect.Visibility.NONE,
31+
getterVisibility = JsonAutoDetect.Visibility.NONE,
32+
setterVisibility = JsonAutoDetect.Visibility.NONE
33+
)
34+
public final class AmmoShipAttachment implements ServerTickListener {
35+
private static final ResourceLocation AMMO_SHIP_TICKET = new ResourceLocation(Constants.MOD_ID, "ammo_ship");
36+
37+
private final MinecraftServer server;
38+
private final ServerShipWorldCore world;
39+
private long shipId;
40+
private int activatedTick;
41+
private int unmanagedTick = 0;
42+
private boolean deactivated = false;
43+
44+
public AmmoShipAttachment() {
45+
this(-1);
46+
}
47+
48+
public AmmoShipAttachment(final long shipId) {
49+
this.server = PlatformHelper.get().getCurrentServer();
50+
this.world = VSGameUtilsKt.getShipObjectWorld(this.server);
51+
this.shipId = shipId;
52+
}
53+
54+
public static AmmoShipAttachment create(final ServerShip ship) {
55+
final AmmoShipAttachment attachment = new AmmoShipAttachment(ship.getId());
56+
ship.saveAttachment(AmmoShipAttachment.class, attachment);
57+
return attachment;
58+
}
59+
60+
@JsonGetter("shipId")
61+
private long getShipId() {
62+
return this.shipId;
63+
}
64+
65+
@JsonSetter("shipId")
66+
private void setShipId(final long shipId) {
67+
this.shipId = shipId;
68+
}
69+
70+
@JsonGetter("activatedTick")
71+
private long getActivatedTick() {
72+
return this.activatedTick;
73+
}
74+
75+
@JsonSetter("activatedTick")
76+
private void setActivatedTick(final int activatedTick) {
77+
this.activatedTick = activatedTick;
78+
}
79+
80+
@Override
81+
public void onServerTick() {
82+
if (this.activatedTick == 0) {
83+
this.checkActivate();
84+
return;
85+
}
86+
if (this.activatedTick > Config.ammoMaxActivateSeconds * 20) {
87+
if (!this.deactivated) {
88+
this.deactivated = true;
89+
this.deactivate();
90+
}
91+
return;
92+
}
93+
this.activatedTick++;
94+
}
95+
96+
public void managerTick() {
97+
this.unmanagedTick = 0;
98+
}
99+
100+
private ServerShip getShip() {
101+
final ServerShip ship = this.world.getLoadedShips().getById(this.shipId);
102+
if (ship != null) {
103+
return ship;
104+
}
105+
return this.world.getAllShips().getById(this.shipId);
106+
}
107+
108+
private void checkActivate() {
109+
if (this.unmanagedTick > 1) {
110+
this.activate();
111+
return;
112+
}
113+
this.unmanagedTick++;
114+
}
115+
116+
private void activate() {
117+
this.activatedTick = 1;
118+
VSCApi.forceLoad(this.server, this.shipId, AMMO_SHIP_TICKET, true);
119+
}
120+
121+
private void deactivate() {
122+
VSCApi.forceLoad(this.server, this.shipId, AMMO_SHIP_TICKET, false);
123+
if (!Config.removeAmmoAfterExpired) {
124+
return;
125+
}
126+
final ServerShip ship = this.getShip();
127+
if (ship == null) {
128+
return;
129+
}
130+
final ServerLevel level = Utils.getLevel(ship.getChunkClaimDimension());
131+
if (level == null) {
132+
this.world.deleteShip(ship);
133+
return;
134+
}
135+
PlatformHelper.get().queueTask(() -> ShipAllocator.get(level).putShip(ship));
136+
}
137+
}

common/src/main/java/com/github/litermc/vschunkloader/attachment/ForceLoadAttachment.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ public static ForceLoadAttachment get(final ServerShip ship) {
3232
return attachment;
3333
}
3434

35+
@JsonGetter("forceLoadTokens")
36+
private Collection<String> getForceLoadTokens() {
37+
return this.forceLoadTokens.stream().map(ResourceLocation::toString).toList();
38+
}
39+
40+
@JsonSetter("forceLoadTokens")
41+
private void setForceLoadTokens(final Collection<String> tokens) {
42+
this.forceLoadTokens.clear();
43+
tokens.stream().map(ResourceLocation::new).forEach(this.forceLoadTokens::add);
44+
}
45+
3546
public boolean isForceLoaded() {
3647
return !this.forceLoadTokens.isEmpty();
3748
}
@@ -55,15 +66,4 @@ public void removeAllForceLoadTokens() {
5566
public Set<ResourceLocation> getAllForceLoadTokens() {
5667
return Collections.unmodifiableSet(this.forceLoadTokens);
5768
}
58-
59-
@JsonGetter("forceLoadTokens")
60-
private Collection<String> getForceLoadTokens() {
61-
return this.forceLoadTokens.stream().map(ResourceLocation::toString).toList();
62-
}
63-
64-
@JsonSetter("forceLoadTokens")
65-
private void setForceLoadTokens(final Collection<String> tokens) {
66-
this.forceLoadTokens.clear();
67-
tokens.stream().map(ResourceLocation::new).forEach(this.forceLoadTokens::add);
68-
}
6969
}

common/src/main/java/com/github/litermc/vschunkloader/block/ChunkLoaderWeakBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import net.minecraft.world.level.block.state.BlockBehaviour;
1313
import net.minecraft.world.level.block.state.BlockState;
1414

15-
public class ChunkLoaderWeakBlock extends Block implements EntityBlock {
15+
public final class ChunkLoaderWeakBlock extends Block implements EntityBlock {
1616
public ChunkLoaderWeakBlock(final BlockBehaviour.Properties props) {
1717
super(props);
1818
}

common/src/main/java/com/github/litermc/vschunkloader/block/ChunkLoaderWeakBlockEntity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import net.minecraft.world.level.block.entity.BlockEntity;
1010
import net.minecraft.world.level.block.state.BlockState;
1111

12-
public class ChunkLoaderWeakBlockEntity extends ChunkLoaderBlockEntity {
12+
public final class ChunkLoaderWeakBlockEntity extends ChunkLoaderBlockEntity {
1313
private int secondsUsed = 0;
1414

1515
public ChunkLoaderWeakBlockEntity(final BlockPos pos, final BlockState state) {

0 commit comments

Comments
 (0)