Add BlockState API
All checks were successful
ScriptCraft/pipeline/head This commit looks good

This commit is contained in:
TheBrokenRail 2020-08-26 17:52:17 -04:00
parent c941b61173
commit 17044be8ca
21 changed files with 382 additions and 133 deletions

View File

@ -48,5 +48,5 @@ Registry.register(Registry.BLOCK, new Identifier('modid', 'my_block'), new MyBlo
```javascript ```javascript
import { Registry, Identifier, BlockItem, ItemSettings } from 'minecraft'; import { Registry, Identifier, BlockItem, ItemSettings } from 'minecraft';
Registry.register(Registry.ITEM, new Identifier('modid', 'my_block'), new BlockItem(new Identifier('modid', 'my_block'), new ItemSettings().setItemGroup('building_blocks'))); Registry.register(Registry.ITEM, new Identifier('modid', 'my_block'), new BlockItem(new Identifier('modid', 'my_block'), new ItemSettings().itemGroup('building_blocks')));
``` ```

View File

@ -112,5 +112,5 @@ Registry.register(Registry.BLOCK, new Identifier('modid', 'my_block'), new MyBlo
```javascript ```javascript
import { Registry, Identifier, BlockItem, ItemSettings } from 'minecraft'; import { Registry, Identifier, BlockItem, ItemSettings } from 'minecraft';
Registry.register(Registry.ITEM, new Identifier('modid', 'my_block'), new BlockItem(new Identifier('modid', 'my_block'), new ItemSettings().setItemGroup('building_blocks'))); Registry.register(Registry.ITEM, new Identifier('modid', 'my_block'), new BlockItem(new Identifier('modid', 'my_block'), new ItemSettings().itemGroup('building_blocks')));
``` ```

View File

@ -7,7 +7,7 @@ import { ActionResult, ItemSettings, CustomItem } from 'minecraft';
class MyItem extends CustomItem { class MyItem extends CustomItem {
constructor() { constructor() {
super(new ItemSettings().setItemGroup('building_blocks').setMaxCount(16)); super(new ItemSettings().itemGroup('building_blocks').maxCount(16));
} }
onUse(world, player, hand) { onUse(world, player, hand) {
@ -33,7 +33,7 @@ import { ActionResult, World, Pos, Hand, PlayerEntity, ItemSettings, CustomItem,
class MyItem extends CustomItem { class MyItem extends CustomItem {
constructor() { constructor() {
super(new ItemSettings().setItemGroup('building_blocks').setMaxCount(18)); super(new ItemSettings().itemGroup('building_blocks').maxCount(18));
} }
onUse(world: World, player: PlayerEntity, hand: Hand): ActionResult { onUse(world: World, player: PlayerEntity, hand: Hand): ActionResult {

View File

@ -9,6 +9,14 @@
#include "com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h" #include "com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h"
#include "console.h" #include "console.h"
#define GET_JAVA_ERROR \
jclass exception_clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/quickjs/JSException"); \
jmethodID err_to_string = (*env)->GetStaticMethodID(env, exception_clazz, "getStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;"); \
jstring err_java_string = (jstring) (*env)->CallObjectMethod(env, exception_clazz, err_to_string, err); \
const char *err_str = (*env)->GetStringUTFChars(env, err_java_string, 0);
#define FREE_JAVA_ERROR (*env)->ReleaseStringUTFChars(env, err_java_string, err_str);
typedef struct { typedef struct {
JSContext *ctx; JSContext *ctx;
JSRuntime *rt; JSRuntime *rt;
@ -66,13 +74,12 @@ static char *js_module_normalize_name(JSContext *ctx, const char *base_name, con
} else { } else {
jthrowable err = (*env)->ExceptionOccurred(env); jthrowable err = (*env)->ExceptionOccurred(env);
if (err) { if (err) {
jmethodID to_string = (*env)->GetMethodID(env, (*env)->FindClass(env, "java/lang/Object"), "toString", "()Ljava/lang/String;"); GET_JAVA_ERROR;
jstring java_string = (jstring) (*env)->CallObjectMethod(env, err, to_string);
const char *str = (*env)->GetStringUTFChars(env, java_string, 0);
JS_ThrowReferenceError(ctx, "could not normalize module name '%s': %s", name, str); JS_ThrowReferenceError(ctx, "could not normalize module name '%s': %s", name, err_str);
FREE_JAVA_ERROR;
(*env)->ReleaseStringUTFChars(env, java_string, str);
(*env)->ExceptionClear(env); (*env)->ExceptionClear(env);
} else { } else {
JS_ThrowReferenceError(ctx, "could not normalize module name '%s'", name); JS_ThrowReferenceError(ctx, "could not normalize module name '%s'", name);
@ -135,13 +142,12 @@ static char *js_load_file(JSContext *ctx, const char *filename) {
} else { } else {
jthrowable err = (*env)->ExceptionOccurred(env); jthrowable err = (*env)->ExceptionOccurred(env);
if (err) { if (err) {
jmethodID to_string = (*env)->GetMethodID(env, (*env)->FindClass(env, "java/lang/Object"), "toString", "()Ljava/lang/String;"); GET_JAVA_ERROR;
jstring java_string = (jstring) (*env)->CallObjectMethod(env, err, to_string);
const char *str = (*env)->GetStringUTFChars(env, java_string, 0);
JS_ThrowReferenceError(ctx, "could not load module filename '%s': %s", filename, str); JS_ThrowReferenceError(ctx, "could not load module filename '%s': %s", filename, err_str);
FREE_JAVA_ERROR;
(*env)->ReleaseStringUTFChars(env, java_string, str);
(*env)->ExceptionClear(env); (*env)->ExceptionClear(env);
} else { } else {
JS_ThrowReferenceError(ctx, "could not load module filename '%s'", filename); JS_ThrowReferenceError(ctx, "could not load module filename '%s'", filename);
@ -334,14 +340,12 @@ static JSValue js_use_bridge(JSContext *ctx, JSValueConst this_val, int argc, JS
} else { } else {
jthrowable err = (*env)->ExceptionOccurred(env); jthrowable err = (*env)->ExceptionOccurred(env);
if (err) { if (err) {
jclass exception_clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/quickjs/JSException"); GET_JAVA_ERROR;
jmethodID to_string = (*env)->GetMethodID(env, exception_clazz, "getStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;");
jstring java_string = (jstring) (*env)->CallObjectMethod(env, err, to_string);
const char *str = (*env)->GetStringUTFChars(env, java_string, 0);
js_out = JS_ThrowReferenceError(ctx, "unable to use bridge '%s': %s", js_bridge_name, str); js_out = JS_ThrowReferenceError(ctx, "unable to use bridge '%s': %s", js_bridge_name, err_str);
FREE_JAVA_ERROR;
(*env)->ReleaseStringUTFChars(env, java_string, str);
(*env)->ExceptionClear(env); (*env)->ExceptionClear(env);
} else { } else {
js_out = JS_NULL; js_out = JS_NULL;

View File

@ -5,6 +5,8 @@ import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.Property;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -12,17 +14,51 @@ import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class CustomBlock extends Block { public abstract class CustomBlock extends Block {
@SuppressWarnings({"unchecked", "rawtypes"})
public static class BlockStatePropertyBuilder {
private final Map<Property, Comparable> map = new HashMap<>();
public void add(Property<?> property, Comparable defaultValue) {
map.put(property, defaultValue);
}
private void appendProperties(StateManager.Builder<Block, BlockState> builder) {
for (Property property : map.keySet()) {
builder.add(property);
}
}
private BlockState updateDefaultState(BlockState defaultState) {
for (Map.Entry<Property, Comparable> entry : map.entrySet()) {
defaultState = defaultState.with(entry.getKey(), entry.getValue());
}
return defaultState;
}
}
protected final Identifier id; protected final Identifier id;
public CustomBlock(Settings settings, Identifier id) { public CustomBlock(Settings settings, Identifier id) {
super(settings); super(settings);
this.id = id; this.id = id;
setDefaultState(getPropertyBuilder().updateDefaultState(getDefaultState()));
} }
@Override @Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
return ValueUtil.getEnumValue(ActionResult.class, (String) ScriptCraftCore.useBridge("CustomBlock.onUse", id.toString(), world, state, pos.getX(), pos.getY(), pos.getZ(), hit.getSide().name(), player, hand.name()), ActionResult.PASS); return ValueUtil.getEnumValue(ActionResult.class, (String) ScriptCraftCore.useBridge("CustomBlock.onUse", id.toString(), world, state, pos.getX(), pos.getY(), pos.getZ(), hit.getSide().name(), player, hand.name()), ActionResult.PASS);
} }
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
getPropertyBuilder().appendProperties(builder);
}
protected abstract BlockStatePropertyBuilder getPropertyBuilder();
} }

View File

@ -6,7 +6,7 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
public class CustomBlockWithEntity extends CustomBlock implements BlockEntityProvider { public abstract class CustomBlockWithEntity extends CustomBlock implements BlockEntityProvider {
public CustomBlockWithEntity(Settings settings, Identifier id) { public CustomBlockWithEntity(Settings settings, Identifier id) {
super(settings, id); super(settings, id);
} }

View File

@ -2,12 +2,15 @@ package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.Material; import net.minecraft.util.registry.Registry;
class BlockBridges { class BlockBridges {
static void register() { static void register() {
ScriptCraftCore.addBridge("Block.getMaterial", args -> ((Block) args[0]).getDefaultState().getMaterial()); ScriptCraftCore.addBridge("Block.getMaterial", args -> ((Block) args[0]).getDefaultState().getMaterial());
ScriptCraftCore.addBridge("Block.getMaterialColor", args -> ((Block) args[0]).getDefaultState().getTopMaterialColor(null, null)); ScriptCraftCore.addBridge("Block.getMaterialColor", args -> ((Block) args[0]).getDefaultState().getTopMaterialColor(null, null));
ScriptCraftCore.addBridge("Block.getID", args -> Registry.BLOCK.getId((Block) args[0]).toString());
ScriptCraftCore.addBridge("Block.getDefaultState", args -> ((Block) args[0]).getDefaultState());
ScriptCraftCore.addBridge("Block.isValid", args -> args[0] instanceof Block); ScriptCraftCore.addBridge("Block.isValid", args -> args[0] instanceof Block);
} }
} }

View File

@ -2,13 +2,52 @@ package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier; import net.minecraft.state.property.Property;
import net.minecraft.util.registry.Registry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@SuppressWarnings({"rawtypes", "unchecked"})
class BlockStateBridges { class BlockStateBridges {
static void register() { static void register() {
ScriptCraftCore.addBridge("BlockState.getDefaultState", args -> Registry.BLOCK.get(new Identifier((String) args[0])).getDefaultState()); ScriptCraftCore.addBridge("BlockState.getBlock", args -> ((BlockState) args[0]).getBlock());
ScriptCraftCore.addBridge("BlockState.getBlock", args -> Registry.BLOCK.getId(((BlockState) args[0]).getBlock()).toString());
ScriptCraftCore.addBridge("BlockState.get", args -> {
BlockState state = (BlockState) args[0];
String name = (String) args[1];
Collection<Property<?>> properties = state.getProperties();
for (Property property : properties) {
if (property.getName().equals(name)) {
return property.name(state.get(property));
}
}
return null;
});
ScriptCraftCore.addBridge("BlockState.with", args -> {
BlockState state = (BlockState) args[0];
String name = (String) args[1];
Comparable value = (Comparable) args[2];
Collection<Property<?>> properties = state.getProperties();
for (Property property : properties) {
if (property.getName().equals(name)) {
if (value instanceof String) {
value = (Comparable) property.parse((String) value).orElse(null);
}
return state.with(property, value);
}
}
return null;
});
ScriptCraftCore.addBridge("BlockState.properties", args -> {
BlockState state = (BlockState) args[0];
List<String> names = new ArrayList<>();
Collection<Property<?>> properties = state.getProperties();
for (Property<?> property : properties) {
names.add(property.getName());
}
return names.toArray();
});
ScriptCraftCore.addBridge("BlockState.isValid", args -> args[0] instanceof BlockState); ScriptCraftCore.addBridge("BlockState.isValid", args -> args[0] instanceof BlockState);
} }

View File

@ -0,0 +1,24 @@
package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.api.block.CustomBlock;
import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.IntProperty;
class BlockStatePropertyBuilderBridges {
static void register() {
ScriptCraftCore.addBridge("BlockStatePropertyBuilder.create", args -> new CustomBlock.BlockStatePropertyBuilder());
ScriptCraftCore.addBridge("BlockStatePropertyBuilder.intProperty", args -> {
((CustomBlock.BlockStatePropertyBuilder) args[0]).add(IntProperty.of((String) args[1], (int) ValueUtil.toDouble(args[2], 0), (int) ValueUtil.toDouble(args[3], 0)), (int) ValueUtil.toDouble(args[4], 0));
return null;
});
ScriptCraftCore.addBridge("BlockStatePropertyBuilder.booleanProperty", args -> {
((CustomBlock.BlockStatePropertyBuilder) args[0]).add(BooleanProperty.of((String) args[1]), (Boolean) args[2]);
return null;
});
ScriptCraftCore.addBridge("BlockStatePropertyBuilder.isValid", args -> args[0] instanceof CustomBlock.BlockStatePropertyBuilder);
}
}

View File

@ -20,5 +20,6 @@ public class Bridges {
MaterialColorBridges.register(); MaterialColorBridges.register();
BlockBridges.register(); BlockBridges.register();
BuiltinRegistryBridges.register(); BuiltinRegistryBridges.register();
BlockStatePropertyBuilderBridges.register();
} }
} }

View File

@ -15,11 +15,23 @@ import net.minecraft.util.registry.Registry;
class RegistryBridges { class RegistryBridges {
static void register() { static void register() {
ScriptCraftCore.addBridge("Registry.registerBlock", args -> { ScriptCraftCore.addBridge("Registry.registerBlock", args -> {
Registry.register(Registry.BLOCK, new Identifier((String) args[0]), new CustomBlock((Block.Settings) args[1], new Identifier((String) args[0]))); CustomBlock.BlockStatePropertyBuilder builder = (CustomBlock.BlockStatePropertyBuilder) args[2];
Registry.register(Registry.BLOCK, new Identifier((String) args[0]), new CustomBlock((Block.Settings) args[1], new Identifier((String) args[0])) {
@Override
protected BlockStatePropertyBuilder getPropertyBuilder() {
return builder;
}
});
return null; return null;
}); });
ScriptCraftCore.addBridge("Registry.registerBlockWithEntity", args -> { ScriptCraftCore.addBridge("Registry.registerBlockWithEntity", args -> {
Registry.register(Registry.BLOCK, new Identifier((String) args[0]), new CustomBlockWithEntity((Block.Settings) args[1], new Identifier((String) args[0]))); CustomBlock.BlockStatePropertyBuilder builder = (CustomBlock.BlockStatePropertyBuilder) args[2];
Registry.register(Registry.BLOCK, new Identifier((String) args[0]), new CustomBlockWithEntity((Block.Settings) args[1], new Identifier((String) args[0])) {
@Override
protected BlockStatePropertyBuilder getPropertyBuilder() {
return builder;
}
});
Registry.register(Registry.BLOCK_ENTITY_TYPE, new Identifier((String) args[0]), BlockEntityType.Builder.create(() -> new CustomBlockEntity(Registry.BLOCK_ENTITY_TYPE.get(new Identifier((String) args[0])), new Identifier((String) args[0])), Registry.BLOCK.get(new Identifier((String) args[0]))).build(null)); Registry.register(Registry.BLOCK_ENTITY_TYPE, new Identifier((String) args[0]), BlockEntityType.Builder.create(() -> new CustomBlockEntity(Registry.BLOCK_ENTITY_TYPE.get(new Identifier((String) args[0])), new Identifier((String) args[0])), Registry.BLOCK.get(new Identifier((String) args[0]))).build(null));
return null; return null;
}); });

View File

@ -9,7 +9,7 @@ public class JSException extends Exception {
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
public String getStackTrace(Throwable e) { public static String getStackTrace(Throwable e) {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer)); e.printStackTrace(new PrintWriter(writer));
return writer.toString(); return writer.toString();

View File

@ -7,5 +7,6 @@
"eslint.format.enable": true, "eslint.format.enable": true,
"editor.insertSpaces": true, "editor.insertSpaces": true,
"editor.detectIndentation": false, "editor.detectIndentation": false,
"editor.tabSize": 4 "editor.tabSize": 4,
"typescript.tsdk": "./node_modules/typescript/lib"
} }

View File

@ -4,11 +4,12 @@ import { Identifier, Hand, Pos, ActionResult, Direction, SimpleRegistry, JavaObj
import { CompoundTag } from './tag'; import { CompoundTag } from './tag';
import { useBridge, addBridge } from 'scriptcraft-core'; import { useBridge, addBridge } from 'scriptcraft-core';
import { Inventory } from './inventory'; import { Inventory } from './inventory';
import { Registry } from './registry';
/** /**
* Block Material * Block Material
*/ */
class Material extends JavaObjectWrapper { export class Material extends JavaObjectWrapper {
/** /**
* Create Material Wrapper From Java Object * Create Material Wrapper From Java Object
* @param javaObject Java Object * @param javaObject Java Object
@ -24,7 +25,7 @@ class Material extends JavaObjectWrapper {
*/ */
getColor(): MaterialColor { getColor(): MaterialColor {
const obj = useBridge('Material.getColor', this.getJavaObject()) as JavaObject; const obj = useBridge('Material.getColor', this.getJavaObject()) as JavaObject;
if (obj) { if (obj !== null) {
return new MaterialColor(obj); return new MaterialColor(obj);
} else { } else {
return null; return null;
@ -35,7 +36,7 @@ class Material extends JavaObjectWrapper {
/** /**
* Block Material Color * Block Material Color
*/ */
class MaterialColor extends JavaObjectWrapper { export class MaterialColor extends JavaObjectWrapper {
/** /**
* Create Material Color Wrapper From Java Object * Create Material Color Wrapper From Java Object
* @param javaObject Java Object * @param javaObject Java Object
@ -76,7 +77,7 @@ export class BlockSettings {
* @param hardness Hardness Value * @param hardness Hardness Value
* @param resistance Blast Resistance Value * @param resistance Blast Resistance Value
*/ */
setStrength(hardness: number, resistance: number): BlockSettings { strength(hardness: number, resistance: number): BlockSettings {
this.#hardness = hardness; this.#hardness = hardness;
this.#resistance = resistance; this.#resistance = resistance;
return this; return this;
@ -86,7 +87,7 @@ export class BlockSettings {
* Set Hardness * Set Hardness
* @param hardness Hardness Value * @param hardness Hardness Value
*/ */
setHardness(hardness: number): BlockSettings { hardness(hardness: number): BlockSettings {
this.#hardness = hardness; this.#hardness = hardness;
return this; return this;
} }
@ -95,7 +96,7 @@ export class BlockSettings {
* Set Blast Resistance * Set Blast Resistance
* @param resistance Blast Resistance Value * @param resistance Blast Resistance Value
*/ */
setResistance(resistance: number): BlockSettings { resistance(resistance: number): BlockSettings {
this.#resistance = resistance; this.#resistance = resistance;
return this; return this;
} }
@ -112,7 +113,7 @@ export class BlockSettings {
* Set Material * Set Material
* @param material Material * @param material Material
*/ */
setMaterial(material: Material): BlockSettings { material(material: Material): BlockSettings {
this.#material = material; this.#material = material;
return this; return this;
} }
@ -121,7 +122,7 @@ export class BlockSettings {
* Set Material Color * Set Material Color
* @param materialColor Material Color * @param materialColor Material Color
*/ */
setMaterialColor(materialColor: MaterialColor): BlockSettings { materialColor(materialColor: MaterialColor): BlockSettings {
this.#materialColor = materialColor; this.#materialColor = materialColor;
return this; return this;
} }
@ -164,6 +165,7 @@ export class BlockSettings {
*/ */
export class CustomBlock { export class CustomBlock {
readonly #settings: Readonly<BlockSettings>; readonly #settings: Readonly<BlockSettings>;
readonly #propertyBuilder: BlockStatePropertyBuilder;
/** /**
* Create Custom Block * Create Custom Block
@ -171,6 +173,8 @@ export class CustomBlock {
*/ */
constructor(settings: BlockSettings) { constructor(settings: BlockSettings) {
this.#settings = Object.freeze(settings); this.#settings = Object.freeze(settings);
this.#propertyBuilder = BlockStatePropertyBuilder.create();
this.appendProperties(this.getPropertyBuilder());
} }
/** /**
@ -181,6 +185,14 @@ export class CustomBlock {
return this.#settings; return this.#settings;
} }
/**
* Get Block State Property Builder
* @returns Block State Property Builder
*/
getPropertyBuilder(): BlockStatePropertyBuilder {
return this.#propertyBuilder;
}
/** /**
* Called When The Block Is Used * Called When The Block Is Used
* @param world World * @param world World
@ -194,6 +206,13 @@ export class CustomBlock {
onUse(world: World, blockState: BlockState, pos: Pos, side: Direction, player: PlayerEntity, hand: Hand): ActionResult { onUse(world: World, blockState: BlockState, pos: Pos, side: Direction, player: PlayerEntity, hand: Hand): ActionResult {
return ActionResult.PASS; return ActionResult.PASS;
} }
/**
* Add Block State Properties
* @param builder Block State Property Builder
*/
appendProperties(builder: BlockStatePropertyBuilder): void {
}
} }
/** /**
@ -266,8 +285,132 @@ export class CustomBlockEntity {
} }
} }
} }
/**
* Get Custom Block Entity by ID
* @param id ID
* @returns Custom Block Entity
*/
static getByID(id: number): CustomBlockEntity {
return BlockRegistry.INSTANCE.getCustomBlockEntityByID(id);
}
} }
/**
* Block
*/
export class Block extends JavaObjectWrapper {
/**
* Create Block Wrapper From Java Object
* @param javaObject Java Object
*/
constructor(javaObject: JavaObject | JavaObjectWrapper) {
super(javaObject);
this.assertValidJavaObject('Block');
}
/**
* Get Block Material
*/
getMaterial(): Material {
const obj = useBridge('Block.getMaterial', this.getJavaObject()) as JavaObject;
if (obj !== null) {
return new Material(obj);
} else {
return null;
}
}
/**
* Get Block Material Color
*/
getMaterialColor(): MaterialColor {
const obj = useBridge('Block.getMaterialColor', this.getJavaObject()) as JavaObject;
if (obj !== null) {
return new MaterialColor(obj);
} else {
return null;
}
}
/**
* Get Block ID
* @returns ID
*/
getID(): Identifier {
const obj = useBridge('Block.getID', this.getJavaObject()) as string;
if (obj !== null) {
return new Identifier(obj);
} else {
return null;
}
}
/**
* Get Default Block State
* @returns Default Block State
*/
getDefaultState(): BlockState {
const obj = useBridge('Block.getDefaultState', this.getJavaObject()) as JavaObject;
if (obj !== null) {
return new BlockState(obj);
} else {
return null;
}
}
}
/**
* Custom Block State Property Builder
*/
export class BlockStatePropertyBuilder extends JavaObjectWrapper {
/**
* Create Block State Property Builder Wrapper From Java Object
* @param javaObject Java Object
*/
constructor(javaObject: JavaObject | JavaObjectWrapper) {
super(javaObject);
this.assertValidJavaObject('BlockStatePropertyBuilder');
}
/**
* Create Block State Property Builder
* @returns New Block State Property Builder
*/
static create(): BlockStatePropertyBuilder {
const obj = useBridge('BlockStatePropertyBuilder.create') as JavaObject;
if (obj) {
return new BlockStatePropertyBuilder(obj);
} else {
return null;
}
}
/**
* Add Integer Property
* @param name Property Name
* @param min Minimum Value
* @param max Maximum Value
* @param defaultValue Default Value
*/
intProperty(name: string, min: number, max: number, defaultValue: number): BlockStatePropertyBuilder {
useBridge('BlockStatePropertyBuilder.intProperty', this.getJavaObject(), name, min, max, defaultValue);
return this;
}
/**
* Add Boolean Property
* @param name Property Name
* @param defaultValue Default Value
*/
booleanProperty(name: string, defaultValue: boolean): BlockStatePropertyBuilder {
useBridge('BlockStatePropertyBuilder.booleanProperty', this.getJavaObject(), name, defaultValue);
return this;
}
}
type BlockStatePropertyType = string | number | boolean;
/** /**
* Block State * Block State
*/ */
@ -281,28 +424,14 @@ export class BlockState extends JavaObjectWrapper {
this.assertValidJavaObject('BlockState'); this.assertValidJavaObject('BlockState');
} }
/**
* Get Default Block State for Block
* @param block Block ID
* @returns Default Block State
*/
static getDefaultState(block: Identifier): BlockState {
const obj = useBridge('BlockState.getDefaultState', block.toString()) as JavaObject;
if (obj) {
return new BlockState(obj);
} else {
return null;
}
}
/** /**
* Get Block ID * Get Block ID
* @returns Block ID * @returns Block ID
*/ */
getBlock(): Identifier { getBlock(): Block {
const obj = useBridge('BlockState.getBlock', this.getJavaObject()) as string; const obj = useBridge('BlockState.getBlock', this.getJavaObject()) as JavaObject;
if (obj) { if (obj !== null) {
return new Identifier(obj); return new Block(obj);
} else { } else {
return null; return null;
} }
@ -314,7 +443,53 @@ export class BlockState extends JavaObjectWrapper {
*/ */
getCustomBlock(): CustomBlock { getCustomBlock(): CustomBlock {
const id = this.getBlock(); const id = this.getBlock();
return BlockRegistry.INSTANCE.get(id); return BlockRegistry.INSTANCE.get(id.getID());
}
/**
* Get Block State Property
* @param property Property Name
* @returns Value
*/
get(property: string): BlockStatePropertyType {
return useBridge('BlockState.get', this.getJavaObject(), property) as BlockStatePropertyType;
}
/**
* Get New Block State With Property Set To Value
* @param property Property Name
* @param value Value
* @returns New Block State
*/
with(property: string, value: BlockStatePropertyType): BlockState {
const obj = useBridge('BlockState.with', this.getJavaObject(), property, value) as JavaObject;
if (obj !== null) {
return new BlockState(obj);
} else {
return null;
}
}
/**
* Get All Block State Properties
* @returns All Block State Properties
*/
properties(): string[] {
return useBridge('BlockState.properties', this.getJavaObject()) as string[];
}
/**
* Convert To String
* @returns String
*/
toString(): string {
const start = this.getBlock().getID().toString();
const properties = this.properties();
const parts: string[] = [];
for (const property of properties) {
parts.push(property + ' = ' + this.get(property).toString());
}
return start + '[' + parts.join(', ') + ']';
} }
} }
@ -378,49 +553,8 @@ export class CustomBlockWithEntity extends CustomBlock {
} }
} }
/** class BlockRegistry implements SimpleRegistry<CustomBlock> {
* Built-In Block static INSTANCE = new BlockRegistry();
*/
export class Block extends JavaObjectWrapper {
/**
* Create Built-In Block Wrapper From Java Object
* @param javaObject Java Object
*/
constructor(javaObject: JavaObject | JavaObjectWrapper) {
super(javaObject);
this.assertValidJavaObject('Block');
}
/**
* Get Block Material
*/
getMaterial(): Material {
const obj = useBridge('Block.getMaterial', this.getJavaObject()) as JavaObject;
if (obj) {
return new Material(obj);
} else {
return null;
}
}
/**
* Get Block MaterialColor
*/
getMaterialColor(): MaterialColor {
const obj = useBridge('Block.getMaterialColor', this.getJavaObject()) as JavaObject;
if (obj) {
return new MaterialColor(obj);
} else {
return null;
}
}
}
/**
* @internal
*/
export class BlockRegistry implements SimpleRegistry<CustomBlock> {
static readonly INSTANCE = new BlockRegistry();
readonly #blocks: Map<string, CustomBlock>; readonly #blocks: Map<string, CustomBlock>;
@ -433,11 +567,7 @@ export class BlockRegistry implements SimpleRegistry<CustomBlock> {
register(id: Identifier, obj: CustomBlock): void { register(id: Identifier, obj: CustomBlock): void {
this.#blocks.set(id.toString(), obj); this.#blocks.set(id.toString(), obj);
if (obj instanceof CustomBlockWithEntity) { useBridge(obj instanceof CustomBlockWithEntity ? 'Registry.registerBlockWithEntity' : 'Registry.registerBlock', id.toString(), obj.getSettings().createJavaObject(), obj.getPropertyBuilder().getJavaObject());
useBridge('Registry.registerBlockWithEntity', id.toString(), obj.getSettings().createJavaObject());
} else {
useBridge('Registry.registerBlock', id.toString(), obj.getSettings().createJavaObject());
}
} }
get(id: Identifier): CustomBlock { get(id: Identifier): CustomBlock {
@ -453,12 +583,8 @@ export class BlockRegistry implements SimpleRegistry<CustomBlock> {
return null; return null;
} }
getCustomBlockEntity(i: number): CustomBlockEntity { getCustomBlockEntityByID(id: number): CustomBlockEntity {
return this.#blockEntities[i]; return this.#blockEntities[id];
}
getCustomBlockEntities(): CustomBlockEntity[] {
return this.#blockEntities;
} }
createCustomBlockEntity(id: Identifier, i: number): void { createCustomBlockEntity(id: Identifier, i: number): void {
@ -471,24 +597,26 @@ export class BlockRegistry implements SimpleRegistry<CustomBlock> {
} }
} }
Registry.BLOCK = BlockRegistry.INSTANCE;
addBridge('CustomBlockEntity.create', (id: string, i: number) => { addBridge('CustomBlockEntity.create', (id: string, i: number) => {
BlockRegistry.INSTANCE.createCustomBlockEntity(new Identifier(id), i); BlockRegistry.INSTANCE.createCustomBlockEntity(new Identifier(id), i);
}); });
addBridge('CustomBlockEntity.fromTag', (i: number, tag: JavaObject) => { addBridge('CustomBlockEntity.fromTag', (i: number, tag: JavaObject) => {
BlockRegistry.INSTANCE.getCustomBlockEntity(i).fromTag(new CompoundTag(tag)); BlockRegistry.INSTANCE.getCustomBlockEntityByID(i).fromTag(new CompoundTag(tag));
}); });
addBridge('CustomBlockEntity.toTag', (i: number, tag: JavaObject): JavaObject => { addBridge('CustomBlockEntity.toTag', (i: number, tag: JavaObject): JavaObject => {
return BlockRegistry.INSTANCE.getCustomBlockEntity(i).toTag(new CompoundTag(tag)).getJavaObject(); return BlockRegistry.INSTANCE.getCustomBlockEntityByID(i).toTag(new CompoundTag(tag)).getJavaObject();
}); });
addBridge('CustomBlockEntity.tick', (i: number) => { addBridge('CustomBlockEntity.tick', (i: number) => {
BlockRegistry.INSTANCE.getCustomBlockEntity(i).tick(); BlockRegistry.INSTANCE.getCustomBlockEntityByID(i).tick();
}); });
addBridge('CustomBlockEntity.setLocation', (i: number, world: JavaObject, x: number, y: number, z: number) => { addBridge('CustomBlockEntity.setLocation', (i: number, world: JavaObject, x: number, y: number, z: number) => {
BlockRegistry.INSTANCE.getCustomBlockEntity(i).setLocation(new World(world), new Pos(x, y, z)); BlockRegistry.INSTANCE.getCustomBlockEntityByID(i).setLocation(new World(world), new Pos(x, y, z));
}); });
addBridge('CustomBlockEntity.free', (i: number) => { addBridge('CustomBlockEntity.free', (i: number) => {
@ -510,7 +638,7 @@ export class BlockBuiltinRegistry implements SimpleBuiltinRegistry<Block> {
get(id: Identifier): Block { get(id: Identifier): Block {
const obj = useBridge('BuiltinRegistry.getBlock', id.toString()) as JavaObject; const obj = useBridge('BuiltinRegistry.getBlock', id.toString()) as JavaObject;
if (obj) { if (obj !== null) {
return new Block(obj); return new Block(obj);
} else { } else {
return null; return null;

View File

@ -242,7 +242,7 @@ export class LivingEntity extends Entity {
*/ */
getStackInHand(hand: Hand): ItemStack { getStackInHand(hand: Hand): ItemStack {
const obj = useBridge('LivingEntity.getStackInHand', this.getJavaObject(), hand.toString()) as JavaObject; const obj = useBridge('LivingEntity.getStackInHand', this.getJavaObject(), hand.toString()) as JavaObject;
if (obj) { if (obj !== null) {
return new ItemStack(obj); return new ItemStack(obj);
} else { } else {
return null; return null;

View File

@ -9,7 +9,7 @@
*/ */
export { Identifier, ActionResult, Hand, Pos, Direction, DirectionUtil } from './core'; export { Identifier, ActionResult, Hand, Pos, Direction, DirectionUtil } from './core';
export { CustomBlock, CustomBlockEntity, CustomBlockWithEntity, BlockSettings, BlockState, BlockEntity } from './block'; export { CustomBlock, CustomBlockEntity, CustomBlockWithEntity, BlockSettings, BlockState, Block, Material, MaterialColor } from './block';
export { ItemStack, ItemSettings, CustomItem, BlockItem, ItemRarity } from './item'; export { ItemStack, ItemSettings, CustomItem, BlockItem, ItemRarity } from './item';
export { World } from './world'; export { World } from './world';
export { LivingEntity, PlayerEntity } from './entity'; export { LivingEntity, PlayerEntity } from './entity';

View File

@ -3,6 +3,7 @@ import { World } from './world';
import { PlayerEntity, LivingEntity } from './entity'; import { PlayerEntity, LivingEntity } from './entity';
import { CompoundTag } from './tag'; import { CompoundTag } from './tag';
import { useBridge, addBridge } from 'scriptcraft-core'; import { useBridge, addBridge } from 'scriptcraft-core';
import { Registry } from './registry';
/** /**
* Item Stack * Item Stack
@ -185,7 +186,7 @@ export class ItemSettings {
* Set Max Count * Set Max Count
* @param maxCount Max Count * @param maxCount Max Count
*/ */
setMaxCount(maxCount: number): ItemSettings { maxCount(maxCount: number): ItemSettings {
this.#maxCount = maxCount; this.#maxCount = maxCount;
return this; return this;
} }
@ -194,7 +195,7 @@ export class ItemSettings {
* Set Item Group * Set Item Group
* @param itemGroup Item Group * @param itemGroup Item Group
*/ */
setItemGroup(itemGroup: string | Identifier): ItemSettings { itemGroup(itemGroup: string | Identifier): ItemSettings {
this.#itemGroup = itemGroup.toString(); this.#itemGroup = itemGroup.toString();
return this; return this;
} }
@ -203,7 +204,7 @@ export class ItemSettings {
* Set Item Rarity * Set Item Rarity
* @param rarity Item Rarity * @param rarity Item Rarity
*/ */
setRarity(rarity: ItemRarity): ItemSettings { rarity(rarity: ItemRarity): ItemSettings {
this.#rarity = rarity; this.#rarity = rarity;
return this; return this;
} }
@ -310,10 +311,7 @@ export class BlockItem {
} }
} }
/** class ItemRegistry implements SimpleRegistry<CustomItem | BlockItem> {
* @internal
*/
export class ItemRegistry implements SimpleRegistry<CustomItem | BlockItem> {
static readonly INSTANCE = new ItemRegistry(); static readonly INSTANCE = new ItemRegistry();
readonly #items: Map<string, CustomItem>; readonly #items: Map<string, CustomItem>;
@ -345,6 +343,8 @@ export class ItemRegistry implements SimpleRegistry<CustomItem | BlockItem> {
} }
} }
Registry.ITEM = ItemRegistry.INSTANCE;
addBridge('CustomItem.onUse', (id: string, world: JavaObject, player: JavaObject, hand: keyof typeof Hand): string => { addBridge('CustomItem.onUse', (id: string, world: JavaObject, player: JavaObject, hand: keyof typeof Hand): string => {
return ItemRegistry.INSTANCE.get(new Identifier(id)).onUse(new World(world), new PlayerEntity(player), Hand[hand]); return ItemRegistry.INSTANCE.get(new Identifier(id)).onUse(new World(world), new PlayerEntity(player), Hand[hand]);
}); });

View File

@ -1,6 +1,6 @@
import { Identifier, SimpleRegistry } from './core'; import { Identifier, SimpleRegistry } from './core';
import { BlockRegistry, CustomBlock } from './block'; import { CustomBlock } from './block';
import { ItemRegistry, CustomItem, BlockItem } from './item'; import { CustomItem, BlockItem } from './item';
/** /**
* Registry * Registry
@ -9,11 +9,11 @@ export abstract class Registry {
/** /**
* Block Registry * Block Registry
*/ */
static BLOCK: SimpleRegistry<CustomBlock> = BlockRegistry.INSTANCE; static BLOCK: SimpleRegistry<CustomBlock>;
/** /**
* Item Registry * Item Registry
*/ */
static ITEM: SimpleRegistry<CustomItem | BlockItem> = ItemRegistry.INSTANCE; static ITEM: SimpleRegistry<CustomItem | BlockItem>;
/** /**
* Register Object * Register Object

View File

@ -3,7 +3,7 @@ import { JavaObjectWrapper } from './core';
type TagType = number | boolean | string | CompoundTag | ListTag; type TagType = number | boolean | string | CompoundTag | ListTag;
function getTagValue(obj: [boolean, BridgeValueType]): Exclude<TagType, boolean> { function getTagValue(obj: [isList: boolean, value: BridgeValueType]): Exclude<TagType, boolean> {
if (typeof obj[1] === 'object') { if (typeof obj[1] === 'object') {
if (obj[0]) { if (obj[0]) {
return new ListTag(obj[1] as JavaObject); return new ListTag(obj[1] as JavaObject);

View File

@ -1,4 +1,4 @@
import { BlockState, CustomBlockEntity, BlockRegistry, BlockEntity } from './block'; import { BlockState, CustomBlockEntity, BlockEntity } from './block';
import { Entity } from './entity'; import { Entity } from './entity';
import { Pos, Identifier, JavaObjectWrapper } from './core'; import { Pos, Identifier, JavaObjectWrapper } from './core';
import { useBridge } from 'scriptcraft-core'; import { useBridge } from 'scriptcraft-core';
@ -62,7 +62,7 @@ export class World extends JavaObjectWrapper {
getCustomBlockEntity(pos: Pos): CustomBlockEntity { getCustomBlockEntity(pos: Pos): CustomBlockEntity {
const obj = useBridge('World.getCustomBlockEntity', this.getJavaObject(), pos.getX(), pos.getY(), pos.getZ()) as number; const obj = useBridge('World.getCustomBlockEntity', this.getJavaObject(), pos.getX(), pos.getY(), pos.getZ()) as number;
if (obj !== null) { if (obj !== null) {
return BlockRegistry.INSTANCE.getCustomBlockEntity(obj); return CustomBlockEntity.getByID(obj);
} else { } else {
return null; return null;
} }

View File

@ -20,6 +20,7 @@ interface Console {
declare const console: Console; declare const console: Console;
interface String { interface String {
// eslint-disable-next-line @typescript-eslint/naming-convention
__quote(): string; __quote(): string;
} }