This commit is contained in:
Chipperfluff 2025-12-18 23:46:01 +01:00
parent 98be4b5aee
commit baa7f4f810
30 changed files with 466 additions and 17 deletions

3
.gitignore vendored
View File

@ -33,3 +33,6 @@ loom-cache/
# ===== Misc ===== # ===== Misc =====
*.tmp *.tmp
*.bak *.bak
__pycache__/
*.pyc

View File

@ -1,16 +1,10 @@
package net.Chipperfluff.chipi; package net.Chipperfluff.chipi;
import net.Chipperfluff.chipi.command.ChpCommand;
import net.Chipperfluff.chipi.item.ModItems;
import net.Chipperfluff.chipi.block.ModBlocks;
import net.Chipperfluff.chipi.world.gen.ChipiDungeonGenerator;
import net.Chipperfluff.chipi.block.ChipperPortalBlock;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.structure.StructurePlacementData; import net.minecraft.structure.StructurePlacementData;
import net.minecraft.structure.StructureTemplate; import net.minecraft.structure.StructureTemplate;
@ -18,15 +12,27 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.GameRules; import net.minecraft.world.GameRules;
import net.Chipperfluff.chipi.item.ModItemGroups;
import net.fabricmc.fabric.api.biome.v1.BiomeModifications; import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryKeys;
import net.minecraft.world.gen.GenerationStep; import net.minecraft.world.gen.GenerationStep;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
import net.Chipperfluff.chipi.effect.ModEffects;
import net.Chipperfluff.chipi.effect.ChipiBlessingEvents;
import net.Chipperfluff.chipi.effect.ChipiHungerHandler;
import net.Chipperfluff.chipi.item.ModItems;
import net.Chipperfluff.chipi.block.ModBlocks;
import net.Chipperfluff.chipi.entity.ModEntities;
import net.Chipperfluff.chipi.item.ModItemGroups;
import net.Chipperfluff.chipi.advancement.ModCriteria; import net.Chipperfluff.chipi.advancement.ModCriteria;
import net.Chipperfluff.chipi.world.gen.ChipiDungeonGenerator;
import net.Chipperfluff.chipi.block.ChipperPortalBlock;
import net.Chipperfluff.chipi.command.ChpCommand;
import net.Chipperfluff.chipi.entity.custom.MepEntity;
public class ChipiMod implements ModInitializer { public class ChipiMod implements ModInitializer {
public static final String MOD_ID = "chipi"; public static final String MOD_ID = "chipi";
@ -44,6 +50,16 @@ public class ChipiMod implements ModInitializer {
ModItems.register(); ModItems.register();
ModItemGroups.register(); ModItemGroups.register();
ModCriteria.register(); ModCriteria.register();
ModEntities.register();
ModEffects.register();
ChipiBlessingEvents.register();
ChipiHungerHandler.register();
FabricDefaultAttributeRegistry.register(
ModEntities.MEP,
MepEntity.createMepAttributes()
);
BiomeModifications.addFeature( BiomeModifications.addFeature(
BiomeSelectors.foundInOverworld(), BiomeSelectors.foundInOverworld(),

View File

@ -1,20 +1,21 @@
package net.Chipperfluff.chipi.client; package net.Chipperfluff.chipi.client;
import net.Chipperfluff.chipi.block.ModBlocks;
import net.Chipperfluff.chipi.client.entity.ModEntityRenderers;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.minecraft.client.render.DimensionEffects;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderLayer;
import net.Chipperfluff.chipi.block.ModBlocks;
public class ChipiClient implements ClientModInitializer { public class ChipiClient implements ClientModInitializer {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
BlockRenderLayerMap.INSTANCE.putBlock( BlockRenderLayerMap.INSTANCE.putBlock(
ModBlocks.CHIPPER_PORTAL, ModBlocks.CHIPPER_PORTAL,
RenderLayer.getTranslucent() RenderLayer.getTranslucent()
); );
ModEntityRenderers.register();
} }
} }

View File

@ -0,0 +1,26 @@
package net.Chipperfluff.chipi.client.entity;
import net.Chipperfluff.chipi.ChipiMod;
import net.Chipperfluff.chipi.entity.custom.MepEntity;
import net.minecraft.client.render.entity.BipedEntityRenderer;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.render.entity.model.EntityModelLayers;
import net.minecraft.util.Identifier;
public class MepRenderer extends BipedEntityRenderer<MepEntity, BipedEntityModel<MepEntity>> {
private static final Identifier TEXTURE =
new Identifier(ChipiMod.MOD_ID, "textures/entity/mep.png");
public MepRenderer(EntityRendererFactory.Context ctx) {
super(ctx,
new BipedEntityModel<>(ctx.getPart(EntityModelLayers.PLAYER)),
0.5f);
}
@Override
public Identifier getTexture(MepEntity entity) {
return TEXTURE;
}
}

View File

@ -0,0 +1,14 @@
package net.Chipperfluff.chipi.client.entity;
import net.Chipperfluff.chipi.entity.ModEntities;
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry;
public class ModEntityRenderers {
public static void register() {
EntityRendererRegistry.register(
ModEntities.MEP,
MepRenderer::new
);
}
}

View File

@ -0,0 +1,25 @@
package net.Chipperfluff.chipi.effect;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectCategory;
import net.minecraft.entity.player.PlayerEntity;
public class ChipiBlessingEffect extends StatusEffect {
public ChipiBlessingEffect() {
super(StatusEffectCategory.BENEFICIAL, 0xFF8000);
}
@Override
public boolean canApplyUpdateEffect(int duration, int amplifier) {
return true; // run every tick
}
@Override
public void applyUpdateEffect(LivingEntity entity, int amplifier) {
if (entity.getHealth() < entity.getMaxHealth()) {
entity.heal(0.05f * (amplifier + 1));
}
}
}

View File

@ -0,0 +1,27 @@
package net.Chipperfluff.chipi.effect;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.damage.DamageTypes;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
public class ChipiBlessingEvents {
public static void register() {
ServerTickEvents.END_SERVER_TICK.register(ChipiBlessingEvents::onServerTick);
}
private static void onServerTick(MinecraftServer server) {
for (ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) {
if (player.hasStatusEffect(ModEffects.CHIPI_BLESSING)) {
player.getHungerManager().setExhaustion(0.0f);
}
}
}
public static boolean cancelFallDamage(ServerPlayerEntity player, DamageSource source) {
return source.isOf(DamageTypes.FALL)
&& player.hasStatusEffect(ModEffects.CHIPI_BLESSING);
}
}

View File

@ -0,0 +1,20 @@
package net.Chipperfluff.chipi.effect;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
public class ChipiHungerHandler {
public static void register() {
ServerTickEvents.END_SERVER_TICK.register(ChipiHungerHandler::onServerTick);
}
private static void onServerTick(MinecraftServer server) {
for (ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) {
if (player.hasStatusEffect(ModEffects.CHIPI_BLESSING)) {
player.getHungerManager().setExhaustion(0.0f);
}
}
}
}

View File

@ -0,0 +1,21 @@
package net.Chipperfluff.chipi.effect;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
import net.Chipperfluff.chipi.ChipiMod;
public class ModEffects {
public static final StatusEffect CHIPI_BLESSING =
new ChipiBlessingEffect();
public static void register() {
Registry.register(
Registries.STATUS_EFFECT,
new Identifier(ChipiMod.MOD_ID, "chipi_blessing"),
CHIPI_BLESSING
);
}
}

View File

@ -0,0 +1,26 @@
package net.Chipperfluff.chipi.entity;
import net.Chipperfluff.chipi.ChipiMod;
import net.Chipperfluff.chipi.entity.custom.MepEntity;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
public class ModEntities {
public static final EntityType<MepEntity> MEP = Registry.register(
Registries.ENTITY_TYPE,
new Identifier(ChipiMod.MOD_ID, "mep"),
FabricEntityTypeBuilder.createMob()
.entityFactory(MepEntity::new)
.dimensions(EntityDimensions.fixed(0.6f, 1.95f))
.build()
);
public static void register() {
// called from mod init
}
}

View File

@ -0,0 +1,94 @@
package net.Chipperfluff.chipi.entity.custom;
import net.minecraft.block.BlockState;
import net.minecraft.block.SlabBlock;
import net.minecraft.block.StairsBlock;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.ai.goal.ActiveTargetGoal;
import net.minecraft.entity.ai.goal.LookAroundGoal;
import net.minecraft.entity.ai.goal.LookAtEntityGoal;
import net.minecraft.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.entity.ai.goal.SwimGoal;
import net.minecraft.entity.ai.goal.WanderAroundFarGoal;
import net.minecraft.entity.attribute.DefaultAttributeContainer;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.mob.PathAwareEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class MepEntity extends PathAwareEntity {
private boolean angryAtPlayer = false;
public MepEntity(EntityType<? extends PathAwareEntity> entityType, World world) {
super(entityType, world);
}
@Override
protected void initGoals() {
this.goalSelector.add(1, new SwimGoal(this));
this.goalSelector.add(2, new MeleeAttackGoal(this, 1.2D, true));
this.goalSelector.add(3, new WanderAroundFarGoal(this, 1.0D));
this.goalSelector.add(4, new LookAtEntityGoal(this, PlayerEntity.class, 8.0F));
this.goalSelector.add(5, new LookAroundGoal(this));
this.targetSelector.add(1, new ActiveTargetGoal<>(
this,
PlayerEntity.class,
true,
target -> target instanceof PlayerEntity player
&& (angryAtPlayer || !isPlayerProtected(player))
));
}
public static DefaultAttributeContainer.Builder createMepAttributes() {
return PathAwareEntity.createMobAttributes()
.add(EntityAttributes.GENERIC_MAX_HEALTH, 20.0)
.add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 4.0)
.add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.25);
}
@Override
public boolean damage(DamageSource source, float amount) {
if (source.getAttacker() instanceof PlayerEntity) {
angryAtPlayer = true;
}
return super.damage(source, amount);
}
@Override
public void tick() {
super.tick();
LivingEntity target = this.getTarget();
if (angryAtPlayer) {
if (!(target instanceof PlayerEntity) || !this.canSee(target)) {
angryAtPlayer = false;
this.setTarget(null);
}
return;
}
if (target instanceof PlayerEntity player && isPlayerProtected(player)) {
this.setTarget(null);
this.getNavigation().stop();
}
}
private static boolean isPlayerProtected(PlayerEntity player) {
BlockPos pos = player.getBlockPos();
BlockState state = player.getWorld().getBlockState(pos);
if (!state.contains(Properties.WATERLOGGED) || !state.get(Properties.WATERLOGGED)) {
return false;
}
return state.getBlock() instanceof StairsBlock
|| state.getBlock() instanceof SlabBlock;
}
}

View File

@ -33,6 +33,13 @@ public class ModItemGroups {
entries.add(ModItems.RAW_CHIPPER_ORE); entries.add(ModItems.RAW_CHIPPER_ORE);
entries.add(ModItems.CHIPPER_INGOT); entries.add(ModItems.CHIPPER_INGOT);
entries.add(ModItems.CHIPPER_ALLOY); entries.add(ModItems.CHIPPER_ALLOY);
entries.add(ModItems.MEP_SPAWN_EGG);
// Armor
entries.add(ModItems.CHIPPER_HELMET);
entries.add(ModItems.CHIPPER_CHESTPLATE);
entries.add(ModItems.CHIPPER_LEGGINGS);
entries.add(ModItems.CHIPPER_BOOTS);
}) })
.build() .build()
); );

