Compare commits
9 Commits
c05e020c86
...
a618f200ee
Author | SHA1 | Date |
---|---|---|
BodgeMaster | a618f200ee | |
BodgeMaster | 84beefbbce | |
BodgeMaster | 2770980d3a | |
BodgeMaster | e52c9b6011 | |
BodgeMaster | 643cef87a7 | |
BodgeMaster | 27d19f57f0 | |
BodgeMaster | 425ff9ba34 | |
BodgeMaster | cff3ed370e | |
BodgeMaster | 9ad0d98e33 |
|
@ -0,0 +1,5 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
!.gitignore
|
||||||
|
!README.md
|
||||||
|
!/src
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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));
|
||||||
|
|
||||||
|
// Don’t 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 couldn’t be placed and that the items have been dropped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 (don’t 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?
|
||||||
|
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
tile.death_chest.name=Death Chest
|
||||||
|
item.obituary.name=Obituary
|
|
@ -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": []
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in New Issue