Add missing mixins to Forge

Add issues url to the mod
Add water hunting to avians
This commit is contained in:
2026-06-06 17:46:33 -04:00
parent 4d2921a925
commit 4447ee8ec4
9 changed files with 268 additions and 45 deletions
@@ -29,6 +29,9 @@ value class ModData(private val project: Project) {
val description: String get() = modProp("description") val description: String get() = modProp("description")
val license: String get() = modProp("license") val license: String get() = modProp("license")
val credits: String get() = modProp("credits") val credits: String get() = modProp("credits")
val issueUrl: String get() = modPropOrNull("issue_url") ?: ""
val homepageUrl: String get() = modPropOrNull("homepage_url") ?: ""
val sourcesUrl: String get() = modPropOrNull("sources_url") ?: ""
val minecraft_version: String get() = propOrNull("minecraft_version") ?: project.stonecutterBuild.current.version val minecraft_version: String get() = propOrNull("minecraft_version") ?: project.stonecutterBuild.current.version
fun propOrNull(key: String) = project.prop(key) fun propOrNull(key: String) = project.prop(key)
@@ -57,6 +57,9 @@ tasks {
"license" to commonMod.license, "license" to commonMod.license,
"description" to commonMod.description, "description" to commonMod.description,
"credits" to commonMod.credits, "credits" to commonMod.credits,
"issue_url" to commonMod.issueUrl,
"homepage_url" to commonMod.homepageUrl,
"sources_url" to commonMod.sourcesUrl,
"minecraft_version" to commonMod.propOrNull("minecraft_version"), "minecraft_version" to commonMod.propOrNull("minecraft_version"),
"minecraft_version_range" to commonMod.propOrNull("minecraft_version_range"), "minecraft_version_range" to commonMod.propOrNull("minecraft_version_range"),
"fabric_api_version" to commonMod.propOrNull("fabric_api_version"), "fabric_api_version" to commonMod.propOrNull("fabric_api_version"),
@@ -6,6 +6,7 @@ import net.cmr.jurassicrevived.util.ModTags;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.tags.FluidTags; import net.minecraft.tags.FluidTags;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
@@ -46,6 +47,10 @@ public class DinoAIController {
private static final int AVIAN_DIVE_RECOVERY_TICKS = 60; private static final int AVIAN_DIVE_RECOVERY_TICKS = 60;
private static final int AVIAN_MIN_SURFACE_RECOVERY_TICKS = 20; private static final int AVIAN_MIN_SURFACE_RECOVERY_TICKS = 20;
private static final int AVIAN_MAX_UNDERWATER_DIVE_TICKS = 40; private static final int AVIAN_MAX_UNDERWATER_DIVE_TICKS = 40;
private static final int AVIAN_BETWEEN_DIVE_REST_TICKS = 80;
private static final double AVIAN_RECOVERY_HEIGHT_ABOVE_WATER = 5.0D;
private static final double AVIAN_RECOVERY_TARGET_REACHED_DISTANCE_SQR = 2.25D;
private static final double AVIAN_RECOVERY_HORIZONTAL_SPEED = 0.08D;
private static final int ROAM_STATE_DURATION = 320; private static final int ROAM_STATE_DURATION = 320;
private static final int ROAM_RETARGET_INTERVAL = 80; private static final int ROAM_RETARGET_INTERVAL = 80;
private static final int NATURAL_BREEDING_CHECK_INTERVAL = 200; private static final int NATURAL_BREEDING_CHECK_INTERVAL = 200;
@@ -56,7 +61,9 @@ public class DinoAIController {
private static final int KILL_REGEN_DURATION_TICKS = 100; private static final int KILL_REGEN_DURATION_TICKS = 100;
private static final double AVIAN_RECOVERY_AIR_UPWARD_SPEED = 0.08D; private static final double AVIAN_RECOVERY_AIR_UPWARD_SPEED = 0.08D;
private static final double AVIAN_RECOVERY_MAX_UPWARD_SPEED = 0.22D; private static final double AVIAN_RECOVERY_MAX_UPWARD_SPEED = 0.22D;
private static final boolean AVIAN_UNDERWATER_HUNTING_ENABLED = false; private static final int AVIAN_MAX_TARGET_DEPTH_BELOW_SURFACE = 10;
private static final int AVIAN_WATER_SURFACE_SEARCH_UP = 16;
private static final boolean AVIAN_UNDERWATER_HUNTING_ENABLED = true;
private static final int HERBIVORE_SELF_FEED_INTERVAL = 40; private static final int HERBIVORE_SELF_FEED_INTERVAL = 40;
private static final float HERBIVORE_SELF_FEED_CHANCE = 0.35f; private static final float HERBIVORE_SELF_FEED_CHANCE = 0.35f;
private static final int HERBIVORE_BROWSE_HORIZONTAL_RANGE = 2; private static final int HERBIVORE_BROWSE_HORIZONTAL_RANGE = 2;
@@ -81,9 +88,11 @@ public class DinoAIController {
private int breedingCheckCooldown = 0; private int breedingCheckCooldown = 0;
private int avianDiveRecoveryTimer = 0; private int avianDiveRecoveryTimer = 0;
private int avianSurfaceRecoveryTimer = 0; private int avianSurfaceRecoveryTimer = 0;
private int avianDiveRestTimer = 0;
private boolean avianDiveInProgress = false; private boolean avianDiveInProgress = false;
private int avianUnderwaterDiveTimer = 0; private int avianUnderwaterDiveTimer = 0;
private boolean avianDiveAttackSpent = false; private boolean avianDiveAttackSpent = false;
private Vec3 avianRecoveryTarget;
// Attack Cooldown Tracker // Attack Cooldown Tracker
private int attackCooldown = 0; private int attackCooldown = 0;
@@ -108,27 +117,27 @@ public class DinoAIController {
this.dino = dino; this.dino = dino;
} }
public void tick() { public void tick() {
if (homePos == null) homePos = dino.blockPosition(); if (homePos == null) homePos = dino.blockPosition();
handleFloating(); handleFloating();
updateSensors(); updateSensors();
checkBreedingReadiness(); checkBreedingReadiness();
switch (currentState) { switch (currentState) {
case IDLE -> tickIdle(); case IDLE -> tickIdle();
case ROAMING -> tickRoaming(); case ROAMING -> tickRoaming();
case TERRITORIAL_ROAMING -> tickTerritorialRoaming(); case TERRITORIAL_ROAMING -> tickTerritorialRoaming();
case CHASING -> tickChasing(); case CHASING -> tickChasing();
case ATTACKING -> tickAttacking(); case ATTACKING -> tickAttacking();
case FLEEING -> tickFleeing(); case FLEEING -> tickFleeing();
case SLEEPING -> tickSleeping(); case SLEEPING -> tickSleeping();
case MATING -> tickMating(); case MATING -> tickMating();
} }
stateTimer++; stateTimer++;
if (attackCooldown > 0) attackCooldown--; if (attackCooldown > 0) attackCooldown--;
if (breedingCheckCooldown > 0) breedingCheckCooldown--; if (breedingCheckCooldown > 0) breedingCheckCooldown--;
if (avianDiveRecoveryTimer > 0) { if (avianDiveRecoveryTimer > 0) {
@@ -138,7 +147,24 @@ public class DinoAIController {
if (avianSurfaceRecoveryTimer > 0 && !dino.isInWater()) { if (avianSurfaceRecoveryTimer > 0 && !dino.isInWater()) {
avianSurfaceRecoveryTimer--; avianSurfaceRecoveryTimer--;
} }
}
if (avianDiveRestTimer > 0 && !dino.isInWater() && avianDiveRecoveryTimer <= 0 && avianSurfaceRecoveryTimer <= 0) {
avianDiveRestTimer--;
}
if (isAvianWaterHunter()
&& attackTarget != null
&& currentState == State.CHASING
&& !isRecoveringFromAvianDive()
&& avianDiveRestTimer <= 0
&& avianDiveAttackSpent
&& isUnderwaterTarget(attackTarget)) {
avianDiveAttackSpent = false;
avianDiveInProgress = true;
avianUnderwaterDiveTimer = 0;
avianRecoveryTarget = null;
}
}
private void handleFloating() { private void handleFloating() {
if (!dino.isInWater()) { if (!dino.isInWater()) {
@@ -204,9 +230,11 @@ public class DinoAIController {
if (newState != State.CHASING && newState != State.ATTACKING) { if (newState != State.CHASING && newState != State.ATTACKING) {
this.avianDiveRecoveryTimer = 0; this.avianDiveRecoveryTimer = 0;
this.avianSurfaceRecoveryTimer = 0; this.avianSurfaceRecoveryTimer = 0;
this.avianDiveRestTimer = 0;
this.avianDiveInProgress = false; this.avianDiveInProgress = false;
this.avianUnderwaterDiveTimer = 0; this.avianUnderwaterDiveTimer = 0;
this.avianDiveAttackSpent = false; this.avianDiveAttackSpent = false;
this.avianRecoveryTarget = null;
} }
// Reset sprinting if we aren't in a high-speed state // Reset sprinting if we aren't in a high-speed state
@@ -520,8 +548,22 @@ public class DinoAIController {
return true; return true;
} }
if (target != null && target.isAlive() && isUnderwaterTarget(target)) { if (target != null && target.isAlive() && target.isInWater()) {
avianDiveInProgress = true; if (avianDiveRestTimer > 0) {
handleAvianDiveRecoveryMovement();
return true;
}
if (!isUnderwaterTarget(target)) {
if (avianDiveInProgress || dino.isInWater()) {
beginAvianDiveRecovery();
return true;
}
avianDiveInProgress = false;
avianUnderwaterDiveTimer = 0;
return false;
}
if (dino.isInWater()) { if (dino.isInWater()) {
avianUnderwaterDiveTimer++; avianUnderwaterDiveTimer++;
@@ -540,12 +582,14 @@ public class DinoAIController {
Vec3 velocity = dino.getDeltaMovement(); Vec3 velocity = dino.getDeltaMovement();
dino.getNavigation().stop(); dino.getNavigation().stop();
faceAvianMovement(toTarget);
dino.setDeltaMovement( dino.setDeltaMovement(
velocity.x * 0.85D + dive.x, velocity.x * 0.85D + dive.x,
Math.max(AVIAN_DIVE_MAX_DOWNWARD_SPEED, velocity.y * 0.75D + dive.y), Math.max(AVIAN_DIVE_MAX_DOWNWARD_SPEED, velocity.y * 0.75D + dive.y),
velocity.z * 0.85D + dive.z velocity.z * 0.85D + dive.z
); );
dino.hasImpulse = true;
} }
return true; return true;
@@ -569,19 +613,45 @@ public class DinoAIController {
private void beginAvianDiveRecovery() { private void beginAvianDiveRecovery() {
this.avianDiveRecoveryTimer = AVIAN_DIVE_RECOVERY_TICKS; this.avianDiveRecoveryTimer = AVIAN_DIVE_RECOVERY_TICKS;
this.avianSurfaceRecoveryTimer = AVIAN_MIN_SURFACE_RECOVERY_TICKS; this.avianSurfaceRecoveryTimer = AVIAN_MIN_SURFACE_RECOVERY_TICKS;
this.avianDiveRestTimer = AVIAN_BETWEEN_DIVE_REST_TICKS;
this.avianDiveInProgress = false; this.avianDiveInProgress = false;
this.avianUnderwaterDiveTimer = 0; this.avianUnderwaterDiveTimer = 0;
this.avianDiveAttackSpent = true; this.avianDiveAttackSpent = true;
this.avianRecoveryTarget = findAvianRecoveryTarget();
this.pathRecalcTimer = 10; this.pathRecalcTimer = 10;
dino.getNavigation().stop(); dino.getNavigation().stop();
} }
private Vec3 findAvianRecoveryTarget() {
BlockPos origin = dino.blockPosition();
BlockPos surface = BlockPos.findClosestMatch(
origin,
10,
16,
p -> dino.level().getFluidState(p).is(FluidTags.WATER)
&& !dino.level().getFluidState(p.above()).is(FluidTags.WATER)
).orElse(null);
if (surface == null) {
return dino.position().add(0.0D, AVIAN_RECOVERY_HEIGHT_ABOVE_WATER, 0.0D);
}
return Vec3.atCenterOf(surface).add(0.0D, AVIAN_RECOVERY_HEIGHT_ABOVE_WATER, 0.0D);
}
private void handleAvianDiveRecoveryMovement() { private void handleAvianDiveRecoveryMovement() {
Vec3 velocity = dino.getDeltaMovement(); Vec3 velocity = dino.getDeltaMovement();
dino.getNavigation().stop(); dino.getNavigation().stop();
if (avianRecoveryTarget == null) {
avianRecoveryTarget = findAvianRecoveryTarget();
}
if (dino.isInWater()) { if (dino.isInWater()) {
Vec3 upwardRecovery = new Vec3(velocity.x * 0.45D, 1.0D, velocity.z * 0.45D);
faceAvianMovement(upwardRecovery);
dino.setDeltaMovement( dino.setDeltaMovement(
velocity.x * 0.45D, velocity.x * 0.45D,
Math.min(Math.max(velocity.y + 0.035D, AVIAN_WATER_EXIT_BOOST), AVIAN_RECOVERY_MAX_UPWARD_SPEED), Math.min(Math.max(velocity.y + 0.035D, AVIAN_WATER_EXIT_BOOST), AVIAN_RECOVERY_MAX_UPWARD_SPEED),
@@ -591,11 +661,31 @@ public class DinoAIController {
return; return;
} }
dino.setDeltaMovement( Vec3 toRecoveryTarget = avianRecoveryTarget.subtract(dino.position());
velocity.x * 0.92D, Vec3 horizontal = new Vec3(toRecoveryTarget.x, 0.0D, toRecoveryTarget.z);
Math.min(Math.max(velocity.y, AVIAN_RECOVERY_AIR_UPWARD_SPEED), AVIAN_RECOVERY_MAX_UPWARD_SPEED), double horizontalLengthSqr = horizontal.lengthSqr();
velocity.z * 0.92D
); double xMotion = velocity.x * 0.82D;
double zMotion = velocity.z * 0.82D;
if (horizontalLengthSqr > AVIAN_RECOVERY_TARGET_REACHED_DISTANCE_SQR) {
Vec3 horizontalMotion = horizontal.normalize().scale(AVIAN_RECOVERY_HORIZONTAL_SPEED);
xMotion += horizontalMotion.x;
zMotion += horizontalMotion.z;
}
double yMotion;
if (toRecoveryTarget.y > 0.35D) {
yMotion = Math.min(Math.max(velocity.y, AVIAN_RECOVERY_AIR_UPWARD_SPEED), AVIAN_RECOVERY_MAX_UPWARD_SPEED);
} else if (toRecoveryTarget.y < -0.75D) {
yMotion = Math.max(velocity.y - 0.03D, -0.08D);
} else {
yMotion = velocity.y * 0.55D;
}
faceAvianMovement(new Vec3(xMotion, yMotion, zMotion));
dino.setDeltaMovement(xMotion, yMotion, zMotion);
dino.hasImpulse = true; dino.hasImpulse = true;
} }
@@ -631,10 +721,58 @@ public class DinoAIController {
&& !(dino instanceof FlyingAnimal); && !(dino instanceof FlyingAnimal);
} }
private boolean isUnderwaterTarget(LivingEntity target) { private boolean isUnderwaterTarget(LivingEntity target) {
return target.isInWater() if (target == null || !target.isInWater()) {
&& target.getFluidHeight(FluidTags.WATER) > target.getFluidJumpThreshold(); return false;
} }
if (target.getFluidHeight(FluidTags.WATER) <= target.getFluidJumpThreshold()) {
return false;
}
if (isAvianWaterHunter()) {
return isWithinAvianDiveDepth(target);
}
return true;
}
private boolean isWithinAvianDiveDepth(LivingEntity target) {
BlockPos targetPos = target.blockPosition();
for (int y = 0; y <= AVIAN_WATER_SURFACE_SEARCH_UP; y++) {
BlockPos checkPos = targetPos.above(y);
if (dino.level().getFluidState(checkPos).is(FluidTags.WATER)) {
continue;
}
int depthBelowSurface = checkPos.getY() - targetPos.getY();
return depthBelowSurface <= AVIAN_MAX_TARGET_DEPTH_BELOW_SURFACE;
}
return false;
}
private void faceAvianMovement(Vec3 direction) {
if (direction.lengthSqr() < 0.0001D) {
return;
}
Vec3 normalized = direction.normalize();
float yaw = (float)(Mth.atan2(normalized.z, normalized.x) * Mth.RAD_TO_DEG) - 90.0F;
float pitch = (float)(-(Mth.atan2(normalized.y, Math.sqrt(normalized.x * normalized.x + normalized.z * normalized.z)) * Mth.RAD_TO_DEG));
dino.setYRot(yaw);
dino.yRotO = yaw;
dino.yBodyRot = yaw;
dino.yBodyRotO = yaw;
dino.yHeadRot = yaw;
dino.yHeadRotO = yaw;
dino.setXRot(Mth.clamp(pitch, -75.0F, 75.0F));
dino.xRotO = dino.getXRot();
}
// --- STATE LOGIC --- // --- STATE LOGIC ---
@@ -1285,6 +1423,17 @@ public class DinoAIController {
return; return;
} }
if (isAvianWaterHunter()
&& !avianDiveInProgress
&& !avianDiveAttackSpent
&& avianDiveRestTimer <= 0
&& isUnderwaterTarget(attackTarget)) {
avianDiveInProgress = true;
avianUnderwaterDiveTimer = 0;
dino.getNavigation().stop();
return;
}
if (distSqr <= reach * 1.1) { if (distSqr <= reach * 1.1) {
transitionTo(State.ATTACKING); transitionTo(State.ATTACKING);
return; return;
@@ -1305,17 +1454,21 @@ public class DinoAIController {
pathRecalcTimer = 10; // Wait before retrying to prevent rapid failure loops pathRecalcTimer = 10; // Wait before retrying to prevent rapid failure loops
failedPathfindingAttempts++; failedPathfindingAttempts++;
// Tolerance allows for temporary pathfinding failures (e.g., target inside hitbox) // Tolerance allows for temporary pathfinding failures (e.g., target inside hitbox)
if (failedPathfindingAttempts > 5) { if (failedPathfindingAttempts > 5) {
attackTarget = null; if (isAvianWaterHunter() && isUnderwaterTarget(attackTarget)) {
transitionTo(State.IDLE); failedPathfindingAttempts = 0;
} } else {
} else { attackTarget = null;
pathRecalcTimer = 10; transitionTo(State.IDLE);
failedPathfindingAttempts = 0; }
} }
} } else {
} pathRecalcTimer = 10;
failedPathfindingAttempts = 0;
}
}
}
private void tickAttacking() { private void tickAttacking() {
if (attackTarget == null) { if (attackTarget == null) {
@@ -1338,6 +1491,17 @@ public class DinoAIController {
return; return;
} }
if (isAvianWaterHunter()
&& !avianDiveInProgress
&& !avianDiveAttackSpent
&& isUnderwaterTarget(attackTarget)) {
avianDiveInProgress = true;
avianUnderwaterDiveTimer = 0;
dino.getNavigation().stop();
transitionTo(State.CHASING);
return;
}
if (distSqr > reach * 2.5) { if (distSqr > reach * 2.5) {
if (isAvianWaterHunter() && avianDiveInProgress) { if (isAvianWaterHunter() && avianDiveInProgress) {
transitionTo(State.CHASING); transitionTo(State.CHASING);
+3 -2
View File
@@ -8,8 +8,9 @@
"${mod_author}" "${mod_author}"
], ],
"contact": { "contact": {
"homepage": "https://fabricmc.net/", "homepage": "${homepage_url}",
"sources": "https://github.com/FabricMC/fabric-example-mod" "sources": "${sources_url}",
"issues": "${issue_url}"
}, },
"license": "${license}", "license": "${license}",
"icon": "jurassicrevived.png", "icon": "jurassicrevived.png",
+4 -1
View File
@@ -10,11 +10,14 @@ fabric.loom.multiProjectOptimisation=true
mod.name=Jurassic Revived mod.name=Jurassic Revived
mod.id=jurassicrevived mod.id=jurassicrevived
mod.group=net.cmr.jurassicrevived mod.group=net.cmr.jurassicrevived
mod.version=0.215.0 mod.version=0.218.0
mod.author=CMR Team, Eli Gibbs mod.author=CMR Team, Eli Gibbs
mod.description=A Minecraft mod that brings dinosaurs back to life using ancient DNA and modern technology\nBreed, study, and build your own prehistoric park with a wide variety of creatures... mod.description=A Minecraft mod that brings dinosaurs back to life using ancient DNA and modern technology\nBreed, study, and build your own prehistoric park with a wide variety of creatures...
mod.license=CC-BY-ND-4.0 mod.license=CC-BY-ND-4.0
mod.credits=Thanks to us mod.credits=Thanks to us
mod.issue_url=https://github.com/classic-mods-revived/Jurassic-Revived/issues
mod.homepage_url=https://classicmodsrevived.com
mod.sources_url=https://github.com/classic-mods-revived/Jurassic-Revived
# Stonecutter # Stonecutter
stonecutter_enabled_platforms=fabricmc, neoforge, minecraftforge stonecutter_enabled_platforms=fabricmc, neoforge, minecraftforge
+41
View File
@@ -69,16 +69,25 @@ legacyForge {
val localResources = project.file("src/main/resources").absolutePath val localResources = project.file("src/main/resources").absolutePath
val generatedResources = project.file("src/generated/resources").absolutePath val generatedResources = project.file("src/generated/resources").absolutePath
fun net.neoforged.moddevgradle.dsl.RunModel.includeMixinConfigs() {
programArguments.addAll(
"-mixin.config=${commonMod.id}.mixins.json",
"-mixin.config=jurassicrevived.minecraftforge.mixins.json"
)
}
runs { runs {
register("client") { register("client") {
client() client()
ideName = "MinecraftForge Client (${project.path})" ideName = "MinecraftForge Client (${project.path})"
logLevel = Level.TRACE logLevel = Level.TRACE
includeMixinConfigs()
} }
register("gameTestServer") { register("gameTestServer") {
type = "gameTestServer" type = "gameTestServer"
ideName = "MinecraftForge GameTestServer (${project.path})" ideName = "MinecraftForge GameTestServer (${project.path})"
logLevel = Level.TRACE logLevel = Level.TRACE
includeMixinConfigs()
} }
register("data") { register("data") {
data() data()
@@ -91,11 +100,13 @@ legacyForge {
"--existing", localResources, "--existing", localResources,
"--existing", commonResources "--existing", commonResources
) )
includeMixinConfigs()
} }
register("server") { register("server") {
server() server()
ideName = "MinecraftForge Server (${project.path})" ideName = "MinecraftForge Server (${project.path})"
logLevel = Level.TRACE logLevel = Level.TRACE
includeMixinConfigs()
} }
} }
@@ -129,6 +140,36 @@ tasks {
rename(atFile.name, "META-INF/accesstransformer.cfg") rename(atFile.name, "META-INF/accesstransformer.cfg")
into("") into("")
} }
inputs.property("mod_id", commonMod.id)
inputs.property("mod_name", commonMod.name)
inputs.property("mod_version", commonMod.version)
inputs.property("mod_author", commonMod.author)
inputs.property("mod_description", commonMod.description)
inputs.property("mod_license", commonMod.license)
inputs.property("mod_credits", commonMod.credits)
inputs.property("mod_issue_url", commonMod.issueUrl)
inputs.property("minecraft_version", commonMod.minecraft_version)
filesMatching("META-INF/mods.toml") {
expand(mapOf(
"mod_id" to commonMod.id,
"mod_name" to commonMod.name,
"version" to commonMod.version,
"mod_author" to commonMod.author,
"description" to commonMod.description,
"license" to commonMod.license,
"credits" to commonMod.credits,
"issue_url" to commonMod.issueUrl,
"minecraft_version" to commonMod.minecraft_version,
"minecraft_version_range" to commonMod.prop("minecraft_version_range"),
"minecraftforge_version" to commonMod.prop("minecraftforge_version"),
"minecraftforge_version_range" to commonMod.prop("minecraftforge_version_range"),
"architectury_version" to commonMod.prop("architectury_version"),
"cloth_config_version_1_20_1" to commonMod.prop("cloth_config_version_1_20_1"),
"geckolib_version" to commonMod.prop("geckolib_version")
))
}
} }
} }
@@ -1,8 +1,15 @@
modLoader = "javafml" #mandatory modLoader = "javafml" #mandatory
loaderVersion = "${minecraftforge_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See https://files.minecraftforge.net/ for a list of versions. loaderVersion = "${minecraftforge_version_range}" #mandatory This is typically bumped every Minecraft version by Forge. See https://files.minecraftforge.net/ for a list of versions.
license = "${license}" # Review your options at https://choosealicense.com/. license = "${license}" # Review your options at https://choosealicense.com/.
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional issueTrackerURL = "${issue_url}" #optional
#clientSideOnly=true #optional #clientSideOnly=true #optional
[[mixins]]
config = "${mod_id}.mixins.json"
[[mixins]]
config = "${mod_id}.minecraftforge.mixins.json"
[[mods]] #mandatory [[mods]] #mandatory
modId = "${mod_id}" #mandatory modId = "${mod_id}" #mandatory
version = "${version}" #mandatory version = "${version}" #mandatory
+1
View File
@@ -147,6 +147,7 @@ tasks {
"mod_license" to commonMod.license, "mod_license" to commonMod.license,
"mod_version" to commonMod.version, "mod_version" to commonMod.version,
"mod_authors" to commonMod.author, "mod_authors" to commonMod.author,
"issue_url" to commonMod.issueUrl,
"mod_description" to commonMod.description "mod_description" to commonMod.description
)) ))
@@ -1,7 +1,7 @@
modLoader = "javafml" #mandatory modLoader = "javafml" #mandatory
loaderVersion = "${neoforge_loader_version_range}" #mandatory loaderVersion = "${neoforge_loader_version_range}" #mandatory
license = "${license}" # Review your options at https://choosealicense.com/. license = "${license}" # Review your options at https://choosealicense.com/.
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional issueTrackerURL= "${issue_url}" #optional
[[mods]] #mandatory [[mods]] #mandatory
modId = "${mod_id}" #mandatory modId = "${mod_id}" #mandatory