Silly Minecraft mod that adds Asbestos
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Port to Kotlin

Signed-off-by: Naomi Roberts <mia@naomieow.xyz>

lesbian.skin 5853dc36 65b2049a

verified
+1310 -1221
+11 -5
build.gradle.kts
··· 1 1 plugins { 2 - id("fabric-loom") version "1.2-SNAPSHOT" 2 + id("fabric-loom") version "1.10-SNAPSHOT" 3 3 id("maven-publish") 4 + kotlin("jvm") version libs.versions.kotlin 5 + alias(libs.plugins.ksp) 4 6 } 5 7 6 8 val minecraft_version = "1.20.1" ··· 10 12 11 13 repositories { 12 14 maven("https://maven.wispforest.io") 15 + maven("https://maven.kosmx.dev/") 13 16 maven("https://maven.ladysnake.org/releases") { 14 17 name = "Ladysnake Mods" 15 18 } ··· 20 23 mappings(loom.officialMojangMappings()) 21 24 22 25 // fabric stuff 26 + modImplementation(libs.fabric.kotlin) 23 27 modImplementation(libs.fabric.loader) 24 28 modImplementation(libs.fabric.api) 25 29 26 30 // owo-lib 27 - modImplementation(libs.owo.lib) 31 + modImplementation(libs.owo.lib)?.let(::annotationProcessor) 28 32 include(libs.owo.sentinel) 29 - annotationProcessor(libs.owo.lib) 33 + implementation(libs.ksp) 34 + implementation(libs.kotlinpoet) 35 + ksp(libs.owo.ksp) 30 36 31 37 // Cardinal Components API 32 38 modImplementation(libs.cca.base)?.let(::include) ··· 38 44 val props = buildMap { 39 45 put("version", project.version) 40 46 put("minecraft_version", minecraft_version) 41 - put("loader_version", libs.versions.fabric.loader) 47 + put("loader_version", "0.16.9") 42 48 } 43 49 44 50 props.forEach(inputs::property) ··· 55 61 rename { "${it}_${base.archivesName}"} 56 62 } 57 63 } 58 - } 64 + }
+1 -1
gradle/wrapper/gradle-wrapper.properties
··· 1 1 distributionBase=GRADLE_USER_HOME 2 2 distributionPath=wrapper/dists 3 - distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip 3 + distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip 4 4 networkTimeout=10000 5 5 zipStoreBase=GRADLE_USER_HOME 6 6 zipStorePath=wrapper/dists
+18 -6
libs.versions.toml
··· 1 1 [versions] 2 - fabric-loader="0.14.22" 3 - fabric-api="0.89.3+1.20.1" 4 - owo="0.11.1+1.20" 2 + kotlin = "2.1.0" 3 + fabric-kotlin = "1.13.0+kotlin.2.1.0" 4 + fabric-loader= "0.16.9" 5 + fabric-api = "0.89.3+1.20.1" 6 + owo-lib = "0.11.1+1.20" 7 + owo-ksp = "0.1.0" 5 8 cca = "5.2.2" 9 + ksp = "2.1.0-1.0.29" 10 + kotlinpoet = "1.17.0" 6 11 7 12 [libraries] 13 + fabric-kotlin = { module = "net.fabricmc:fabric-language-kotlin", version.ref = "fabric-kotlin" } 8 14 fabric-loader = { module = "net.fabricmc:fabric-loader", version.ref = "fabric-loader" } 9 15 fabric-api = { module = "net.fabricmc.fabric-api:fabric-api", version.ref = "fabric-api" } 10 - owo-lib = { module = "io.wispforest:owo-lib", version.ref = "owo" } 11 - owo-sentinel = { module = "io.wispforest:owo-sentinel", version.ref = "owo" } 16 + owo-lib = { module = "io.wispforest:owo-lib", version.ref = "owo-lib" } 17 + owo-sentinel = { module = "io.wispforest:owo-sentinel", version.ref = "owo-lib" } 18 + owo-ksp = { module = "dev.kosmx.kowoconfig:ksp-owo-config", version.ref = "owo-ksp" } 12 19 cca-base = { module = "dev.onyxstudios.cardinal-components-api:cardinal-components-base", version.ref = "cca" } 13 - cca-entity = { module = "dev.onyxstudios.cardinal-components-api:cardinal-components-entity", version.ref = "cca" } 20 + cca-entity = { module = "dev.onyxstudios.cardinal-components-api:cardinal-components-entity", version.ref = "cca" } 21 + ksp = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } 22 + kotlinpoet = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlinpoet" } 23 + 24 + [plugins] 25 + ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
-56
src/main/java/xyz/naomieow/asbestos/AsbestosMod.java
··· 1 - package xyz.naomieow.asbestos; 2 - 3 - import dev.onyxstudios.cca.api.v3.component.ComponentKey; 4 - import dev.onyxstudios.cca.api.v3.component.ComponentRegistryV3; 5 - import dev.onyxstudios.cca.api.v3.entity.EntityComponentFactoryRegistry; 6 - import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer; 7 - import dev.onyxstudios.cca.api.v3.entity.RespawnCopyStrategy; 8 - import io.wispforest.owo.registration.reflect.FieldRegistrationHandler; 9 - import net.fabricmc.api.ModInitializer; 10 - import net.fabricmc.fabric.api.biome.v1.BiomeModifications; 11 - import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; 12 - import net.minecraft.core.Registry; 13 - import net.minecraft.core.registries.BuiltInRegistries; 14 - import net.minecraft.core.registries.Registries; 15 - import net.minecraft.resources.ResourceKey; 16 - import net.minecraft.resources.ResourceLocation; 17 - import net.minecraft.world.effect.MobEffect; 18 - import net.minecraft.world.level.block.Block; 19 - import net.minecraft.world.level.levelgen.GenerationStep; 20 - import net.minecraft.world.level.levelgen.placement.PlacedFeature; 21 - import xyz.naomieow.asbestos.block.ModBlocks; 22 - import xyz.naomieow.asbestos.config.AsbestosConfig; 23 - import xyz.naomieow.asbestos.item.ModGroups; 24 - import xyz.naomieow.asbestos.item.ModItems; 25 - import xyz.naomieow.asbestos.mesothelioma.MesoComponent; 26 - import xyz.naomieow.asbestos.mesothelioma.MesoStatusEffect; 27 - import xyz.naomieow.asbestos.mesothelioma.PlayerMesoComponet; 28 - import xyz.naomieow.asbestos.screen.ModHandlers; 29 - 30 - public class AsbestosMod implements ModInitializer, EntityComponentInitializer { 31 - public static final String MOD_ID = "asbestos"; 32 - public static final ComponentKey<MesoComponent> MESOTHELIOMA = ComponentRegistryV3.INSTANCE 33 - .getOrCreate(new ResourceLocation(MOD_ID, "mesothelioma"), MesoComponent.class); 34 - public static final AsbestosConfig CONFIG = AsbestosConfig.createAndLoad(); 35 - public static final MobEffect MESO_STATUS = new MesoStatusEffect(); 36 - public static final Block[] HARMFUL_PASSIVE_BLOCKS = { ModBlocks.ASBESTOS_BLOCK}; 37 - public static final ResourceKey<PlacedFeature> SERPENTINITE_PLACED_KEY = ResourceKey.create(Registries.PLACED_FEATURE, new ResourceLocation(MOD_ID, "serpentinite")); 38 - 39 - 40 - 41 - @Override 42 - public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) { 43 - registry.registerForPlayers(MESOTHELIOMA, PlayerMesoComponet::new, RespawnCopyStrategy.NEVER_COPY); 44 - } 45 - 46 - @Override 47 - public void onInitialize() { 48 - FieldRegistrationHandler.register(ModItems.class, MOD_ID, false); 49 - FieldRegistrationHandler.register(ModBlocks.class, MOD_ID, false); 50 - FieldRegistrationHandler.register(ModHandlers.class, MOD_ID, false); 51 - Registry.register(BuiltInRegistries.MOB_EFFECT, new ResourceLocation(MOD_ID, "mesothelioma"), MESO_STATUS); 52 - BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, SERPENTINITE_PLACED_KEY); 53 - ModGroups.init(); 54 - ModScheduler.init(); 55 - } 56 - }
-16
src/main/java/xyz/naomieow/asbestos/AsbestosModClient.java
··· 1 - package xyz.naomieow.asbestos; 2 - 3 - import net.fabricmc.api.ClientModInitializer; 4 - import net.fabricmc.api.EnvType; 5 - import net.fabricmc.api.Environment; 6 - import net.minecraft.client.gui.screens.MenuScreens; 7 - import xyz.naomieow.asbestos.screen.CancerMeterScreen; 8 - import xyz.naomieow.asbestos.screen.ModHandlers; 9 - 10 - @Environment(EnvType.CLIENT) 11 - public class AsbestosModClient implements ClientModInitializer { 12 - @Override 13 - public void onInitializeClient() { 14 - MenuScreens.register(ModHandlers.CANCER_METER, CancerMeterScreen::new); 15 - } 16 - }
-46
src/main/java/xyz/naomieow/asbestos/ModScheduler.java
··· 1 - package xyz.naomieow.asbestos; 2 - 3 - import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; 4 - import net.minecraft.core.BlockPos; 5 - import net.minecraft.world.effect.MobEffectInstance; 6 - import net.minecraft.world.level.block.Block; 7 - import net.minecraft.world.phys.Vec3; 8 - import xyz.naomieow.asbestos.block.CarcinogenicBlock; 9 - 10 - import java.util.Arrays; 11 - 12 - public class ModScheduler { 13 - public static void init() { 14 - ServerTickEvents.END_SERVER_TICK.register( server -> { 15 - if (server.getTickCount() % (AsbestosMod.CONFIG.period() * 20) == 0) { 16 - server.getAllLevels().forEach(serverWorld -> serverWorld.players().forEach(serverPlayerEntity -> { 17 - int exposure = AsbestosMod.MESOTHELIOMA.get(serverPlayerEntity).getMesothelioma(); 18 - 19 - if (exposure >= (AsbestosMod.CONFIG.threshold() / 2)) { 20 - serverPlayerEntity.addEffect(new MobEffectInstance(AsbestosMod.MESO_STATUS, -1)); 21 - } 22 - 23 - if (CarcinogenicBlock.isProtectedFromAsbestos(serverPlayerEntity)) { 24 - return; 25 - } 26 - 27 - int offset = AsbestosMod.CONFIG.offset(); 28 - 29 - findasbestos: for (int i = -offset; i < offset; i++) { 30 - for (int j = -offset; j < offset; j++) { 31 - for (int k = -offset; k < offset; k++) { 32 - Vec3 offsetPos = serverPlayerEntity.position().add(i, j, k); 33 - BlockPos pos = new BlockPos((int) offsetPos.x(), (int) offsetPos.y(), (int) offsetPos.z()); 34 - Block block = serverWorld.getBlockState(pos).getBlock(); 35 - if (Arrays.asList(AsbestosMod.HARMFUL_PASSIVE_BLOCKS).contains(block)) { 36 - AsbestosMod.MESOTHELIOMA.get(serverPlayerEntity).setMesothelioma(exposure + 1); 37 - break findasbestos; 38 - } 39 - } 40 - } 41 - } 42 - })); 43 - } 44 - }); 45 - } 46 - }
-55
src/main/java/xyz/naomieow/asbestos/armour/ProtectiveMaterial.java
··· 1 - package xyz.naomieow.asbestos.armour; 2 - 3 - import net.minecraft.sounds.SoundEvent; 4 - import net.minecraft.sounds.SoundEvents; 5 - import net.minecraft.world.item.ArmorItem; 6 - import net.minecraft.world.item.ArmorMaterial; 7 - import net.minecraft.world.item.Items; 8 - import net.minecraft.world.item.crafting.Ingredient; 9 - 10 - public class ProtectiveMaterial implements ArmorMaterial { 11 - private static final int[] BASE_DURABILITY = new int[] { 13, 15, 16, 11 }; 12 - private static final int[] PROTECTION_VALUES = new int[] { 1, 1, 2, 1 }; 13 - 14 - public static final ProtectiveMaterial INSTANCE = new ProtectiveMaterial(); 15 - 16 - @Override 17 - public int getDurabilityForType(ArmorItem.Type type) { 18 - return BASE_DURABILITY[type.getSlot().getIndex()]; 19 - } 20 - 21 - @Override 22 - public int getDefenseForType(ArmorItem.Type type) { 23 - return PROTECTION_VALUES[type.getSlot().getIndex()]; 24 - } 25 - 26 - @Override 27 - public int getEnchantmentValue() { 28 - return 4; 29 - } 30 - 31 - @Override 32 - public SoundEvent getEquipSound() { 33 - return SoundEvents.WOOL_HIT; 34 - } 35 - 36 - @Override 37 - public Ingredient getRepairIngredient() { 38 - return Ingredient.of(Items.STRING); 39 - } 40 - 41 - @Override 42 - public String getName() { 43 - return "asbestos_protective"; 44 - } 45 - 46 - @Override 47 - public float getToughness() { 48 - return 0; 49 - } 50 - 51 - @Override 52 - public float getKnockbackResistance() { 53 - return 0; 54 - } 55 - }
-64
src/main/java/xyz/naomieow/asbestos/block/AsbestosRoofBlock.java
··· 1 - package xyz.naomieow.asbestos.block; 2 - 3 - import net.fabricmc.api.EnvType; 4 - import net.fabricmc.api.Environment; 5 - import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; 6 - import net.fabricmc.loader.api.FabricLoader; 7 - import net.minecraft.client.renderer.RenderType; 8 - import net.minecraft.core.BlockPos; 9 - import net.minecraft.core.Direction; 10 - import net.minecraft.world.item.context.BlockPlaceContext; 11 - import net.minecraft.world.level.BlockGetter; 12 - import net.minecraft.world.level.block.Block; 13 - import net.minecraft.world.level.block.state.BlockState; 14 - import net.minecraft.world.level.block.state.StateDefinition; 15 - import net.minecraft.world.level.block.state.properties.BlockStateProperties; 16 - import net.minecraft.world.phys.shapes.CollisionContext; 17 - import net.minecraft.world.phys.shapes.Shapes; 18 - import net.minecraft.world.phys.shapes.VoxelShape; 19 - import org.jetbrains.annotations.Nullable; 20 - 21 - public class AsbestosRoofBlock extends CarcinogenicBlock { 22 - public AsbestosRoofBlock(Properties settings, int dangerLevel) { 23 - super(settings, dangerLevel); 24 - registerDefaultState(this.getStateDefinition().any().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.NORTH)); 25 - if (FabricLoader.getInstance().getEnvironmentType() != EnvType.SERVER) { 26 - BlockRenderLayerMap.INSTANCE.putBlock(this, RenderType.cutout()); 27 - } 28 - } 29 - 30 - @Override 31 - protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { 32 - builder.add(BlockStateProperties.HORIZONTAL_FACING); 33 - } 34 - 35 - @Override 36 - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { 37 - 38 - Direction dir = state.getValue(BlockStateProperties.HORIZONTAL_FACING); 39 - return switch (dir) { 40 - case NORTH -> Shapes.or(Shapes.box(0, 0, 0, 1, 0.5, 1), 41 - Shapes.box(0, 0.5, 0.5, 1, 1, 1)); 42 - case SOUTH -> Shapes.or(Shapes.box(0, 0, 0, 1, 0.5, 1), 43 - Shapes.box(0, 0.5, 0, 1, 1, 0.5)); 44 - case EAST -> Shapes.or(Shapes.box(0, 0, 0, 1, 0.5, 1), 45 - Shapes.box(0, 0.5, 0, 0.5, 1, 1)); 46 - case WEST -> Shapes.or(Shapes.box(0, 0, 0, 1, 0.5, 1), 47 - Shapes.box(0.5, 0.5, 0, 1, 1, 1)); 48 - default -> Shapes.block(); 49 - }; 50 - } 51 - 52 - @Nullable 53 - @Override 54 - public BlockState getStateForPlacement(BlockPlaceContext ctx) { 55 - return this.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, 56 - ctx.getHorizontalDirection().getOpposite()); 57 - } 58 - 59 - @Environment(EnvType.CLIENT) 60 - @Override 61 - public float getShadeBrightness(BlockState state, BlockGetter world, BlockPos pos) { 62 - return 1.0f; 63 - } 64 - }
-41
src/main/java/xyz/naomieow/asbestos/block/CarcinogenicBlock.java
··· 1 - package xyz.naomieow.asbestos.block; 2 - 3 - import xyz.naomieow.asbestos.AsbestosMod; 4 - import xyz.naomieow.asbestos.item.ModItems; 5 - 6 - import java.util.Arrays; 7 - import net.minecraft.core.BlockPos; 8 - import net.minecraft.world.entity.player.Player; 9 - import net.minecraft.world.item.Item; 10 - import net.minecraft.world.item.ItemStack; 11 - import net.minecraft.world.level.Level; 12 - import net.minecraft.world.level.block.Block; 13 - import net.minecraft.world.level.block.state.BlockState; 14 - 15 - public class CarcinogenicBlock extends Block { 16 - private int dangerLevel; 17 - public static Item[] PROTECTIVE_ARMOUR = {ModItems.PPE_HELMET, ModItems.PPE_CHESTPLATE, ModItems.PPE_LEGGINGS, ModItems.PPE_BOOTS}; 18 - 19 - public CarcinogenicBlock(Properties settings, int dangerLevel) { 20 - super(settings); 21 - this.dangerLevel = dangerLevel; 22 - } 23 - 24 - public static boolean isProtectedFromAsbestos(Player player) { 25 - for (ItemStack item : player.getArmorSlots()) { 26 - if (!Arrays.asList(PROTECTIVE_ARMOUR).contains(item.getItem())) { 27 - return false; 28 - } 29 - } 30 - return true; 31 - } 32 - 33 - @Override 34 - public void playerWillDestroy(Level world, BlockPos pos, BlockState state, Player player) { 35 - super.playerWillDestroy(world, pos, state, player); 36 - if (!isProtectedFromAsbestos(player)) { 37 - int exposure = AsbestosMod.MESOTHELIOMA.get(player).getMesothelioma(); 38 - AsbestosMod.MESOTHELIOMA.get(player).setMesothelioma(exposure + dangerLevel); 39 - } 40 - } 41 - }
-27
src/main/java/xyz/naomieow/asbestos/block/ModBlocks.java
··· 1 - package xyz.naomieow.asbestos.block; 2 - 3 - import io.wispforest.owo.itemgroup.OwoItemSettings; 4 - import io.wispforest.owo.registration.reflect.BlockRegistryContainer; 5 - import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; 6 - import net.minecraft.world.item.BlockItem; 7 - import net.minecraft.world.level.block.Block; 8 - import net.minecraft.world.level.block.Blocks; 9 - import xyz.naomieow.asbestos.item.ModGroups; 10 - 11 - public class ModBlocks implements BlockRegistryContainer { 12 - public static final Block ASBESTOS_BLOCK = new CarcinogenicBlock( 13 - FabricBlockSettings.copyOf(Blocks.WHITE_WOOL).destroyTime(1.0f), 40); 14 - public static final Block SERPENTINITE_BLOCK = new CarcinogenicBlock( 15 - FabricBlockSettings.copyOf(Blocks.STONE).destroyTime(3.0f).requiresCorrectToolForDrops(), 20); 16 - public static final Block POPCORN_CEILING_BLOCK = new CarcinogenicBlock( 17 - FabricBlockSettings.copyOf(Blocks.OAK_PLANKS).destroyTime(2.0f), 20); 18 - public static final Block ASBESTOS_TILE_BLOCK = new CarcinogenicBlock( 19 - FabricBlockSettings.copyOf(Blocks.NETHER_BRICKS).destroyTime(3.0f), 20); 20 - public static final Block ASBESTOS_ROOF_BLOCK = new AsbestosRoofBlock( 21 - FabricBlockSettings.copyOf(ASBESTOS_TILE_BLOCK).noOcclusion(), 20); 22 - 23 - @Override 24 - public BlockItem createBlockItem(Block block, String identifier) { 25 - return new BlockItem(block, new OwoItemSettings().group(ModGroups.ASBESTOS_GROUP)); 26 - } 27 - }
-16
src/main/java/xyz/naomieow/asbestos/config/ModConfigModel.java
··· 1 - package xyz.naomieow.asbestos.config; 2 - 3 - import io.wispforest.owo.config.annotation.Config; 4 - import io.wispforest.owo.config.annotation.Modmenu; 5 - import io.wispforest.owo.config.annotation.RangeConstraint; 6 - import xyz.naomieow.asbestos.AsbestosMod; 7 - 8 - @Modmenu(modId = AsbestosMod.MOD_ID) 9 - @Config(name = "asbestos_config", wrapperName = "AsbestosConfig") 10 - public class ModConfigModel { 11 - @RangeConstraint(min = 0, max = 32) 12 - public int offset = 3; 13 - public int period = 5; 14 - public int threshold = 180; 15 - public int exsanguination = 1; 16 - }
-20
src/main/java/xyz/naomieow/asbestos/damage/ModDamageTypes.java
··· 1 - package xyz.naomieow.asbestos.damage; 2 - 3 - 4 - import net.minecraft.core.registries.Registries; 5 - import net.minecraft.resources.ResourceKey; 6 - import net.minecraft.resources.ResourceLocation; 7 - import net.minecraft.world.damagesource.DamageSource; 8 - import net.minecraft.world.damagesource.DamageType; 9 - import net.minecraft.world.level.Level; 10 - import xyz.naomieow.asbestos.AsbestosMod; 11 - 12 - public class ModDamageTypes { 13 - public static final ResourceKey<DamageType> MESOTHELIOMA = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(AsbestosMod.MOD_ID, "mesothelioma")); 14 - public static final ResourceKey<DamageType> BLOOD_EXTRACT = ResourceKey.create(Registries.DAMAGE_TYPE, new ResourceLocation(AsbestosMod.MOD_ID, "blood_extract")); 15 - 16 - public static DamageSource of(Level world, ResourceKey<DamageType> key) { 17 - return new DamageSource(world.registryAccess().registryOrThrow(Registries.DAMAGE_TYPE).getHolderOrThrow(key)); 18 - } 19 - 20 - }
-160
src/main/java/xyz/naomieow/asbestos/inventory/CancerMeterInventory.java
··· 1 - package xyz.naomieow.asbestos.inventory; 2 - 3 - import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; 4 - import net.minecraft.core.NonNullList; 5 - import net.minecraft.nbt.CompoundTag; 6 - import net.minecraft.nbt.ListTag; 7 - import net.minecraft.network.FriendlyByteBuf; 8 - import net.minecraft.network.chat.Component; 9 - import net.minecraft.server.level.ServerPlayer; 10 - import net.minecraft.world.entity.player.Inventory; 11 - import net.minecraft.world.entity.player.Player; 12 - import net.minecraft.world.inventory.AbstractContainerMenu; 13 - import net.minecraft.world.item.ItemStack; 14 - import net.minecraft.world.level.Level; 15 - import org.jetbrains.annotations.Nullable; 16 - import xyz.naomieow.asbestos.screen.CancerMeterScreenHandler; 17 - 18 - public class CancerMeterInventory implements ICancerMeterInventory { 19 - private InventoryImproved inventory = createInventory(1); 20 - private final Player player; 21 - private final byte screenID; 22 - private ItemStack stack; 23 - 24 - 25 - public CancerMeterInventory(ItemStack stack, Player player, byte screenID) { 26 - this.player = player; 27 - this.stack = stack; 28 - this.screenID = screenID; 29 - 30 - if (stack != null){ 31 - this.readAllData(stack.getOrCreateTag()); 32 - } 33 - } 34 - 35 - public void setStack(ItemStack stack) { 36 - this.stack = stack; 37 - } 38 - 39 - @Override 40 - public InventoryImproved getInventory() { 41 - return this.inventory; 42 - } 43 - 44 - @Override 45 - public void writeAllData(CompoundTag nbt) { 46 - this.writeItems(nbt); 47 - } 48 - 49 - @Override 50 - public void readAllData(CompoundTag nbt) { 51 - this.readItems(nbt); 52 - } 53 - 54 - @Override 55 - public void writeItems(CompoundTag nbt) { 56 - CancerMeterInventory.writeNbt(nbt, this.inventory.getStacks(), true); 57 - } 58 - 59 - @Override 60 - public void readItems(CompoundTag nbt) { 61 - this.inventory = createInventory(1); 62 - CancerMeterInventory.readNbt(nbt, this.inventory.getStacks()); 63 - } 64 - 65 - @Override 66 - public Level getWorld() { 67 - return this.player.level(); 68 - } 69 - 70 - @Override 71 - public byte getScreenID() { 72 - return this.screenID; 73 - } 74 - 75 - @Override 76 - public ItemStack getItemStack() { 77 - return this.stack == null ? ItemStack.EMPTY : this.stack; 78 - } 79 - 80 - @Override 81 - public void setUsingPlayer(@Nullable Player player) { } 82 - 83 - @Override 84 - public void markDataDirty(byte... dataIds) { 85 - if (this.getWorld().isClientSide() || this.stack == null) return; 86 - 87 - for (byte data : dataIds) { 88 - switch (data) { 89 - case INVENTORY_DATA -> CancerMeterInventory.writeNbt(this.stack.getOrCreateTag(), this.getInventory().getStacks(), true); 90 - case COMBINED_INVENTORY_DATA -> writeItems(stack.getOrCreateTag()); 91 - case ALL_DATA -> writeAllData(stack.getOrCreateTag()); 92 - } 93 - } 94 - } 95 - 96 - @Override 97 - public void markDirty() { } 98 - 99 - public static void openHandledScreen(Player player, ItemStack stack, byte screenID) { 100 - if (!player.level().isClientSide()) { 101 - player.openMenu(new ExtendedScreenHandlerFactory() { 102 - @Override 103 - public void writeScreenOpeningData(ServerPlayer player, FriendlyByteBuf buf) { 104 - buf.writeByte(screenID); 105 - } 106 - 107 - @Override 108 - public Component getDisplayName() { 109 - return Component.translatable("screen.asbestos.cancer_meter"); 110 - } 111 - 112 - @Nullable 113 - @Override 114 - public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) { 115 - return new CancerMeterScreenHandler(syncId, playerInventory, new CancerMeterInventory(stack, player, screenID)); 116 - } 117 - }); 118 - } 119 - } 120 - 121 - private InventoryImproved createInventory(int size) { 122 - return new InventoryImproved(NonNullList.withSize(size, ItemStack.EMPTY)) { 123 - @Override 124 - public void setChanged() { 125 - markDataDirty(COMBINED_INVENTORY_DATA); 126 - } 127 - }; 128 - } 129 - 130 - private static CompoundTag writeNbt(CompoundTag nbt, NonNullList<ItemStack> stacks, boolean setIfEmpty) { 131 - ListTag nbtList = new ListTag(); 132 - for (int i = 0; i < stacks.size(); ++i) { 133 - ItemStack itemStack = stacks.get(i); 134 - if (!itemStack.isEmpty()) { 135 - CompoundTag nbtCompound = new CompoundTag(); 136 - nbtCompound.putByte("Slot", (byte)i); 137 - itemStack.save(nbtCompound); 138 - nbtList.add(nbtCompound); 139 - } 140 - } 141 - 142 - if (!nbtList.isEmpty() || setIfEmpty) { 143 - nbt.put("Inventory", nbtList); 144 - } 145 - 146 - return nbt; 147 - } 148 - 149 - private static void readNbt(CompoundTag nbt, NonNullList<ItemStack> stacks) { 150 - ListTag nbtList = nbt.getList("Inventory", 10); 151 - 152 - for(int i = 0; i < nbtList.size(); ++i) { 153 - CompoundTag nbtCompound = nbtList.getCompound(i); 154 - int j = nbtCompound.getByte("Slot") & 255; 155 - if (j >= 0 && j < stacks.size()) { 156 - stacks.set(j, ItemStack.of(nbtCompound)); 157 - } 158 - } 159 - } 160 - }
-26
src/main/java/xyz/naomieow/asbestos/inventory/ICancerMeterInventory.java
··· 1 - package xyz.naomieow.asbestos.inventory; 2 - 3 - import net.minecraft.nbt.CompoundTag; 4 - import net.minecraft.world.entity.player.Player; 5 - import net.minecraft.world.item.ItemStack; 6 - import net.minecraft.world.level.Level; 7 - 8 - public interface ICancerMeterInventory { 9 - void writeItems(CompoundTag nbt); 10 - void readItems(CompoundTag nbt); 11 - void writeAllData(CompoundTag nbt); 12 - void readAllData(CompoundTag nbt); 13 - InventoryImproved getInventory(); 14 - byte getScreenID(); 15 - Level getWorld(); 16 - ItemStack getItemStack(); 17 - void setUsingPlayer(Player player); 18 - 19 - byte INVENTORY_DATA = 0; 20 - byte COMBINED_INVENTORY_DATA = 1; 21 - byte SLOT_DATA = 2; 22 - byte ALL_DATA = 3; 23 - 24 - void markDataDirty(byte... dataIds); 25 - void markDirty(); 26 - }
-112
src/main/java/xyz/naomieow/asbestos/inventory/InventoryImproved.java
··· 1 - package xyz.naomieow.asbestos.inventory; 2 - 3 - import net.minecraft.core.NonNullList; 4 - import net.minecraft.world.Container; 5 - import net.minecraft.world.ContainerHelper; 6 - import net.minecraft.world.entity.player.Player; 7 - import net.minecraft.world.item.ItemStack; 8 - import xyz.naomieow.asbestos.item.ModItems; 9 - 10 - /* 11 - Originally by Tiviacz1337<br> 12 - https://github.com/Tiviacz1337/Travelers-Backpack/blob/1.20.1-fabric/src/main/java/com/tiviacz/travelersbackpack/inventory/InventoryImproved.java 13 - */ 14 - public abstract class InventoryImproved implements Container 15 - { 16 - protected final NonNullList<ItemStack> stacks; 17 - 18 - public InventoryImproved(NonNullList<ItemStack> stacks) 19 - { 20 - this.stacks = stacks; 21 - } 22 - 23 - public NonNullList<ItemStack> getStacks() 24 - { 25 - return this.stacks; 26 - } 27 - 28 - @Override 29 - public int getContainerSize() 30 - { 31 - return this.stacks.size(); 32 - } 33 - 34 - @Override 35 - public boolean isEmpty() 36 - { 37 - for(int i = 0; i < getContainerSize(); i++) 38 - { 39 - if(!getItem(i).isEmpty()) 40 - { 41 - return false; 42 - } 43 - } 44 - return true; 45 - } 46 - 47 - @Override 48 - public ItemStack getItem(int slot) 49 - { 50 - return this.stacks.get(slot); 51 - } 52 - 53 - @Override 54 - public ItemStack removeItem(int slot, int amount) 55 - { 56 - ItemStack itemstack = ContainerHelper.removeItem(this.stacks, slot, amount); 57 - 58 - if(!itemstack.isEmpty()) 59 - { 60 - this.setChanged(); 61 - } 62 - return itemstack; 63 - } 64 - 65 - @Override 66 - public ItemStack removeItemNoUpdate(int slot) 67 - { 68 - ItemStack itemStack = this.stacks.get(slot); 69 - if(itemStack.isEmpty()) 70 - { 71 - return ItemStack.EMPTY; 72 - } 73 - else 74 - { 75 - this.stacks.set(slot, ItemStack.EMPTY); 76 - return itemStack; 77 - } 78 - } 79 - 80 - @Override 81 - public void setItem(int slot, ItemStack stack) 82 - { 83 - this.stacks.set(slot, stack); 84 - if(!stack.isEmpty() && stack.getCount() > this.getMaxStackSize()) 85 - { 86 - stack.setCount(this.getMaxStackSize()); 87 - } 88 - 89 - this.setChanged(); 90 - } 91 - 92 - @Override 93 - public abstract void setChanged(); 94 - 95 - @Override 96 - public boolean canPlaceItem(int slot, ItemStack stack) 97 - { 98 - return !(stack.getItem() == ModItems.CANCER_METER); 99 - } 100 - 101 - @Override 102 - public boolean stillValid(Player player) 103 - { 104 - return true; 105 - } 106 - 107 - @Override 108 - public void clearContent() 109 - { 110 - 111 - } 112 - }
-28
src/main/java/xyz/naomieow/asbestos/item/CancerMeterItem.java
··· 1 - package xyz.naomieow.asbestos.item; 2 - 3 - import net.minecraft.world.InteractionHand; 4 - import net.minecraft.world.InteractionResultHolder; 5 - import net.minecraft.world.entity.player.Player; 6 - import net.minecraft.world.item.Item; 7 - import net.minecraft.world.item.ItemStack; 8 - import net.minecraft.world.level.Level; 9 - import xyz.naomieow.asbestos.inventory.CancerMeterInventory; 10 - 11 - public class CancerMeterItem extends Item { 12 - public CancerMeterItem(Properties settings) { 13 - super(settings); 14 - } 15 - 16 - @Override 17 - public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) { 18 - ItemStack itemStack = user.getItemInHand(hand); 19 - if (hand == InteractionHand.OFF_HAND) { 20 - return InteractionResultHolder.fail(itemStack); 21 - } 22 - 23 - if (!world.isClientSide()) { 24 - CancerMeterInventory.openHandledScreen(user, user.getMainHandItem(), (byte) 1); 25 - } 26 - return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide()); 27 - } 28 - }
-49
src/main/java/xyz/naomieow/asbestos/item/EmptySyringeItem.java
··· 1 - package xyz.naomieow.asbestos.item; 2 - 3 - import net.minecraft.sounds.SoundEvents; 4 - import net.minecraft.sounds.SoundSource; 5 - import net.minecraft.world.InteractionHand; 6 - import net.minecraft.world.InteractionResult; 7 - import net.minecraft.world.InteractionResultHolder; 8 - import net.minecraft.world.entity.LivingEntity; 9 - import net.minecraft.world.entity.player.Player; 10 - import net.minecraft.world.item.Item; 11 - import net.minecraft.world.item.ItemStack; 12 - import net.minecraft.world.level.Level; 13 - import xyz.naomieow.asbestos.AsbestosMod; 14 - import xyz.naomieow.asbestos.damage.ModDamageTypes; 15 - 16 - public class EmptySyringeItem extends Item { 17 - public EmptySyringeItem(Properties settings) { 18 - super(settings); 19 - } 20 - 21 - @Override 22 - public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) { 23 - useEmptySyringe(user, user, hand, world); 24 - return InteractionResultHolder.consume(user.getItemInHand(hand)); 25 - } 26 - 27 - @Override 28 - public InteractionResult interactLivingEntity(ItemStack stack, Player user, LivingEntity entity, InteractionHand hand) { 29 - Level world = user.level(); 30 - useEmptySyringe(user, entity, hand, world); 31 - return InteractionResult.CONSUME; 32 - } 33 - 34 - 35 - private void useEmptySyringe(Player user, LivingEntity target, InteractionHand hand, Level world) { 36 - world.playSound(null, user.blockPosition(), SoundEvents.BOTTLE_FILL, SoundSource.PLAYERS, 1.0F, 1.0F); 37 - ItemStack handStack = user.getItemInHand(hand); 38 - ItemStack newStack = new ItemStack(ModItems.FILLED_SYRINGE, 1); 39 - newStack.setTag(handStack.getOrCreateTag().copy()); 40 - FilledSyringeItem.writeNbt(target, newStack); 41 - target.hurt(ModDamageTypes.of(user.level(), ModDamageTypes.BLOOD_EXTRACT), AsbestosMod.CONFIG.exsanguination()); 42 - if (!user.getInventory().add(newStack)) { 43 - user.drop(newStack, false); 44 - } 45 - if (!user.getAbilities().instabuild) { 46 - handStack.shrink(1); 47 - } 48 - } 49 - }
-29
src/main/java/xyz/naomieow/asbestos/item/FilledSyringeItem.java
··· 1 - package xyz.naomieow.asbestos.item; 2 - 3 - import net.minecraft.ChatFormatting; 4 - import net.minecraft.nbt.CompoundTag; 5 - import net.minecraft.network.chat.Component; 6 - import net.minecraft.world.entity.EntityType; 7 - import net.minecraft.world.entity.LivingEntity; 8 - import net.minecraft.world.entity.player.Player; 9 - import net.minecraft.world.item.Item; 10 - import net.minecraft.world.item.ItemStack; 11 - import xyz.naomieow.asbestos.AsbestosMod; 12 - 13 - public class FilledSyringeItem extends Item { 14 - private static final String TYPE_KEY = "EntityType"; 15 - private static final String CANCER_KEY = "CancerMeter"; 16 - public FilledSyringeItem(Properties settings) { 17 - super(settings); 18 - } 19 - 20 - 21 - public static void writeNbt(LivingEntity target, ItemStack syringe) { 22 - CompoundTag nbt = syringe.getOrCreateTag(); 23 - syringe.setHoverName(Component.translatable("item.asbestos.filled_syringe", target.getName()).withStyle(ChatFormatting.RESET)); 24 - nbt.putString(TYPE_KEY, EntityType.getKey(target.getType()).toString()); 25 - if (target instanceof Player player) { 26 - nbt.putInt(CANCER_KEY, AsbestosMod.MESOTHELIOMA.get(player).getMesothelioma()); 27 - } 28 - } 29 - }
-16
src/main/java/xyz/naomieow/asbestos/item/ModGroups.java
··· 1 - package xyz.naomieow.asbestos.item; 2 - 3 - import io.wispforest.owo.itemgroup.Icon; 4 - import io.wispforest.owo.itemgroup.OwoItemGroup; 5 - import net.minecraft.resources.ResourceLocation; 6 - import xyz.naomieow.asbestos.AsbestosMod; 7 - 8 - public class ModGroups { 9 - public static final OwoItemGroup ASBESTOS_GROUP = OwoItemGroup 10 - .builder(new ResourceLocation(AsbestosMod.MOD_ID, "asbestos_group"), () -> Icon.of(ModItems.ASBESTOS_FIBERS)) 11 - .build(); 12 - 13 - public static void init() { 14 - ASBESTOS_GROUP.initialize(); 15 - } 16 - }
-45
src/main/java/xyz/naomieow/asbestos/item/ModItems.java
··· 1 - package xyz.naomieow.asbestos.item; 2 - 3 - import io.wispforest.owo.itemgroup.OwoItemSettings; 4 - import io.wispforest.owo.registration.reflect.ItemRegistryContainer; 5 - import net.minecraft.world.effect.MobEffectInstance; 6 - import net.minecraft.world.effect.MobEffects; 7 - import net.minecraft.world.food.FoodProperties; 8 - import net.minecraft.world.item.ArmorItem; 9 - import net.minecraft.world.item.Item; 10 - import net.minecraft.world.item.TieredItem; 11 - import xyz.naomieow.asbestos.armour.ProtectiveMaterial; 12 - 13 - public class ModItems implements ItemRegistryContainer { 14 - public static final Item ASBESTOS_FIBERS = new Item( 15 - new OwoItemSettings() 16 - .group(ModGroups.ASBESTOS_GROUP) 17 - .fireResistant() 18 - .food(new FoodProperties.Builder().alwaysEat().effect( 19 - new MobEffectInstance(MobEffects.WITHER, 30 * 20, 4, false, false), 1.0f) 20 - .build())); 21 - 22 - public static final TieredItem IRON_SCRAPER = new ScraperItem(ScraperItemMaterial.INSTANCE, 0.0f, -3.0f, 23 - new OwoItemSettings().group(ModGroups.ASBESTOS_GROUP)); 24 - 25 - public static final Item FILLED_SYRINGE = new FilledSyringeItem(new OwoItemSettings().group(ModGroups.ASBESTOS_GROUP).stacksTo(1)); 26 - public static final Item EMPTY_SYRINGE = new EmptySyringeItem(new OwoItemSettings().group(ModGroups.ASBESTOS_GROUP).stacksTo(16)); 27 - public static final Item CANCER_METER = new CancerMeterItem(new OwoItemSettings().group(ModGroups.ASBESTOS_GROUP).stacksTo(1)); 28 - 29 - public static final Item PPE_HELMET = new ArmorItem( 30 - ProtectiveMaterial.INSTANCE, ArmorItem.Type.HELMET, 31 - new OwoItemSettings().group(ModGroups.ASBESTOS_GROUP) 32 - ); 33 - public static final Item PPE_CHESTPLATE = new ArmorItem( 34 - ProtectiveMaterial.INSTANCE, ArmorItem.Type.CHESTPLATE, 35 - new OwoItemSettings().group(ModGroups.ASBESTOS_GROUP) 36 - ); 37 - public static final Item PPE_LEGGINGS = new ArmorItem( 38 - ProtectiveMaterial.INSTANCE, ArmorItem.Type.LEGGINGS, 39 - new OwoItemSettings().group(ModGroups.ASBESTOS_GROUP) 40 - ); 41 - public static final Item PPE_BOOTS = new ArmorItem( 42 - ProtectiveMaterial.INSTANCE, ArmorItem.Type.BOOTS, 43 - new OwoItemSettings().group(ModGroups.ASBESTOS_GROUP) 44 - ); 45 - }
-17
src/main/java/xyz/naomieow/asbestos/item/ScraperItem.java
··· 1 - package xyz.naomieow.asbestos.item; 2 - 3 - import net.minecraft.core.registries.Registries; 4 - import net.minecraft.resources.ResourceLocation; 5 - import net.minecraft.tags.TagKey; 6 - import net.minecraft.world.item.DiggerItem; 7 - import net.minecraft.world.item.Tier; 8 - import net.minecraft.world.level.block.Block; 9 - import xyz.naomieow.asbestos.AsbestosMod; 10 - 11 - public class ScraperItem extends DiggerItem { 12 - private static TagKey<Block> affectedBlocks = TagKey.create(Registries.BLOCK, new ResourceLocation(AsbestosMod.MOD_ID, "scrapable")); 13 - 14 - public ScraperItem(Tier material, float attackDamage, float attackSpeed, Properties settings) { 15 - super(attackDamage, attackSpeed, material, affectedBlocks, settings); 16 - } 17 - }
-40
src/main/java/xyz/naomieow/asbestos/item/ScraperItemMaterial.java
··· 1 - package xyz.naomieow.asbestos.item; 2 - 3 - import net.minecraft.world.item.Items; 4 - import net.minecraft.world.item.Tier; 5 - import net.minecraft.world.item.crafting.Ingredient; 6 - 7 - public class ScraperItemMaterial implements Tier { 8 - 9 - public static final ScraperItemMaterial INSTANCE = new ScraperItemMaterial(); 10 - 11 - @Override 12 - public int getUses() { 13 - return 300; 14 - } 15 - 16 - @Override 17 - public float getSpeed() { 18 - return 5.0f; 19 - } 20 - 21 - @Override 22 - public float getAttackDamageBonus() { 23 - return 2.5f; 24 - } 25 - 26 - @Override 27 - public int getLevel() { 28 - return 1; 29 - } 30 - 31 - @Override 32 - public int getEnchantmentValue() { 33 - return 10; 34 - } 35 - 36 - @Override 37 - public Ingredient getRepairIngredient() { 38 - return Ingredient.of(Items.IRON_INGOT); 39 - } 40 - }
-8
src/main/java/xyz/naomieow/asbestos/mesothelioma/MesoComponent.java
··· 1 - package xyz.naomieow.asbestos.mesothelioma; 2 - 3 - import dev.onyxstudios.cca.api.v3.component.ComponentV3; 4 - 5 - public interface MesoComponent extends ComponentV3 { 6 - int getMesothelioma(); 7 - void setMesothelioma(int exposure); 8 - }
-36
src/main/java/xyz/naomieow/asbestos/mesothelioma/MesoStatusEffect.java
··· 1 - package xyz.naomieow.asbestos.mesothelioma; 2 - 3 - import net.minecraft.world.effect.MobEffect; 4 - import net.minecraft.world.effect.MobEffectCategory; 5 - import net.minecraft.world.effect.MobEffectInstance; 6 - import net.minecraft.world.effect.MobEffects; 7 - import net.minecraft.world.entity.LivingEntity; 8 - import net.minecraft.world.entity.player.Player; 9 - import xyz.naomieow.asbestos.AsbestosMod; 10 - import xyz.naomieow.asbestos.damage.ModDamageTypes; 11 - 12 - public class MesoStatusEffect extends MobEffect { 13 - public MesoStatusEffect() { 14 - super(MobEffectCategory.HARMFUL, 0x302412); 15 - } 16 - 17 - @Override 18 - public boolean isDurationEffectTick(int duration, int amplifier) { 19 - return true; 20 - } 21 - 22 - @Override 23 - public void applyEffectTick(LivingEntity entity, int amplifier) { 24 - super.applyEffectTick(entity, amplifier); 25 - if (entity instanceof Player playerEntity) { 26 - int exposure = AsbestosMod.MESOTHELIOMA.get(playerEntity).getMesothelioma(); 27 - if (exposure >= (AsbestosMod.CONFIG.threshold() / 1.5)) { 28 - playerEntity.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, -1, 1)); 29 - } 30 - 31 - if (exposure >= AsbestosMod.CONFIG.threshold()) { 32 - playerEntity.hurt(ModDamageTypes.of(playerEntity.level(), ModDamageTypes.MESOTHELIOMA), 1 << amplifier); 33 - } 34 - } 35 - } 36 - }
-37
src/main/java/xyz/naomieow/asbestos/mesothelioma/PlayerMesoComponet.java
··· 1 - package xyz.naomieow.asbestos.mesothelioma; 2 - 3 - import dev.onyxstudios.cca.api.v3.component.sync.AutoSyncedComponent; 4 - import net.minecraft.nbt.CompoundTag; 5 - import net.minecraft.world.entity.player.Player; 6 - import xyz.naomieow.asbestos.AsbestosMod; 7 - 8 - public class PlayerMesoComponet implements MesoComponent, AutoSyncedComponent { 9 - private Player playerEntity; 10 - private int mesothelioma; 11 - 12 - public PlayerMesoComponet(Player playerEntity) { 13 - this.playerEntity = playerEntity; 14 - this.mesothelioma = 0; 15 - } 16 - 17 - @Override 18 - public int getMesothelioma() { 19 - return this.mesothelioma; 20 - } 21 - 22 - @Override 23 - public void setMesothelioma(int exposure) { 24 - this.mesothelioma = exposure; 25 - AsbestosMod.MESOTHELIOMA.sync(playerEntity); 26 - } 27 - 28 - @Override 29 - public void readFromNbt(CompoundTag tag) { 30 - this.mesothelioma = tag.getInt("mesothelioma"); 31 - } 32 - 33 - @Override 34 - public void writeToNbt(CompoundTag tag) { 35 - tag.putInt("mesothelioma", this.mesothelioma); 36 - } 37 - }
-80
src/main/java/xyz/naomieow/asbestos/screen/CancerMeterScreen.java
··· 1 - package xyz.naomieow.asbestos.screen; 2 - 3 - import net.fabricmc.api.EnvType; 4 - import net.fabricmc.api.Environment; 5 - import net.minecraft.client.gui.GuiGraphics; 6 - import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; 7 - import net.minecraft.network.chat.Component; 8 - import net.minecraft.resources.ResourceLocation; 9 - import net.minecraft.world.entity.player.Inventory; 10 - import xyz.naomieow.asbestos.AsbestosMod; 11 - import xyz.naomieow.asbestos.screen.util.MouseUtil; 12 - 13 - import java.util.List; 14 - import java.util.Optional; 15 - 16 - @Environment(EnvType.CLIENT) 17 - public class CancerMeterScreen extends AbstractContainerScreen<CancerMeterScreenHandler> { 18 - private static final ResourceLocation TEXTURE = new ResourceLocation(AsbestosMod.MOD_ID, "textures/gui/cancer_meter.png"); 19 - CancerMeterScreenHandler screenHandler; 20 - 21 - public CancerMeterScreen(CancerMeterScreenHandler handler, Inventory inventory, Component title) { 22 - super(handler, inventory, title); 23 - screenHandler = handler; 24 - } 25 - //109, 56 -- 176, 56 -- 58x7 26 - 27 - @Override 28 - protected void renderBg(GuiGraphics context, float delta, int mouseX, int mouseY) { 29 - int x = (width - imageWidth) / 2; 30 - int y = (height - imageHeight) / 2; 31 - context.blit(TEXTURE, x, y, 0, 0, imageWidth, imageHeight); 32 - drawCancerProgress(context, x + 109, y + 56); 33 - } 34 - 35 - @Override 36 - protected void renderLabels(GuiGraphics context, int mouseX, int mouseY) { 37 - int x = (width - imageWidth) / 2; 38 - int y = (height - imageHeight) / 2; 39 - 40 - if (isMouseAboveArea(mouseX, mouseY, x, y, 108, 55, 58, 7)) { 41 - context.renderTooltip( 42 - font, 43 - List.of(Component.literal(screenHandler.getCancerMeter() + "/" + AsbestosMod.CONFIG.threshold())), 44 - Optional.empty(), 45 - mouseX - x, 46 - mouseY - y 47 - ); 48 - } 49 - context.drawString(this.font, this.playerInventoryTitle, this.inventoryLabelX, this.inventoryLabelY + 2, 4210752, false); 50 - } 51 - 52 - private void drawCancerProgress(GuiGraphics context, int x, int y) { 53 - int offset = screenHandler.getCancerMeter() * 58 / AsbestosMod.CONFIG.threshold(); 54 - context.blit(TEXTURE, 55 - x, y, 56 - 176, 56, 57 - offset, 7); 58 - } 59 - 60 - @Override 61 - public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { 62 - renderBackground(context); 63 - super.render(context, mouseX, mouseY, delta); 64 - renderTooltip(context, mouseX, mouseY); 65 - } 66 - 67 - private boolean isMouseAboveArea( 68 - int mouseX, int mouseY, 69 - int x, int y, 70 - int offsetX, int offsetY, 71 - int width, int height 72 - ) { 73 - return MouseUtil.isMouseOver( 74 - mouseX, mouseY, 75 - x + offsetX, y + offsetY, 76 - width, height 77 - ); 78 - } 79 - 80 - }
-143
src/main/java/xyz/naomieow/asbestos/screen/CancerMeterScreenHandler.java
··· 1 - package xyz.naomieow.asbestos.screen; 2 - 3 - import xyz.naomieow.asbestos.inventory.CancerMeterInventory; 4 - import xyz.naomieow.asbestos.inventory.ICancerMeterInventory; 5 - import xyz.naomieow.asbestos.item.CancerMeterItem; 6 - import xyz.naomieow.asbestos.item.ModItems; 7 - 8 - import java.util.Objects; 9 - import net.minecraft.nbt.CompoundTag; 10 - import net.minecraft.network.FriendlyByteBuf; 11 - import net.minecraft.world.entity.EquipmentSlot; 12 - import net.minecraft.world.entity.player.Inventory; 13 - import net.minecraft.world.entity.player.Player; 14 - import net.minecraft.world.inventory.AbstractContainerMenu; 15 - import net.minecraft.world.inventory.MenuType; 16 - import net.minecraft.world.inventory.Slot; 17 - import net.minecraft.world.item.ItemStack; 18 - 19 - public class CancerMeterScreenHandler extends AbstractContainerMenu { 20 - private final int INVENTORY_START = 1, INVENTORY_END = 28, HOTBAR_START = 28, HOTBAR_END = 37; 21 - 22 - public Inventory playerInventory; 23 - public ICancerMeterInventory inventory; 24 - 25 - public CancerMeterScreenHandler(int syncId, Inventory playerInventory, FriendlyByteBuf buf) { 26 - this(syncId, playerInventory, createInventory(playerInventory, buf)); 27 - } 28 - 29 - private CancerMeterScreenHandler(MenuType<?> type, int syncId, Inventory playerInventory, ICancerMeterInventory inventory) { 30 - super(type, syncId); 31 - this.playerInventory = playerInventory; 32 - this.inventory = inventory; 33 - 34 - this.addSlot(new Slot(inventory.getInventory(), 0, 80, 54) { 35 - @Override 36 - public boolean mayPlace(ItemStack stack) { 37 - return stack.is(ModItems.FILLED_SYRINGE); 38 - } 39 - }); 40 - 41 - this.addPlayerInventory(playerInventory); 42 - this.addPlayerHotbar(playerInventory); 43 - } 44 - 45 - public CancerMeterScreenHandler(int syncId, Inventory playerInventory, ICancerMeterInventory inventory) { 46 - this(ModHandlers.CANCER_METER, syncId, playerInventory, inventory); 47 - } 48 - 49 - private static CancerMeterInventory createInventory(final Inventory playerInventory, final FriendlyByteBuf buf) { 50 - Objects.requireNonNull(playerInventory); 51 - Objects.requireNonNull(buf); 52 - 53 - final ItemStack stack; 54 - final byte screenID = buf.readByte(); 55 - 56 - if (screenID == 1) { 57 - stack = playerInventory.player.getItemBySlot(EquipmentSlot.MAINHAND); 58 - } else { 59 - stack = ItemStack.EMPTY; 60 - } 61 - 62 - if (stack.getItem() instanceof CancerMeterItem) { 63 - if (screenID == 1) { 64 - return new CancerMeterInventory(stack, playerInventory.player, screenID); 65 - } 66 - } 67 - throw new IllegalStateException("Incorrect ItemStack " + stack); 68 - } 69 - 70 - 71 - @Override 72 - public ItemStack quickMoveStack(Player player, int slotIndex) { 73 - ItemStack itemStack = ItemStack.EMPTY; 74 - Slot slot = this.slots.get(slotIndex); 75 - if (slot.hasItem()) { 76 - ItemStack stackInSlot = slot.getItem(); 77 - itemStack = stackInSlot.copy(); 78 - if (slotIndex == 0) { 79 - if (!this.moveItemStackTo(stackInSlot, INVENTORY_START, HOTBAR_END, true)) { 80 - return ItemStack.EMPTY; 81 - } 82 - slot.onQuickCraft(stackInSlot, itemStack); 83 - } else if (itemStack.is(ModItems.FILLED_SYRINGE)) { 84 - if (!this.moveItemStackTo(stackInSlot, 0, 1, false)) { 85 - return ItemStack.EMPTY; 86 - } 87 - } else if (slotIndex >= INVENTORY_START && slotIndex < INVENTORY_END) { 88 - if (!this.moveItemStackTo(stackInSlot, HOTBAR_START, HOTBAR_END, false)) { 89 - return ItemStack.EMPTY; 90 - } 91 - } else if (slotIndex >= HOTBAR_START && slotIndex < HOTBAR_END) { 92 - if (!this.moveItemStackTo(stackInSlot, INVENTORY_START, INVENTORY_END, false)) { 93 - return ItemStack.EMPTY; 94 - } 95 - } else { 96 - if (!this.moveItemStackTo(stackInSlot, INVENTORY_START, HOTBAR_END, false)) { 97 - return ItemStack.EMPTY; 98 - } 99 - } 100 - 101 - if (stackInSlot.isEmpty()) { 102 - slot.setByPlayer(ItemStack.EMPTY); 103 - } else { 104 - slot.setChanged(); 105 - } 106 - 107 - if (stackInSlot.getCount() == itemStack.getCount()) { 108 - return ItemStack.EMPTY; 109 - } 110 - 111 - slot.onTake(player, stackInSlot); 112 - 113 - if (slotIndex == 0) { 114 - player.drop(stackInSlot, false); 115 - } 116 - } 117 - return itemStack; 118 - } 119 - 120 - @Override 121 - public boolean stillValid(Player player) { 122 - return true; 123 - } 124 - 125 - private void addPlayerInventory(Inventory inventory) { 126 - for (int row = 0; row < 3; ++row) { 127 - for (int column = 0; column < 9; ++column) { 128 - this.addSlot(new Slot(inventory, column + row * 9 + 9, 8 + column * 18, 84 + row * 18)); 129 - } 130 - } 131 - } 132 - 133 - private void addPlayerHotbar(Inventory inventory) { 134 - for (int slot = 0; slot < 9; ++slot) { 135 - this.addSlot(new Slot(inventory, slot, 8 + slot * 18, 142)); 136 - } 137 - } 138 - 139 - public int getCancerMeter() { 140 - CompoundTag nbt = this.inventory.getInventory().getItem(0).getOrCreateTag(); 141 - return nbt.contains("CancerMeter") ? nbt.getInt("CancerMeter") : 0; 142 - } 143 - }
-24
src/main/java/xyz/naomieow/asbestos/screen/ModHandlers.java
··· 1 - package xyz.naomieow.asbestos.screen; 2 - 3 - import io.wispforest.owo.registration.reflect.AutoRegistryContainer; 4 - import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType; 5 - import net.minecraft.core.Registry; 6 - import net.minecraft.core.registries.BuiltInRegistries; 7 - import net.minecraft.world.inventory.MenuType; 8 - 9 - public class ModHandlers implements AutoRegistryContainer<MenuType<?>> { 10 - public static final MenuType<CancerMeterScreenHandler> CANCER_METER = 11 - new ExtendedScreenHandlerType<>(CancerMeterScreenHandler::new); 12 - 13 - 14 - @Override 15 - public Registry<MenuType<?>> getRegistry() { 16 - return BuiltInRegistries.MENU; 17 - } 18 - 19 - @Override 20 - public Class<MenuType<?>> getTargetFieldType() { 21 - return (Class<MenuType<?>>) (Object) MenuType.class; 22 - } 23 - 24 - }
-15
src/main/java/xyz/naomieow/asbestos/screen/util/MouseUtil.java
··· 1 - package xyz.naomieow.asbestos.screen.util; 2 - 3 - public class MouseUtil { 4 - public static boolean isMouseOver(double mouseX, double mouseY, int x, int y) { 5 - return isMouseOver(mouseX, mouseY, x, y, 16); 6 - } 7 - 8 - public static boolean isMouseOver(double mouseX, double mouseY, int x, int y, int size) { 9 - return isMouseOver(mouseX, mouseY, x, y, size, size); 10 - } 11 - 12 - public static boolean isMouseOver(double mouseX, double mouseY, int x, int y, int sizeX, int sizeY) { 13 - return (mouseX >= x && mouseX <= x + sizeX) && (mouseY >= y && mouseY <= y + sizeY); 14 - } 15 - }
+67
src/main/kotlin/xyz/naomieow/asbestos/AsbestosMod.kt
··· 1 + package xyz.naomieow.asbestos 2 + 3 + import dev.onyxstudios.cca.api.v3.component.ComponentKey 4 + import dev.onyxstudios.cca.api.v3.component.ComponentRegistryV3 5 + import dev.onyxstudios.cca.api.v3.entity.EntityComponentFactoryRegistry 6 + import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer 7 + import io.wispforest.owo.registration.reflect.FieldRegistrationHandler 8 + import net.fabricmc.api.ModInitializer 9 + import net.fabricmc.fabric.api.biome.v1.BiomeModifications 10 + import net.fabricmc.fabric.api.biome.v1.BiomeSelectors 11 + import net.minecraft.core.Registry 12 + import net.minecraft.core.registries.BuiltInRegistries 13 + import net.minecraft.core.registries.Registries 14 + import net.minecraft.resources.ResourceKey 15 + import net.minecraft.resources.ResourceLocation 16 + import net.minecraft.world.effect.MobEffect 17 + import net.minecraft.world.level.block.Block 18 + import net.minecraft.world.level.levelgen.GenerationStep 19 + import net.minecraft.world.level.levelgen.placement.PlacedFeature 20 + import xyz.naomieow.asbestos.block.ModBlocks 21 + import xyz.naomieow.asbestos.config.AsbestosConfig 22 + import xyz.naomieow.asbestos.item.ModGroups 23 + import xyz.naomieow.asbestos.item.ModItems 24 + import xyz.naomieow.asbestos.mesothelioma.IMesoComponent 25 + import xyz.naomieow.asbestos.mesothelioma.MesoStatusEffect 26 + import xyz.naomieow.asbestos.screen.ModHandlers 27 + 28 + 29 + object AsbestosMod: ModInitializer, EntityComponentInitializer { 30 + const val MOD_ID: String = "asbestos" 31 + val MESOTHELIOMA: ComponentKey<IMesoComponent> = ComponentRegistryV3.INSTANCE.getOrCreate( 32 + ResourceLocation(MOD_ID, "mesothelioma"), 33 + IMesoComponent::class.java 34 + ) 35 + val CONFIG: AsbestosConfig = AsbestosConfig.createAndLoad() 36 + val MESO_STATUS: MobEffect = MesoStatusEffect() 37 + val HARMFUL_PASSIVE_BLOCKS: Array<Block?> = arrayOf(ModBlocks.ASBESTOS_BLOCK) 38 + val SERPENTINITE_PLACED_KEY: ResourceKey<PlacedFeature> = ResourceKey.create( 39 + Registries.PLACED_FEATURE, 40 + ResourceLocation(MOD_ID, "serpentinite") 41 + ) 42 + 43 + override fun registerEntityComponentFactories(registry: EntityComponentFactoryRegistry) { 44 + TODO("Not yet implemented") 45 + } 46 + 47 + override fun onInitialize() { 48 + FieldRegistrationHandler.register(ModItems::class.java, MOD_ID, false) 49 + FieldRegistrationHandler.register(ModBlocks::class.java, MOD_ID, false) 50 + FieldRegistrationHandler.register(ModHandlers::class.java, MOD_ID, false) 51 + 52 + Registry.register( 53 + BuiltInRegistries.MOB_EFFECT, 54 + ResourceLocation(MOD_ID, "mesothelioma"), 55 + MESO_STATUS 56 + ) 57 + 58 + BiomeModifications.addFeature( 59 + BiomeSelectors.foundInOverworld(), 60 + GenerationStep.Decoration.UNDERGROUND_ORES, 61 + SERPENTINITE_PLACED_KEY 62 + ) 63 + 64 + ModGroups.init() 65 + ModScheduler.init() 66 + } 67 + }
+16
src/main/kotlin/xyz/naomieow/asbestos/AsbestosModClient.kt
··· 1 + package xyz.naomieow.asbestos 2 + 3 + import net.fabricmc.api.ClientModInitializer 4 + import net.fabricmc.api.EnvType 5 + import net.fabricmc.api.Environment 6 + import net.minecraft.client.gui.screens.MenuScreens 7 + import xyz.naomieow.asbestos.screen.CancerMeterScreen 8 + import xyz.naomieow.asbestos.screen.ModHandlers 9 + 10 + @Environment(EnvType.CLIENT) 11 + class AsbestosModClient : ClientModInitializer { 12 + override fun onInitializeClient() { 13 + MenuScreens.register(ModHandlers.CANCER_METER, ::CancerMeterScreen) 14 + } 15 + 16 + }
+54
src/main/kotlin/xyz/naomieow/asbestos/ModScheduler.kt
··· 1 + package xyz.naomieow.asbestos 2 + 3 + import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents 4 + import net.minecraft.core.BlockPos 5 + import net.minecraft.server.MinecraftServer 6 + import net.minecraft.server.level.ServerLevel 7 + import net.minecraft.server.level.ServerPlayer 8 + import net.minecraft.world.effect.MobEffectInstance 9 + import xyz.naomieow.asbestos.block.CarcinogenicBlock 10 + import java.util.function.Consumer 11 + 12 + object ModScheduler { 13 + fun init() { 14 + ServerTickEvents.END_SERVER_TICK.register(ServerTickEvents.EndTick { server: MinecraftServer -> 15 + if (server.tickCount % (AsbestosMod.CONFIG.period * 20) == 0) { 16 + server.allLevels.forEach(Consumer { level: ServerLevel -> 17 + level.players().forEach( 18 + Consumer { player: ServerPlayer -> 19 + val exposure = AsbestosMod.MESOTHELIOMA.get(player).mesothelioma 20 + if (exposure >= (AsbestosMod.CONFIG.threshold / 2)) { 21 + player.addEffect(MobEffectInstance(AsbestosMod.MESO_STATUS, -1)) 22 + } 23 + 24 + if (CarcinogenicBlock.isProtectedFromAsbestos(player)) { 25 + return@Consumer 26 + } 27 + 28 + val offset = AsbestosMod.CONFIG.offset 29 + findasbestos@ for (i in -offset..< offset) { 30 + for (j in -offset..< offset) { 31 + for (k in -offset..< offset) { 32 + val offsetPos = player.position() 33 + .add(i.toDouble(), j.toDouble(), k.toDouble()) 34 + val pos = BlockPos( 35 + offsetPos.x().toInt(), 36 + offsetPos.y().toInt(), 37 + offsetPos.z().toInt() 38 + ) 39 + val block = level.getBlockState(pos).block 40 + if (listOf(*AsbestosMod.HARMFUL_PASSIVE_BLOCKS) 41 + .contains(block) 42 + ) { 43 + AsbestosMod.MESOTHELIOMA.get(player).mesothelioma = exposure + 1 44 + break@findasbestos 45 + } 46 + } 47 + } 48 + } 49 + }) 50 + }) 51 + } 52 + }) 53 + } 54 + }
+49
src/main/kotlin/xyz/naomieow/asbestos/armor/ProtectiveMaterial.kt
··· 1 + package xyz.naomieow.asbestos.armor 2 + 3 + import net.minecraft.sounds.SoundEvent 4 + import net.minecraft.sounds.SoundEvents 5 + import net.minecraft.world.item.ArmorItem 6 + import net.minecraft.world.item.ArmorMaterial 7 + import net.minecraft.world.item.Items 8 + import net.minecraft.world.item.crafting.Ingredient 9 + 10 + class ProtectiveMaterial : ArmorMaterial { 11 + override fun getDurabilityForType(type: ArmorItem.Type): Int { 12 + return BASE_DURABILITY[type.slot.index] 13 + } 14 + 15 + override fun getDefenseForType(type: ArmorItem.Type): Int { 16 + return PROTECTION_VALUES[type.slot.index] 17 + } 18 + 19 + override fun getEnchantmentValue(): Int { 20 + return 4 21 + } 22 + 23 + override fun getEquipSound(): SoundEvent { 24 + return SoundEvents.WOOL_HIT 25 + } 26 + 27 + override fun getRepairIngredient(): Ingredient { 28 + return Ingredient.of(Items.STRING) 29 + } 30 + 31 + override fun getName(): String { 32 + return "asbestos_protective" 33 + } 34 + 35 + override fun getToughness(): Float { 36 + return 0f 37 + } 38 + 39 + override fun getKnockbackResistance(): Float { 40 + return 0f 41 + } 42 + 43 + companion object { 44 + private val BASE_DURABILITY = intArrayOf(13, 15, 16, 11) 45 + private val PROTECTION_VALUES = intArrayOf(1, 1, 2, 1) 46 + 47 + val INSTANCE: ProtectiveMaterial = ProtectiveMaterial() 48 + } 49 + }
+80
src/main/kotlin/xyz/naomieow/asbestos/block/AsbestosRoofBlock.kt
··· 1 + package xyz.naomieow.asbestos.block 2 + 3 + import net.fabricmc.api.EnvType 4 + import net.fabricmc.api.Environment 5 + import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap 6 + import net.fabricmc.loader.api.FabricLoader 7 + import net.minecraft.client.renderer.RenderType 8 + import net.minecraft.core.BlockPos 9 + import net.minecraft.core.Direction 10 + import net.minecraft.world.item.context.BlockPlaceContext 11 + import net.minecraft.world.level.BlockGetter 12 + import net.minecraft.world.level.block.Block 13 + import net.minecraft.world.level.block.state.BlockState 14 + import net.minecraft.world.level.block.state.StateDefinition 15 + import net.minecraft.world.level.block.state.properties.BlockStateProperties 16 + import net.minecraft.world.phys.shapes.CollisionContext 17 + import net.minecraft.world.phys.shapes.Shapes 18 + import net.minecraft.world.phys.shapes.VoxelShape 19 + 20 + class AsbestosRoofBlock(settings: Properties, dangerLevel: Int) : CarcinogenicBlock(settings, dangerLevel) { 21 + init { 22 + registerDefaultState( 23 + this.getStateDefinition().any() 24 + .setValue<Direction?, Direction?>(BlockStateProperties.HORIZONTAL_FACING, Direction.NORTH) 25 + ) 26 + if (FabricLoader.getInstance().environmentType != EnvType.SERVER) { 27 + BlockRenderLayerMap.INSTANCE.putBlock(this, RenderType.cutout()) 28 + } 29 + } 30 + 31 + override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block?, BlockState?>) { 32 + builder.add(BlockStateProperties.HORIZONTAL_FACING) 33 + } 34 + 35 + @Deprecated("Deprecated in Java") 36 + override fun getShape( 37 + state: BlockState, 38 + world: BlockGetter, 39 + pos: BlockPos, 40 + context: CollisionContext 41 + ): VoxelShape { 42 + val dir = state.getValue<Direction?>(BlockStateProperties.HORIZONTAL_FACING) 43 + return when (dir) { 44 + Direction.NORTH -> Shapes.or( 45 + Shapes.box(0.0, 0.0, 0.0, 1.0, 0.5, 1.0), 46 + Shapes.box(0.0, 0.5, 0.5, 1.0, 1.0, 1.0) 47 + ) 48 + 49 + Direction.SOUTH -> Shapes.or( 50 + Shapes.box(0.0, 0.0, 0.0, 1.0, 0.5, 1.0), 51 + Shapes.box(0.0, 0.5, 0.0, 1.0, 1.0, 0.5) 52 + ) 53 + 54 + Direction.EAST -> Shapes.or( 55 + Shapes.box(0.0, 0.0, 0.0, 1.0, 0.5, 1.0), 56 + Shapes.box(0.0, 0.5, 0.0, 0.5, 1.0, 1.0) 57 + ) 58 + 59 + Direction.WEST -> Shapes.or( 60 + Shapes.box(0.0, 0.0, 0.0, 1.0, 0.5, 1.0), 61 + Shapes.box(0.5, 0.5, 0.0, 1.0, 1.0, 1.0) 62 + ) 63 + 64 + else -> Shapes.block() 65 + } 66 + } 67 + 68 + override fun getStateForPlacement(ctx: BlockPlaceContext): BlockState? { 69 + return this.defaultBlockState().setValue( 70 + BlockStateProperties.HORIZONTAL_FACING, 71 + ctx.horizontalDirection.opposite 72 + ) 73 + } 74 + 75 + @Deprecated("Deprecated in Java") 76 + @Environment(EnvType.CLIENT) 77 + override fun getShadeBrightness(state: BlockState, world: BlockGetter, pos: BlockPos): Float { 78 + return 1.0f 79 + } 80 + }
+34
src/main/kotlin/xyz/naomieow/asbestos/block/CarcinogenicBlock.kt
··· 1 + package xyz.naomieow.asbestos.block 2 + 3 + import net.minecraft.core.BlockPos 4 + import net.minecraft.world.entity.player.Player 5 + import net.minecraft.world.item.Item 6 + import net.minecraft.world.level.Level 7 + import net.minecraft.world.level.block.Block 8 + import net.minecraft.world.level.block.state.BlockState 9 + import xyz.naomieow.asbestos.AsbestosMod 10 + import xyz.naomieow.asbestos.item.ModItems 11 + 12 + open class CarcinogenicBlock(settings: Properties, private val dangerLevel: Int) : Block(settings) { 13 + override fun playerWillDestroy(world: Level, pos: BlockPos, state: BlockState, player: Player) { 14 + super.playerWillDestroy(world, pos, state, player) 15 + if (!isProtectedFromAsbestos(player)) { 16 + val exposure = AsbestosMod.MESOTHELIOMA.get(player).mesothelioma 17 + AsbestosMod.MESOTHELIOMA.get(player).mesothelioma = exposure + dangerLevel 18 + } 19 + } 20 + 21 + companion object { 22 + var PROTECTIVE_ARMOUR: Array<Item> = 23 + arrayOf<Item>(ModItems.PPE_HELMET, ModItems.PPE_CHESTPLATE, ModItems.PPE_LEGGINGS, ModItems.PPE_BOOTS) 24 + 25 + fun isProtectedFromAsbestos(player: Player): Boolean { 26 + for (item in player.armorSlots) { 27 + if (!listOf(*PROTECTIVE_ARMOUR).contains(item.item)) { 28 + return false 29 + } 30 + } 31 + return true 32 + } 33 + } 34 + }
+38
src/main/kotlin/xyz/naomieow/asbestos/block/ModBlocks.kt
··· 1 + package xyz.naomieow.asbestos.block 2 + 3 + import io.wispforest.owo.itemgroup.OwoItemSettings 4 + import io.wispforest.owo.registration.reflect.BlockRegistryContainer 5 + import net.fabricmc.fabric.api.`object`.builder.v1.block.FabricBlockSettings 6 + import net.minecraft.world.item.BlockItem 7 + import net.minecraft.world.level.block.Block 8 + import net.minecraft.world.level.block.Blocks 9 + import xyz.naomieow.asbestos.item.ModGroups 10 + 11 + class ModBlocks: BlockRegistryContainer { 12 + override fun createBlockItem(block: Block, identifier: String): BlockItem { 13 + return BlockItem(block, OwoItemSettings().group(ModGroups.ASBESTOS_GROUP)) 14 + } 15 + 16 + companion object { 17 + @JvmStatic 18 + val ASBESTOS_BLOCK: Block = CarcinogenicBlock( 19 + FabricBlockSettings.copyOf(Blocks.WHITE_WOOL).destroyTime(1.0f), 40 20 + ) 21 + @JvmStatic 22 + val SERPENTINITE_BLOCK: Block = CarcinogenicBlock( 23 + FabricBlockSettings.copyOf(Blocks.STONE).destroyTime(3.0f).requiresCorrectToolForDrops(), 20 24 + ) 25 + @JvmStatic 26 + val POPCORN_CEILING_BLOCK: Block = CarcinogenicBlock( 27 + FabricBlockSettings.copyOf(Blocks.OAK_PLANKS).destroyTime(2.0f), 20 28 + ) 29 + @JvmStatic 30 + val ASBESTOS_TILE_BLOCK: Block = CarcinogenicBlock( 31 + FabricBlockSettings.copyOf(Blocks.NETHER_BRICKS).destroyTime(3.0f), 20 32 + ) 33 + @JvmStatic 34 + val ASBESTOS_ROOF_BLOCK: Block = AsbestosRoofBlock( 35 + FabricBlockSettings.copyOf(ASBESTOS_TILE_BLOCK).noOcclusion(), 20 36 + ) 37 + } 38 + }
+21
src/main/kotlin/xyz/naomieow/asbestos/config/ModConfigModel.kt
··· 1 + package xyz.naomieow.asbestos.config 2 + 3 + import io.wispforest.owo.config.annotation.Config 4 + import io.wispforest.owo.config.annotation.Modmenu 5 + import io.wispforest.owo.config.annotation.RangeConstraint 6 + import xyz.naomieow.asbestos.AsbestosMod 7 + 8 + @Suppress("UNUSED") 9 + @Modmenu(modId = AsbestosMod.MOD_ID) 10 + @Config(name = "asbestos_config", wrapperName = "AsbestosConfig") 11 + class ModConfigModel { 12 + @JvmField 13 + @RangeConstraint(min = 0.0, max = 32.0) 14 + var offset: Int = 3 15 + @JvmField 16 + var period: Int = 5 17 + @JvmField 18 + var threshold: Int = 180 19 + @JvmField 20 + var exsanguination: Int = 1 21 + }
+28
src/main/kotlin/xyz/naomieow/asbestos/damage/ModDamageTypes.kt
··· 1 + package xyz.naomieow.asbestos.damage 2 + 3 + import net.minecraft.core.registries.Registries 4 + import net.minecraft.resources.ResourceKey 5 + import net.minecraft.resources.ResourceLocation 6 + import net.minecraft.world.damagesource.DamageSource 7 + import net.minecraft.world.damagesource.DamageType 8 + import net.minecraft.world.level.Level 9 + import xyz.naomieow.asbestos.AsbestosMod 10 + 11 + object ModDamageTypes { 12 + val MESOTHELIOMA: ResourceKey<DamageType> = ResourceKey.create( 13 + Registries.DAMAGE_TYPE, 14 + ResourceLocation(AsbestosMod.MOD_ID, "mesothelioma") 15 + ) 16 + val BLOOD_EXTRACT: ResourceKey<DamageType> = ResourceKey.create( 17 + Registries.DAMAGE_TYPE, 18 + ResourceLocation(AsbestosMod.MOD_ID, "blood_extract") 19 + ) 20 + 21 + fun of(level: Level, key: ResourceKey<DamageType>): DamageSource { 22 + return DamageSource(level 23 + .registryAccess() 24 + .registryOrThrow(Registries.DAMAGE_TYPE) 25 + .getHolderOrThrow(key) 26 + ) 27 + } 28 + }
+152
src/main/kotlin/xyz/naomieow/asbestos/inventory/CancerMeterInventory.kt
··· 1 + package xyz.naomieow.asbestos.inventory 2 + 3 + import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory 4 + import net.minecraft.core.NonNullList 5 + import net.minecraft.nbt.CompoundTag 6 + import net.minecraft.nbt.ListTag 7 + import net.minecraft.network.FriendlyByteBuf 8 + import net.minecraft.network.chat.Component 9 + import net.minecraft.server.level.ServerPlayer 10 + import net.minecraft.world.entity.player.Inventory 11 + import net.minecraft.world.entity.player.Player 12 + import net.minecraft.world.inventory.AbstractContainerMenu 13 + import net.minecraft.world.item.ItemStack 14 + import net.minecraft.world.level.Level 15 + import xyz.naomieow.asbestos.screen.CancerMeterScreenHandler 16 + 17 + class CancerMeterInventory( 18 + private var stack: ItemStack, 19 + private val player: Player, 20 + private val screenId: Byte, 21 + ): ICancerMeterInventory { 22 + private var inventory: InventoryImproved = createInventory(1) 23 + 24 + init { 25 + readAllData(stack.orCreateTag) 26 + } 27 + 28 + fun setStack(itemStack: ItemStack) { 29 + stack = itemStack 30 + } 31 + 32 + override fun getInventory(): InventoryImproved { 33 + return inventory 34 + } 35 + 36 + override fun writeAllData(tag: CompoundTag) { 37 + writeItems(tag) 38 + } 39 + 40 + override fun readAllData(tag: CompoundTag) { 41 + readItems(tag) 42 + } 43 + 44 + override fun writeItems(tag: CompoundTag) { 45 + writeTag(tag, inventory.getStacks(), true) 46 + } 47 + 48 + override fun readItems(tag: CompoundTag) { 49 + readTag(tag, inventory.getStacks()) 50 + } 51 + 52 + override fun getLevel(): Level { 53 + return player.level() 54 + } 55 + 56 + override fun getScreenID(): Byte { 57 + return screenId 58 + } 59 + 60 + override fun getItemStack(): ItemStack { 61 + return stack 62 + } 63 + 64 + override fun setUsingPlayer(player: Player?) { } 65 + 66 + override fun markDataDirty(vararg dataIds: Byte) { 67 + if (getLevel().isClientSide) { 68 + return 69 + } 70 + 71 + for (data in dataIds) { 72 + when (data) { 73 + ICancerMeterInventory.Companion.INVENTORY_DATA -> CancerMeterInventory.writeTag( 74 + stack.getOrCreateTag(), 75 + getInventory().getStacks(), 76 + true 77 + ) 78 + ICancerMeterInventory.Companion.COMBINED_INVENTORY_DATA -> writeItems(stack.getOrCreateTag()) 79 + ICancerMeterInventory.Companion.ALL_DATA -> writeAllData(stack.getOrCreateTag()) 80 + } 81 + } 82 + } 83 + 84 + override fun markDirty() { } 85 + 86 + private fun createInventory(size: Int): InventoryImproved { 87 + return object : InventoryImproved(NonNullList.withSize(size, ItemStack.EMPTY)) { 88 + override fun setChanged() { 89 + markDataDirty(ICancerMeterInventory.Companion.COMBINED_INVENTORY_DATA) 90 + } 91 + } 92 + } 93 + 94 + companion object { 95 + fun openHandledScreen(player: Player, stack: ItemStack, screenID: Byte) { 96 + if (!player.level().isClientSide()) { 97 + player.openMenu(object : ExtendedScreenHandlerFactory { 98 + override fun writeScreenOpeningData(player: ServerPlayer, buf: FriendlyByteBuf) { 99 + buf.writeByte(screenID.toInt()) 100 + } 101 + 102 + override fun getDisplayName(): Component { 103 + return Component.translatable("screen.asbestos.cancer_meter") 104 + } 105 + 106 + override fun createMenu( 107 + syncId: Int, 108 + playerInventory: Inventory, 109 + player: Player 110 + ): AbstractContainerMenu { 111 + return CancerMeterScreenHandler( 112 + syncId, 113 + playerInventory, 114 + CancerMeterInventory(stack, player, screenID) 115 + ) 116 + } 117 + }) 118 + } 119 + } 120 + 121 + private fun writeTag(tag: CompoundTag, stacks: NonNullList<ItemStack>, setIfEmpty: Boolean): CompoundTag { 122 + val tags = ListTag() 123 + for (i in stacks.indices) { 124 + val itemStack = stacks[i] 125 + if (!itemStack.isEmpty) { 126 + val newTag = CompoundTag() 127 + newTag.putByte("Slot", i.toByte()) 128 + itemStack.save(newTag) 129 + tags.add(newTag) 130 + } 131 + } 132 + 133 + if (!tags.isEmpty() || setIfEmpty) { 134 + tag.put("Inventory", tags) 135 + } 136 + 137 + return tag 138 + } 139 + 140 + private fun readTag(tag: CompoundTag, stacks: NonNullList<ItemStack>) { 141 + val tags = tag.getList("Inventory", 10) 142 + 143 + for (i in tags.indices) { 144 + val newTag = tags.getCompound(i) 145 + val j = newTag.getByte("Slot").toInt() and 255 146 + if (j >= 0 && j < stacks.size) { 147 + stacks[j] = ItemStack.of(newTag) 148 + } 149 + } 150 + } 151 + } 152 + }
+27
src/main/kotlin/xyz/naomieow/asbestos/inventory/ICancerMeterInventory.kt
··· 1 + package xyz.naomieow.asbestos.inventory 2 + 3 + import net.minecraft.nbt.CompoundTag 4 + import net.minecraft.world.entity.player.Player 5 + import net.minecraft.world.item.ItemStack 6 + import net.minecraft.world.level.Level 7 + 8 + interface ICancerMeterInventory { 9 + fun writeItems(tag: CompoundTag) 10 + fun readItems(tag: CompoundTag) 11 + fun writeAllData(tag: CompoundTag) 12 + fun readAllData(tag: CompoundTag) 13 + fun getInventory(): InventoryImproved 14 + fun getScreenID(): Byte 15 + fun getLevel(): Level 16 + fun getItemStack(): ItemStack 17 + fun setUsingPlayer(player: Player?) 18 + fun markDataDirty(vararg dataIds: Byte) 19 + fun markDirty() 20 + 21 + companion object { 22 + const val INVENTORY_DATA: Byte = 0 23 + const val COMBINED_INVENTORY_DATA: Byte = 1 24 + const val SLOT_DATA: Byte = 2 25 + const val ALL_DATA: Byte = 3 26 + } 27 + }
+78
src/main/kotlin/xyz/naomieow/asbestos/inventory/InventoryImproved.kt
··· 1 + package xyz.naomieow.asbestos.inventory 2 + 3 + import net.minecraft.core.NonNullList 4 + import net.minecraft.world.Container 5 + import net.minecraft.world.ContainerHelper 6 + import net.minecraft.world.entity.player.Player 7 + import net.minecraft.world.item.ItemStack 8 + import xyz.naomieow.asbestos.item.ModItems 9 + 10 + /* 11 + * Converted from Tiviacz1337's InventoryImproved from Travelers Backpack: 12 + * https://github.com/Tiviacz1337/Travelers-Backpack/blob/3dc0bfeec381537a5ce85c2ae1e6e00d62542206/src/main/java/com/tiviacz/travelersbackpack/inventory/InventoryImproved.java 13 + */ 14 + abstract class InventoryImproved( 15 + @get:JvmName("getInventoryStacks") 16 + protected var stacks: NonNullList<ItemStack> 17 + ): Container { 18 + fun getStacks(): NonNullList<ItemStack> { 19 + return stacks 20 + } 21 + 22 + override fun getContainerSize(): Int { 23 + return stacks.size 24 + } 25 + override fun isEmpty(): Boolean { 26 + for (i in 0..< containerSize) { 27 + if (!getItem(i).isEmpty) { 28 + return false 29 + } 30 + } 31 + return true 32 + } 33 + 34 + override fun getItem(slot: Int): ItemStack { 35 + return stacks[slot] 36 + } 37 + 38 + override fun removeItem(slot: Int, amount: Int): ItemStack { 39 + val itemStack = ContainerHelper.removeItem(stacks, slot, amount) 40 + 41 + if (!itemStack.isEmpty) { 42 + setChanged() 43 + } 44 + return itemStack 45 + } 46 + 47 + override fun removeItemNoUpdate(slot: Int): ItemStack { 48 + val itemStack = stacks[slot] 49 + if (itemStack.isEmpty) { 50 + return ItemStack.EMPTY 51 + } else { 52 + stacks[slot] = ItemStack.EMPTY 53 + return itemStack 54 + } 55 + } 56 + 57 + override fun setItem(slot: Int, itemStack: ItemStack) { 58 + stacks[slot] = itemStack 59 + if (!itemStack.isEmpty && itemStack.count > maxStackSize) { 60 + itemStack.count = maxStackSize 61 + } 62 + 63 + setChanged() 64 + } 65 + 66 + abstract override fun setChanged() 67 + 68 + override fun canPlaceItem(slot: Int, itemStack: ItemStack): Boolean { 69 + return itemStack.item !== ModItems.CANCER_METER 70 + } 71 + 72 + override fun stillValid(player: Player): Boolean { 73 + return true 74 + } 75 + 76 + override fun clearContent() { 77 + } 78 + }
+27
src/main/kotlin/xyz/naomieow/asbestos/item/CancerMeterItem.kt
··· 1 + package xyz.naomieow.asbestos.item 2 + 3 + import net.minecraft.world.InteractionHand 4 + import net.minecraft.world.InteractionResultHolder 5 + import net.minecraft.world.entity.player.Player 6 + import net.minecraft.world.item.Item 7 + import net.minecraft.world.item.ItemStack 8 + import net.minecraft.world.level.Level 9 + import xyz.naomieow.asbestos.inventory.CancerMeterInventory 10 + 11 + class CancerMeterItem( 12 + properties: Properties 13 + ): Item( 14 + properties 15 + ) { 16 + override fun use(world: Level, user: Player, hand: InteractionHand): InteractionResultHolder<ItemStack?> { 17 + val itemStack = user.getItemInHand(hand) 18 + if (hand == InteractionHand.OFF_HAND) { 19 + return InteractionResultHolder.fail<ItemStack?>(itemStack) 20 + } 21 + 22 + if (!world.isClientSide()) { 23 + CancerMeterInventory.openHandledScreen(user, user.mainHandItem, 1.toByte()) 24 + } 25 + return InteractionResultHolder.sidedSuccess<ItemStack?>(itemStack, world.isClientSide()) 26 + } 27 + }
+60
src/main/kotlin/xyz/naomieow/asbestos/item/EmptySyringeItem.kt
··· 1 + package xyz.naomieow.asbestos.item 2 + 3 + import net.minecraft.sounds.SoundEvents 4 + import net.minecraft.sounds.SoundSource 5 + import net.minecraft.world.InteractionHand 6 + import net.minecraft.world.InteractionResult 7 + import net.minecraft.world.InteractionResultHolder 8 + import net.minecraft.world.entity.LivingEntity 9 + import net.minecraft.world.entity.player.Player 10 + import net.minecraft.world.item.Item 11 + import net.minecraft.world.item.ItemStack 12 + import net.minecraft.world.level.Level 13 + import xyz.naomieow.asbestos.AsbestosMod 14 + import xyz.naomieow.asbestos.damage.ModDamageTypes 15 + 16 + class EmptySyringeItem( 17 + properties: Item.Properties 18 + ): Item( 19 + properties 20 + ) { 21 + override fun use(world: Level, user: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> { 22 + useEmptySyringe(user, user, hand, world) 23 + return InteractionResultHolder.consume<ItemStack>(user.getItemInHand(hand)) 24 + } 25 + 26 + override fun interactLivingEntity( 27 + stack: ItemStack, 28 + user: Player, 29 + entity: LivingEntity, 30 + hand: InteractionHand 31 + ): InteractionResult { 32 + val world = user.level() 33 + useEmptySyringe(user, entity, hand, world) 34 + return InteractionResult.CONSUME 35 + } 36 + 37 + private fun useEmptySyringe(user: Player, target: LivingEntity, hand: InteractionHand, world: Level) { 38 + world.playSound( 39 + null, 40 + user.blockPosition(), 41 + SoundEvents.BOTTLE_FILL, 42 + SoundSource.PLAYERS, 43 + 1.0f, 1.0f 44 + ) 45 + val handStack = user.getItemInHand(hand) 46 + val newStack = ItemStack(ModItems.FILLED_SYRINGE, 1) 47 + newStack.tag = handStack.getOrCreateTag().copy() 48 + FilledSyringeItem.writeNbt(target, newStack) 49 + target.hurt( 50 + ModDamageTypes.of(user.level(), ModDamageTypes.BLOOD_EXTRACT), 51 + AsbestosMod.CONFIG.exsanguination.toFloat() 52 + ) 53 + if (!user.inventory.add(newStack)) { 54 + user.drop(newStack, false) 55 + } 56 + if (!user.abilities.instabuild) { 57 + handStack.shrink(1) 58 + } 59 + } 60 + }
+34
src/main/kotlin/xyz/naomieow/asbestos/item/FilledSyringeItem.kt
··· 1 + package xyz.naomieow.asbestos.item 2 + 3 + import net.minecraft.ChatFormatting 4 + import net.minecraft.network.chat.Component 5 + import net.minecraft.world.entity.EntityType 6 + import net.minecraft.world.entity.LivingEntity 7 + import net.minecraft.world.entity.player.Player 8 + import net.minecraft.world.item.Item 9 + import net.minecraft.world.item.ItemStack 10 + import xyz.naomieow.asbestos.AsbestosMod 11 + 12 + class FilledSyringeItem( 13 + properties: Properties 14 + ): Item( 15 + properties 16 + ) { 17 + companion object { 18 + private const val TYPE_KEY: String = "EntityType" 19 + private const val CANCER_KEY: String = "CancerMeter" 20 + 21 + fun writeNbt(target: LivingEntity, syringe: ItemStack) { 22 + val nbt = syringe.getOrCreateTag() 23 + syringe.setHoverName(Component.translatable( 24 + "item.asbestos.filled_syringe", 25 + target.name) 26 + .withStyle(ChatFormatting.RESET) 27 + ) 28 + nbt.putString(TYPE_KEY, EntityType.getKey(target.type).toString()) 29 + if (target is Player) { 30 + nbt.putInt(CANCER_KEY, AsbestosMod.MESOTHELIOMA.get(target).mesothelioma) 31 + } 32 + } 33 + } 34 + }
+19
src/main/kotlin/xyz/naomieow/asbestos/item/ModGroups.kt
··· 1 + package xyz.naomieow.asbestos.item 2 + 3 + import io.wispforest.owo.itemgroup.Icon 4 + import io.wispforest.owo.itemgroup.OwoItemGroup 5 + import net.minecraft.resources.ResourceLocation 6 + import xyz.naomieow.asbestos.AsbestosMod 7 + 8 + object ModGroups { 9 + @JvmStatic 10 + val ASBESTOS_GROUP: OwoItemGroup = OwoItemGroup 11 + .builder(ResourceLocation(AsbestosMod.MOD_ID, "asbestos_group")) { 12 + Icon.of(ModItems.ASBESTOS_FIBERS) 13 + } 14 + .build() 15 + 16 + fun init() { 17 + ASBESTOS_GROUP.initialize() 18 + } 19 + }
+70
src/main/kotlin/xyz/naomieow/asbestos/item/ModItems.kt
··· 1 + package xyz.naomieow.asbestos.item 2 + 3 + import io.wispforest.owo.itemgroup.OwoItemSettings 4 + import io.wispforest.owo.registration.reflect.ItemRegistryContainer 5 + import net.minecraft.world.effect.MobEffectInstance 6 + import net.minecraft.world.effect.MobEffects 7 + import net.minecraft.world.food.FoodProperties 8 + import net.minecraft.world.item.ArmorItem 9 + import net.minecraft.world.item.Item 10 + import net.minecraft.world.item.TieredItem 11 + import xyz.naomieow.asbestos.armor.ProtectiveMaterial 12 + 13 + class ModItems: ItemRegistryContainer { 14 + companion object { 15 + @JvmStatic 16 + val ASBESTOS_FIBERS: Item = Item( 17 + OwoItemSettings() 18 + .group(ModGroups.ASBESTOS_GROUP) 19 + .fireResistant() 20 + .food( 21 + FoodProperties.Builder().alwaysEat().effect( 22 + MobEffectInstance(MobEffects.WITHER, 30 * 20, 4, false, false), 1.0f 23 + ).build() 24 + ) 25 + ) 26 + 27 + @JvmStatic 28 + val IRON_SCRAPER: TieredItem = ScraperItem( 29 + ScraperItemMaterial.INSTANCE, 0.0f, -3.0f, 30 + OwoItemSettings().group(ModGroups.ASBESTOS_GROUP) 31 + ) 32 + 33 + @JvmStatic 34 + val FILLED_SYRINGE: Item = FilledSyringeItem(OwoItemSettings() 35 + .group(ModGroups.ASBESTOS_GROUP) 36 + .stacksTo(1) 37 + ) 38 + @JvmStatic 39 + val EMPTY_SYRINGE: Item = EmptySyringeItem(OwoItemSettings() 40 + .group(ModGroups.ASBESTOS_GROUP) 41 + .stacksTo(16) 42 + ) 43 + @JvmStatic 44 + val CANCER_METER: Item = CancerMeterItem(OwoItemSettings() 45 + .group(ModGroups.ASBESTOS_GROUP) 46 + .stacksTo(1) 47 + ) 48 + 49 + @JvmStatic 50 + val PPE_HELMET: Item = ArmorItem( 51 + ProtectiveMaterial.INSTANCE, ArmorItem.Type.HELMET, 52 + OwoItemSettings().group(ModGroups.ASBESTOS_GROUP) 53 + ) 54 + @JvmStatic 55 + val PPE_CHESTPLATE: Item = ArmorItem( 56 + ProtectiveMaterial.INSTANCE, ArmorItem.Type.CHESTPLATE, 57 + OwoItemSettings().group(ModGroups.ASBESTOS_GROUP) 58 + ) 59 + @JvmStatic 60 + val PPE_LEGGINGS: Item = ArmorItem( 61 + ProtectiveMaterial.INSTANCE, ArmorItem.Type.LEGGINGS, 62 + OwoItemSettings().group(ModGroups.ASBESTOS_GROUP) 63 + ) 64 + @JvmStatic 65 + val PPE_BOOTS: Item = ArmorItem( 66 + ProtectiveMaterial.INSTANCE, ArmorItem.Type.BOOTS, 67 + OwoItemSettings().group(ModGroups.ASBESTOS_GROUP) 68 + ) 69 + } 70 + }
+29
src/main/kotlin/xyz/naomieow/asbestos/item/ScraperItem.kt
··· 1 + package xyz.naomieow.asbestos.item 2 + 3 + import net.minecraft.core.registries.Registries 4 + import net.minecraft.resources.ResourceLocation 5 + import net.minecraft.tags.TagKey 6 + import net.minecraft.world.item.DiggerItem 7 + import net.minecraft.world.item.Tier 8 + import net.minecraft.world.level.block.Block 9 + import xyz.naomieow.asbestos.AsbestosMod 10 + 11 + class ScraperItem( 12 + tier: Tier, 13 + attackDamage: Float, 14 + attackSpeed: Float, 15 + properties: Properties 16 + ): DiggerItem( 17 + attackDamage, 18 + attackSpeed, 19 + tier, 20 + AFFECTED_BLOCKS, 21 + properties 22 + ) { 23 + companion object { 24 + private val AFFECTED_BLOCKS: TagKey<Block> = TagKey.create( 25 + Registries.BLOCK, 26 + ResourceLocation(AsbestosMod.MOD_ID, "scrapeable") 27 + ) 28 + } 29 + }
+35
src/main/kotlin/xyz/naomieow/asbestos/item/ScraperItemMaterial.kt
··· 1 + package xyz.naomieow.asbestos.item 2 + 3 + import net.minecraft.world.item.Items 4 + import net.minecraft.world.item.Tier 5 + import net.minecraft.world.item.crafting.Ingredient 6 + 7 + class ScraperItemMaterial: Tier { 8 + override fun getUses(): Int { 9 + return 300 10 + } 11 + 12 + override fun getSpeed(): Float { 13 + return 5.0f 14 + } 15 + 16 + override fun getAttackDamageBonus(): Float { 17 + return 2.5f 18 + } 19 + 20 + override fun getLevel(): Int { 21 + return 1 22 + } 23 + 24 + override fun getEnchantmentValue(): Int { 25 + return 10 26 + } 27 + 28 + override fun getRepairIngredient(): Ingredient { 29 + return Ingredient.of(Items.IRON_INGOT) 30 + } 31 + 32 + companion object { 33 + val INSTANCE: ScraperItemMaterial = ScraperItemMaterial() 34 + } 35 + }
+9
src/main/kotlin/xyz/naomieow/asbestos/mesothelioma/MesoComponent.kt
··· 1 + package xyz.naomieow.asbestos.mesothelioma 2 + 3 + import dev.onyxstudios.cca.api.v3.component.ComponentV3 4 + 5 + interface IMesoComponent: ComponentV3 { 6 + var mesothelioma: Int 7 + get() = mesothelioma 8 + set(exposure: Int) { mesothelioma = exposure } 9 + }
+34
src/main/kotlin/xyz/naomieow/asbestos/mesothelioma/MesoStatusEffect.kt
··· 1 + package xyz.naomieow.asbestos.mesothelioma 2 + 3 + import net.minecraft.world.effect.MobEffect 4 + import net.minecraft.world.effect.MobEffectCategory 5 + import net.minecraft.world.effect.MobEffectInstance 6 + import net.minecraft.world.effect.MobEffects 7 + import net.minecraft.world.entity.LivingEntity 8 + import net.minecraft.world.entity.player.Player 9 + import xyz.naomieow.asbestos.AsbestosMod 10 + import xyz.naomieow.asbestos.damage.ModDamageTypes 11 + 12 + class MesoStatusEffect: MobEffect( 13 + MobEffectCategory.HARMFUL, 14 + 0x302412, 15 + ) { 16 + 17 + override fun isDurationEffectTick(duration: Int, amplifier: Int): Boolean { 18 + return true 19 + } 20 + 21 + override fun applyEffectTick(entity: LivingEntity, amplifier: Int) { 22 + super.applyEffectTick(entity, amplifier) 23 + if (entity is Player) { 24 + val exposure: Int = AsbestosMod.MESOTHELIOMA.get(entity).mesothelioma 25 + if (exposure >= (AsbestosMod.CONFIG.threshold / 1.5)) { 26 + entity.addEffect(MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, -1, 1)) 27 + } 28 + 29 + if (exposure >= AsbestosMod.CONFIG.threshold) { 30 + entity.hurt(ModDamageTypes.of(entity.level(), ModDamageTypes.MESOTHELIOMA), (1 shl amplifier).toFloat()) 31 + } 32 + } 33 + } 34 + }
+25
src/main/kotlin/xyz/naomieow/asbestos/mesothelioma/PlayerMesoComponent.kt
··· 1 + package xyz.naomieow.asbestos.mesothelioma 2 + 3 + import dev.onyxstudios.cca.api.v3.component.sync.AutoSyncedComponent 4 + import net.minecraft.nbt.CompoundTag 5 + import net.minecraft.world.entity.player.Player 6 + import xyz.naomieow.asbestos.AsbestosMod 7 + 8 + class PlayerMesoComponent( 9 + var playerEntity: Player 10 + ): IMesoComponent, AutoSyncedComponent { 11 + override var mesothelioma: Int 12 + get() = mesothelioma 13 + set(exposure: Int) { 14 + mesothelioma = exposure 15 + AsbestosMod.MESOTHELIOMA.sync(playerEntity) 16 + } 17 + 18 + override fun readFromNbt(tag: CompoundTag) { 19 + mesothelioma = tag.getInt("mesothelioma") 20 + } 21 + 22 + override fun writeToNbt(tag: CompoundTag) { 23 + tag.putInt("mesothelioma", mesothelioma) 24 + } 25 + }
+98
src/main/kotlin/xyz/naomieow/asbestos/screen/CancerMeterScreen.kt
··· 1 + package xyz.naomieow.asbestos.screen 2 + 3 + import net.fabricmc.api.EnvType 4 + import net.fabricmc.api.Environment 5 + import net.minecraft.client.gui.GuiGraphics 6 + import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen 7 + import net.minecraft.network.chat.Component 8 + import net.minecraft.resources.ResourceLocation 9 + import net.minecraft.world.entity.player.Inventory 10 + import xyz.naomieow.asbestos.AsbestosMod 11 + import xyz.naomieow.asbestos.screen.util.MouseUtil 12 + import java.util.Optional 13 + 14 + @Environment(EnvType.CLIENT) 15 + class CancerMeterScreen( 16 + abstractContainerMenu: CancerMeterScreenHandler, 17 + inventory: Inventory, 18 + component: Component, 19 + ): AbstractContainerScreen<CancerMeterScreenHandler>( 20 + abstractContainerMenu, 21 + inventory, 22 + component 23 + ) { 24 + private val TEXTURE: ResourceLocation = ResourceLocation( 25 + AsbestosMod.MOD_ID, 26 + "textures/gui/cancer_meter.png" 27 + ) 28 + var screenHandler = abstractContainerMenu; 29 + 30 + override fun render(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) { 31 + renderBackground(context) 32 + super.render(context, mouseX, mouseY, delta) 33 + renderTooltip(context, mouseX, mouseY) 34 + } 35 + 36 + override fun renderBg(context: GuiGraphics, delta: Float, mouseX: Int, mouseY: Int) { 37 + val x = (width - imageWidth) / 2 38 + val y = (height - imageHeight) / 2 39 + context.blit( 40 + TEXTURE, 41 + x, y, 42 + 0, 0, 43 + imageWidth, 44 + imageHeight 45 + ) 46 + drawCancerProgress(context, x + 109, y + 56) 47 + } 48 + 49 + override fun renderLabels(context: GuiGraphics, mouseX: Int, mouseY: Int) { 50 + val x = (width - imageWidth) / 2 51 + val y = (height - imageHeight) / 2 52 + 53 + if (isMouseAboveArea(mouseX, mouseY, x, y, 108, 55, 58, 7)) { 54 + context.renderTooltip( 55 + font, 56 + listOf( 57 + Component.literal( 58 + screenHandler.getCancerMeter().toString() + "/" + AsbestosMod.CONFIG.threshold 59 + ) 60 + ), 61 + Optional.empty(), 62 + mouseX - x, 63 + mouseY - y 64 + ) 65 + } 66 + context.drawString( 67 + this.font, 68 + this.playerInventoryTitle, 69 + this.inventoryLabelX, 70 + this.inventoryLabelY + 2, 71 + 4210752, 72 + false 73 + ) 74 + } 75 + 76 + private fun drawCancerProgress(context: GuiGraphics, x: Int, y: Int) { 77 + val offset = screenHandler.getCancerMeter() * 58 / AsbestosMod.CONFIG.threshold 78 + context.blit( 79 + TEXTURE, 80 + x, y, 81 + 176, 56, 82 + offset, 7 83 + ) 84 + } 85 + 86 + private fun isMouseAboveArea( 87 + mouseX: Int, mouseY: Int, 88 + x: Int, y: Int, 89 + offsetX: Int, offsetY: Int, 90 + width: Int, height: Int 91 + ): Boolean { 92 + return MouseUtil.isMouseOver( 93 + mouseX.toDouble(), mouseY.toDouble(), 94 + x + offsetX, y + offsetY, 95 + width, height 96 + ) 97 + } 98 + }
+144
src/main/kotlin/xyz/naomieow/asbestos/screen/CancerMeterScreenHandler.kt
··· 1 + package xyz.naomieow.asbestos.screen 2 + 3 + import net.minecraft.network.FriendlyByteBuf 4 + import net.minecraft.world.entity.EquipmentSlot 5 + import net.minecraft.world.entity.player.Inventory 6 + import net.minecraft.world.entity.player.Player 7 + import net.minecraft.world.inventory.AbstractContainerMenu 8 + import net.minecraft.world.inventory.MenuType 9 + import net.minecraft.world.inventory.Slot 10 + import net.minecraft.world.item.ItemStack 11 + import xyz.naomieow.asbestos.inventory.CancerMeterInventory 12 + import xyz.naomieow.asbestos.inventory.ICancerMeterInventory 13 + import xyz.naomieow.asbestos.item.CancerMeterItem 14 + import xyz.naomieow.asbestos.item.ModItems 15 + import java.util.* 16 + 17 + class CancerMeterScreenHandler( 18 + type: MenuType<*>, 19 + syncId: Int, 20 + var playerInventory: Inventory, 21 + var inventory: ICancerMeterInventory, 22 + ): AbstractContainerMenu(type, syncId) { 23 + constructor( 24 + syncId: Int, 25 + playerInventory: Inventory, 26 + buf: FriendlyByteBuf 27 + ): this(syncId, playerInventory, createInventory(playerInventory, buf)) 28 + 29 + constructor( 30 + syncId: Int, 31 + playerInventory: Inventory, 32 + inventory: ICancerMeterInventory, 33 + ): this(ModHandlers.CANCER_METER, syncId, playerInventory, inventory) 34 + 35 + init { 36 + addSlot(object : Slot(inventory.getInventory(), 0, 80, 54) { 37 + override fun mayPlace(stack: ItemStack): Boolean { 38 + return stack.`is`(ModItems.FILLED_SYRINGE) 39 + } 40 + }) 41 + 42 + addPlayerInventory(playerInventory) 43 + addPlayerHotbar(playerInventory) 44 + } 45 + 46 + override fun quickMoveStack(player: Player, slotIndex: Int): ItemStack { 47 + var itemStack = ItemStack.EMPTY 48 + val slot = this.slots[slotIndex] 49 + if (slot.hasItem()) { 50 + val stackInSlot = slot.item 51 + itemStack = stackInSlot.copy() 52 + if (slotIndex == 0) { 53 + if (!this.moveItemStackTo(stackInSlot, INVENTORY_START, HOTBAR_END, true)) { 54 + return ItemStack.EMPTY 55 + } 56 + slot.onQuickCraft(stackInSlot, itemStack) 57 + } else if (itemStack.`is`(ModItems.FILLED_SYRINGE)) { 58 + if (!this.moveItemStackTo(stackInSlot, 0, 1, false)) { 59 + return ItemStack.EMPTY 60 + } 61 + } else if (slotIndex >= INVENTORY_START && slotIndex < INVENTORY_END) { 62 + if (!this.moveItemStackTo(stackInSlot, HOTBAR_START, HOTBAR_END, false)) { 63 + return ItemStack.EMPTY 64 + } 65 + } else if (slotIndex >= HOTBAR_START && slotIndex < HOTBAR_END) { 66 + if (!this.moveItemStackTo(stackInSlot, INVENTORY_START, INVENTORY_END, false)) { 67 + return ItemStack.EMPTY 68 + } 69 + } else { 70 + if (!this.moveItemStackTo(stackInSlot, INVENTORY_START, HOTBAR_END, false)) { 71 + return ItemStack.EMPTY 72 + } 73 + } 74 + 75 + if (stackInSlot.isEmpty) { 76 + slot.setByPlayer(ItemStack.EMPTY) 77 + } else { 78 + slot.setChanged() 79 + } 80 + 81 + if (stackInSlot.count == itemStack.count) { 82 + return ItemStack.EMPTY 83 + } 84 + 85 + slot.onTake(player, stackInSlot) 86 + 87 + if (slotIndex == 0) { 88 + player.drop(stackInSlot, false) 89 + } 90 + } 91 + return itemStack 92 + } 93 + 94 + override fun stillValid(player: Player): Boolean { 95 + return true 96 + } 97 + 98 + private fun addPlayerInventory(inventory: Inventory) { 99 + for (row in 0..2) { 100 + for (column in 0..8) { 101 + this.addSlot(Slot(inventory, column + row * 9 + 9, 8 + column * 18, 84 + row * 18)) 102 + } 103 + } 104 + } 105 + 106 + private fun addPlayerHotbar(inventory: Inventory) { 107 + for (slot in 0..8) { 108 + this.addSlot(Slot(inventory, slot, 8 + slot * 18, 142)) 109 + } 110 + } 111 + 112 + fun getCancerMeter(): Int { 113 + val nbt = this.inventory.getInventory().getItem(0).getOrCreateTag() 114 + return if (nbt.contains("CancerMeter")) nbt.getInt("CancerMeter") else 0 115 + } 116 + 117 + companion object { 118 + private const val INVENTORY_START: Int = 1 119 + private const val INVENTORY_END: Int = 28 120 + private const val HOTBAR_START: Int = 28 121 + private const val HOTBAR_END: Int = 37 122 + 123 + private fun createInventory(playerInventory: Inventory?, buf: FriendlyByteBuf?): CancerMeterInventory { 124 + Objects.requireNonNull<Inventory?>(playerInventory) 125 + Objects.requireNonNull<FriendlyByteBuf?>(buf) 126 + 127 + val stack: ItemStack 128 + val screenID = buf!!.readByte() 129 + 130 + if (screenID.toInt() == 1) { 131 + stack = playerInventory!!.player.getItemBySlot(EquipmentSlot.MAINHAND) 132 + } else { 133 + stack = ItemStack.EMPTY 134 + } 135 + 136 + if (stack.item is CancerMeterItem) { 137 + if (screenID.toInt() == 1) { 138 + return CancerMeterInventory(stack, playerInventory!!.player, screenID) 139 + } 140 + } 141 + throw IllegalStateException("Incorrect ItemStack $stack") 142 + } 143 + } 144 + }
+22
src/main/kotlin/xyz/naomieow/asbestos/screen/ModHandlers.kt
··· 1 + package xyz.naomieow.asbestos.screen 2 + 3 + import io.wispforest.owo.registration.reflect.AutoRegistryContainer 4 + import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType 5 + import net.minecraft.core.Registry 6 + import net.minecraft.core.registries.BuiltInRegistries 7 + import net.minecraft.world.inventory.MenuType 8 + 9 + class ModHandlers: AutoRegistryContainer<MenuType<*>> { 10 + override fun getRegistry(): Registry<MenuType<*>> { 11 + return BuiltInRegistries.MENU 12 + } 13 + 14 + override fun getTargetFieldType(): Class<MenuType<*>> { 15 + return MenuType::class.java 16 + } 17 + 18 + companion object { 19 + @JvmStatic 20 + val CANCER_METER: MenuType<CancerMeterScreenHandler> = ExtendedScreenHandlerType(::CancerMeterScreenHandler) 21 + } 22 + }
+18
src/main/kotlin/xyz/naomieow/asbestos/screen/util/MouseUtil.kt
··· 1 + package xyz.naomieow.asbestos.screen.util 2 + 3 + object MouseUtil { 4 + @JvmStatic 5 + fun isMouseOver(mouseX: Double, mouseY: Double, x: Int, y: Int): Boolean { 6 + return isMouseOver(mouseX, mouseY, x, y, 16) 7 + } 8 + 9 + @JvmStatic 10 + fun isMouseOver(mouseX: Double, mouseY: Double, x: Int, y: Int, size: Int): Boolean { 11 + return isMouseOver(mouseX, mouseY, x, y, size, size) 12 + } 13 + 14 + @JvmStatic 15 + fun isMouseOver(mouseX: Double, mouseY: Double, x: Int, y: Int, sizeX: Int, sizeY: Int): Boolean { 16 + return (mouseX >= x && mouseX <= x + sizeX) && (mouseY >= y && mouseY <= y + sizeY) 17 + } 18 + }
+12 -3
src/main/resources/fabric.mod.json
··· 16 16 "environment": "*", 17 17 "entrypoints": { 18 18 "main": [ 19 - "xyz.naomieow.asbestos.AsbestosMod" 19 + { 20 + "value": "xyz.naomieow.asbestos.AsbestosMod", 21 + "adapter": "kotlin" 22 + } 20 23 ], 21 24 "client": [ 22 - "xyz.naomieow.asbestos.AsbestosModClient" 25 + { 26 + "value": "xyz.naomieow.asbestos.AsbestosModClient", 27 + "adapter": "kotlin" 28 + } 23 29 ], 24 30 "cardinal-components-entity": [ 25 - "xyz.naomieow.asbestos.AsbestosMod" 31 + { 32 + "value": "xyz.naomieow.asbestos.AsbestosMod", 33 + "adapter": "kotlin" 34 + } 26 35 ] 27 36 }, 28 37 "custom": {