View File

@ -8,6 +8,11 @@ import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings; import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.Chipperfluff.chipi.ChipiMod; import net.Chipperfluff.chipi.ChipiMod;
import net.Chipperfluff.chipi.block.ModBlocks; import net.Chipperfluff.chipi.block.ModBlocks;
import net.minecraft.item.SpawnEggItem;
import net.Chipperfluff.chipi.entity.ModEntities;
import net.minecraft.item.ArmorItem;
import net.Chipperfluff.chipi.item.armor.ChipperArmorMaterial;
public class ModItems { public class ModItems {
@ -43,6 +48,17 @@ public class ModItems {
new BlockItem(ModBlocks.CHIPPER_ALLOY_BLOCK, new FabricItemSettings()) new BlockItem(ModBlocks.CHIPPER_ALLOY_BLOCK, new FabricItemSettings())
); );
public static final Item MEP_SPAWN_EGG = Registry.register(
Registries.ITEM,
new Identifier(ChipiMod.MOD_ID, "mep_spawn_egg"),
new SpawnEggItem(
ModEntities.MEP,
0x1E3A5F,
0x6BB6FF,
new Item.Settings()
)
);
// ===== NORMAL ITEMS ===== // ===== NORMAL ITEMS =====
public static final Item NUT = Registry.register( public static final Item NUT = Registry.register(
Registries.ITEM, Registries.ITEM,
@ -70,5 +86,30 @@ public class ModItems {
new Item(new FabricItemSettings()) new Item(new FabricItemSettings())
); );
public static final Item CHIPPER_HELMET = Registry.register(
Registries.ITEM,
new Identifier("chipi", "chipper_helmet"),
new ArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.HELMET, new Item.Settings())
);
public static final Item CHIPPER_CHESTPLATE = Registry.register(
Registries.ITEM,
new Identifier("chipi", "chipper_chestplate"),
new ArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.CHESTPLATE, new Item.Settings())
);
public static final Item CHIPPER_LEGGINGS = Registry.register(
Registries.ITEM,
new Identifier("chipi", "chipper_leggings"),
new ArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.LEGGINGS, new Item.Settings())
);
public static final Item CHIPPER_BOOTS = Registry.register(
Registries.ITEM,
new Identifier("chipi", "chipper_boots"),
new ArmorItem(ChipperArmorMaterial.INSTANCE, ArmorItem.Type.BOOTS, new Item.Settings())
);
public static void register() {} public static void register() {}
} }

