Improve API
Some checks failed
ScriptCraft/pipeline/head There was a failure building this commit

This commit is contained in:
TheBrokenRail 2020-04-28 16:18:22 -04:00
parent ba7f312349
commit cb9b124ec7
23 changed files with 247 additions and 65 deletions

View File

@ -1,13 +0,0 @@
package com.thebrokenrail.scriptcraft;
import com.thebrokenrail.scriptcraft.api.ScriptCraftAPI;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import net.fabricmc.api.ModInitializer;
public class ScriptCraft implements ModInitializer {
@Override
public void onInitialize() {
ScriptCraftAPI.init();
ScriptCraftCore.init();
}
}

View File

@ -2,7 +2,7 @@ package com.thebrokenrail.scriptcraft;
import com.thebrokenrail.scriptcraft.core.ScriptCraftEntrypoint;
public class Demo implements ScriptCraftEntrypoint {
public class Test implements ScriptCraftEntrypoint {
@Override
public String getModID() {
return "test";

View File

@ -20,7 +20,7 @@ public class ScriptCraftAPI implements ScriptCraftEntrypoint {
return false;
}
public static void init() {
static {
Bridges.init();
}
}

View File

@ -0,0 +1,26 @@
package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.util.registry.Registry;
import java.util.Objects;
class BlockEntityBridges {
static void register() {
ScriptCraftCore.addBridge("BlockEntity.getID", args -> Objects.requireNonNull(Registry.BLOCK_ENTITY_TYPE.getId(((BlockEntity) args[0]).getType())).toString());
ScriptCraftCore.addBridge("BlockEntity.getInventory", args -> {
BlockEntity entity = (BlockEntity) args[0];
if (entity instanceof Inventory) {
return entity;
} else {
return null;
}
});
ScriptCraftCore.addBridge("BlockEntity.markDirty", args -> {
((BlockEntity) args[0]).markDirty();
return null;
});
}
}

View File

@ -12,5 +12,8 @@ public class Bridges {
EntityBridges.register();
DamageSourceBridges.register();
TagBridges.register();
InventoryBridges.register();
PlayerEntityBridges.register();
BlockEntityBridges.register();
}
}

View File

@ -0,0 +1,19 @@
package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
class InventoryBridges {
static void register() {
ScriptCraftCore.addBridge("Inventory.get", args -> ((Inventory) args[0]).getInvStack((int) ValueUtil.toDouble(args[1], 0)));
ScriptCraftCore.addBridge("Inventory.take", args -> ((Inventory) args[0]).takeInvStack((int) ValueUtil.toDouble(args[1], 0), (int) ValueUtil.toDouble(args[2], 0)));
ScriptCraftCore.addBridge("Inventory.set", args -> {
((Inventory) args[0]).setInvStack((int) ValueUtil.toDouble(args[1], 0), (ItemStack) args[2]);
return null;
});
ScriptCraftCore.addBridge("Inventory.size", args -> ((Inventory) args[0]).getInvSize());
ScriptCraftCore.addBridge("Inventory.getMaxStackSize", args -> ((Inventory) args[0]).getInvMaxStackAmount());
}
}

View File

@ -34,5 +34,7 @@ class ItemStackBridges {
ScriptCraftCore.addBridge("ItemStack.toTag", args -> ((ItemStack) args[0]).toTag(new CompoundTag()));
ScriptCraftCore.addBridge("ItemStack.fromTag", args -> ItemStack.fromTag((CompoundTag) args[1]));
ScriptCraftCore.addBridge("ItemStack.split", args -> ((ItemStack) args[0]).split((int) ValueUtil.toDouble(args[1], 0)));
}
}

View File

@ -0,0 +1,10 @@
package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import net.minecraft.entity.player.PlayerEntity;
class PlayerEntityBridges {
static void register() {
ScriptCraftCore.addBridge("PlayerEntity.getInventory", args -> ((PlayerEntity) args[0]).inventory);
}
}

View File

@ -2,6 +2,7 @@ package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.AbstractListTag;
import net.minecraft.nbt.AbstractNumberTag;
import net.minecraft.nbt.ByteTag;
@ -23,6 +24,7 @@ class TagBridges {
private static Object[] toOut(Tag obj) {
Object[] out = new Object[2];
out[0] = false;
out[1] = null;
if (obj instanceof StringTag) {
out[1] = obj.asString();
} else if (obj instanceof AbstractNumberTag) {

View File

@ -11,8 +11,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import java.util.Objects;
class WorldBridges {
static void register() {
ScriptCraftCore.addBridge("World.getBlockState", args -> ((World) args[0]).getBlockState(new BlockPos((double) args[1], (double) args[2], (double) args[3])));
@ -29,25 +27,10 @@ class WorldBridges {
}
});
ScriptCraftCore.addBridge("World.markBlockEntityDirty", args -> {
World world = (World) args[0];
BlockPos pos = new BlockPos(ValueUtil.toDouble(args[1], 0), ValueUtil.toDouble(args[2], 0), ValueUtil.toDouble(args[3], 0));
BlockEntity entity = world.getBlockEntity(pos);
if (entity != null) {
entity.markDirty();
}
return null;
});
ScriptCraftCore.addBridge("World.getBlockEntity", args -> {
World world = (World) args[0];
BlockPos pos = new BlockPos(ValueUtil.toDouble(args[1], 0), ValueUtil.toDouble(args[2], 0), ValueUtil.toDouble(args[3], 0));
BlockEntity entity = world.getBlockEntity(pos);
if (entity != null) {
return Objects.requireNonNull(Registry.BLOCK_ENTITY_TYPE.getId(entity.getType())).toString();
} else {
return null;
}
return world.getBlockEntity(pos);
});
ScriptCraftCore.addBridge("World.getCustomBlockEntity", args -> {
@ -60,5 +43,7 @@ class WorldBridges {
return null;
}
});
ScriptCraftCore.addBridge("World.isClient", args -> ((World) args[0]).isClient());
}
}

View File

@ -2,6 +2,7 @@ package com.thebrokenrail.scriptcraft.core;
import com.thebrokenrail.scriptcraft.core.quickjs.QuickJSNative;
import com.thebrokenrail.scriptcraft.core.quickjs.QuickJSManager;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import java.util.HashMap;
@ -9,7 +10,7 @@ import java.util.List;
import java.util.regex.Pattern;
@SuppressWarnings("unused")
public class ScriptCraftCore {
public class ScriptCraftCore implements ModInitializer {
private static final HashMap<String, Bridge> bridges = new HashMap<>();
public static void addBridge(String name, Bridge bridge) {
@ -33,7 +34,8 @@ public class ScriptCraftCore {
public static final String NAMESPACE = "scriptcraft";
public static final Pattern MOD_ID_PATTERN = Pattern.compile("[a-z][a-z0-9-_]{1,63}");
public static void init() {
@Override
public void onInitialize() {
QuickJSManager.init(new QuickJSManager.Task() {
@Override
protected Object run(QuickJSNative quickjs) {

View File

@ -17,11 +17,11 @@
"environment": "*",
"entrypoints": {
"main": [
"com.thebrokenrail.scriptcraft.ScriptCraft"
"com.thebrokenrail.scriptcraft.core.ScriptCraftCore"
],
"scriptcraft": [
"com.thebrokenrail.scriptcraft.api.ScriptCraftAPI",
"com.thebrokenrail.scriptcraft.Demo"
"com.thebrokenrail.scriptcraft.Test"
]
},
"depends": {

View File

@ -52,6 +52,7 @@
"dot-notation": "off",
"@typescript-eslint/dot-notation": "error",
"no-extra-semi": "off",
"@typescript-eslint/no-extra-semi": "error"
"@typescript-eslint/no-extra-semi": "error",
"@typescript-eslint/explicit-function-return-type": "error"
}
}

View File

@ -3,6 +3,7 @@ import { PlayerEntity } from './entity';
import { Identifier, Hand, Pos, ActionResult, Direction, SimpleRegistry } from './core';
import { CompoundTag } from './tag';
import { useBridge, addBridge } from 'scriptcraft-core';
import { Inventory } from './inventory';
/**
* Settings for {@link CustomBlock}
@ -75,6 +76,10 @@ export class CustomBlock {
*/
readonly settings: BlockSettings;
/**
* Create Custom Block
* @param settings Block Settings
*/
constructor(settings: BlockSettings) {
this.settings = settings;
}
@ -158,7 +163,10 @@ export class CustomBlockEntity {
*/
markDirty(): void {
if (this.getWorld() !== null) {
useBridge('World.markBlockEntityDirty', this.getWorld().javaObject, this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
const entity = this.getWorld().getBlockEntity(this.getPos());
if (entity !== null) {
entity.markDirty();
}
}
}
}
@ -172,6 +180,9 @@ export class BlockState {
*/
readonly javaObject: JavaObject;
/**
* @internal
*/
constructor(javaObject: JavaObject) {
this.javaObject = javaObject;
}
@ -213,6 +224,56 @@ export class BlockState {
}
}
/**
* Block Entity
*/
export class BlockEntity {
/**
* @internal
*/
readonly javaObject: JavaObject;
/**
* @internal
*/
constructor(object: JavaObject) {
this.javaObject = object;
}
/**
* Get Block Entity ID
* @returns ID
*/
getID(): Identifier {
const obj = useBridge('BlockEntity.getID', this.javaObject) as string;
if (obj !== null) {
return new Identifier(obj);
} else {
return null;
}
}
/**
* Get Block Entity Inventory
* @returns Inventory If Block Entity Has One, Otherwise NULL
*/
getInventory(): Inventory {
const obj = useBridge('BlockEntity.getInventory', this.javaObject) as JavaObject;
if (obj !== null) {
return new Inventory(obj);
} else {
return null;
}
}
/**
* Mark Dirty
*/
markDirty(): void {
useBridge('BlockEntity.markDirty', this.javaObject);
}
}
/**
* {@link CustomBlock} With {@link CustomBlockEntity}
*/
@ -230,11 +291,11 @@ export class CustomBlockWithEntity extends CustomBlock {
* @internal
*/
export class BlockRegistry implements SimpleRegistry<CustomBlock> {
static INSTANCE = new BlockRegistry();
static readonly INSTANCE = new BlockRegistry();
#blocks: Map<string, CustomBlock>;
readonly #blocks: Map<string, CustomBlock>;
#blockEntities: CustomBlockEntity[];
readonly #blockEntities: CustomBlockEntity[];
private constructor() {
this.#blocks = new Map<string, CustomBlock>();
@ -302,9 +363,7 @@ addBridge('CustomBlockEntity.setLocation', (i: number, world: JavaObject, x: num
});
addBridge('CustomBlockEntity.free', (i: number) => {
console.log('Free: ' + i);
BlockRegistry.INSTANCE.freeCustomBlockEntity(i);
console.log('Free After: ' + BlockRegistry.INSTANCE.getCustomBlockEntity(i));
});
addBridge('CustomBlock.onUse', (id: string, world: JavaObject, state: JavaObject, x: number, y: number, z: number, side: keyof typeof Direction, player: JavaObject, hand: keyof typeof Hand): string => {

View File

@ -136,6 +136,7 @@ export class Identifier {
/**
* Convert To String
* @returns String
*/
toString(): string {
return this.#namespace + ':' + this.#path;
@ -249,6 +250,7 @@ export class Pos {
/**
* Convert To String
* @returns String
*/
toString(): string {
return 'Pos{' + this.getX() + ', ' + this.getY() + ', ' + this.getZ() + '}';

View File

@ -3,6 +3,7 @@ import { Hand, Identifier, Pos } from './core';
import { World } from './world';
import { CompoundTag } from './tag';
import { useBridge } from 'scriptcraft-core';
import { Inventory } from './inventory';
/**
* Damage Source
@ -70,7 +71,8 @@ export class Entity {
readonly javaObject: JavaObject;
/**
* @internal
* Cast Existing Entity To This Class (Use With Caution)
* @param object Existing Entity
*/
constructor(object: JavaObject | Entity) {
if (object instanceof Entity) {
@ -132,6 +134,7 @@ export class Entity {
/**
* Convert To String
* @returns String
*/
toString(): string {
return this.getName();
@ -249,4 +252,13 @@ export class LivingEntity extends Entity {
/**
* Player Entity
*/
export class PlayerEntity extends LivingEntity {}
export class PlayerEntity extends LivingEntity {
getInventory(): Inventory {
const obj = useBridge('PlayerEntity.getInventory', this.javaObject) as JavaObject;
if (obj !== null) {
return new Inventory(obj);
} else {
return null;
}
}
}

View File

@ -9,9 +9,10 @@
*/
export { Identifier, ActionResult, Hand, Pos, Direction, DirectionUtil } from './core';
export { CustomBlock, CustomBlockEntity, CustomBlockWithEntity, BlockSettings, BlockState } from './block';
export { CustomBlock, CustomBlockEntity, CustomBlockWithEntity, BlockSettings, BlockState, BlockEntity } from './block';
export { ItemStack, ItemSettings, CustomItem, BlockItem } from './item';
export { World } from './world';
export { LivingEntity, PlayerEntity } from './entity';
export { CompoundTag, ListTag, NumberType } from './tag';
export { Registry } from './registry';
export { Inventory } from './inventory';

View File

@ -142,6 +142,20 @@ export class ItemStack {
return null;
}
}
/**
* Split Item Stack
* @param amount Amount
* @returns New Item Stack
*/
split(amount: number): ItemStack {
const obj = useBridge('ItemStack.split', this.javaObject, amount) as JavaObject;
if (obj !== null) {
return new ItemStack(obj);
} else {
return null;
}
}
}
/**
@ -212,8 +226,12 @@ export class CustomItem {
/**
* @internal
*/
settings: ItemSettings;
readonly settings: ItemSettings;
/**
* Create Custom Item
* @param settings Item Settings
*/
constructor(settings: ItemSettings) {
this.settings = settings;
}
@ -261,11 +279,11 @@ export class BlockItem {
/**
* @internal
*/
settings: ItemSettings;
readonly settings: ItemSettings;
/**
* @internal
*/
block: Identifier;
readonly block: Identifier;
/**
* Create Block Item
@ -282,9 +300,9 @@ export class BlockItem {
* @internal
*/
export class ItemRegistry implements SimpleRegistry<CustomItem | BlockItem> {
static INSTANCE = new ItemRegistry();
static readonly INSTANCE = new ItemRegistry();
#items: Map<string, CustomItem>;
readonly #items: Map<string, CustomItem>;
private constructor() {
this.#items = new Map<string, CustomItem>();

View File

@ -2,9 +2,6 @@ import { useBridge } from 'scriptcraft-core';
type TagType = number | boolean | string | CompoundTag | ListTag;
/**
* @internal
*/
function getTagValue(obj: [boolean, BridgeValueType]): Exclude<TagType, boolean> {
if (typeof obj[1] === 'object') {
if (obj[0]) {
@ -12,10 +9,16 @@ function getTagValue(obj: [boolean, BridgeValueType]): Exclude<TagType, boolean>
} else {
return new CompoundTag(obj[1] as JavaObject);
}
} else if (obj[1]) {
return obj[1] as Exclude<TagType, boolean>;
} else {
return null;
return obj[1] as Exclude<TagType, boolean>;
}
}
function valueToString(obj: Exclude<TagType, boolean>): string {
if (typeof obj === 'string') {
return obj.__quote();
} else {
return String(obj);
}
}
@ -109,6 +112,27 @@ export class CompoundTag {
return null;
}
}
/**
* Convert To String
* @returns String
*/
toString(): string {
const keys = this.keys();
let out = '{';
let first = true;
for (const key of keys) {
if (!first) {
out = out + ', ';
} else {
first = false;
}
out = out + key + ': ' + valueToString(this.get(key));
}
return out + '}';
}
}
/**
@ -171,4 +195,25 @@ export class ListTag {
return null;
}
}
/**
* Convert To String
* @returns String
*/
toString(): string {
const size = this.size();
let out = '[';
let first = true;
for (let i = 0; i < size; i++) {
if (!first) {
out = out + ', ';
} else {
first = false;
}
out = out + valueToString(this.get(i));
}
return out + ']';
}
}

View File

@ -1,4 +1,4 @@
import { BlockState, CustomBlockEntity, BlockRegistry } from './block';
import { BlockState, CustomBlockEntity, BlockRegistry, BlockEntity } from './block';
import { Entity } from './entity';
import { Pos, Identifier } from './core';
import { useBridge } from 'scriptcraft-core';
@ -76,12 +76,16 @@ export class World {
* @param pos Position
* @returns Block Entity ID At Position
*/
getBlockEntity(pos: Pos): Identifier {
const obj = useBridge('World.getBlockEntity', this.javaObject, pos.getX(), pos.getY(), pos.getZ()) as string;
getBlockEntity(pos: Pos): BlockEntity {
const obj = useBridge('World.getBlockEntity', this.javaObject, pos.getX(), pos.getY(), pos.getZ()) as JavaObject;
if (obj !== null) {
return new Identifier(obj);
return new BlockEntity(obj);
} else {
return null;
}
}
isClient(): boolean {
return useBridge('World.isClient', this.javaObject) as boolean;
}
}

View File

@ -1,4 +1,4 @@
import { BlockSettings, Identifier, Registry, BlockState, ActionResult, World, Pos, Hand, PlayerEntity, BlockItem, ItemSettings, CustomItem, Direction, LivingEntity, CustomBlockWithEntity, CustomBlockEntity, CompoundTag, NumberType } from 'src/minecraft/index';
import { BlockSettings, Identifier, Registry, BlockState, ActionResult, World, Pos, Hand, PlayerEntity, BlockItem, ItemSettings, CustomItem, Direction, LivingEntity, CustomBlockWithEntity, CustomBlockEntity, CompoundTag, NumberType } from 'minecraft';
console.log('hello');
@ -64,7 +64,7 @@ class MyItem extends CustomItem {
}
onUseOnEntity(player: PlayerEntity, target: LivingEntity, hand: Hand): ActionResult {
console.log('Item Use: Entity ' + target.toTag().keys());
console.log('Item Use: Entity ' + target.toTag().toString());
console.log('Health: ' + target.toTag().get('Health').toString());
return ActionResult.SUCCESS;
}

View File

@ -19,6 +19,10 @@ interface Console {
declare const console: Console;
interface String {
__quote(): string;
}
declare module 'scriptcraft-core' {
function addBridge(name: string, bridge: BridgeType): void;

View File

@ -11,7 +11,7 @@
"rootDir": "src",
"baseUrl": "src",
"paths": {
"minecraft": ["src/minecraft/index"]
"minecraft": ["minecraft/index"]
}
},
"include": [