Compare commits
10 commits
70111e68ed
...
c236325a51
Author | SHA1 | Date | |
---|---|---|---|
c236325a51 | |||
9dc92e5e8a | |||
8bdffdb09f | |||
55a8fbef43 | |||
f849e49e42 | |||
a5873a9619 | |||
79a1bbd605 | |||
4c269e6938 | |||
|
a01101aa2f | ||
cf2671380b |
11 changed files with 113 additions and 44 deletions
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) <year> <owner>. All rights reserved.
|
Copyright (c) 2021 vodofrede. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
# ImmersiveXP
|
# ImmersiveXP
|
||||||
|
|
||||||
A mod for Minecraft (Fabric) that allows players to get experience from various sources other than fighting mobs or mining.
|
A mod for Minecraft (Fabric) that allows players to get experience from various sources other than fighting mobs or mining.
|
||||||
|
|
||||||
|
Currently, this mods adds a small amount of experience for doing the following actions:
|
||||||
|
- Chopping a log from a naturally-grown tree
|
||||||
|
- Harvesting crops
|
||||||
|
- Harvesting melons
|
||||||
|
- Harvesting berries from sweet berry bushes
|
||||||
|
|
11
build.gradle
11
build.gradle
|
@ -11,24 +11,13 @@ version = project.mod_version
|
||||||
group = project.maven_group
|
group = project.maven_group
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// Add repositories to retrieve artifacts from in here.
|
|
||||||
// You should only use this when depending on other mods because
|
|
||||||
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
|
||||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
|
||||||
// for more information about repositories.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// To change the versions see the gradle.properties file
|
|
||||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
|
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
|
||||||
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
|
||||||
// You may need to force-disable transitiveness on them.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
|
|
@ -2,14 +2,13 @@
|
||||||
org.gradle.jvmargs=-Xmx1G
|
org.gradle.jvmargs=-Xmx1G
|
||||||
|
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://fabricmc.net/versions.html
|
|
||||||
minecraft_version=1.17.1
|
minecraft_version=1.17.1
|
||||||
yarn_mappings=1.17.1+build.39
|
yarn_mappings=1.17.1+build.39
|
||||||
loader_version=0.11.6
|
loader_version=0.11.6
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 1.0.0
|
mod_version = 1.0.3
|
||||||
maven_group = eu.vodofrede
|
maven_group = dk.palmoe
|
||||||
archives_base_name = immersivexp
|
archives_base_name = immersivexp
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
63
src/main/java/dk/palmoe/immersivexp/Config.java
Normal file
63
src/main/java/dk/palmoe/immersivexp/Config.java
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package dk.palmoe.immersivexp;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.Reader;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;;
|
||||||
|
|
||||||
|
public class Config {
|
||||||
|
public int logBaseXP = 0;
|
||||||
|
public int logRandXP = 2;
|
||||||
|
public int cropBaseXP = 0;
|
||||||
|
public int cropRandXP = 2;
|
||||||
|
public int berriesBaseXP = 0;
|
||||||
|
public int berriesRandXP = 2;
|
||||||
|
|
||||||
|
public static final File FILE = new File("config/immersivexp.json");
|
||||||
|
public static Config INSTANCE = null;
|
||||||
|
|
||||||
|
public static Config getInstance() {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
INSTANCE = new Config().read();
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Config read() {
|
||||||
|
if (!FILE.exists())
|
||||||
|
return new Config().write();
|
||||||
|
|
||||||
|
Reader reader = null;
|
||||||
|
try {
|
||||||
|
return new Gson().fromJson(reader = new FileReader(FILE), Config.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Config write() {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
JsonWriter writer = null;
|
||||||
|
try {
|
||||||
|
writer = gson.newJsonWriter(new FileWriter(FILE));
|
||||||
|
writer.setIndent(" ");
|
||||||
|
|
||||||
|
gson.toJson(gson.toJsonTree(this, Config.class), writer);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ImmersiveXP.LOGGER.error("Couldn't save config");
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(writer);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package eu.vodofrede.immersivexp;
|
package dk.palmoe.immersivexp;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
|
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
|
||||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||||
|
@ -15,10 +15,18 @@ import net.minecraft.util.registry.Registry;
|
||||||
public class Events {
|
public class Events {
|
||||||
public static void init() {
|
public static void init() {
|
||||||
PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {
|
PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {
|
||||||
// TODO: Make experience amount configurable
|
|
||||||
if (world instanceof ServerWorld) {
|
if (world instanceof ServerWorld) {
|
||||||
if (state.getBlock() instanceof CropBlock || state.getBlock() instanceof MelonBlock) {
|
if (state.getBlock() instanceof CropBlock) {
|
||||||
Util.spawnExp((ServerWorld) world, pos, 1, 1);
|
int age = state.get(CropBlock.AGE);
|
||||||
|
if (age == 7) {
|
||||||
|
Config config = Config.getInstance();
|
||||||
|
Util.spawnXp((ServerWorld) world, pos, config.cropBaseXP, config.cropRandXP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.getBlock() instanceof MelonBlock) {
|
||||||
|
Config config = Config.getInstance();
|
||||||
|
Util.spawnXp((ServerWorld) world, pos, config.cropBaseXP, config.cropRandXP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.isIn(BlockTags.LOGS)) {
|
if (state.isIn(BlockTags.LOGS)) {
|
||||||
|
@ -26,18 +34,25 @@ public class Events {
|
||||||
boolean isGrown = Util.isTreeNaturallyGrown(world, pos);
|
boolean isGrown = Util.isTreeNaturallyGrown(world, pos);
|
||||||
|
|
||||||
if (holdingAxe && isGrown) {
|
if (holdingAxe && isGrown) {
|
||||||
Util.spawnExp((ServerWorld) world, pos, 1, 4);
|
Config config = Config.getInstance();
|
||||||
|
Util.spawnXp((ServerWorld) world, pos, config.logBaseXP, config.logRandXP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
UseBlockCallback.EVENT.register(((player, world, hand, hitResult) -> {
|
UseBlockCallback.EVENT.register(((player, world, hand, hitResult) -> {
|
||||||
// TODO: Make experience amount configurable
|
|
||||||
BlockState state = world.getBlockState(hitResult.getBlockPos());
|
BlockState state = world.getBlockState(hitResult.getBlockPos());
|
||||||
|
|
||||||
if (state.getBlock() instanceof SweetBerryBushBlock && world instanceof ServerWorld) {
|
if (state.getBlock() instanceof SweetBerryBushBlock && world instanceof ServerWorld) {
|
||||||
Util.spawnExp((ServerWorld) world, hitResult.getBlockPos(), 1, 1);
|
int age = state.get(SweetBerryBushBlock.AGE);
|
||||||
|
if (age == 3) {
|
||||||
|
ImmersiveXP.LOGGER.info("Giving xp for sweet berry bush");
|
||||||
|
Config config = Config.getInstance();
|
||||||
|
Util.spawnXp((ServerWorld) world, hitResult.getBlockPos(), config.berriesBaseXP,
|
||||||
|
config.berriesRandXP);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ActionResult.PASS;
|
return ActionResult.PASS;
|
|
@ -1,4 +1,4 @@
|
||||||
package eu.vodofrede.immersivexp;
|
package dk.palmoe.immersivexp;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
|
@ -1,7 +1,6 @@
|
||||||
package eu.vodofrede.immersivexp;
|
package dk.palmoe.immersivexp;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.LeavesBlock;
|
import net.minecraft.block.LeavesBlock;
|
||||||
import net.minecraft.entity.ExperienceOrbEntity;
|
import net.minecraft.entity.ExperienceOrbEntity;
|
||||||
|
@ -12,11 +11,14 @@ import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class Util {
|
public class Util {
|
||||||
|
public static final int MAX_SEARCH_DEPTH = 100;
|
||||||
|
|
||||||
public static boolean isTreeNaturallyGrown(World world, BlockPos pos) {
|
public static boolean isTreeNaturallyGrown(World world, BlockPos pos) {
|
||||||
LinkedList<BlockPos> queue = new LinkedList<BlockPos>();
|
LinkedList<BlockPos> queue = new LinkedList<BlockPos>();
|
||||||
queue.push(pos.up());
|
queue.push(pos.up());
|
||||||
|
int search_depth = 0;
|
||||||
|
|
||||||
while (!queue.isEmpty()) {
|
while (!queue.isEmpty() && (search_depth <= MAX_SEARCH_DEPTH)) {
|
||||||
BlockPos nextPos = queue.pop();
|
BlockPos nextPos = queue.pop();
|
||||||
|
|
||||||
BlockPos[] dirs = { nextPos.north(), nextPos.east(), nextPos.south(), nextPos.west(), nextPos.up() };
|
BlockPos[] dirs = { nextPos.north(), nextPos.east(), nextPos.south(), nextPos.west(), nextPos.up() };
|
||||||
|
@ -30,13 +32,15 @@ public class Util {
|
||||||
queue.push(dir);
|
queue.push(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
search_depth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void spawnExp(ServerWorld world, BlockPos pos, int min, int cap) {
|
public static void spawnXp(ServerWorld world, BlockPos pos, int min, int cap) {
|
||||||
Vec3d exp_pos = new Vec3d(pos.getX(), pos.getY(), pos.getZ());
|
Vec3d xp_pos = new Vec3d(pos.getX(), pos.getY(), pos.getZ());
|
||||||
ExperienceOrbEntity.spawn(world, exp_pos, min + world.random.nextInt(cap));
|
ExperienceOrbEntity.spawn(world, xp_pos, min + world.random.nextInt(cap));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
package eu.vodofrede.immersivexp.mixin;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.screen.TitleScreen;
|
|
||||||
|
|
||||||
@Mixin(TitleScreen.class)
|
|
||||||
public class ImmersiveXPMixin {
|
|
||||||
|
|
||||||
}
|
|
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": ["eu.vodofrede.immersivexp.ImmersiveXP"]
|
"main": ["dk.palmoe.immersivexp.ImmersiveXP"]
|
||||||
},
|
},
|
||||||
"mixins": ["immersivexp.mixins.json"],
|
"mixins": [],
|
||||||
|
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.11.3",
|
"fabricloader": ">=0.11.3",
|
||||||
|
@ -28,5 +28,8 @@
|
||||||
},
|
},
|
||||||
"suggests": {
|
"suggests": {
|
||||||
"another-mod": "*"
|
"another-mod": "*"
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
"modmenu": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "eu.vodofrede.immersivexp.mixin",
|
"package": "dk.palmoe.immersivexp.mixin",
|
||||||
"compatibilityLevel": "JAVA_16",
|
"compatibilityLevel": "JAVA_16",
|
||||||
"mixins": ["ImmersiveXPMixin"],
|
"mixins": [],
|
||||||
"client": ["ImmersiveXPMixin"],
|
"client": [],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue