Compare commits

...

9 Commits

Author SHA1 Message Date
BodgeMaster a618f200ee Add event hook that places the death chest in the world 2022-12-15 12:56:55 +01:00
BodgeMaster 84beefbbce Add maxDistance 2022-12-15 12:56:29 +01:00
BodgeMaster 2770980d3a Add 'Obituary' item that will be used for retrieving the death location after respawning
I just want to mke it a little thing that prints the coords and possibly dim to chat when right-clicked.
2022-12-15 12:55:09 +01:00
BodgeMaster e52c9b6011 Switch to using a singleton
The reason for this is that the object needs to stay accessible
because adding a block into the world is done by the object
that was used to register it in the game registry, not by the type.
2022-12-15 12:50:16 +01:00
BodgeMaster 643cef87a7 Use Debug.out() instead of System.out.println() 2022-12-15 12:48:07 +01:00
BodgeMaster 27d19f57f0 Config: Fix loader
Java, why can’t I compare sthings with double equals!?
2022-12-15 09:46:52 +01:00
BodgeMaster 425ff9ba34 Initial mod code
Features:
- Config
- Chest block clone
2022-12-15 09:19:11 +01:00
BodgeMaster cff3ed370e mcmod.info: Add information 2022-12-15 08:29:17 +01:00
BodgeMaster 9ad0d98e33 gitignore: Ignore everything except /src
... and README.md and .gitignore ...
2022-12-15 00:40:59 +01:00
9 changed files with 388 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/*
!.gitignore
!README.md
!/src

View File

@ -0,0 +1,64 @@
package lostcave.deathchests;
import lostcave.deathchests.block.BlockDeathChest;
import lostcave.deathchests.item.Obituary;
import lostcave.deathchests.util.Config;
import lostcave.deathchests.util.Debug;
import net.minecraft.init.Blocks;
import net.minecraftforge.common.MinecraftForge;
import java.io.File;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.GameRegistry;
@Mod(modid = DeathChests.MODID, version = DeathChests.VERSION)
public class DeathChests {
public static final String MODID = "deathchests";
public static final String VERSION = "0-SNAPSHOT";
@EventHandler
public void init(FMLConstructionEvent event) {
Debug.out("Received FMLConstructionEvent");
Config.configDir = Loader.instance().getConfigDir();
Debug.out("Config file is: " + Config.configDir.toString() + System.getProperty("file.separator") + Config.configFileName);
Config.loadConfig();
Debug.out("Loaded config.");
if (Config.fixLog4J) {
// TODO: Mitigate the Log4J security vulnerability if it's in any way convenient
Debug.err("Log4J fix is currently not implemented!");
}
}
@EventHandler
public void init(FMLPreInitializationEvent event) {
Debug.out("Received FMLPreInitializationEvent");
}
@EventHandler
public void init(FMLInitializationEvent event) {
Debug.out("Received FMLInitializationEvent");
GameRegistry.registerBlock(BlockDeathChest.getInstance(), "death_chest");
GameRegistry.registerItem(Obituary.getInstance(), "obituary");
Debug.out("Registered block and item.");
MinecraftForge.EVENT_BUS.register(new EventHook());
Debug.out("Registered event hook.");
}
@EventHandler
public void init(FMLPostInitializationEvent event) {
Debug.out("Received FMLPostInitializationEvent");
}
}

View File

@ -0,0 +1,166 @@
package lostcave.deathchests;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import lostcave.deathchests.block.BlockDeathChest;
import lostcave.deathchests.util.Config;
import lostcave.deathchests.util.Debug;
import net.minecraft.block.BlockAir;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
public class EventHook {
@SubscribeEvent
public void PlayerDropsEvent(net.minecraftforge.event.entity.player.PlayerDropsEvent event) {
// This is kinda misleadingly named.
// The event fires only when a player entity produces drops (due to death),
// not when a player drops an item.
if (!event.entity.worldObj.isRemote) {
Debug.out(event.entityPlayer.getDisplayName());
// subtract 0.5 because that's the center of the block
int x = (int) Math.round(event.entityPlayer.posX - 0.5d);
int y = (int) Math.round(event.entityPlayer.posY - 0.5d);
int z = (int) Math.round(event.entityPlayer.posZ - 0.5d);
Debug.out("X: " + Long.toString(x));
Debug.out("Y: " + Long.toString(y));
Debug.out("Z: " + Long.toString(z));
// Dont place the chest outside the world
if (y < 0) y = 0;
if (y > 255) y = 255;
boolean foundSuitableBlock = false;
int[] suitableBlock = new int[3];
World world = event.entity.worldObj;
// search for air block by checking the outside walls of an expanding cube
if (world.getBlock(x, y, z) instanceof BlockAir) {
suitableBlock[0] = x;
suitableBlock[1] = y;
suitableBlock[2] = z;
foundSuitableBlock = true;
} else {
for (int i = 1; i <= Config.maxDistance; i++) {
int j; //x
int k; //y
int l; //z
// Top and bottom sides
if (!foundSuitableBlock) {
k = -1 * i;
for (j = -1 * i; j <= i; j++) {
if (k < 0) break;
for (l = -1 * i; l <= i; l++) {
if (world.getBlock(x + j, y + k, z + l) instanceof BlockAir) {
suitableBlock[0] = x + j;
suitableBlock[1] = y + k;
suitableBlock[2] = z + l;
foundSuitableBlock = true;
break;
}
}
if (foundSuitableBlock) break;
}
}
if (!foundSuitableBlock) {
k = i;
for (j = -1 * i; j <= i; j++) {
if (k > 255) break;
for (l = -1 * i; l <= i; l++) {
if (world.getBlock(x + j, y + k, z + l) instanceof BlockAir) {
suitableBlock[0] = x + j;
suitableBlock[1] = y + k;
suitableBlock[2] = z + l;
foundSuitableBlock = true;
break;
}
}
if (foundSuitableBlock) break;
}
}
// Left and right sides
if (!foundSuitableBlock) {
j = -1 * i;
for (k = (-1 * i) + 1; k <= i - 1; k++) {
if (k < 0 || k > 255) continue;
for (l = -1 * i; l <= i; l++) {
if (world.getBlock(x + j, y + k, z + l) instanceof BlockAir) {
suitableBlock[0] = x + j;
suitableBlock[1] = y + k;
suitableBlock[2] = z + l;
foundSuitableBlock = true;
break;
}
}
if (foundSuitableBlock) break;
}
}
if (!foundSuitableBlock) {
j = i;
for (k = (-1 * i) + 1; k <= i - 1; k++) {
if (k < 0 || k > 255) continue;
for (l = -1 * i; l <= i; l++) {
if (world.getBlock(x + j, y + k, z + l) instanceof BlockAir) {
suitableBlock[0] = x + j;
suitableBlock[1] = y + k;
suitableBlock[2] = z + l;
foundSuitableBlock = true;
break;
}
}
if (foundSuitableBlock) break;
}
}
// Front and back sides
if (!foundSuitableBlock) {
l = -1 * i;
for (j = (-1 * i) + 1; j <= i - 1; j++) {
for (k = (-1 * i) + 1; k <= i - 1; k++) {
if (k < 0 || k > 255) continue;
if (world.getBlock(x + j, y + k, z + l) instanceof BlockAir) {
suitableBlock[0] = x + j;
suitableBlock[1] = y + k;
suitableBlock[2] = z + l;
foundSuitableBlock = true;
break;
}
}
if (foundSuitableBlock) break;
}
}
if (!foundSuitableBlock) {
l = i;
for (j = (-1 * i) + 1; j <= i - 1; j++) {
for (k = (-1 * i) + 1; k <= i - 1; k++) {
if (k < 0 || k > 255) continue;
if (world.getBlock(x + j, y + k, z + l) instanceof BlockAir) {
suitableBlock[0] = x + j;
suitableBlock[1] = y + k;
suitableBlock[2] = z + l;
foundSuitableBlock = true;
break;
}
}
if (foundSuitableBlock) break;
}
}
// big outer loop
if (foundSuitableBlock) break;
}
}
if (foundSuitableBlock) {
Debug.out("Suitable block X: " + Integer.toString(suitableBlock[0]));
Debug.out("Suitable block Y: " + Integer.toString(suitableBlock[1]));
Debug.out("Suitable block Z: " + Integer.toString(suitableBlock[2]));
//TODO: place death chest
world.setBlock(suitableBlock[0], suitableBlock[1], suitableBlock[2], BlockDeathChest.getInstance());
//TODO: Get the player's items and put them in the death chest
event.setCanceled(true);
Debug.out("Canceled PlayerDropEvent");
//TODO: Tell the player about death chest location upon respawn
} else {
Debug.out("No suitable location could be found.");
//TODO: tell player that a death chest couldnt be placed and that the items have been dropped
}
}
}
}

View File

@ -0,0 +1,25 @@
package lostcave.deathchests.block;
import net.minecraft.block.BlockChest;
public class BlockDeathChest extends BlockChest {
private static final BlockDeathChest instance = new BlockDeathChest();
public static BlockDeathChest getInstance() {
return instance;
}
private BlockDeathChest() {
super(0);
this.setBlockName("death_chest");
}
//TODO: Make death chest unobtanium (dont drop the chest when broken)
//TODO: Change capacity somehow?
//TODO: Custom texture? (optional)
//TODO: Make it so items can only be taken out of the chest?
// Custom GUI? Maybe remove GUI altogether and have it drop the items when broken?
}

View File

@ -0,0 +1,17 @@
package lostcave.deathchests.item;
import net.minecraft.item.Item;
public class Obituary extends Item {
private static final Obituary instance = new Obituary();
public static Obituary getInstance() {
return instance;
}
private Obituary() {
this.setUnlocalizedName("obituary");
this.setTextureName("paper");
}
}

View File

@ -0,0 +1,82 @@
package lostcave.deathchests.util;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import cpw.mods.fml.common.FMLCommonHandler;
public class Config {
public static final String configFileName = "deathchests.txt";
public static File configDir = null;
public static boolean debug = true;
public static boolean fixLog4J = true;
public static int maxDistance = 50;
private static final String configHeader = "# The format of this file is strictly `option=value` (no spaces).\n# Lines starting with # and empty lines are ignored.\n";
public static void writeConfig() {
String configOut = configHeader;
configOut += "\n\n# Enable debug output?\n";
configOut += "debug=";
configOut += debug ? "true" : "false";
configOut += "\n\n# Enable Log4Shell counter measures?\n";
configOut += "fixLog4J=";
configOut += fixLog4J ? "true" : "false";
configOut += "\n\n# The maximum search radius for finding a suitable location for placing the death chest\n";
configOut += "maxDistance=";
configOut += Integer.toString(maxDistance);
File configFile = new File(configDir, configFileName);
try {
Files.write(configFile.toPath(), configOut.getBytes());
} catch (IOException e) {
System.err.println("Failed to write to file at " + configFile.toString() + ":");
e.printStackTrace();
System.err.println("Proceeding as if nothing happened...");
}
}
public static void loadConfig() {
List<String> configData = null;
File configFile = new File(configDir, configFileName);
if (configFile.exists()) {
try {
configData = Files.readAllLines(configFile.toPath());
for (int i = 0; i < configData.size(); i++) {
if (configData.get(i).length() != 0 && configData.get(i).charAt(0) != '#') {
int equalsSign = configData.get(i).indexOf('=');
switch (configData.get(i).substring(0, equalsSign)) {
case ("debug"): {
debug = configData.get(i).substring(equalsSign + 1).equals("true") ? true : false;
break;
}
case ("fixLog4J"): {
fixLog4J = configData.get(i).substring(equalsSign + 1).equals("true") ? true : false;
break;
}
case ("maxDistance"): {
maxDistance = Integer.parseInt(configData.get(i).substring(equalsSign + 1));
break;
}
default: {
System.err.println("Failed parsing config entry: " + configData.get(i));
FMLCommonHandler.instance().exitJava(1, false);
}
}
}
}
} catch (IOException e) {
System.err.println("An error was encountered while trying to read the file at " + configFile.toString() + ":");
e.printStackTrace();
System.err.println("Proceeding with default configuration...");
}
} else {
// Skip reading config and set up initial config file with default values
writeConfig();
}
}
}

View File

@ -0,0 +1,11 @@
package lostcave.deathchests.util;
public class Debug {
public static void out(String string) {
if (Config.debug) System.out.println("DEBUG: " + string);
}
public static void err(String string) {
if (Config.debug) System.err.println("DEBUG: " + string);
}
}

View File

@ -0,0 +1,2 @@
tile.death_chest.name=Death Chest
item.obituary.name=Obituary

View File

@ -0,0 +1,16 @@
[
{
"modid": "deathchests",
"name": "Death Chests",
"description": "When a player dies, their items are collected and put into a special chest. Basically just another gravestone mod, but compatible with this very specific private mod pack...",
"version": "0-SNAPSHOT",
"mcversion": "1.7.10",
"url": "",
"updateUrl": "",
"authorList": ["BodgeMaster"],
"credits": "",
"logoFile": "",
"screenshots": [],
"dependencies": []
}
]