This repository has been archived on 2023-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
ScriptCraft/src/main/resources/scriptcraft/minecraft/block.ts

293 lines
7.7 KiB
TypeScript

import { World } from './world';
import { PlayerEntity } from './entity';
import { useBridge, addBridge, Identifier, Hand, Pos, ActionResult, Direction, SingleRegistry } from './core';
import { CompoundTag } from './tag';
/**
* 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 abstract class CustomBlock {
/**
* @internal
*/
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
*/
abstract onUse(world: World, blockState: BlockState, pos: Pos, side: Direction, player: PlayerEntity, hand: Hand): ActionResult;
}
/**
* 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;
}
}
}
/**
* Custom Block Entity
*/
export abstract 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) {
this.world = world;
this.pos = pos;
}
/**
* Save Data To Tag
* @param tag Tag
* @returns Tag
*/
abstract toTag(tag: CompoundTag): CompoundTag;
/**
* Load Data From Tag
* @param tag Tag
*/
abstract fromTag(tag: CompoundTag): void;
/**
* Runs Every Tick
*/
abstract tick(): void;
/**
* Get World
* @returns World
*/
getWorld(): World {
return this.world;
}
/**
* Get Position
* @returns Position
*/
getPos(): Pos {
return this.pos;
}
/**
* Mark Dirty
*/
markDirty() {
if (this.getWorld() != null) {
useBridge('World.markBlockEntityDirty', this.getWorld().javaObject, this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
}
}
}
/**
* {@link CustomBlock} With {@link CustomBlockEntity}
*/
export abstract class CustomBlockWithEntity extends CustomBlock {
/**
* Create Custom Block Entity
* @returns Custom Block Entity
*/
abstract createBlockEntity(): CustomBlockEntity;
}
/**
* @internal
*/
export class BlockRegistry implements SingleRegistry<CustomBlock> {
static INSTANCE = new BlockRegistry();
#blocks: Map<string, CustomBlock>;
#blockEntities: Map<string, CustomBlockEntity[]>;
private constructor() {
this.#blocks = new Map<string, CustomBlock>();
this.#blockEntities = new Map<string, CustomBlockEntity[]>();
}
register(id: Identifier, obj: CustomBlock) {
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());
}
getBlockEntity(id: Identifier, i: number): CustomBlockEntity {
return this.#blockEntities.get(id.toString())[i];
}
getBlockEntities(): CustomBlockEntity[] {
let out: CustomBlockEntity[] = [];
for (const key of this.#blockEntities.keys()) {
const list = this.#blockEntities.get(key);
out = out.concat(list);
}
return out;
}
createBlockEntity(id: Identifier, i: number) {
const block = this.get(id) as CustomBlockWithEntity;
if (!this.#blockEntities.get(id.toString())) {
this.#blockEntities.set(id.toString(), []);
}
this.#blockEntities.get(id.toString()).push(block.createBlockEntity());
}
freeBlockEntity(id: Identifier, i: number) {
delete this.#blockEntities.get(id.toString())[i];
}
}
addBridge('CustomBlockEntity.create', (id: string, i: number) => {
BlockRegistry.INSTANCE.createBlockEntity(new Identifier(id), i);
});
addBridge('CustomBlockEntity.fromTag', (id: string, i: number, tag: JavaObject) => {
BlockRegistry.INSTANCE.getBlockEntity(new Identifier(id), i).fromTag(new CompoundTag(tag));
});
addBridge('CustomBlockEntity.toTag', (id: string, i: number, tag: JavaObject): JavaObject => {
return BlockRegistry.INSTANCE.getBlockEntity(new Identifier(id), i).toTag(new CompoundTag(tag)).javaObject;
});
addBridge('CustomBlockEntity.tick', (id: string, i: number) => {
BlockRegistry.INSTANCE.getBlockEntity(new Identifier(id), i).tick();
});
addBridge('CustomBlockEntity.setLocation', (id: string, i: number, world: JavaObject, x: number, y: number, z: number) => {
BlockRegistry.INSTANCE.getBlockEntity(new Identifier(id), i).setLocation(new World(world), new Pos(x, y, z));
});
addBridge('CustomBlockEntity.free', (id: string, i: number) => {
BlockRegistry.INSTANCE.freeBlockEntity(new Identifier(id), 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]);
});