View File

@ -0,0 +1,66 @@
package net.Chipperfluff.chipi.item.armor;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.ArmorMaterial;
import net.minecraft.recipe.Ingredient;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Util;
import java.util.EnumMap;
import java.util.Map;
public class ChipperArmorMaterial implements ArmorMaterial {
public static final ChipperArmorMaterial INSTANCE = new ChipperArmorMaterial();
private static final Map<ArmorItem.Type, Integer> PROTECTION = Util.make(
new EnumMap<>(ArmorItem.Type.class),
map -> {
map.put(ArmorItem.Type.HELMET, 2);
map.put(ArmorItem.Type.CHESTPLATE, 5);
map.put(ArmorItem.Type.LEGGINGS, 4);
map.put(ArmorItem.Type.BOOTS, 2);
}
);
@Override
public int getDurability(ArmorItem.Type type) {
return 3 * type.getEquipmentSlot().getEntitySlotId();
}
@Override
public int getProtection(ArmorItem.Type type) {
return PROTECTION.get(type);
}
@Override
public int getEnchantability() {
return 10;
}
@Override
public SoundEvent getEquipSound() {
return SoundEvents.ITEM_ARMOR_EQUIP_IRON;
}
@Override
public Ingredient getRepairIngredient() {
return Ingredient.ofItems(net.Chipperfluff.chipi.item.ModItems.CHIPPER_INGOT);
}
@Override
public String getName() {
return "chipi:chipper";
}
@Override
public float getToughness() {
return 2.0f;
}
@Override
public float getKnockbackResistance() {
return 0.4f;
}
}

