Compare commits

..

10 commits

11 changed files with 113 additions and 44 deletions

View file

@ -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:

View file

@ -1,3 +1,9 @@
# ImmersiveXP
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

View file

@ -11,24 +11,13 @@ version = project.mod_version
group = project.maven_group
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 {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
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}"
// 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 {

View file

@ -2,14 +2,13 @@
org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/versions.html
minecraft_version=1.17.1
yarn_mappings=1.17.1+build.39
loader_version=0.11.6
# Mod Properties
mod_version = 1.0.0
maven_group = eu.vodofrede
mod_version = 1.0.3
maven_group = dk.palmoe
archives_base_name = immersivexp
# Dependencies

View 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;
}
}

View file

@ -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.UseBlockCallback;
@ -15,10 +15,18 @@ import net.minecraft.util.registry.Registry;
public class Events {
public static void init() {
PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, entity) -> {
// TODO: Make experience amount configurable
if (world instanceof ServerWorld) {
if (state.getBlock() instanceof CropBlock || state.getBlock() instanceof MelonBlock) {
Util.spawnExp((ServerWorld) world, pos, 1, 1);
if (state.getBlock() instanceof CropBlock) {
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)) {
@ -26,18 +34,25 @@ public class Events {
boolean isGrown = Util.isTreeNaturallyGrown(world, pos);
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) -> {
// TODO: Make experience amount configurable
BlockState state = world.getBlockState(hitResult.getBlockPos());
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;

View file

@ -1,4 +1,4 @@
package eu.vodofrede.immersivexp;
package dk.palmoe.immersivexp;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

View file

@ -1,7 +1,6 @@
package eu.vodofrede.immersivexp;
package dk.palmoe.immersivexp;
import java.util.LinkedList;
import net.minecraft.block.BlockState;
import net.minecraft.block.LeavesBlock;
import net.minecraft.entity.ExperienceOrbEntity;
@ -12,11 +11,14 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class Util {
public static final int MAX_SEARCH_DEPTH = 100;
public static boolean isTreeNaturallyGrown(World world, BlockPos pos) {
LinkedList<BlockPos> queue = new LinkedList<BlockPos>();
queue.push(pos.up());
int search_depth = 0;
while (!queue.isEmpty()) {
while (!queue.isEmpty() && (search_depth <= MAX_SEARCH_DEPTH)) {
BlockPos nextPos = queue.pop();
BlockPos[] dirs = { nextPos.north(), nextPos.east(), nextPos.south(), nextPos.west(), nextPos.up() };
@ -30,13 +32,15 @@ public class Util {
queue.push(dir);
}
}
search_depth++;
}
return false;
}
public static void spawnExp(ServerWorld world, BlockPos pos, int min, int cap) {
Vec3d exp_pos = new Vec3d(pos.getX(), pos.getY(), pos.getZ());
ExperienceOrbEntity.spawn(world, exp_pos, min + world.random.nextInt(cap));
public static void spawnXp(ServerWorld world, BlockPos pos, int min, int cap) {
Vec3d xp_pos = new Vec3d(pos.getX(), pos.getY(), pos.getZ());
ExperienceOrbEntity.spawn(world, xp_pos, min + world.random.nextInt(cap));
}
}

View file

@ -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 {
}

View file

@ -16,9 +16,9 @@
"environment": "*",
"entrypoints": {
"main": ["eu.vodofrede.immersivexp.ImmersiveXP"]
"main": ["dk.palmoe.immersivexp.ImmersiveXP"]
},
"mixins": ["immersivexp.mixins.json"],
"mixins": [],
"depends": {
"fabricloader": ">=0.11.3",
@ -28,5 +28,8 @@
},
"suggests": {
"another-mod": "*"
},
"custom": {
"modmenu": {}
}
}

View file

@ -1,10 +1,10 @@
{
"required": true,
"minVersion": "0.8",
"package": "eu.vodofrede.immersivexp.mixin",
"package": "dk.palmoe.immersivexp.mixin",
"compatibilityLevel": "JAVA_16",
"mixins": ["ImmersiveXPMixin"],
"client": ["ImmersiveXPMixin"],
"mixins": [],
"client": [],
"injectors": {
"defaultRequire": 1
}