major rework, more documentation, configuration, and lots of fixes
This commit is contained in:
parent
e5a415ddd5
commit
c0ebe09a02
21
blockPropertyDocumentation.txt
Normal file
21
blockPropertyDocumentation.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
"material":
|
||||
|
||||
//controls what happens when a piston pushes this block
|
||||
|
||||
"blocksMovement" ~ boolean
|
||||
//this sets whether water can flow away this block if "collidable" is false, otherwise subtily changes how fluids look around it
|
||||
|
||||
"collidable" ~ boolean
|
||||
//this sets whether the block has collision. if false you (and monsters) can walk throught the block.
|
||||
|
||||
"burnable" ~ boolean
|
||||
//does lava ignite the block
|
||||
|
||||
"burnChance" ~ int
|
||||
//how fast the block burns down (leaves 60, wood 5, flowers 100) if 0, block will never burn down.
|
||||
|
||||
"spreadChance" ~ int
|
||||
//how easily this block catches fire ( wood 5, leaves 30, flowers 60) if null, block can only be ignited by lava if burnable.
|
||||
|
||||
"breakByHand" ~ boolean
|
||||
//this sets whether the block drops when brocken without tool.
|
10
build.gradle
10
build.gradle
|
@ -18,8 +18,14 @@ dependencies {
|
|||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
|
||||
|
||||
modCompile "me.sargunvohra.mcmods:autoconfig1u:2.0"
|
||||
include "me.sargunvohra.mcmods:autoconfig1u:2.0"
|
||||
modApi "me.shedaniel.cloth:config-2:2.13.1"
|
||||
include "me.shedaniel.cloth:config-2:2.13.1"
|
||||
modImplementation "io.github.prospector:modmenu:1.10.0+build.28"
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
@ -76,4 +82,4 @@ publishing {
|
|||
// uncomment to publish to the local maven
|
||||
// mavenLocal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ yarn_mappings = 1.15.2+build.15
|
|||
loader_version = 0.8.2+build.194
|
||||
|
||||
#Mod properties
|
||||
mod_version = 0.7.0
|
||||
mod_version = 0.8.0
|
||||
maven_group = quimufu.simple_creator
|
||||
archives_base_name = simple_creator
|
||||
|
||||
|
|
462
materialsDocumentation.txt
Normal file
462
materialsDocumentation.txt
Normal file
|
@ -0,0 +1,462 @@
|
|||
Some materials have certain effects, apart from their properties.
|
||||
They have effect on how noteblocks sound when the block is below:
|
||||
material -> soundtype
|
||||
---------------------
|
||||
stone -> basedrum
|
||||
sand -> snare
|
||||
glass -> hat
|
||||
wood -> bass
|
||||
others -> harp
|
||||
The "water" material should cause crashes (or at least errors in connection with the frostwalker enchantment. (untested)
|
||||
Some materials prevent the block being broken by water, even if the other conditions are met:
|
||||
portal
|
||||
structure_void
|
||||
underwater_plant
|
||||
seagrass
|
||||
The "ice" material negates the stronger downward flow next to solid blocks. i.e. for waterfalls: block ~ air
|
||||
Some materials are broken faster by sword. This can also be achieved via tag "leaves".
|
||||
plant
|
||||
replaceable_plant
|
||||
unused_plant
|
||||
pumpkin
|
||||
Some materials let the block when mined with an axe be broken faster:
|
||||
wood
|
||||
plant
|
||||
replaceable_plant
|
||||
bamboo
|
||||
Some materials let the block when mined with an Pickaxe be broken faster and drop loot:
|
||||
metal
|
||||
anvil
|
||||
stone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
All materials with their settings:
|
||||
"air"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: true
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"structure_void"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: true
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"portal"
|
||||
pistonBehavior: "block"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"carpet"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: false
|
||||
burnable: true
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"plant"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"underwater_plant"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"replaceable_plant"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: true
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: true
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"seagrass"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: true
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"water"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: true
|
||||
replaceable: true
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"bubble_column"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: true
|
||||
replaceable: true
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"lava"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: true
|
||||
replaceable: true
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"snow"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: false
|
||||
liquid: false
|
||||
replaceable: true
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"fire"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: true
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"part"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: false
|
||||
blocksLight: false
|
||||
|
||||
"cobweb"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: false
|
||||
breakByHand: false
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: false
|
||||
|
||||
"redstone_lamp"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"clay"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"earth"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"organic"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"packed_ice"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"sand"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"sponge"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"shulker_box"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"wood"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: true
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"bamboo_sapling"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: false
|
||||
burnable: true
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"bamboo"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: true
|
||||
burnable: true
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"wool"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: true
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"tnt"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: true
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: false
|
||||
|
||||
"leaves"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: true
|
||||
burnable: true
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: false
|
||||
|
||||
"glass"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: false
|
||||
|
||||
"ice"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: false
|
||||
|
||||
"cactus"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: false
|
||||
|
||||
"stone"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: false
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"metal"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: false
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"snow_block"
|
||||
pistonBehavior: "normal"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: false
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"anvil"
|
||||
pistonBehavior: "block"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: false
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"barrier"
|
||||
pistonBehavior: "block"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: false
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"piston"
|
||||
pistonBehavior: "block"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"unused_plant"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"pumpkin"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"egg"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"cake"
|
||||
pistonBehavior: "destroy"
|
||||
blocksMovement: true
|
||||
burnable: false
|
||||
breakByHand: true
|
||||
liquid: false
|
||||
replaceable: false
|
||||
solid: true
|
||||
blocksLight: true
|
||||
|
||||
"pistonBehavior":
|
||||
normal,
|
||||
destroy,
|
||||
block,
|
||||
ignore,
|
||||
push_only
|
|
@ -4,9 +4,7 @@ import com.google.common.collect.Maps;
|
|||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.block.MaterialColor;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.piston.PistonBehavior;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -49,86 +47,223 @@ public class BlockResourceLoader extends GenericManualResourceLoader<Pair<Block,
|
|||
@Override
|
||||
protected Pair<Block, Item> deserialize(Pair<Identifier, JsonObject> e) {
|
||||
JsonObject jo = e.getRight();
|
||||
|
||||
PistonBehavior pistonBehavior;
|
||||
boolean blocksMovement;
|
||||
boolean burnable;
|
||||
boolean breakByHand;
|
||||
boolean liquid;
|
||||
boolean replaceable;
|
||||
boolean solid;
|
||||
MaterialColor color;
|
||||
boolean blocksLight;
|
||||
Material material;
|
||||
String materialStr = JsonHelper.getString(jo, "material", "stone");
|
||||
material = getMaterial(materialStr);
|
||||
if(JsonHelper.hasString(jo, "material")){
|
||||
String materialString = JsonHelper.getString(jo, "material");
|
||||
material = getMaterial(materialString);
|
||||
} else if (JsonHelper.getObject(jo,"material", null)!=null){
|
||||
// get material information
|
||||
JsonObject jmo = JsonHelper.getObject(jo, "material");
|
||||
MaterialSettingsPojo mspj = GSON.fromJson(jmo, MaterialSettingsPojo.class);
|
||||
//build material
|
||||
material = getSettings(mspj);
|
||||
} else {
|
||||
material = Material.EARTH;
|
||||
}
|
||||
|
||||
// get block information
|
||||
BlockSettingsPojo bspj = GSON.fromJson(jo, BlockSettingsPojo.class);
|
||||
|
||||
// move block information in Block.Settings (!!hacky!!)
|
||||
Block.Settings bs = getSettings(material, bspj);
|
||||
|
||||
// parse item group
|
||||
String group = JsonHelper.getString(jo, "itemGroup", "misc");
|
||||
ItemGroup g = ItemResourceLoader.findGroup(group);
|
||||
//create block and corresponding item
|
||||
Block resB = new Block(bs);
|
||||
Item resI = new BlockItem(resB, new Item.Settings().group(g));
|
||||
|
||||
FireBlock fireBlock = (FireBlock) Blocks.FIRE;
|
||||
|
||||
int burnChance = JsonHelper.getInt(jo,"burnChance", -1);
|
||||
int spreadChance = JsonHelper.getInt(jo,"spreadChance", -1);
|
||||
if(burnChance!=-1 && spreadChance!=-1){
|
||||
//spreadChance and burnChance are the wrong way around in yarn
|
||||
fireBlock.registerFlammableBlock(resB, spreadChance, burnChance);
|
||||
}
|
||||
|
||||
|
||||
// construct block information
|
||||
BlockSoundGroup soundGroup;
|
||||
Identifier dropTableId;
|
||||
boolean collidable;
|
||||
int luminance;
|
||||
float resistance;
|
||||
float hardness;
|
||||
float slipperiness;
|
||||
float slowDownMultiplier;
|
||||
float jumpVelocityMultiplier;
|
||||
boolean opaque;
|
||||
return new Pair<>(resB, resI);
|
||||
}
|
||||
|
||||
String soundGroupStr = JsonHelper.getString(jo, "soundGroup", "stone");
|
||||
soundGroup = getSoundGroup(soundGroupStr);
|
||||
String dropTableIdStr = JsonHelper.getString(jo, "dropTableId", null);
|
||||
dropTableId = getDropTableId(dropTableIdStr);
|
||||
collidable = JsonHelper.getBoolean(jo, "collidable", true);
|
||||
luminance = JsonHelper.getInt(jo, "lightLevel", 0);
|
||||
resistance = JsonHelper.getFloat(jo, "explosionResistance", 6.0F);
|
||||
hardness = JsonHelper.getFloat(jo, "hardness", 1.5F);
|
||||
slipperiness = JsonHelper.getFloat(jo, "slipperiness", 0.6F);
|
||||
slowDownMultiplier = JsonHelper.getFloat(jo, "slowDownMultiplier", 1.0F);
|
||||
jumpVelocityMultiplier = JsonHelper.getFloat(jo, "jumpVelocityMultiplier", 1.0F);
|
||||
opaque = JsonHelper.getBoolean(jo, "opaque", true);
|
||||
private Material getSettings(MaterialSettingsPojo mspj) {
|
||||
return new Material(
|
||||
MaterialColor.PINK,
|
||||
mspj.liquid,
|
||||
mspj.solid,
|
||||
mspj.blocksMovement,
|
||||
mspj.blocksLight,
|
||||
mspj.breakByHand,
|
||||
mspj.burnable,
|
||||
mspj.replaceable,
|
||||
getPistonBehavior(mspj.pistonBehavior));
|
||||
|
||||
// save block information in Block.Settings (!!hacky!!)
|
||||
}
|
||||
|
||||
private PistonBehavior getPistonBehavior(String pistonBehavior) {
|
||||
switch (pistonBehavior.toUpperCase()) {
|
||||
case "NORMAL":
|
||||
return PistonBehavior.NORMAL;
|
||||
case "DESTROY":
|
||||
return PistonBehavior.DESTROY;
|
||||
case "BLOCK":
|
||||
return PistonBehavior.BLOCK;
|
||||
case "IGNORE":
|
||||
return PistonBehavior.IGNORE;
|
||||
case "PUSH_ONLY":
|
||||
return PistonBehavior.PUSH_ONLY;
|
||||
default:
|
||||
log(Level.WARN, "Piston Behavior " + pistonBehavior + " not found, using normal");
|
||||
return PistonBehavior.NORMAL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private MaterialColor getMaterialColor(String color) {
|
||||
switch (color.toUpperCase()) {
|
||||
case "AIR":
|
||||
return MaterialColor.AIR;
|
||||
case "GRASS":
|
||||
return MaterialColor.GRASS;
|
||||
case "SAND":
|
||||
return MaterialColor.SAND;
|
||||
case "WEB":
|
||||
return MaterialColor.WEB;
|
||||
case "LAVA":
|
||||
return MaterialColor.LAVA;
|
||||
case "ICE":
|
||||
return MaterialColor.ICE;
|
||||
case "IRON":
|
||||
return MaterialColor.IRON;
|
||||
case "FOLIAGE":
|
||||
return MaterialColor.FOLIAGE;
|
||||
case "WHITE":
|
||||
return MaterialColor.WHITE;
|
||||
case "CLAY":
|
||||
return MaterialColor.CLAY;
|
||||
case "DIRT":
|
||||
return MaterialColor.DIRT;
|
||||
case "STONE":
|
||||
return MaterialColor.STONE;
|
||||
case "WATER":
|
||||
return MaterialColor.WATER;
|
||||
case "WOOD":
|
||||
return MaterialColor.WOOD;
|
||||
case "QUARTZ":
|
||||
return MaterialColor.QUARTZ;
|
||||
case "ORANGE":
|
||||
return MaterialColor.ORANGE;
|
||||
case "MAGENTA":
|
||||
return MaterialColor.MAGENTA;
|
||||
case "LIGHT_BLUE":
|
||||
return MaterialColor.LIGHT_BLUE;
|
||||
case "YELLOW":
|
||||
return MaterialColor.YELLOW;
|
||||
case "LIME":
|
||||
return MaterialColor.LIME;
|
||||
case "PINK":
|
||||
return MaterialColor.PINK;
|
||||
case "GRAY":
|
||||
return MaterialColor.GRAY;
|
||||
case "LIGHT_GRAY":
|
||||
return MaterialColor.LIGHT_GRAY;
|
||||
case "CYAN":
|
||||
return MaterialColor.CYAN;
|
||||
case "PURPLE":
|
||||
return MaterialColor.PURPLE;
|
||||
case "BLUE":
|
||||
return MaterialColor.BLUE;
|
||||
case "BROWN":
|
||||
return MaterialColor.BROWN;
|
||||
case "GREEN":
|
||||
return MaterialColor.GREEN;
|
||||
case "RED":
|
||||
return MaterialColor.RED;
|
||||
case "BLACK":
|
||||
return MaterialColor.BLACK;
|
||||
case "GOLD":
|
||||
return MaterialColor.GOLD;
|
||||
case "DIAMOND":
|
||||
return MaterialColor.DIAMOND;
|
||||
case "LAPIS":
|
||||
return MaterialColor.LAPIS;
|
||||
case "EMERALD":
|
||||
return MaterialColor.EMERALD;
|
||||
case "SPRUCE":
|
||||
return MaterialColor.SPRUCE;
|
||||
case "NETHER":
|
||||
return MaterialColor.NETHER;
|
||||
case "WHITE_TERRACOTTA":
|
||||
return MaterialColor.WHITE_TERRACOTTA;
|
||||
case "ORANGE_TERRACOTTA":
|
||||
return MaterialColor.ORANGE_TERRACOTTA;
|
||||
case "MAGENTA_TERRACOTTA":
|
||||
return MaterialColor.MAGENTA_TERRACOTTA;
|
||||
case "LIGHT_BLUE_TERRACOTTA":
|
||||
return MaterialColor.LIGHT_BLUE_TERRACOTTA;
|
||||
case "YELLOW_TERRACOTTA":
|
||||
return MaterialColor.YELLOW_TERRACOTTA;
|
||||
case "LIME_TERRACOTTA":
|
||||
return MaterialColor.LIME_TERRACOTTA;
|
||||
case "PINK_TERRACOTTA":
|
||||
return MaterialColor.PINK_TERRACOTTA;
|
||||
case "GRAY_TERRACOTTA":
|
||||
return MaterialColor.GRAY_TERRACOTTA;
|
||||
case "LIGHT_GRAY_TERRACOTTA":
|
||||
return MaterialColor.LIGHT_GRAY_TERRACOTTA;
|
||||
case "CYAN_TERRACOTTA":
|
||||
return MaterialColor.CYAN_TERRACOTTA;
|
||||
case "PURPLE_TERRACOTTA":
|
||||
return MaterialColor.PURPLE_TERRACOTTA;
|
||||
case "BLUE_TERRACOTTA":
|
||||
return MaterialColor.BLUE_TERRACOTTA;
|
||||
case "BROWN_TERRACOTTA":
|
||||
return MaterialColor.BROWN_TERRACOTTA;
|
||||
case "GREEN_TERRACOTTA":
|
||||
return MaterialColor.GREEN_TERRACOTTA;
|
||||
case "RED_TERRACOTTA":
|
||||
return MaterialColor.RED_TERRACOTTA;
|
||||
case "BLACK_TERRACOTTA":
|
||||
return MaterialColor.BLACK_TERRACOTTA;
|
||||
default:
|
||||
log(Level.WARN, "MapColor " + color + " not found, using pink");
|
||||
return MaterialColor.PINK;
|
||||
}
|
||||
}
|
||||
|
||||
private Block.Settings getSettings(Material material, BlockSettingsPojo bspj) {
|
||||
Block.Settings bs = Block.Settings.of(material, material.getColor());
|
||||
Field[] fields = Block.Settings.class.getDeclaredFields();
|
||||
try {
|
||||
fields[0].setAccessible(true);
|
||||
fields[0].set(bs, material);
|
||||
fields[1].setAccessible(true);
|
||||
fields[1].set(bs, material.getColor());
|
||||
fields[1].set(bs, getMaterialColor(bspj.mapColor));
|
||||
fields[2].setAccessible(true);
|
||||
fields[2].setBoolean(bs, collidable);
|
||||
fields[2].setBoolean(bs, bspj.collidable);
|
||||
fields[3].setAccessible(true);
|
||||
fields[3].set(bs, soundGroup);
|
||||
fields[3].set(bs, getSoundGroup(bspj.soundGroup));
|
||||
fields[4].setAccessible(true);
|
||||
fields[4].setInt(bs, luminance);
|
||||
fields[4].setInt(bs, bspj.lightLevel);
|
||||
fields[5].setAccessible(true);
|
||||
fields[5].setFloat(bs, resistance);
|
||||
fields[5].setFloat(bs, bspj.explosionResistance);
|
||||
fields[6].setAccessible(true);
|
||||
fields[6].setFloat(bs, hardness);
|
||||
fields[6].setFloat(bs, bspj.hardness);
|
||||
fields[8].setAccessible(true);
|
||||
fields[8].setFloat(bs, slipperiness);
|
||||
fields[8].setFloat(bs, bspj.slipperiness);
|
||||
fields[9].setAccessible(true);
|
||||
fields[9].setFloat(bs, slowDownMultiplier);
|
||||
fields[9].setFloat(bs, bspj.slowDownMultiplier);
|
||||
fields[10].setAccessible(true);
|
||||
fields[10].setFloat(bs, jumpVelocityMultiplier);
|
||||
fields[10].setFloat(bs, bspj.jumpVelocityMultiplier);
|
||||
fields[11].setAccessible(true);
|
||||
fields[11].set(bs, dropTableId);
|
||||
fields[11].set(bs, getDropTableId(bspj.dropTableId));
|
||||
fields[12].setAccessible(true);
|
||||
fields[12].setBoolean(bs, opaque);
|
||||
fields[12].setBoolean(bs, bspj.opaque);
|
||||
} catch (IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
// parse item group
|
||||
String group = JsonHelper.getString(jo, "group", "misc");
|
||||
ItemGroup g = ItemResourceLoader.findGroup(group);
|
||||
//create block and corresponding item
|
||||
Block resB = new Block(bs);
|
||||
Item resI = new BlockItem(resB, new Item.Settings().group(g));
|
||||
|
||||
return new Pair<>(resB, resI);
|
||||
return bs;
|
||||
}
|
||||
|
||||
private Identifier getDropTableId(String s) {
|
||||
|
|
15
src/main/java/quimufu/simple_creator/BlockSettingsPojo.java
Normal file
15
src/main/java/quimufu/simple_creator/BlockSettingsPojo.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package quimufu.simple_creator;
|
||||
|
||||
public class BlockSettingsPojo {
|
||||
public String soundGroup = "stone";
|
||||
public String dropTableId = null;
|
||||
public boolean collidable = true;
|
||||
public int lightLevel = 0;
|
||||
public float explosionResistance = 6.0F;
|
||||
public float hardness = 1.5F;
|
||||
public float slipperiness = 0.6F;
|
||||
public float slowDownMultiplier = 1.0F;
|
||||
public float jumpVelocityMultiplier = 1.0F;
|
||||
public boolean opaque = true;
|
||||
String mapColor = "stone";
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
/*package quimufu.simple_creator;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.block.MaterialColor;
|
||||
import net.minecraft.sound.BlockSoundGroup;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class FlexibleBlockSettings extends Block {
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public BlockSoundGroup getSoundGroup() {
|
||||
return soundGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getDropTableId() {
|
||||
return dropTableId;
|
||||
}
|
||||
|
||||
public void setDropTableId(Identifier dropTableId) {
|
||||
this.dropTableId = dropTableId;
|
||||
}
|
||||
|
||||
public boolean isCollidable() {
|
||||
return collidable;
|
||||
}
|
||||
|
||||
public void setCollidable(boolean collidable) {
|
||||
this.collidable = collidable;
|
||||
}
|
||||
|
||||
public int getLuminance() {
|
||||
return luminance;
|
||||
}
|
||||
|
||||
public void setLuminance(int luminance) {
|
||||
this.luminance = luminance;
|
||||
}
|
||||
|
||||
public float getResistance() {
|
||||
return resistance;
|
||||
}
|
||||
|
||||
public void setResistance(float resistance) {
|
||||
this.resistance = resistance;
|
||||
}
|
||||
|
||||
public float getHardness() {
|
||||
return hardness;
|
||||
}
|
||||
|
||||
public void setHardness(float hardness) {
|
||||
this.hardness = hardness;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSlipperiness() {
|
||||
return slipperiness;
|
||||
}
|
||||
|
||||
public void setSlipperiness(float slipperiness) {
|
||||
this.slipperiness = slipperiness;
|
||||
}
|
||||
|
||||
public float getSlowDownMultiplier() {
|
||||
return slowDownMultiplier;
|
||||
}
|
||||
|
||||
public void setSlowDownMultiplier(float slowDownMultiplier) {
|
||||
this.slowDownMultiplier = slowDownMultiplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getJumpVelocityMultiplier() {
|
||||
return jumpVelocityMultiplier;
|
||||
}
|
||||
|
||||
public void setJumpVelocityMultiplier(float jumpVelocityMultiplier) {
|
||||
this.jumpVelocityMultiplier = jumpVelocityMultiplier;
|
||||
}
|
||||
|
||||
public boolean isOpaque() {
|
||||
return opaque;
|
||||
}
|
||||
|
||||
public void setOpaque(boolean opaque) {
|
||||
this.opaque = opaque;
|
||||
}
|
||||
|
||||
public MaterialColor getMaterialColor() {
|
||||
return materialColor;
|
||||
}
|
||||
|
||||
public void setMaterialColor(MaterialColor materialColor) {
|
||||
this.materialColor = materialColor;
|
||||
}
|
||||
|
||||
public boolean isRandomTicks() {
|
||||
return randomTicks;
|
||||
}
|
||||
|
||||
public void setRandomTicks(boolean randomTicks) {
|
||||
this.randomTicks = randomTicks;
|
||||
}
|
||||
|
||||
public boolean isDynamicBounds() {
|
||||
return dynamicBounds;
|
||||
}
|
||||
|
||||
public void setDynamicBounds(boolean dynamicBounds) {
|
||||
this.dynamicBounds = dynamicBounds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public FlexibleBlockSettings() {
|
||||
super(Settings.of(Material.AIR));
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -1,33 +0,0 @@
|
|||
package quimufu.simple_creator;
|
||||
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.block.MaterialColor;
|
||||
import net.minecraft.block.piston.PistonBehavior;
|
||||
|
||||
public class FlexibleMaterialBuilder extends Material.Builder {
|
||||
|
||||
public FlexibleMaterialBuilder(MaterialColor color) {
|
||||
super(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material.Builder blocksPistons() {
|
||||
return super.blocksPistons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material.Builder burnable() {
|
||||
return super.burnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material.Builder destroyedByPiston() {
|
||||
return super.destroyedByPiston();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material.Builder requiresTool() {
|
||||
return super.requiresTool();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
package quimufu.simple_creator;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
|
||||
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackCreator;
|
||||
import net.minecraft.resource.*;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
@ -12,15 +15,14 @@ import org.apache.logging.log4j.Level;
|
|||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static quimufu.simple_creator.SimpleCreatorMod.log;
|
||||
|
||||
public abstract class GenericManualResourceLoader<T> {
|
||||
private Gson GSON;
|
||||
private String dataType;
|
||||
private SimpleCreatorConfig config;
|
||||
|
||||
GenericManualResourceLoader(Gson gson, String dt) {
|
||||
GSON = gson;
|
||||
|
@ -31,10 +33,10 @@ public abstract class GenericManualResourceLoader<T> {
|
|||
log(Level.INFO, "Start loading " + dataType);
|
||||
for (Pair<Identifier, JsonObject> e : itemJsonList) {
|
||||
Identifier id = e.getLeft();
|
||||
log(Level.INFO, "Loading " + dataType.substring(0,dataType.length()-1) + " " + id);
|
||||
log(Level.INFO, "Loading " + dataType.substring(0, dataType.length() - 1) + " " + id);
|
||||
T thing = deserialize(e);
|
||||
save(id, thing);
|
||||
log(Level.INFO, "Registering " + dataType.substring(0,dataType.length()-1) + " " + id);
|
||||
log(Level.INFO, "Registering " + dataType.substring(0, dataType.length() - 1) + " " + id);
|
||||
register(id, thing);
|
||||
}
|
||||
log(Level.INFO, "Finished loading " + dataType);
|
||||
|
@ -47,10 +49,12 @@ public abstract class GenericManualResourceLoader<T> {
|
|||
protected abstract void save(Identifier id, T item);
|
||||
|
||||
public void load() {
|
||||
config = AutoConfig.getConfigHolder(SimpleCreatorConfig.class).getConfig();
|
||||
ResourcePackManager<ResourcePackProfile> resourcePackManager = new ResourcePackManager<>(ResourcePackProfile::new);
|
||||
resourcePackManager.registerProvider(new VanillaDataPackProvider());
|
||||
resourcePackManager.registerProvider(new FileResourcePackProvider(new File("./datapacks")));
|
||||
resourcePackManager.registerProvider(new ModResourcePackCreator(ResourceType.SERVER_DATA));
|
||||
if (config.enableTestThings)
|
||||
resourcePackManager.registerProvider(new ModResourcePackCreator(ResourceType.SERVER_DATA));
|
||||
resourcePackManager.scanPacks();
|
||||
List<ResourcePackProfile> ep = Lists.newArrayList(resourcePackManager.getEnabledProfiles());
|
||||
for (ResourcePackProfile rpp : resourcePackManager.getProfiles()) {
|
||||
|
@ -62,26 +66,42 @@ public abstract class GenericManualResourceLoader<T> {
|
|||
|
||||
|
||||
ArrayList<Pair<Identifier, JsonObject>> itemJsonList = new ArrayList<>();
|
||||
HashMap<Identifier, JsonObject> itemJsonMap = Maps.newHashMap();
|
||||
for (ResourcePackProfile rpp : resourcePackManager.getEnabledProfiles()) {
|
||||
ResourcePack rp = rpp.createResourcePack();
|
||||
log(Level.INFO, "Loading ResourcePack " + rp.getName());
|
||||
for (String ns : rp.getNamespaces(ResourceType.SERVER_DATA)) {
|
||||
log(Level.INFO, "Loading namespace " + ns);
|
||||
Collection<Identifier> ressurces = rp.findResources(ResourceType.SERVER_DATA, ns, dataType, 5, s -> s.endsWith(".json"));
|
||||
for (Identifier id : ressurces) {
|
||||
Collection<Identifier> resources = rp.findResources(ResourceType.SERVER_DATA, ns, dataType, 5, s -> s.endsWith(".json"));
|
||||
for (Identifier id : resources) {
|
||||
if (config.extendedLogging)
|
||||
log(Level.INFO, "found: " + id.toString() + " in Pack: " + rp.getName());
|
||||
Identifier idNice = new Identifier(id.getNamespace(), getName(id));
|
||||
try {
|
||||
InputStream is = rp.open(ResourceType.SERVER_DATA, id);
|
||||
Reader r = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
|
||||
JsonObject jo = JsonHelper.deserialize(GSON, r, JsonObject.class);
|
||||
if (jo != null)
|
||||
itemJsonList.add(new Pair<>(idNice, jo));
|
||||
if (jo.entrySet().isEmpty()) {
|
||||
itemJsonMap.remove(idNice);
|
||||
if (config.extendedLogging)
|
||||
log(Level.INFO, "deleting " + idNice + " because of an empty override in " + rp.getName());
|
||||
} else {
|
||||
itemJsonMap.put(idNice, jo);
|
||||
if (config.extendedLogging)
|
||||
log(Level.INFO, "adding " + idNice + " from " + rp.getName());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log(Level.ERROR, "error loading " + id + " " + e.getMessage());
|
||||
} catch (JsonParseException e) {
|
||||
log(Level.ERROR, "error parsing json for " + id + " " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Map.Entry<Identifier, JsonObject> e : itemJsonMap.entrySet()) {
|
||||
itemJsonList.add(new Pair<>(e.getKey(), e.getValue()));
|
||||
}
|
||||
loadItems(itemJsonList);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package quimufu.simple_creator;
|
||||
|
||||
import net.minecraft.block.MaterialColor;
|
||||
import net.minecraft.block.piston.PistonBehavior;
|
||||
|
||||
public class MaterialSettingsPojo {
|
||||
String pistonBehavior = "normal";
|
||||
boolean blocksMovement = true;
|
||||
boolean burnable = false;
|
||||
boolean breakByHand = true;
|
||||
boolean liquid = false;
|
||||
boolean replaceable = false;
|
||||
boolean solid = true;
|
||||
boolean blocksLight = true;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package quimufu.simple_creator;
|
||||
|
||||
import me.sargunvohra.mcmods.autoconfig1u.ConfigData;
|
||||
import me.sargunvohra.mcmods.autoconfig1u.annotation.Config;
|
||||
|
||||
@Config(name = "simple_creator")
|
||||
public class SimpleCreatorConfig implements ConfigData {
|
||||
public boolean enableTestThings = false;
|
||||
public boolean extendedLogging = false;
|
||||
}
|
|
@ -1,11 +1,17 @@
|
|||
package quimufu.simple_creator;
|
||||
|
||||
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
|
||||
import me.sargunvohra.mcmods.autoconfig1u.ConfigHolder;
|
||||
import me.sargunvohra.mcmods.autoconfig1u.serializer.GsonConfigSerializer;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
//import net.minecraft.block.Material;
|
||||
|
||||
//import java.lang.reflect.Field;
|
||||
|
||||
public class SimpleCreatorMod implements ModInitializer {
|
||||
|
||||
public static Logger LOGGER = LogManager.getLogger();
|
||||
|
@ -18,12 +24,34 @@ public class SimpleCreatorMod implements ModInitializer {
|
|||
@Override
|
||||
public void onInitialize() {
|
||||
log(Level.INFO, "Initializing");
|
||||
AutoConfig.register(SimpleCreatorConfig.class, GsonConfigSerializer::new);
|
||||
// for(Material m : Material.class.getEnumConstants()){
|
||||
// log(Level.INFO, String.valueOf(m.getColor().color));
|
||||
// }
|
||||
// for (Field f : Material.class.getDeclaredFields()) {
|
||||
// log(Level.INFO, f.getName());
|
||||
// try {
|
||||
// Material m = ((Material) f.get(Material.class));
|
||||
// log(Level.INFO, "pistonBehavior: " + m.getPistonBehavior().name());
|
||||
// log(Level.INFO, "blocksMovement: " + m.blocksMovement());
|
||||
// log(Level.INFO, "burnable: " + m.isBurnable());
|
||||
// log(Level.INFO, "breakByHand: " + m.canBreakByHand());
|
||||
// log(Level.INFO, "liquid: " + m.isLiquid());
|
||||
// log(Level.INFO, "replaceable: " + m.isReplaceable());
|
||||
// log(Level.INFO, "solid: " + m.isSolid());
|
||||
// log(Level.INFO, "blocksLight: " + m.blocksLight());
|
||||
// log(Level.INFO, "");
|
||||
// log(Level.INFO, "");
|
||||
//
|
||||
// } catch (IllegalAccessException ignored) {
|
||||
// }
|
||||
// }
|
||||
irl.load();
|
||||
brl.load();
|
||||
}
|
||||
|
||||
public static void log(Level level, String message){
|
||||
LOGGER.log(level, "["+MOD_NAME+"] " + message);
|
||||
public static void log(Level level, String message) {
|
||||
LOGGER.log(level, "[" + MOD_NAME + "] " + message);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package quimufu.simple_creator;
|
||||
|
||||
import io.github.prospector.modmenu.api.ConfigScreenFactory;
|
||||
import io.github.prospector.modmenu.api.ModMenuApi;
|
||||
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
|
||||
public class SimpleCreatorModMenuIntegration implements ModMenuApi {
|
||||
@Override
|
||||
public String getModId() {
|
||||
return SimpleCreatorMod.MOD_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||
return this::getScreen;
|
||||
}
|
||||
|
||||
private Screen getScreen(Screen parent) {
|
||||
return AutoConfig.getConfigScreen(SimpleCreatorConfig.class, parent).get();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
{
|
||||
"item.simple_creator.test_item": "Forbidden Fruit"
|
||||
"text.autoconfig.simple_creator.title": "Simple Item/Block Creator Settings",
|
||||
"text.autoconfig.simple_creator.option.enableTestThings": "Enable a test item and block",
|
||||
"item.simple_creator.test_item": "Forbidden Fruit",
|
||||
"block.simple_creator.test_block": "Fast jumpy wooly diamond-dropping block of Eternal Fire"
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
{
|
||||
"material": "LAVA",
|
||||
"mapColor" :
|
||||
"soundGroup": "wool",
|
||||
"dropTableId": "minecraft:blocks/diamond_ore",
|
||||
"material": "ice",
|
||||
"mapColor": "yellow",
|
||||
"collidable": true,
|
||||
"soundGroup": "wool",
|
||||
"burnChance": 0,
|
||||
"spreadChance": 100,
|
||||
"dropTableId": "minecraft:blocks/diamond_ore",
|
||||
"lightLevel": 1,
|
||||
"explosionResistance": 5.0,
|
||||
"hardness": 0.5,
|
||||
|
@ -11,5 +13,5 @@
|
|||
"slowDownMultiplier": 2.0,
|
||||
"jumpVelocityMultiplier": 2.0,
|
||||
"opaque": true,
|
||||
"group": "food"
|
||||
"itemGroup": "food"
|
||||
}
|
|
@ -17,7 +17,10 @@
|
|||
"quimufu.simple_creator.SimpleCreatorMod"
|
||||
],
|
||||
"client": [],
|
||||
"server": []
|
||||
"server": [],
|
||||
"modmenu": [
|
||||
"quimufu.simple_creator.SimpleCreatorModMenuIntegration"
|
||||
]
|
||||
},
|
||||
"mixins": [],
|
||||
"depends": {
|
||||
|
|
Loading…
Reference in New Issue
Block a user