View File

@ -4,6 +4,8 @@
"itemGroup.chipi.chipi": "Chipi", "itemGroup.chipi.chipi": "Chipi",
"effect.chipi.chipi_blessing": "Chipi's Blessing",
"block.chipi.void_block": "Void Block", "block.chipi.void_block": "Void Block",
"block.chipi.chipper_frame": "Chipper Frame", "block.chipi.chipper_frame": "Chipper Frame",
"block.chipi.chipper_portal": "Chipper Portal", "block.chipi.chipper_portal": "Chipper Portal",
@ -18,5 +20,29 @@
"item.chipi.nut": "Nut", "item.chipi.nut": "Nut",
"item.chipi.raw_chipper_ore": "Raw Chipper Ore", "item.chipi.raw_chipper_ore": "Raw Chipper Ore",
"item.chipi.chipper_ingot": "Chipper Ingot", "item.chipi.chipper_ingot": "Chipper Ingot",
"item.chipi.chipper_alloy": "Chipper Alloy" "item.chipi.chipper_alloy": "Chipper Alloy",
"item.chipi.mep_spawn_egg": "Mep Spawn Egg",
"item.chipi.chipper_helmet": "Chipper Helmet",
"item.chipi.chipper_chestplate": "Chipper Chestplate",
"item.chipi.chipper_leggings": "Chipper Leggings",
"item.chipi.chipper_boots": "Chipper Boots",
"tooltip.chipi.void_block": "§8It hums quietly.§r §7Do not listen.",
"tooltip.chipi.chipper_frame": "§7Built to hold a mistake in place.",
"tooltip.chipi.chipper_portal": "§5Something on the other side is already aware of you.",
"tooltip.chipi.chipper_ore": "§7Common.§r §8Uncomfortably so.",
"tooltip.chipi.chipper_alloy_block": "§7Pressed together until it stopped screaming.",
"tooltip.chipi.nut": "§7Probably edible.§r §8Probably.",
"tooltip.chipi.raw_chipper_ore": "§7Still warm to the touch.",
"tooltip.chipi.chipper_ingot": "§7Dense.§r §8Too dense.",
"tooltip.chipi.chipper_alloy": "§7Stronger than it looks.§r §8Worse than it feels.",
"tooltip.chipi.mep_spawn_egg": "§8It knows where you are.§r §7It always did.",
"tooltip.chipi.chipper_helmet": "§7Soaks the hit.§r §8Cracks immediately.",
"tooltip.chipi.chipper_chestplate": "§7Lets you stand your ground.§r §8Once.",
"tooltip.chipi.chipper_leggings": "§7Heavy steps.§r §8Short lifespan.",
"tooltip.chipi.chipper_boots": "§7You wont be moved.§r §8You will be broken."
} }

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "chipi:item/armor/chipper_boots"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "chipi:item/armor/chipper_chestplate"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "chipi:item/armor/chipper_helmet"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "chipi:item/armor/chipper_leggings"
}
}

View File

@ -0,0 +1,3 @@
{
"parent": "minecraft:item/template_spawn_egg"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -8,9 +8,13 @@
}, },
"criteria": { "criteria": {
"mine": { "mine": {
"trigger": "minecraft:mined_block", "trigger": "minecraft:inventory_changed",
"conditions": { "conditions": {
"block": "chipi:chipper_ore" "items": [
{
"items": ["chipi:raw_chipper_ore"]
}
]
} }
} }
} }

View File

@ -10,8 +10,13 @@
"place": { "place": {
"trigger": "minecraft:placed_block", "trigger": "minecraft:placed_block",
"conditions": { "conditions": {
"location": [
{
"condition": "minecraft:block_state_property",
"block": "chipi:chipper_alloy_block" "block": "chipi:chipper_alloy_block"
} }
]
}
} }
} }
} }