313 lines
7.8 KiB
TypeScript
313 lines
7.8 KiB
TypeScript
import { World } from './world';
|
|
import { PlayerEntity } from './entity';
|
|
import { Identifier, Hand, Pos, ActionResult, Direction, SimpleRegistry } from './core';
|
|
import { CompoundTag } from './tag';
|
|
import { useBridge, addBridge } from 'scriptcraft-core';
|
|
|
|
/**
|
|
* Settings for {@link CustomBlock}
|
|
*/
|
|
export class BlockSettings {
|
|
readonly #material: string;
|
|
readonly #materialColor: string;
|
|
|
|
#resistance: number;
|
|
#hardness: number;
|
|
|
|
/**
|
|
* Create Block Settings
|
|
* @param material Material
|
|
* @param materialColor Material Color
|
|
*/
|
|
constructor(material: string);
|
|
constructor(material: string, materialColor: string);
|
|
constructor(material: string, materialColor?: string) {
|
|
this.#material = material;
|
|
this.#materialColor = materialColor;
|
|
|
|
this.#resistance = 0;
|
|
this.#hardness = 0;
|
|
}
|
|
|
|
/**
|
|
* Set Block Strength
|
|
* @param hardness Hardness Value
|
|
* @param resistance Blast Resistance Value
|
|
*/
|
|
setStrength(hardness: number, resistance: number): BlockSettings {
|
|
this.#hardness = hardness;
|
|
this.#resistance = resistance;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set Hardness
|
|
* @param hardness Hardness Value
|
|
*/
|
|
setHardness(hardness: number): BlockSettings {
|
|
this.#hardness = hardness;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set Blast Resistance
|
|
* @param resistance Blast Resistance Value
|
|
*/
|
|
setResistance(resistance: number): BlockSettings {
|
|
this.#resistance = resistance;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
createJavaObject(): JavaObject {
|
|
return useBridge('BlockSettings.create', this.#material, this.#materialColor, this.#hardness, this.#resistance) as JavaObject;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Custom Block
|
|
*/
|
|
export class CustomBlock {
|
|
/**
|
|
* @internal
|
|
*/
|
|
readonly settings: BlockSettings;
|
|
|
|
constructor(settings: BlockSettings) {
|
|
this.settings = settings;
|
|
}
|
|
|
|
/**
|
|
* Called When The Block Is Used
|
|
* @param world World
|
|
* @param blockState Block State
|
|
* @param pos Block Position
|
|
* @param side Side Of The Block Used
|
|
* @param player Player
|
|
* @param hand Hand
|
|
* @returns Action Result
|
|
*/
|
|
onUse(world: World, blockState: BlockState, pos: Pos, side: Direction, player: PlayerEntity, hand: Hand): ActionResult {
|
|
return ActionResult.PASS;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Custom Block Entity
|
|
*/
|
|
export class CustomBlockEntity {
|
|
/**
|
|
* World
|
|
*/
|
|
protected world: World;
|
|
/**
|
|
* Position
|
|
*/
|
|
protected pos: Pos;
|
|
|
|
/**
|
|
* Set Location
|
|
* @param world New World
|
|
* @param pos New Position
|
|
*/
|
|
setLocation(world: World, pos: Pos): void {
|
|
this.world = world;
|
|
this.pos = pos;
|
|
}
|
|
|
|
/**
|
|
* Save Data To Tag
|
|
* @param tag Tag
|
|
* @returns Tag
|
|
*/
|
|
toTag(tag: CompoundTag): CompoundTag {
|
|
return tag;
|
|
}
|
|
|
|
/**
|
|
* Load Data From Tag
|
|
* @param tag Tag
|
|
*/
|
|
fromTag(tag: CompoundTag): void {}
|
|
|
|
/**
|
|
* Runs Every Tick
|
|
*/
|
|
tick(): void {}
|
|
|
|
/**
|
|
* Get World
|
|
* @returns World
|
|
*/
|
|
getWorld(): World {
|
|
return this.world;
|
|
}
|
|
|
|
/**
|
|
* Get Position
|
|
* @returns Position
|
|
*/
|
|
getPos(): Pos {
|
|
return this.pos;
|
|
}
|
|
|
|
/**
|
|
* Mark Dirty
|
|
*/
|
|
markDirty(): void {
|
|
if (this.getWorld() !== null) {
|
|
useBridge('World.markBlockEntityDirty', this.getWorld().javaObject, this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Block State
|
|
*/
|
|
export class BlockState {
|
|
/**
|
|
* @internal
|
|
*/
|
|
readonly javaObject: JavaObject;
|
|
|
|
constructor(javaObject: JavaObject) {
|
|
this.javaObject = javaObject;
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* @returns Block ID
|
|
*/
|
|
getBlock(): Identifier {
|
|
const obj = useBridge('BlockState.getBlock', this.javaObject) as string;
|
|
if (obj) {
|
|
return new Identifier(obj);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get Custom Block
|
|
* @returns Custom Block
|
|
*/
|
|
getCustomBlock(): CustomBlock {
|
|
const id = this.getBlock();
|
|
return BlockRegistry.INSTANCE.get(id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* {@link CustomBlock} With {@link CustomBlockEntity}
|
|
*/
|
|
export class CustomBlockWithEntity extends CustomBlock {
|
|
/**
|
|
* Create Custom Block Entity
|
|
* @returns Custom Block Entity
|
|
*/
|
|
createBlockEntity(): CustomBlockEntity {
|
|
throw new Error('CustomBlockWithEntity.createBlockEntity is not implemented');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
export class BlockRegistry implements SimpleRegistry<CustomBlock> {
|
|
static INSTANCE = new BlockRegistry();
|
|
|
|
#blocks: Map<string, CustomBlock>;
|
|
|
|
#blockEntities: CustomBlockEntity[];
|
|
|
|
private constructor() {
|
|
this.#blocks = new Map<string, CustomBlock>();
|
|
this.#blockEntities = [];
|
|
}
|
|
|
|
register(id: Identifier, obj: CustomBlock): void {
|
|
this.#blocks.set(id.toString(), obj);
|
|
if (obj instanceof CustomBlockWithEntity) {
|
|
useBridge('Registry.registerBlockWithEntity', id.toString(), obj.settings.createJavaObject());
|
|
} else {
|
|
useBridge('Registry.registerBlock', id.toString(), obj.settings.createJavaObject());
|
|
}
|
|
}
|
|
|
|
get(id: Identifier): CustomBlock {
|
|
return this.#blocks.get(id.toString());
|
|
}
|
|
|
|
getID(obj: CustomBlock): Identifier {
|
|
for (const block of this.#blocks) {
|
|
if (block[1] === obj) {
|
|
return new Identifier(block[0]);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getCustomBlockEntity(i: number): CustomBlockEntity {
|
|
return this.#blockEntities[i];
|
|
}
|
|
|
|
getCustomBlockEntities(): CustomBlockEntity[] {
|
|
return this.#blockEntities;
|
|
}
|
|
|
|
createCustomBlockEntity(id: Identifier, i: number): void {
|
|
const block = this.get(id) as CustomBlockWithEntity;
|
|
this.#blockEntities[i] = block.createBlockEntity();
|
|
}
|
|
|
|
freeCustomBlockEntity(i: number): void {
|
|
delete this.#blockEntities[i];
|
|
}
|
|
}
|
|
|
|
addBridge('CustomBlockEntity.create', (id: string, i: number) => {
|
|
BlockRegistry.INSTANCE.createCustomBlockEntity(new Identifier(id), i);
|
|
});
|
|
|
|
addBridge('CustomBlockEntity.fromTag', (i: number, tag: JavaObject) => {
|
|
BlockRegistry.INSTANCE.getCustomBlockEntity(i).fromTag(new CompoundTag(tag));
|
|
});
|
|
|
|
addBridge('CustomBlockEntity.toTag', (i: number, tag: JavaObject): JavaObject => {
|
|
return BlockRegistry.INSTANCE.getCustomBlockEntity(i).toTag(new CompoundTag(tag)).javaObject;
|
|
});
|
|
|
|
addBridge('CustomBlockEntity.tick', (i: number) => {
|
|
BlockRegistry.INSTANCE.getCustomBlockEntity(i).tick();
|
|
});
|
|
|
|
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));
|
|
});
|
|
|
|
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 => {
|
|
return BlockRegistry.INSTANCE.get(new Identifier(id)).onUse(new World(world), new BlockState(state), new Pos(x, y, z), Direction[side], new PlayerEntity(player), Hand[hand]);
|
|
});
|