This commit is contained in:
2026-09-17 18:38:15 +08:00
parent e9224db163
commit 5f442f2b8e
17 changed files with 119 additions and 113 deletions
+9 -5
View File
@@ -1,9 +1,13 @@
# Example Mod # 自然之需:可抱起后代
——三小时摸鱼作品
## Setup [English readme here](./README_en.md)
For setup instructions, please see the [Fabric Documentation page](https://docs.fabricmc.net/develop/getting-started/creating-a-project#setting-up) related to the IDE that you are using. 在使用 carryon 抱起生物的时候,默认是不能抱起敌对生物的——很合理,毕竟直觉上它们会反抗。
## License 但是,自然之需有一个选项“敌对后代不攻击玩家”,这意味着它们大概不会反抗你抱起来了。
This template is available under the CC0 license. Feel free to learn from it and incorporate it in your own projects. 因此,我们将此限制解除:如果是玩家产下的后代(无论谁生的,因为自然之需没有记录后代的母亲是哪个玩家),则无视敌对和体型限制,使其更符合直觉。
## todo
此 mod 没有读取自然之需的配置 `NeedsOfNature.getConfig().pregnancyFriendlyMobsIgnorePlayers()` 也没有新建一个配置,因为作为只有一个选项的 mod,关掉还不如直接卸了方便些。
+12
View File
@@ -0,0 +1,12 @@
# Needs of Nature: Picking Up Offspring
[中文文档](./README.md)
By default, the `carryon` mod prevents players from picking up hostile creatures—which makes sense, as one would intuitively expect them to resist.
However, the "Needs of Nature" mod includes an option called "Spawned hostiles ignore players," implying that such offspring likely wouldn't resist being picked up.
Therefore, we have lifted this restriction: if the offspring was produced by a player (regardless of which specific player gave birth, as "Needs of Nature" does not track the mother's identity), the hostility and size constraints are ignored, making the behavior more intuitive.
## TODO
This mod neither reads the "Needs of Nature" configuration setting `NeedsOfNature.getConfig().pregnancyFriendlyMobsIgnorePlayers()` nor introduces a new config option; since this mod has only a single function, simply uninstalling it is more convenient than toggling a setting off.
+12 -1
View File
@@ -9,13 +9,18 @@ repositories {
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically. // Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html // See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories. // for more information about repositories.
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content { includeGroup "maven.modrinth" }
}
} }
loom { loom {
splitEnvironmentSourceSets() splitEnvironmentSourceSets()
mods { mods {
"modid" { "non-carryon" {
sourceSet sourceSets.main sourceSet sourceSets.main
sourceSet sourceSets.client sourceSet sourceSets.client
} }
@@ -30,6 +35,12 @@ dependencies {
// Fabric API. This is technically optional, but you probably want it anyway. // Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
modImplementation files("lib/needsofnature-1.5.1+1.21.11.jar")
// modImplementation files("lib/carryon-fabric-1.21.11-2.9.2.jar")
modImplementation "maven.modrinth:carry-on:2.9.2"
} }
processResources { processResources {
Binary file not shown.
+1 -1
View File
@@ -10,4 +10,4 @@ pluginManagement {
} }
// Should match your modid // Should match your modid
rootProject.name = 'modid' rootProject.name = 'non-carryon'
@@ -1,10 +0,0 @@
package com.example.client;
import net.fabricmc.api.ClientModInitializer;
public class ExampleModClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
// This entrypoint is suitable for setting up client-specific logic, such as rendering.
}
}
@@ -1,15 +0,0 @@
package com.example.client.mixin;
import net.minecraft.client.Minecraft;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Minecraft.class)
public class ExampleClientMixin {
@Inject(at = @At("HEAD"), method = "run")
private void init(CallbackInfo info) {
// This code is injected into the start of Minecraft.run()V
}
}
@@ -1,14 +0,0 @@
{
"required": true,
"package": "com.example.client.mixin",
"compatibilityLevel": "JAVA_21",
"client": [
"ExampleClientMixin"
],
"injectors": {
"defaultRequire": 1
},
"overwrites": {
"requireAnnotations": true
}
}
-30
View File
@@ -1,30 +0,0 @@
package com.example;
import net.fabricmc.api.ModInitializer;
import net.minecraft.resources.Identifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ExampleMod implements ModInitializer {
public static final String MOD_ID = "modid";
// This logger is used to write text to the console and the log file.
// It is considered best practice to use your mod id as the logger's name.
// That way, it's clear which mod wrote info, warnings, and errors.
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
@Override
public void onInitialize() {
// This code runs as soon as Minecraft is in a mod-load-ready state.
// However, some things (like resources) may still be uninitialized.
// Proceed with mild caution.
LOGGER.info("Hello Fabric world!");
}
public static Identifier id(String path) {
return Identifier.fromNamespaceAndPath(MOD_ID, path);
}
}
@@ -1,15 +0,0 @@
package com.example.mixin;
import net.minecraft.server.MinecraftServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MinecraftServer.class)
public class ExampleMixin {
@Inject(at = @At("HEAD"), method = "loadLevel")
private void init(CallbackInfo info) {
// This code is injected into the start of MinecraftServer.loadLevel()V
}
}
+61
View File
@@ -0,0 +1,61 @@
package mystya.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import tschipp.carryon.common.carry.PickupHandler;
import org.spongepowered.asm.mixin.Mixin;
import tschipp.carryon.utils.SizeHelper;
@Mixin(PickupHandler.class)
public class carryon {
private static boolean hasTag(Entity e) {
return e.getTags().contains("non.pregnancy_friendly");
}
@Redirect(
method = "tryPickupEntity",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/entity/EntityType;getCategory()Lnet/minecraft/world/entity/MobCategory;"
)
)
private static MobCategory skipMonsterCheck(EntityType instance, @Local(argsOnly = true) Entity entity) {
MobCategory category = entity.getType().getCategory();
if (category == MobCategory.MONSTER && hasTag(entity))
return MobCategory.CREATURE;
return category;
}
@Redirect(
method = "tryPickupEntity",
at = @At(
value = "INVOKE",
target = "Ltschipp/carryon/utils/SizeHelper;getRelativeEntityHeight(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/entity/Entity;)F"
)
)
private static float skipHeightCheck(Player player, Entity entity) {
if (hasTag(entity)) return 0;
return SizeHelper.getRelativeEntityHeight(player, entity);
}
@Redirect(
method = "tryPickupEntity",
at = @At(
value = "INVOKE",
target = "Ltschipp/carryon/utils/SizeHelper;getRelativeEntityWidth(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/entity/Entity;)F"
)
)
private static float skipWidthCheck(Player player, Entity entity) {
if (hasTag(entity)) return 0;
return SizeHelper.getRelativeEntityWidth(player, entity);
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

@@ -0,0 +1,4 @@
{
"mystya.non-carryon.name": "non: allow carry on pickup hostile offspring",
"mystya.non-carryon.description": "skip carry on mob type check & size check for needs of nature pregnancy offspring"
}
@@ -0,0 +1,4 @@
{
"mystya.non-carryon.name": "自然之需:可抱起后代",
"mystya.non-carryon.description": "自然之需产下的后代可以被玩家 carryon 抱起,无论是敌对生物还是大体积生物。"
}
+14 -20
View File
@@ -1,38 +1,32 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"id": "modid", "id": "non-carryon",
"version": "${version}", "version": "${version}",
"name": "Example Mod", "name": "allow carry on pickup hostile offspring",
"description": "This is an example description! Tell everyone what your mod is about!", "description": "skip carry on mob type check & size check for needs of nature pregnancy offspring",
"modmenu": {
"nameTranslation": "mystya.non-carryon.name",
"descriptionTranslation": "mystya.non-carryon.description"
},
"authors": [ "authors": [
"Me!" "mystya"
], ],
"contact": { "contact": {
"homepage": "https://fabricmc.net/", "sources": "example.com"
"sources": "https://github.com/FabricMC/fabric-example-mod"
}, },
"license": "CC0-1.0", "license": "CC BY-NC 4.0",
"icon": "assets/modid/icon.png", "icon": "assets/non-carryon/icon.png",
"environment": "*", "environment": "*",
"entrypoints": { "entrypoints": {
"main": [
"com.example.ExampleMod"
],
"client": [
"com.example.client.ExampleModClient"
]
}, },
"mixins": [ "mixins": [
"modid.mixins.json", "non-carryon.mixins.json"
{
"config": "modid.client.mixins.json",
"environment": "client"
}
], ],
"depends": { "depends": {
"fabricloader": ">=0.19.5", "fabricloader": ">=0.19.5",
"minecraft": "~1.21.11", "minecraft": "~1.21.11",
"java": ">=21", "java": ">=21",
"fabric-api": "*" "carryon": ">=2.9.2",
"needsofnature": ">=1.5.1"
} }
} }
@@ -1,9 +1,9 @@
{ {
"required": true, "required": true,
"package": "com.example.mixin", "package": "mystya.mixin",
"compatibilityLevel": "JAVA_21", "compatibilityLevel": "JAVA_21",
"mixins": [ "mixins": [
"ExampleMixin" "carryon"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1