├── .classpath ├── .gitignore ├── .project ├── LICENSE ├── README.md ├── declarations ├── android-declarations.d.ts ├── android.d.ts ├── core-engine.d.ts └── lib │ ├── LiquidLib.d.ts │ ├── StorageInterface.d.ts │ ├── energy-net.d.ts │ └── numbers.d.ts ├── make.json ├── src ├── assets │ ├── assets │ │ ├── items-opaque │ │ │ ├── bc_wrench_0.png │ │ │ ├── engine_creative_0.png │ │ │ ├── engine_electric_0.png │ │ │ ├── engine_iron_0.png │ │ │ ├── engine_stone_0.png │ │ │ ├── engine_wooden_0.png │ │ │ ├── gear_diamond_0.png │ │ │ ├── gear_gold_0.png │ │ │ ├── gear_iron_0.png │ │ │ ├── gear_stone_0.png │ │ │ ├── gear_tin_0.png │ │ │ ├── gear_wood_0.png │ │ │ └── pipe_sealant_0.png │ │ ├── model │ │ │ ├── buildcraft_engine_atlas.png │ │ │ ├── buildcraft_lava_atlas.png │ │ │ ├── buildcraft_milk_atlas.png │ │ │ └── buildcraft_water_atlas.png │ │ └── terrain-atlas │ │ │ ├── bc_drill_0.png │ │ │ ├── bc_drill_1.png │ │ │ ├── bc_machine_0.png │ │ │ ├── bc_pump_0.png │ │ │ ├── bc_pump_1.png │ │ │ ├── empty_0.png │ │ │ ├── engine │ │ │ ├── chamber_0.png │ │ │ ├── creative │ │ │ │ ├── engine_creative_0.png │ │ │ │ ├── engine_creative_1.png │ │ │ │ └── engine_creative_2.png │ │ │ ├── engine_trunk_0.png │ │ │ ├── engine_trunk_1.png │ │ │ └── wood │ │ │ │ ├── engine_wood_0.png │ │ │ │ ├── engine_wood_1.png │ │ │ │ └── engine_wood_2.png │ │ │ ├── my_liquid_0.png │ │ │ ├── pipe_fluid_cobble_0.png │ │ │ ├── pipe_fluid_cobble_1.png │ │ │ ├── pipe_fluid_emerald_0.png │ │ │ ├── pipe_fluid_emerald_1.png │ │ │ ├── pipe_fluid_gold_0.png │ │ │ ├── pipe_fluid_gold_1.png │ │ │ ├── pipe_fluid_iron_0.png │ │ │ ├── pipe_fluid_iron_1.png │ │ │ ├── pipe_fluid_sandstone_0.png │ │ │ ├── pipe_fluid_sandstone_1.png │ │ │ ├── pipe_fluid_stone_0.png │ │ │ ├── pipe_fluid_stone_1.png │ │ │ ├── pipe_fluid_wood_0.png │ │ │ ├── pipe_fluid_wood_1.png │ │ │ ├── pipe_item_cobble_0.png │ │ │ ├── pipe_item_cobble_1.png │ │ │ ├── pipe_item_diamond_0.png │ │ │ ├── pipe_item_diamond_1.png │ │ │ ├── pipe_item_diamond_2.png │ │ │ ├── pipe_item_diamond_3.png │ │ │ ├── pipe_item_diamond_4.png │ │ │ ├── pipe_item_diamond_5.png │ │ │ ├── pipe_item_diamond_6.png │ │ │ ├── pipe_item_emerald_0.png │ │ │ ├── pipe_item_emerald_1.png │ │ │ ├── pipe_item_emerald_2.png │ │ │ ├── pipe_item_gold_0.png │ │ │ ├── pipe_item_gold_1.png │ │ │ ├── pipe_item_gold_2.png │ │ │ ├── pipe_item_gold_3.png │ │ │ ├── pipe_item_iron_0.png │ │ │ ├── pipe_item_iron_1.png │ │ │ ├── pipe_item_iron_2.png │ │ │ ├── pipe_item_obsidian_0.png │ │ │ ├── pipe_item_obsidian_1.png │ │ │ ├── pipe_item_quartz_0.png │ │ │ ├── pipe_item_quartz_1.png │ │ │ ├── pipe_item_sandstone_0.png │ │ │ ├── pipe_item_sandstone_1.png │ │ │ ├── pipe_item_stone_0.png │ │ │ ├── pipe_item_stone_1.png │ │ │ ├── pipe_item_void_0.png │ │ │ ├── pipe_item_void_1.png │ │ │ ├── pipe_item_wood_0.png │ │ │ ├── pipe_item_wood_1.png │ │ │ ├── pipe_item_wood_2.png │ │ │ ├── tank_0.png │ │ │ └── tank_1.png │ ├── gui │ │ ├── button_36x12_down.png │ │ ├── button_36x12_up.png │ │ ├── diamond_pipe_slot_black.png │ │ ├── diamond_pipe_slot_blue.png │ │ ├── diamond_pipe_slot_green.png │ │ ├── diamond_pipe_slot_red.png │ │ ├── diamond_pipe_slot_white.png │ │ ├── diamond_pipe_slot_yellow.png │ │ ├── electric_scale.png │ │ ├── electric_scale_background.png │ │ ├── emerald_blacklist.png │ │ ├── emerald_button_active.png │ │ ├── emerald_button_inactive.png │ │ ├── emerald_order.png │ │ ├── emerald_whitelist.png │ │ ├── fire_background.png │ │ ├── fire_scale.png │ │ ├── liquid_scale_40x8_background.png │ │ ├── liquid_scale_40x8_empty.png │ │ └── liquid_scale_40x8_overlay.png │ └── root │ │ ├── config.json │ │ └── mod_icon.png ├── dev │ ├── .includes │ ├── Header.ts │ ├── core │ │ ├── ClientFactory.ts │ │ ├── energy.ts │ │ ├── engine │ │ │ ├── EngineHeat.ts │ │ │ ├── EngineTextures.ts │ │ │ ├── PowerMode.ts │ │ │ ├── abstract │ │ │ │ ├── BCEngine.ts │ │ │ │ └── BCEngineTileEntity.ts │ │ │ ├── components │ │ │ │ ├── EngineAnimation.ts │ │ │ │ ├── EngineBlock.ts │ │ │ │ ├── EngineItem.ts │ │ │ │ ├── animation │ │ │ │ │ ├── AnimationComponent.ts │ │ │ │ │ ├── BaseAnimation.ts │ │ │ │ │ └── PistonAnimation.ts │ │ │ │ ├── model │ │ │ │ │ ├── EngineItemModel.ts │ │ │ │ │ ├── EngineItemModelTexture.ts │ │ │ │ │ ├── IEnginePartModel.ts │ │ │ │ │ ├── ModelBox.ts │ │ │ │ │ └── parts │ │ │ │ │ │ ├── EngineBaseModelPart.ts │ │ │ │ │ │ ├── EngineChamberModelPart.ts │ │ │ │ │ │ ├── EnginePistonModelPart.ts │ │ │ │ │ │ └── EngineTrunkModelPart.ts │ │ │ │ └── recipe │ │ │ │ │ ├── EngineIngredients.ts │ │ │ │ │ └── EngineRecipe.ts │ │ │ ├── creative │ │ │ │ ├── CreativeEngine.ts │ │ │ │ ├── CreativeEngineRecipe.ts │ │ │ │ └── CreativeEngineTileEntity.ts │ │ │ ├── interface │ │ │ │ ├── IEngine.ts │ │ │ │ └── IHeatable.ts │ │ │ ├── model │ │ │ │ ├── EngineRotation.ts │ │ │ │ ├── render │ │ │ │ │ ├── BaseRender.ts │ │ │ │ │ ├── EngineRender.ts │ │ │ │ │ ├── PistonRender.ts │ │ │ │ │ └── RenderManager.ts │ │ │ │ └── texture │ │ │ │ │ ├── EngineTexture.ts │ │ │ │ │ └── ITexture.ts │ │ │ └── wood │ │ │ │ ├── WoodEngine.ts │ │ │ │ └── WoodEngineTileEntity.ts │ │ ├── importLib.ts │ │ └── pipe │ │ │ ├── PipeSpeed.ts │ │ │ ├── abstract │ │ │ ├── BCPipe.ts │ │ │ └── PipeConnector.ts │ │ │ ├── components │ │ │ ├── PipeBlock.ts │ │ │ ├── PipeDoubleRecipe.ts │ │ │ ├── PipeIdMap.ts │ │ │ ├── PipeRecipe.ts │ │ │ ├── PipeRenderer.ts │ │ │ └── PipeTexture.ts │ │ │ └── item │ │ │ ├── ItemMachines.ts │ │ │ ├── abstract │ │ │ ├── BCTransportPipe.ts │ │ │ └── TransportPipeConnector.ts │ │ │ ├── cobble │ │ │ ├── CobblePipeConnector.ts │ │ │ └── PipeCobble.ts │ │ │ ├── diamond │ │ │ ├── DiamondPipeGUI.ts │ │ │ ├── DiamondPipeRenderer.ts │ │ │ ├── DiamondPipeTileEntity.ts │ │ │ └── PipeDiamond.ts │ │ │ ├── gold │ │ │ └── PipeGold.ts │ │ │ ├── iron │ │ │ ├── IronPipeClient.ts │ │ │ ├── IronPipeRenderConnector.ts │ │ │ ├── IronPipeTileEntity.ts │ │ │ └── PipeIron.ts │ │ │ ├── obsidian │ │ │ ├── AxisBoxes.ts │ │ │ ├── ObsidianPipeConnector.ts │ │ │ ├── ObsidianPipeItemAccelerator.ts │ │ │ ├── ObsidianPipeItemEjector.ts │ │ │ ├── ObsidianPipeTargetConnector.ts │ │ │ ├── ObsidianPipeTileEntity.ts │ │ │ └── PipeObsidian.ts │ │ │ ├── quartz │ │ │ ├── PipeQuartz.ts │ │ │ └── QuartzPipeConnector.ts │ │ │ ├── sandstone │ │ │ ├── PipeSandstone.ts │ │ │ └── SandstonePipeConnector.ts │ │ │ ├── stone │ │ │ ├── PipeStone.ts │ │ │ └── StonePipeConnector.ts │ │ │ ├── travelingItem │ │ │ ├── TravelingItem.ts │ │ │ ├── TravelingItemAnimation.ts │ │ │ ├── TravelingItemMoveData.ts │ │ │ ├── TravelingItemMover.ts │ │ │ └── TravelingItemNetworkEntity.ts │ │ │ ├── void │ │ │ ├── PipeVoid.ts │ │ │ └── VoidPipeTileEntity.ts │ │ │ └── wooden │ │ │ ├── PipeWooden.ts │ │ │ ├── WoodenPipeClient.ts │ │ │ ├── WoodenPipeConnector.ts │ │ │ ├── WoodenPipeItemEjector.ts │ │ │ ├── WoodenPipeStorageConnector.ts │ │ │ └── WoodenPipeTileEntity.ts │ ├── item │ │ ├── gears.ts │ │ └── wrench.ts │ ├── misc │ │ └── Translations.ts │ └── tsconfig.json ├── launcher.js └── lib │ ├── StorageInterface.js │ └── energy-net.js └── tslint.json /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.bat 2 | *.zip 3 | *.rar 4 | *.icmod 5 | 6 | .vscode/* 7 | *.code-workspace 8 | 9 | # Local History for Visual Studio Code 10 | .history/ 11 | 12 | toolchain/* 13 | output 14 | **/__pycache__ 15 | test.ts 16 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | java 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | 19 | 1600006817591 20 | 21 | 30 22 | 23 | org.eclipse.core.resources.regexFilterMatcher 24 | node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BuildCraft 2 | BuildCraft PE mod by Nikolay Savenko 3 | 4 | ## Environment setup: 5 | 1. Clone [toolchain](https://github.com/zheka2304/innercore-mod-toolchain) repo 6 | 2. Delete src folder and make.json from toolchain-mod folder 7 | 3. Put src folder, make.json and tslint.json from BuildCraft repo to toolchain-mod folder 8 | 4. Configure make.json (pushTo) 9 | 5. Configure ADB path if you have problems with connections. 10 | 6. Configure declarations(toolchain/tslibs) if you have problems with build. 11 | 12 | ## Build mod 13 | 1. Connect to phone using ADB if you need push. 14 | 2. Choose some build task from build menu(ctrl+shift+B) 15 | -------------------------------------------------------------------------------- /declarations/android-declarations.d.ts: -------------------------------------------------------------------------------- 1 | declare module native { export class Array { constructor(); length: number; [index: number]: T; } } 2 | 3 | import globalAndroid = android; 4 | 5 | -------------------------------------------------------------------------------- /declarations/lib/LiquidLib.d.ts: -------------------------------------------------------------------------------- 1 | declare var BLOCK_TYPE_LIQUID: any; 2 | declare var LiquidLib: { 3 | liquids: {}; 4 | registerLiquid: (liquidId: any, texture: any, fluidity: any) => void; 5 | }; 6 | declare function buildFlowMesh(texture: any, direction: any, from: any, to: any): any; 7 | declare function getRotationMatrix(direction: any): number[][]; 8 | declare var SIDES: number[][]; 9 | declare var LiquidUpdater: { 10 | blocks: any[]; 11 | updates: any[]; 12 | update: (x: any, y: any, z: any) => void; 13 | tick: () => void; 14 | }; 15 | -------------------------------------------------------------------------------- /declarations/lib/StorageInterface.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare type Container = NativeTileEntity | UI.Container | ItemContainer; 3 | interface StorageDescriptor { 4 | slots?: { 5 | [key: string]: SlotData; 6 | }; 7 | liquidUnitRatio?: number; 8 | isValidInput?(item: ItemInstance, side: number, tileEntity: TileEntity): boolean; 9 | addItem?(item: ItemInstance, side?: number, maxCount?: number): number; 10 | getInputSlots?(side?: number): string[] | number[]; 11 | getOutputSlots?(side?: number): string[] | number[]; 12 | canReceiveLiquid?(liquid: string, side: number): boolean; 13 | canTransportLiquid?(liquid: string, side: number): boolean; 14 | receiveLiquid?(liquidStorage: ILiquidStorage, liquid: string, amount: number): number; 15 | extractLiquid?(liquidStorage: ILiquidStorage, liquid: string, amount: number): number; 16 | getInputTank?(side: number): ILiquidStorage; 17 | getOutputTank?(side: number): ILiquidStorage; 18 | } 19 | interface Storage extends StorageDescriptor { 20 | container: Container; 21 | isNativeContainer: boolean; 22 | getSlot(name: string | number): ItemInstance; 23 | setSlot(name: string | number, id: number, count: number, data: number, extra?: ItemExtraData): void; 24 | getContainerSlots(): string[] | number[]; 25 | getInputSlots(side?: number): string[] | number[]; 26 | getOutputSlots(side?: number): string[] | number[]; 27 | getReceivingItemCount(item: ItemInstance, side?: number): number; 28 | addItemToSlot(name: string | number, item: ItemInstance, maxCount?: number): number; 29 | addItem(item: ItemInstance, side?: number, maxCount?: number): number; 30 | clearContainer(): void; 31 | } 32 | interface SlotData { 33 | input?: boolean; 34 | output?: boolean; 35 | side?: number | "horizontal" | "verctical" | "down" | "up"; 36 | maxStack?: number; 37 | isValid?(item: ItemInstance, side: number, tileEntity: TileEntity): boolean; 38 | canOutput?(item: ItemInstance, side: number, tileEntity: TileEntity): boolean; 39 | } 40 | interface ILiquidStorage { 41 | getLiquidStored(): string; 42 | getLimit(liquid: string): number; 43 | getAmount(liquid: string): number; 44 | getLiquid(liquid: string, amount: number): number; 45 | addLiquid(liquid: string, amount: number): number; 46 | isFull(): boolean; 47 | isEmpty(): boolean; 48 | } 49 | declare class NativeContainerInterface implements Storage { 50 | readonly container: NativeTileEntity; 51 | readonly isNativeContainer = true; 52 | constructor(container: NativeTileEntity); 53 | getSlot(index: number): ItemInstance; 54 | setSlot(index: number, id: number, count: number, data: number, extra?: ItemExtraData): void; 55 | getContainerSlots(): any[]; 56 | getInputSlots(side: number): number[]; 57 | getReceivingItemCount(item: ItemInstance, side: number): number; 58 | addItemToSlot(index: number, item: ItemInstance, maxCount?: number): number; 59 | addItem(item: ItemInstance, side: number, maxCount?: number): number; 60 | getOutputSlots(): number[]; 61 | clearContainer(): void; 62 | } 63 | declare class TileEntityInterface implements Storage { 64 | readonly liquidUnitRatio: number; 65 | readonly slots?: { 66 | [key: string]: SlotData; 67 | }; 68 | readonly container: UI.Container | ItemContainer; 69 | readonly tileEntity: TileEntity; 70 | readonly isNativeContainer = false; 71 | constructor(tileEntity: TileEntity); 72 | getSlot(name: string): ItemInstance; 73 | setSlot(name: string, id: number, count: number, data: number, extra?: ItemExtraData): void; 74 | getSlotData(name: string): SlotData; 75 | getSlotMaxStack(name: string): number; 76 | private isValidSlotSide; 77 | private isValidSlotInput; 78 | getContainerSlots(): string[]; 79 | private getDefaultSlots; 80 | getInputSlots(side?: number): string[]; 81 | getReceivingItemCount(item: ItemInstance, side?: number): number; 82 | isValidInput(item: ItemInstance, side: number, tileEntity: TileEntity): boolean; 83 | addItemToSlot(name: string, item: ItemInstance, maxCount?: number): number; 84 | addItem(item: ItemInstance, side?: number, maxCount?: number): number; 85 | getOutputSlots(side?: number): string[]; 86 | clearContainer(): void; 87 | canReceiveLiquid(liquid: string, side: number): boolean; 88 | canTransportLiquid(liquid: string, side: number): boolean; 89 | receiveLiquid(liquidStorage: ILiquidStorage, liquid: string, amount: number): number; 90 | extractLiquid(liquidStorage: ILiquidStorage, liquid: string, amount: number): number; 91 | getInputTank(side: number): ILiquidStorage; 92 | getOutputTank(side: number): ILiquidStorage; 93 | } 94 | declare namespace StorageInterface { 95 | type ContainersMap = { 96 | [key: number]: Container; 97 | }; 98 | type StoragesMap = { 99 | [key: number]: Storage; 100 | }; 101 | export var data: { 102 | [key: number]: StorageDescriptor; 103 | }; 104 | export function getData(id: number): StorageDescriptor; 105 | export var directionsBySide: { 106 | x: number; 107 | y: number; 108 | z: number; 109 | }[]; 110 | export function getRelativeCoords(coords: Vector, side: number): Vector; 111 | export function setSlotMaxStackPolicy(container: ItemContainer, slotName: string, maxCount: number): void; 112 | export function setSlotValidatePolicy(container: ItemContainer, slotName: string, func: (name: string, id: number, amount: number, data: number, extra: ItemExtraData, container: ItemContainer, playerUid: number) => boolean): void; 113 | export function setGlobalValidatePolicy(container: ItemContainer, func: (name: string, id: number, amount: number, data: number, extra: ItemExtraData, container: ItemContainer, playerUid: number) => boolean): void; 114 | /** Creates new interface instance for TileEntity or Container */ 115 | export function getInterface(storage: TileEntity | Container): Storage; 116 | /** Registers interface for block container */ 117 | export function createInterface(id: number, descriptor: StorageDescriptor): void; 118 | /** Trasfers item to slot 119 | * @count amount to transfer. Default is 64. 120 | * @returns transfered amount 121 | */ 122 | export function addItemToSlot(item: ItemInstance, slot: ItemInstance, count?: number): number; 123 | /** Returns storage interface for container in the world */ 124 | export function getStorage(region: BlockSource, x: number, y: number, z: number): Nullable; 125 | /** Returns storage interface for TileEntity with liquid storage */ 126 | export function getLiquidStorage(region: BlockSource, x: number, y: number, z: number): Nullable; 127 | /** Returns storage interface for neighbour container on specified side */ 128 | export function getNeighbourStorage(region: BlockSource, coords: Vector, side: number): Nullable; 129 | /** Returns storage interface for neighbour TileEntity with liquid storage on specified side */ 130 | export function getNeighbourLiquidStorage(region: BlockSource, coords: Vector, side: number): Nullable; 131 | /** 132 | * Returns object containing neigbour containers where keys are block side numbers 133 | * @coords position from which check neighbour blocks 134 | */ 135 | export function getNearestContainers(coords: Vector, region: BlockSource): ContainersMap; 136 | /** 137 | * Returns object containing neigbour liquid storages where keys are block side numbers 138 | * @coords position from which check neighbour blocks 139 | */ 140 | export function getNearestLiquidStorages(coords: Vector, region: BlockSource): StoragesMap; 141 | /** 142 | * Returns array of slot indexes for vanilla container or array of slot names for mod container 143 | */ 144 | export function getContainerSlots(container: Container): string[] | number[]; 145 | /** Puts items to containers */ 146 | export function putItems(items: ItemInstance[], containers: ContainersMap): void; 147 | /** 148 | * @side block side of container which receives item 149 | * @maxCount max count of item to transfer (optional) 150 | */ 151 | export function putItemToContainer(item: ItemInstance, container: TileEntity | Container, side?: number, maxCount?: number): number; 152 | /** 153 | * Extracts items from one container to another 154 | * @inputContainer container to receive items 155 | * @outputContainer container to extract items 156 | * @inputSide block side of input container which is receiving items 157 | * @maxCount max total count of extracted items (optional) 158 | * @oneStack if true, will extract only 1 item 159 | */ 160 | export function extractItemsFromContainer(inputContainer: TileEntity | Container, outputContainer: TileEntity | Container, inputSide: number, maxCount?: number, oneStack?: boolean): number; 161 | /** 162 | * Extracts items from one container to another 163 | * @inputStorage container interface to receive items 164 | * @outputStorage container interface to extract items 165 | * @inputSide block side of input container which is receiving items 166 | * @maxCount max total count of extracted items (optional) 167 | * @oneStack if true, will extract only 1 item 168 | */ 169 | export function extractItemsFromStorage(inputStorage: Storage, outputStorage: Storage, inputSide: number, maxCount?: number, oneStack?: boolean): number; 170 | /** 171 | * Extract liquid from one storage to another 172 | * @liquid liquid to extract. If null, will extract liquid stored in output storage 173 | * @maxAmount max amount of liquid that can be transfered 174 | * @inputStorage storage to input liquid 175 | * @outputStorage storage to extract liquid 176 | * @inputSide block side of input storage which is receiving 177 | * @returns left liquid amount 178 | */ 179 | export function extractLiquid(liquid: Nullable, maxAmount: number, inputStorage: TileEntity | Storage, outputStorage: Storage, inputSide: number): number; 180 | /** Similar to StorageInterface.extractLiquid, but liquid must be specified */ 181 | export function transportLiquid(liquid: string, maxAmount: number, outputStorage: TileEntity | Storage, inputStorage: Storage, outputSide: number): number; 182 | /** 183 | * Every 8 ticks checks neigbour hoppers and transfers items. 184 | * Use it in tick function of TileEntity 185 | */ 186 | export function checkHoppers(tile: TileEntity): void; 187 | export {}; 188 | } 189 | -------------------------------------------------------------------------------- /declarations/lib/energy-net.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare namespace EnergyTypeRegistry { 4 | type WireData = { 5 | type: EnergyType; 6 | value: number; 7 | class: typeof EnergyGrid; 8 | }; 9 | let energyTypes: {}; 10 | let wireData: {}; 11 | /** 12 | * name - name of this energy type, 13 | * value - value of one unit in [Eu] (IC2 Energy) 14 | */ 15 | function createEnergyType(name: string, value: number): EnergyType; 16 | function assureEnergyType(name: string, value: number): EnergyType; 17 | function getEnergyType(name: string): EnergyType; 18 | function getValueRatio(name1: string, name2: string): number; 19 | function getWireData(blockID: number): WireData; 20 | function registerWire(blockID: number, type: EnergyType, maxValue: number, energyGridClass?: typeof EnergyGrid): void; 21 | function isWire(blockID: number, type?: string): boolean; 22 | } 23 | declare class EnergyType { 24 | name: string; 25 | value: number; 26 | constructor(name: string, value?: number); 27 | registerWire(id: number, maxValue: number, energyGridClass?: typeof EnergyGrid): void; 28 | } 29 | declare class EnergyPacket { 30 | energyName: string; 31 | size: number; 32 | source: EnergyNode; 33 | passedNodes: object; 34 | constructor(energyName: string, size: number, source: EnergyNode); 35 | validateNode(nodeId: number): boolean; 36 | } 37 | declare let GLOBAL_NODE_ID: number; 38 | declare class EnergyNode { 39 | id: number; 40 | baseEnergy: string; 41 | energyTypes: object; 42 | dimension: number; 43 | maxValue: number; 44 | initialized: boolean; 45 | removed: boolean; 46 | blocksMap: object; 47 | entries: EnergyNode[]; 48 | receivers: EnergyNode[]; 49 | energyIn: number; 50 | currentIn: number; 51 | energyOut: number; 52 | currentOut: number; 53 | energyPower: number; 54 | currentPower: number; 55 | constructor(energyType: EnergyType, dimension: number); 56 | addEnergyType(energyType: EnergyType): void; 57 | addCoords(x: number, y: number, z: number): void; 58 | removeCoords(x: number, y: number, z: number): void; 59 | private addEntry; 60 | private removeEntry; 61 | /** 62 | * @param node receiver node 63 | * @returns true if link to the node was added, false if it already exists 64 | */ 65 | private addReceiver; 66 | /** 67 | * @param node receiver node 68 | * @returns true if link to the node was removed, false if it already removed 69 | */ 70 | private removeReceiver; 71 | /** 72 | * Adds output connection to specified node 73 | * @param node receiver node 74 | */ 75 | addConnection(node: EnergyNode): void; 76 | /** 77 | * Removes output connection to specified node 78 | * @param node receiver node 79 | */ 80 | removeConnection(node: EnergyNode): void; 81 | resetConnections(): void; 82 | receiveEnergy(amount: number, packet: EnergyPacket): number; 83 | add(amount: number, power?: number): number; 84 | addPacket(energyName: string, amount: number, size: number): number; 85 | transferEnergy(amount: number, packet: EnergyPacket): number; 86 | /** @deprecated */ 87 | addAll(amount: number, power?: number): void; 88 | onOverload(packetSize: number): void; 89 | isConductor(type: string): boolean; 90 | canReceiveEnergy(side: number, type: string): boolean; 91 | canExtractEnergy(side: number, type: string): boolean; 92 | canConductEnergy(coord1: Vector, coord2: Vector, side: number): boolean; 93 | isCompatible(node: EnergyNode): boolean; 94 | init(): void; 95 | tick(): void; 96 | destroy(): void; 97 | toString(): string; 98 | } 99 | declare class EnergyGrid extends EnergyNode { 100 | blockID: number; 101 | region: BlockSource; 102 | constructor(energyType: EnergyType, maxValue: number, wireID: number, region: BlockSource); 103 | isCompatible(node: EnergyNode): boolean; 104 | mergeGrid(grid: EnergyNode): EnergyNode; 105 | rebuildRecursive(x: number, y: number, z: number, side?: number): void; 106 | rebuildFor6Sides(x: number, y: number, z: number): void; 107 | } 108 | declare class EnergyTileNode extends EnergyNode { 109 | tileEntity: EnergyTile; 110 | constructor(energyType: EnergyType, parent: EnergyTile); 111 | getParent(): EnergyTile; 112 | receiveEnergy(amount: number, packet: EnergyPacket): number; 113 | isConductor(type: string): boolean; 114 | canReceiveEnergy(side: number, type: string): boolean; 115 | canExtractEnergy(side: number, type: string): boolean; 116 | init(): void; 117 | tick(): void; 118 | } 119 | interface EnergyTile extends TileEntity { 120 | isEnergyTile: boolean; 121 | energyTypes: {}; 122 | energyNode: EnergyTileNode; 123 | energyTick(type: string, node: EnergyTileNode): void; 124 | energyReceive(type: string, amount: number, voltage: number): number; 125 | isConductor(type: string): boolean; 126 | canReceiveEnergy(side: number, type: string): boolean; 127 | canExtractEnergy(side: number, type: string): boolean; 128 | } 129 | declare namespace EnergyTileRegistry { 130 | function addEnergyType(Prototype: EnergyTile, energyType: EnergyType): void; 131 | function addEnergyTypeForId(id: number, energyType: EnergyType): void; 132 | function setupAsEnergyTile(Prototype: EnergyTile): void; 133 | let machineIDs: {}; 134 | function isMachine(id: number): boolean; 135 | } 136 | declare namespace EnergyGridBuilder { 137 | function connectNodes(node1: EnergyNode, node2: EnergyNode): void; 138 | function buildGridForTile(te: EnergyTile): void; 139 | function buildWireGrid(region: BlockSource, x: number, y: number, z: number): EnergyGrid; 140 | function rebuildWireGrid(region: BlockSource, x: number, y: number, z: number): void; 141 | function rebuildForWire(region: BlockSource, x: number, y: number, z: number, wireID: number): EnergyGrid; 142 | function onWirePlaced(region: BlockSource, x: number, y: number, z: number): void; 143 | function onWireDestroyed(region: BlockSource, x: number, y: number, z: number, id: number): void; 144 | } 145 | declare namespace EnergyNet { 146 | function getNodesByDimension(dimension: number): EnergyNode[]; 147 | function addEnergyNode(node: EnergyNode): void; 148 | function removeEnergyNode(node: EnergyNode): void; 149 | function getNodeOnCoords(region: BlockSource, x: number, y: number, z: number): EnergyNode; 150 | } 151 | -------------------------------------------------------------------------------- /declarations/lib/numbers.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * numbers.js 3 | * http://github.com/sjkaliski/numbers.js 4 | * 5 | * Copyright 2012 Stephen Kaliski 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | declare var numbers: {}; 20 | /** 21 | * basic.js 22 | * http://github.com/sjkaliski/numbers.js 23 | * 24 | * Copyright 2012 Stephen Kaliski 25 | * 26 | * Licensed under the Apache License, Version 2.0 (the "License"); 27 | * you may not use this file except in compliance with the License. 28 | * You may obtain a copy of the License at 29 | * 30 | * http://www.apache.org/licenses/LICENSE-2.0 31 | * 32 | * Unless required by applicable law or agreed to in writing, software 33 | * distributed under the License is distributed on an "AS IS" BASIS, 34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35 | * See the License for the specific language governing permissions and 36 | * limitations under the License. 37 | */ 38 | declare var basic: {}; 39 | /** 40 | * calculus.js 41 | * http://github.com/sjkaliski/numbers.js 42 | * 43 | * Copyright 2012 Stephen Kaliski 44 | * 45 | * Licensed under the Apache License, Version 2.0 (the "License"); 46 | * you may not use this file except in compliance with the License. 47 | * You may obtain a copy of the License at 48 | * 49 | * http://www.apache.org/licenses/LICENSE-2.0 50 | * 51 | * Unless required by applicable law or agreed to in writing, software 52 | * distributed under the License is distributed on an "AS IS" BASIS, 53 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 54 | * See the License for the specific language governing permissions and 55 | * limitations under the License. 56 | */ 57 | declare var calculus: {}; 58 | /** 59 | * Helper function in calculating integral of a function 60 | * from a to b using simpson quadrature. 61 | * 62 | * @param {Function} math function to be evaluated. 63 | * @param {Number} point to initiate evaluation. 64 | * @param {Number} point to complete evaluation. 65 | * @return {Number} evaluation. 66 | */ 67 | declare function SimpsonDef(func: any, a: any, b: any): number; 68 | /** 69 | * Helper function in calculating integral of a function 70 | * from a to b using simpson quadrature. Manages recursive 71 | * investigation, handling evaluations within an error bound. 72 | * 73 | * @param {Function} math function to be evaluated. 74 | * @param {Number} point to initiate evaluation. 75 | * @param {Number} point to complete evaluation. 76 | * @param {Number} total value. 77 | * @param {Number} Error bound (epsilon). 78 | * @return {Number} recursive evaluation of left and right side. 79 | */ 80 | declare function SimpsonRecursive(func: any, a: any, b: any, whole: any, eps: any): any; 81 | /** 82 | * complex.js 83 | * http://github.com/sjkaliski/numbers.js 84 | * 85 | * Copyright 2012 Stephen Kaliski 86 | * 87 | * Licensed under the Apache License, Version 2.0 (the "License"); 88 | * you may not use this file except in compliance with the License. 89 | * You may obtain a copy of the License at 90 | * 91 | * http://www.apache.org/licenses/LICENSE-2.0 92 | * 93 | * Unless required by applicable law or agreed to in writing, software 94 | * distributed under the License is distributed on an "AS IS" BASIS, 95 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 96 | * See the License for the specific language governing permissions and 97 | * limitations under the License. 98 | */ 99 | declare var Complex: (re: any, im: any) => void; 100 | /** 101 | * dsp.js 102 | * http://github.com/sjkaliski/numbers.js 103 | * 104 | * Copyright 2012 Stephen Kaliski 105 | * 106 | * Licensed under the Apache License, Version 2.0 (the "License"); 107 | * you may not use this file except in compliance with the License. 108 | * You may obtain a copy of the License at 109 | * 110 | * http://www.apache.org/licenses/LICENSE-2.0 111 | * 112 | * Unless required by applicable law or agreed to in writing, software 113 | * distributed under the License is distributed on an "AS IS" BASIS, 114 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 115 | * See the License for the specific language governing permissions and 116 | * limitations under the License. 117 | */ 118 | declare var dsp: {}; 119 | /** 120 | * generators.js 121 | * http://github.com/sjkaliski/numbers.js 122 | * 123 | * Copyright 2012 Stephen Kaliski, Kartik Talwar 124 | * 125 | * Licensed under the Apache License, Version 2.0 (the "License"); 126 | * you may not use this file except in compliance with the License. 127 | * You may obtain a copy of the License at 128 | * 129 | * http://www.apache.org/licenses/LICENSE-2.0 130 | * 131 | * Unless required by applicable law or agreed to in writing, software 132 | * distributed under the License is distributed on an "AS IS" BASIS, 133 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134 | * See the License for the specific language governing permissions and 135 | * limitations under the License. 136 | */ 137 | declare var generate: {}; 138 | /** 139 | * matrix.js 140 | * http://github.com/sjkaliski/numbers.js 141 | * 142 | * Copyright 2012 Stephen Kaliski 143 | * 144 | * Licensed under the Apache License, Version 2.0 (the "License"); 145 | * you may not use this file except in compliance with the License. 146 | * You may obtain a copy of the License at 147 | * 148 | * http://www.apache.org/licenses/LICENSE-2.0 149 | * 150 | * Unless required by applicable law or agreed to in writing, software 151 | * distributed under the License is distributed on an "AS IS" BASIS, 152 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 153 | * See the License for the specific language governing permissions and 154 | * limitations under the License. 155 | */ 156 | declare var matrix: {}; 157 | declare var ERROR_MATRIX_NOT_SQUARE: string, ERROR_VECTOR_NOT_2D: string; 158 | /** 159 | * Add all of the elements in an array together except for the i'th one. 160 | * This is a helper function for determining diagonal dominance, and it 161 | * should be noted that each element is passed to Math.abs() beforehand. 162 | * 163 | * @param {Array} array 164 | * @param {Int} index of element to ignore. 165 | * @return {Number} sum. 166 | */ 167 | declare var sumNondiagonalElements: (arr: any, i: any) => number; 168 | /** 169 | * prime.js 170 | * http://github.com/sjkaliski/numbers.js 171 | * 172 | * Copyright 2012 Stephen Kaliski 173 | * 174 | * Licensed under the Apache License, Version 2.0 (the "License"); 175 | * you may not use this file except in compliance with the License. 176 | * You may obtain a copy of the License at 177 | * 178 | * http://www.apache.org/licenses/LICENSE-2.0 179 | * 180 | * Unless required by applicable law or agreed to in writing, software 181 | * distributed under the License is distributed on an "AS IS" BASIS, 182 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 183 | * See the License for the specific language governing permissions and 184 | * limitations under the License. 185 | */ 186 | declare var prime: {}; 187 | declare var random: {}; 188 | declare var rGen: () => number; 189 | /** 190 | * statistic.js 191 | * http://github.com/sjkaliski/numbers.js 192 | * 193 | * Copyright 2012 Stephen Kaliski 194 | * 195 | * Licensed under the Apache License, Version 2.0 (the "License"); 196 | * you may not use this file except in compliance with the License. 197 | * You may obtain a copy of the License at 198 | * 199 | * http://www.apache.org/licenses/LICENSE-2.0 200 | * 201 | * Unless required by applicable law or agreed to in writing, software 202 | * distributed under the License is distributed on an "AS IS" BASIS, 203 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 204 | * See the License for the specific language governing permissions and 205 | * limitations under the License. 206 | */ 207 | declare var statistic: {}; 208 | -------------------------------------------------------------------------------- /make.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "info": { 4 | "name": "BuildCraft PE", 5 | "author": "Nikolay Savenko", 6 | "version": "1.0.3", 7 | "description": "Port of PC version of BuildCraft" 8 | }, 9 | "api": "CoreEngine" 10 | }, 11 | "make": { 12 | "debugAbi": "armeabi-v7a", 13 | "abis": [ 14 | "armeabi-v7a", 15 | "x86" 16 | ], 17 | "linkNative": [ 18 | "minecraftpe", 19 | "innercore", 20 | "nativejs" 21 | ], 22 | "excludeFromRelease": [], 23 | "pushTo": "storage/emulated/0/games/horizon/packs/innercore-dev/innercore/mods/BuildCraft", 24 | "ndkPath": null 25 | }, 26 | "resources": [ 27 | { 28 | "path": "src/assets/resource_packs/*", 29 | "type": "minecraft_resource_pack" 30 | }, 31 | { 32 | "path": "src/assets/behavior_packs/*", 33 | "type": "minecraft_behavior_pack" 34 | }, 35 | { 36 | "path": "src/assets/assets", 37 | "type": "resource_directory" 38 | }, 39 | { 40 | "path": "src/assets/gui", 41 | "type": "gui" 42 | } 43 | ], 44 | "sources": [ 45 | { 46 | "source": "src/lib/*", 47 | "type": "library", 48 | "language": "javascript" 49 | }, 50 | { 51 | "source": "src/preloader/*", 52 | "type": "preloader", 53 | "language": "javascript" 54 | }, 55 | { 56 | "source": "src/dev", 57 | "target": "main.js", 58 | "type": "main", 59 | "language": "typescript" 60 | }, 61 | { 62 | "type": "launcher", 63 | "language": "javascript", 64 | "source": "src/launcher.js" 65 | } 66 | ], 67 | "compile": [ 68 | { 69 | "source": "src/native/*", 70 | "type": "native" 71 | }, 72 | { 73 | "source": "src/java/*", 74 | "type": "java" 75 | } 76 | ], 77 | "additional": [ 78 | { 79 | "source": "src/assets/root/*", 80 | "targetDir": "." 81 | } 82 | ] 83 | } -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/bc_wrench_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/bc_wrench_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/engine_creative_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/engine_creative_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/engine_electric_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/engine_electric_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/engine_iron_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/engine_iron_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/engine_stone_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/engine_stone_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/engine_wooden_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/engine_wooden_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/gear_diamond_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/gear_diamond_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/gear_gold_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/gear_gold_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/gear_iron_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/gear_iron_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/gear_stone_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/gear_stone_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/gear_tin_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/gear_tin_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/gear_wood_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/gear_wood_0.png -------------------------------------------------------------------------------- /src/assets/assets/items-opaque/pipe_sealant_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/items-opaque/pipe_sealant_0.png -------------------------------------------------------------------------------- /src/assets/assets/model/buildcraft_engine_atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/model/buildcraft_engine_atlas.png -------------------------------------------------------------------------------- /src/assets/assets/model/buildcraft_lava_atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/model/buildcraft_lava_atlas.png -------------------------------------------------------------------------------- /src/assets/assets/model/buildcraft_milk_atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/model/buildcraft_milk_atlas.png -------------------------------------------------------------------------------- /src/assets/assets/model/buildcraft_water_atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/model/buildcraft_water_atlas.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/bc_drill_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/bc_drill_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/bc_drill_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/bc_drill_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/bc_machine_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/bc_machine_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/bc_pump_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/bc_pump_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/bc_pump_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/bc_pump_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/empty_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/empty_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/engine/chamber_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/engine/chamber_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/engine/creative/engine_creative_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/engine/creative/engine_creative_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/engine/creative/engine_creative_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/engine/creative/engine_creative_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/engine/creative/engine_creative_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/engine/creative/engine_creative_2.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/engine/engine_trunk_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/engine/engine_trunk_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/engine/engine_trunk_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/engine/engine_trunk_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/engine/wood/engine_wood_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/engine/wood/engine_wood_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/engine/wood/engine_wood_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/engine/wood/engine_wood_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/engine/wood/engine_wood_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/engine/wood/engine_wood_2.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/my_liquid_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/my_liquid_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_cobble_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_cobble_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_cobble_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_cobble_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_emerald_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_emerald_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_emerald_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_emerald_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_gold_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_gold_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_gold_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_gold_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_iron_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_iron_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_iron_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_iron_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_sandstone_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_sandstone_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_sandstone_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_sandstone_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_stone_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_stone_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_stone_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_stone_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_wood_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_wood_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_fluid_wood_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_fluid_wood_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_cobble_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_cobble_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_cobble_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_cobble_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_diamond_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_diamond_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_diamond_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_diamond_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_diamond_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_diamond_2.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_diamond_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_diamond_3.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_diamond_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_diamond_4.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_diamond_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_diamond_5.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_diamond_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_diamond_6.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_emerald_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_emerald_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_emerald_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_emerald_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_emerald_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_emerald_2.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_gold_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_gold_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_gold_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_gold_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_gold_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_gold_2.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_gold_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_gold_3.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_iron_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_iron_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_iron_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_iron_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_iron_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_iron_2.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_obsidian_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_obsidian_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_obsidian_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_obsidian_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_quartz_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_quartz_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_quartz_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_quartz_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_sandstone_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_sandstone_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_sandstone_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_sandstone_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_stone_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_stone_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_stone_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_stone_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_void_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_void_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_void_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_void_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_wood_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_wood_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_wood_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_wood_1.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/pipe_item_wood_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/pipe_item_wood_2.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/tank_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/tank_0.png -------------------------------------------------------------------------------- /src/assets/assets/terrain-atlas/tank_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/assets/terrain-atlas/tank_1.png -------------------------------------------------------------------------------- /src/assets/gui/button_36x12_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/button_36x12_down.png -------------------------------------------------------------------------------- /src/assets/gui/button_36x12_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/button_36x12_up.png -------------------------------------------------------------------------------- /src/assets/gui/diamond_pipe_slot_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/diamond_pipe_slot_black.png -------------------------------------------------------------------------------- /src/assets/gui/diamond_pipe_slot_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/diamond_pipe_slot_blue.png -------------------------------------------------------------------------------- /src/assets/gui/diamond_pipe_slot_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/diamond_pipe_slot_green.png -------------------------------------------------------------------------------- /src/assets/gui/diamond_pipe_slot_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/diamond_pipe_slot_red.png -------------------------------------------------------------------------------- /src/assets/gui/diamond_pipe_slot_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/diamond_pipe_slot_white.png -------------------------------------------------------------------------------- /src/assets/gui/diamond_pipe_slot_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/diamond_pipe_slot_yellow.png -------------------------------------------------------------------------------- /src/assets/gui/electric_scale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/electric_scale.png -------------------------------------------------------------------------------- /src/assets/gui/electric_scale_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/electric_scale_background.png -------------------------------------------------------------------------------- /src/assets/gui/emerald_blacklist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/emerald_blacklist.png -------------------------------------------------------------------------------- /src/assets/gui/emerald_button_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/emerald_button_active.png -------------------------------------------------------------------------------- /src/assets/gui/emerald_button_inactive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/emerald_button_inactive.png -------------------------------------------------------------------------------- /src/assets/gui/emerald_order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/emerald_order.png -------------------------------------------------------------------------------- /src/assets/gui/emerald_whitelist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/emerald_whitelist.png -------------------------------------------------------------------------------- /src/assets/gui/fire_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/fire_background.png -------------------------------------------------------------------------------- /src/assets/gui/fire_scale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/fire_scale.png -------------------------------------------------------------------------------- /src/assets/gui/liquid_scale_40x8_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/liquid_scale_40x8_background.png -------------------------------------------------------------------------------- /src/assets/gui/liquid_scale_40x8_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/liquid_scale_40x8_empty.png -------------------------------------------------------------------------------- /src/assets/gui/liquid_scale_40x8_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/gui/liquid_scale_40x8_overlay.png -------------------------------------------------------------------------------- /src/assets/root/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": true, 3 | "animation_movement_interpolation": false, 4 | "travelingItem_offset_distance": 0, 5 | "obsidian_pipe_drop_velocity": 1.2, 6 | "item_drop_velocity": 0.25, 7 | "relative_max_ping": 100 8 | } -------------------------------------------------------------------------------- /src/assets/root/mod_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mineprogramming/BuildCraft/2ecc9a295cd4a5833b58a0358432497ab10c7d86/src/assets/root/mod_icon.png -------------------------------------------------------------------------------- /src/dev/.includes: -------------------------------------------------------------------------------- 1 | # autogenerated includes 2 | 3 | # allowJs 4 | # experimentalDecorators 5 | # plugins 6 | 7 | **/* 8 | -------------------------------------------------------------------------------- /src/dev/Header.ts: -------------------------------------------------------------------------------- 1 | ItemModel.setCurrentCacheGroup("buildcraft", FileTools.ReadJSON(__dir__ + "mod.info").version); -------------------------------------------------------------------------------- /src/dev/core/ClientFactory.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * I use "private type" instead generic because we cant 3 | * correctly translate generic to ES5 4 | */ 5 | class ClientFactory { 6 | constructor(private type) {} 7 | public instantiate(...args) { 8 | return new this.type(...args); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/dev/core/energy.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const RF = EnergyTypeRegistry.assureEnergyType("RF", .25); -------------------------------------------------------------------------------- /src/dev/core/engine/EngineHeat.ts: -------------------------------------------------------------------------------- 1 | enum EngineHeat { 2 | BLUE = "BLUE", 3 | GREEN = "GREEN", 4 | ORANGE = "ORANGE", 5 | RED = "RED", 6 | OVERHEAT = "OVERHEAT", 7 | BLACK = "BLACK" 8 | } 9 | 10 | const HeatOrder = [ 11 | EngineHeat.BLUE, 12 | EngineHeat.GREEN, 13 | EngineHeat.ORANGE, 14 | EngineHeat.RED, 15 | EngineHeat.BLACK 16 | ]; -------------------------------------------------------------------------------- /src/dev/core/engine/EngineTextures.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class EngineTextures { 3 | static wood = new EngineTexture("engine_wood", STANDART_TEXTURE, { x: 256, y: 0 }, STANDART_SIZE); 4 | static creative = new EngineTexture("engine_creative", STANDART_TEXTURE, { x: 256, y: 96 }, STANDART_SIZE); 5 | } -------------------------------------------------------------------------------- /src/dev/core/engine/PowerMode.ts: -------------------------------------------------------------------------------- 1 | enum PowerMode { 2 | M2 = 20, 3 | M4 = 40, 4 | M8 = 80, 5 | M16 = 160, 6 | M32 = 320, 7 | M64 = 640, 8 | M128 = 1280, 9 | M256 = 2560 10 | }; 11 | 12 | const PowerModeOrder = [ 13 | PowerMode.M2, 14 | PowerMode.M4, 15 | PowerMode.M8, 16 | PowerMode.M16, 17 | PowerMode.M32, 18 | PowerMode.M64, 19 | PowerMode.M128, 20 | PowerMode.M256 21 | ]; -------------------------------------------------------------------------------- /src/dev/core/engine/abstract/BCEngine.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | /// 8 | abstract class BCEngine { 9 | protected block: EngineBlock; 10 | 11 | protected engineItemModel: EngineItemModel; 12 | 13 | protected recipe: EngineRecipe; 14 | 15 | public get engineType(): string { 16 | return null 17 | } 18 | 19 | protected abstract requireTileEntity(): object 20 | 21 | constructor() { 22 | this.block = new EngineBlock(this.engineType); 23 | this.engineItemModel = new EngineItemModel(this.texture); 24 | this.recipe = this.getRecipe(this.getIngredientsForRecipe()); 25 | this.recipe.registerFor({ id: this.block.id, count: 1, data: 1 }); 26 | Block.setupAsRedstoneReceiver(this.block.stringId, true); 27 | TileEntity.registerPrototype(this.block.id, this.requireTileEntity()); 28 | EnergyTileRegistry.addEnergyTypeForId(this.block.id, RF); 29 | this.registerHandModel(); 30 | this.registerDrop(); 31 | this.registerNeighbourChangeFunction(); 32 | } 33 | 34 | protected get texture(): EngineTexture { 35 | return null; 36 | } 37 | 38 | /** 39 | * it a method because we need this in constructor 40 | */ 41 | protected getRecipe(ingredients: EngineIngredients): EngineRecipe { 42 | return new EngineRecipe(ingredients); 43 | } 44 | 45 | /** 46 | * it a method because we need this in constructor 47 | */ 48 | protected abstract getIngredientsForRecipe(): EngineIngredients 49 | 50 | private registerHandModel(): void { 51 | ItemModel.getFor(this.block.id, 1).setModel(this.engineItemModel.Model); 52 | } 53 | 54 | private registerNeighbourChangeFunction(): void { 55 | Block.registerNeighbourChangeFunctionForID(this.block.id, (coords, block, changeCoords, region: BlockSource) => { 56 | const tile = World.getTileEntity(coords.x, coords.y, coords.z, region); 57 | if (tile) tile.checkOrientation = true; 58 | }); 59 | } 60 | 61 | private registerDrop(): void { 62 | Block.registerDropFunction(this.block.stringId, () => { 63 | return [[this.block.id, 1, 1]] 64 | }); 65 | } 66 | } -------------------------------------------------------------------------------- /src/dev/core/engine/abstract/BCEngineTileEntity.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /** 6 | * !WARNING 7 | * this code adapted from JAVA source of PC mod 8 | * this structure created not by me 9 | * dont punch me pls 10 | */ 11 | abstract class BCEngineTileEntity implements TileEntity.TileEntityPrototype, IHeatable, IEngine { 12 | public readonly MIN_HEAT: number = 20; 13 | public readonly IDEAL_HEAT: number = 100; 14 | public readonly MAX_HEAT: number = 250; 15 | 16 | public currentOutput: number = 0; 17 | public isRedstonePowered: boolean = false; 18 | public energyStage = EngineHeat.BLUE; 19 | 20 | protected progressPart: number = 0; 21 | 22 | protected isPumping: boolean = false; // Used for SMP synch // ?WTF is SMP 23 | public checkOrientation: boolean = false; 24 | // How many ticks ago it gave out power, capped to 4. 25 | private lastTick: number = 0; 26 | 27 | constructor(protected texture: EngineTexture) { } 28 | protected data: any = {// * it will be rewriten during runtime 29 | meta: null, // * this.orientation in PC version 30 | energy: 0, // * this.energy in PC version 31 | heat: this.MIN_HEAT, // * this.heat in PC version 32 | progress: 0 33 | } 34 | public defaultValues: any = { 35 | meta: null, // * this.orientation in PC version //? maybe we can use it instead of save value? 36 | energy: 0, // * this.energy in PC version 37 | heat: this.MIN_HEAT, // * this.heat in PC version 38 | progress: 0 39 | } 40 | 41 | public x: number; 42 | public y: number; 43 | public z: number; 44 | 45 | public blockSource: BlockSource; 46 | public networkData: SyncedNetworkData; 47 | 48 | public readonly isEngine: boolean = true; 49 | 50 | public engineAnimation: EngineAnimation = null; 51 | 52 | /* 53 | ! I use old get set methods because Core Engine has special errors in runtime 54 | ! during I use new get set methods 55 | */ 56 | 57 | public getOrientation(): number { 58 | return this.blockSource?.getBlockData(this.x, this.y, this.z); 59 | } 60 | 61 | public setOrientation(value: number) { 62 | if (typeof (value) == "number") { 63 | const { x, y, z } = this; 64 | this.blockSource.setBlock(x, y, z, this.blockSource.getBlockId(x, y, z), value); 65 | this.updateClientOrientation(); 66 | } 67 | } 68 | 69 | private updateClientOrientation() { 70 | this.networkData.putInt("orientation", this.blockSource.getBlockData(this.x, this.y, this.z)); 71 | this.networkData.sendChanges(); 72 | } 73 | 74 | private setProgress(value: number) { 75 | this.data.progress = value; 76 | this.networkData.putFloat("progress", value); 77 | } 78 | 79 | private getProgress(): number { 80 | return this.data.progress; 81 | } 82 | 83 | private setProgressPart(value: number) { 84 | this.progressPart = value; 85 | } 86 | 87 | private getProgressPart(): number { 88 | return this.progressPart; 89 | } 90 | 91 | private setEnergyStage(value: EngineHeat) { 92 | this.energyStage = value; 93 | this.networkData.putInt("energyStageIndex", HeatOrder.indexOf(this.energyStage)); 94 | this.networkData.sendChanges(); 95 | } 96 | 97 | public getPumping(): boolean { 98 | return this.isPumping; 99 | } 100 | 101 | public setPumping(value: boolean) { 102 | if (this.isPumping == value) return; 103 | this.isPumping = value; 104 | this.lastTick = 0; 105 | this.networkData.putBoolean("isPumping", value); 106 | this.networkData.sendChanges(); 107 | } 108 | 109 | public client = { 110 | orientation: null, 111 | energyStage: null, 112 | isPumping: false, 113 | progress: 0, 114 | progressPart: 0, 115 | 116 | engineAnimation: null, 117 | 118 | // !TileEntity event 119 | load() { 120 | this.orientation = this.networkData.getInt("orientation"); 121 | this.energyStage = HeatOrder[this.networkData.getInt("energyStageIndex")]; 122 | this.isPumping = this.networkData.getBoolean("isPumping"); 123 | this.progress = this.networkData.getFloat("progress"); 124 | 125 | this.engineAnimation = new EngineAnimation(this, this.getTrunkTexture(this.energyStage, this.progress), this.getEngineTexture()); 126 | this.engineAnimation.ConnectionSide = this.orientation; 127 | this.networkData.addOnDataChangedListener((networkData, isExternalChange) => { 128 | this.orientation = networkData.getInt("orientation"); 129 | this.energyStage = HeatOrder[networkData.getInt("energyStageIndex")]; 130 | this.isPumping = this.networkData.getBoolean("isPumping"); 131 | this.engineAnimation.ConnectionSide = this.orientation; 132 | }); 133 | }, 134 | 135 | // !TileEntity event 136 | unload() { 137 | this.engineAnimation.destroy(); 138 | }, 139 | 140 | // !TileEntity event 141 | tick() { 142 | if (!this.engineAnimation) return; 143 | if (this.progressPart != 0) { 144 | this.progress += this.getPistonSpeed(this.energyStage); 145 | if (this.progress > 1) { 146 | this.progressPart = 0; 147 | this.progress = 0; 148 | } 149 | } 150 | else if (this.isPumping) { 151 | this.progressPart = 1; 152 | } 153 | this.engineAnimation.update(this.progress, this.getTrunkTexture(this.energyStage, this.progress)); 154 | }, 155 | 156 | // ? please override in derived class 157 | getEngineTexture(stage: EngineHeat) { 158 | return null; 159 | }, 160 | 161 | getTrunkTexture(stage: EngineHeat, progress: number): EngineHeat { 162 | return stage; 163 | }, 164 | 165 | getPistonSpeed(energyStage: EngineHeat): number { 166 | switch (energyStage) { 167 | case EngineHeat.BLUE: 168 | return 0.02; 169 | case EngineHeat.GREEN: 170 | return 0.04; 171 | case EngineHeat.ORANGE: 172 | return 0.08; 173 | case EngineHeat.RED: 174 | return 0.16; 175 | default: 176 | return 0; 177 | } 178 | } 179 | } 180 | 181 | // !TileEntity event 182 | public init() { 183 | this.checkOrientation = true; 184 | } 185 | 186 | // !TileEntity event 187 | public redstone(params) { 188 | this.isRedstonePowered = params.signal > 0; 189 | } 190 | 191 | // !TileEntity event 192 | public tick() { 193 | if (this.checkOrientation) this.updateConnectionSide(); 194 | if (this.lastTick < 4) this.lastTick++; 195 | 196 | this.updateHeat(); 197 | this.getEnergyStage(); 198 | 199 | if (this.getEnergyStage() === EngineHeat.OVERHEAT) { 200 | this.data.energy = Math.max(this.data.energy - 50, 0); 201 | return; 202 | } 203 | 204 | this.engineUpdate(); 205 | 206 | const tile = this.getEnergyProvider(this.getOrientation()); 207 | 208 | if (this.getProgressPart() != 0) { 209 | this.setProgress(this.getProgress() + this.getPistonSpeed()); 210 | if (this.getProgress() > 0.5 && this.getProgressPart() == 1) { 211 | this.setProgressPart(2); 212 | } else if (this.getProgress() >= 1) { 213 | this.setProgress(0); 214 | this.setProgressPart(0); 215 | } 216 | } else if (this.isRedstonePowered && this.isActive()) { 217 | if (this.isPoweredTile(tile, this.getOrientation())) { 218 | this.setProgressPart(1); 219 | this.setPumping(true); 220 | if (this.getPowerToExtract() > 0) { 221 | this.setProgressPart(1); 222 | this.setPumping(true); 223 | } else { 224 | this.setPumping(false); 225 | } 226 | } else { 227 | this.setPumping(false); 228 | } 229 | } else { 230 | this.setPumping(false); 231 | } 232 | 233 | this.burn(); 234 | 235 | if (!this.isRedstonePowered) { 236 | this.currentOutput = 0; 237 | } else if (this.isRedstonePowered && this.isActive()) { 238 | this.sendPower(); 239 | } 240 | } 241 | 242 | public click(id, count, data) { 243 | if (id != ItemID.bc_wrench) return false; 244 | if (this.getEnergyStage() == EngineHeat.OVERHEAT) { 245 | this.setEnergyStage(this.computeEnergyStage()); 246 | } 247 | this.setOrientation(this.getConnectionSide(true)); 248 | return true; 249 | } 250 | 251 | public isActive(): boolean { // ? why we need it? Ask PC author... I dont know 252 | return true; 253 | } 254 | 255 | // ! @MineExplorer PLEASE make EnergyTileRegistry BlockSource support 256 | // TODO move to blockSource getConnectionSide 257 | /** @param findNext - use true value if you want to rerotate engine like a wrench */ 258 | protected getConnectionSide(findNext: boolean = false) { 259 | // * In common situation ends when i gets max in 5 index 260 | // * But if fhis function calling by wrench index can go beyound 261 | // * I think this code is poor, but maybe i fix it in future 262 | const orientation = this.getOrientation(); 263 | for (let t = 0; t < 12; t++) { 264 | const i = t % 6; 265 | if (findNext) { 266 | if (orientation == t) findNext = false; 267 | continue; 268 | } 269 | const { x, y, z } = World.getRelativeCoords(this.x, this.y, this.z, i); 270 | // * ?. is new ESNext feature. Its amazing! 271 | let node = EnergyNet.getNodeOnCoords(this.blockSource, x, y, z); 272 | let thisNode = EnergyNet.getNodeOnCoords(this.blockSource, this.x, this.y, this.z); 273 | if (node && thisNode.isCompatible(node)) { 274 | return i; 275 | } 276 | } 277 | return null; 278 | } 279 | 280 | public updateConnectionSide(): void { 281 | this.checkOrientation = false; 282 | const orientation = this.getOrientation(); 283 | if (!this.isPoweredTile(this.getEnergyProvider(orientation), orientation)) { 284 | const side = this.getConnectionSide(); 285 | if (typeof (side) == "number") { 286 | this.setOrientation(side); 287 | } else this.updateClientOrientation(); 288 | } else this.updateClientOrientation(); 289 | } 290 | 291 | // ! @MineExplorer PLEASE make EnergyTileRegistry BlockSource support 292 | // TODO move to blockSource getEnergyProvider 293 | public getEnergyProvider(orientation: number): any { 294 | const { x, y, z } = World.getRelativeCoords(this.x, this.y, this.z, orientation); 295 | return World.getTileEntity(x, y, z, this.blockSource); 296 | } 297 | 298 | protected sendPower(): void { 299 | const tile = this.getEnergyProvider(this.getOrientation()); 300 | if (this.isPoweredTile(tile, this.getOrientation())) { 301 | const extracted = this.getPowerToExtract(); 302 | if (extracted <= 0) { 303 | this.setPumping(false); 304 | return; 305 | } 306 | 307 | this.setPumping(true); 308 | const oppositeSide = World.getInverseBlockSide(this.getOrientation()); 309 | 310 | if (tile.isEngine) { 311 | const neededRF = tile.receiveEnergyFromEngine(oppositeSide, extracted, false); 312 | this.extractEnergy(neededRF, true); 313 | } else if (tile.canReceiveEnergy(oppositeSide, "RF")) { 314 | const neededRF = tile.energyReceive("RF", extracted, this.data.energy); 315 | this.extractEnergy(neededRF, true); 316 | } 317 | } 318 | } 319 | 320 | private getPowerToExtract(): number { 321 | const tile = this.getEnergyProvider(this.getOrientation()); 322 | if (!tile) return 0; 323 | 324 | const oppositeSide = World.getInverseBlockSide(this.getOrientation()); 325 | 326 | const canExtract = Math.min(this.getCurrentOutputLimit(), this.data.energy); 327 | 328 | if (tile.isEngine) { 329 | const maxEnergy = tile.receiveEnergyFromEngine(oppositeSide, canExtract, true); 330 | return this.extractEnergy(maxEnergy, false); 331 | } else if (tile.canReceiveEnergy(oppositeSide, "RF")) { 332 | const maxEnergy = Math.min(this.getCurrentOutputLimit(), tile.getMaxEnergyStored() - tile.data.energy); 333 | return this.extractEnergy(maxEnergy, false); 334 | } 335 | return 0; 336 | } 337 | 338 | public isPoweredTile(tile: any, side: number): boolean { 339 | if (!tile) return false; 340 | const oppositeSide = World.getInverseBlockSide(this.getOrientation()); 341 | 342 | if (tile.isEngine) { 343 | return tile.canReceiveFromEngine(oppositeSide); 344 | } else if (tile.canReceiveEnergy(oppositeSide, "RF")) { 345 | // return ((IEnergyConnection) tile).canConnectEnergy(side.getOpposite()); // ? is next line correct 346 | return tile.canReceiveEnergy(oppositeSide, "RF"); 347 | } 348 | return false; 349 | } 350 | 351 | public getPistonSpeed(): number { 352 | return Math.max(0.16 * this.getHeatLevel(), 0.01); 353 | } 354 | 355 | public getEnergyStage(): EngineHeat { 356 | if (this.energyStage == EngineHeat.OVERHEAT) return this.energyStage; 357 | 358 | const newStage = this.computeEnergyStage(); 359 | if (this.energyStage !== newStage) { 360 | this.setEnergyStage(newStage); 361 | if (newStage == EngineHeat.OVERHEAT) this.overheat(); 362 | } 363 | return this.energyStage; 364 | } 365 | 366 | public addEnergy(addition: number): void { 367 | if (this.getEnergyStage() == EngineHeat.OVERHEAT) return; 368 | 369 | this.data.energy += addition; 370 | if (this.data.energy > this.getMaxEnergy()) { 371 | this.data.energy = this.getMaxEnergy(); 372 | } 373 | } 374 | 375 | protected computeEnergyStage(): EngineHeat { 376 | const energyLevel = this.getHeatLevel(); 377 | if (energyLevel < 0.25) { 378 | return EngineHeat.BLUE; 379 | } else if (energyLevel < 0.5) { 380 | return EngineHeat.GREEN; 381 | } else if (energyLevel < 0.75) { 382 | return EngineHeat.ORANGE; 383 | } else if (energyLevel < 1) { 384 | return EngineHeat.RED; 385 | } 386 | return EngineHeat.OVERHEAT; 387 | } 388 | 389 | public getEnergyStored(): number { 390 | return this.data.energy; 391 | } 392 | 393 | public getMaxEnergyStored(): number { 394 | return this.getMaxEnergy(); 395 | } 396 | 397 | public canConnectEnergy(from: number): boolean { 398 | return from == this.getOrientation(); 399 | } 400 | 401 | public getEnergyLevel(): number { 402 | return this.data.energy / this.getMaxEnergy(); 403 | } 404 | 405 | public extractEnergy(energyMax: number, doExtract: boolean): number { 406 | const max = Math.min(energyMax, this.getCurrentOutputLimit()); 407 | 408 | let extracted; 409 | const energy = this.data.energy; 410 | 411 | if (energy >= max) { 412 | extracted = max; 413 | if (doExtract) { 414 | this.data.energy -= max; 415 | } 416 | } else { 417 | extracted = energy; 418 | if (doExtract) { 419 | this.data.energy = 0; 420 | } 421 | } 422 | 423 | return extracted; 424 | } 425 | 426 | public getCurrentOutputLimit(): number { 427 | return Number.MAX_VALUE; 428 | } 429 | 430 | protected engineUpdate(): void { 431 | if (!this.isRedstonePowered) { 432 | if (this.data.energy >= 10) { 433 | this.data.energy -= 10; 434 | } else if (this.data.energy < 10) { 435 | this.data.energy = 0; 436 | } 437 | } 438 | } 439 | 440 | public getHeatLevel(): number { 441 | return (this.data.heat - this.MIN_HEAT) / (this.MAX_HEAT - this.MIN_HEAT); 442 | } 443 | 444 | public updateHeat(): void { 445 | this.data.heat = ((this.MAX_HEAT - this.MIN_HEAT) * this.getEnergyLevel()) + this.MIN_HEAT; 446 | } 447 | 448 | public overheat(): void { 449 | this.isPumping = false; 450 | this.blockSource.explode(this.x, this.y, this.z, 3, true); 451 | } 452 | 453 | // ? why we need it? ask PC author about it. Maybe it should be overrided in future 454 | protected burn(): void { } 455 | 456 | // abstract methods 457 | public abstract isBurning(): boolean 458 | 459 | public abstract getIdealOutput(): number 460 | 461 | public abstract getMaxEnergy(): number 462 | 463 | // IEngine 464 | public canReceiveFromEngine(side: number): boolean { 465 | return side == World.getInverseBlockSide(this.getOrientation()); 466 | } 467 | 468 | public receiveEnergyFromEngine(side: number, amount: number, simulate: boolean): number { 469 | if (this.canReceiveFromEngine(side)) { 470 | const targetEnergy = Math.min(this.getMaxEnergy() - this.data.energy, amount); 471 | if (!simulate) { 472 | this.data.energy += targetEnergy; 473 | } 474 | return targetEnergy; 475 | } 476 | return 0; 477 | } 478 | 479 | // IHeatable 480 | public getMinHeatValue(): number { 481 | return this.MIN_HEAT; 482 | } 483 | public getIdealHeatValue(): number { 484 | return this.IDEAL_HEAT; 485 | } 486 | 487 | public getMaxHeatValue(): number { 488 | return this.MAX_HEAT; 489 | } 490 | 491 | public getCurrentHeatValue(): number { 492 | return this.data.heat; 493 | } 494 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/EngineAnimation.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | 6 | class EngineAnimation { 7 | private readonly base: BaseAnimation; 8 | private readonly piston: PistonAnimation; 9 | 10 | private readonly yOffset: number = 31;// magic const 11 | private coords: Vector; 12 | 13 | private side: number = null;// connected side index 14 | 15 | private directions = [ 16 | {rotation: EngineRotation.Y, direction: -1}, 17 | {rotation: EngineRotation.Y, direction: 1}, 18 | {rotation: EngineRotation.Z, direction: -1}, 19 | {rotation: EngineRotation.Z, direction: 1}, 20 | {rotation: EngineRotation.X, direction: 1}, 21 | {rotation: EngineRotation.X, direction: -1} 22 | ]; 23 | 24 | public set ConnectionSide(value: number){ 25 | let rotate = false; 26 | if (this.side != value) rotate = true; 27 | this.side = value; 28 | if (rotate) this.rotateByMeta(); 29 | } 30 | 31 | public get ConnectionSide(): number { 32 | return this.side; 33 | } 34 | 35 | constructor(public readonly position: Vector, private heatStage: EngineHeat, private engineTexture: EngineTexture){ 36 | this.piston = new PistonAnimation(position, engineTexture); 37 | this.base = new BaseAnimation(position, engineTexture); 38 | } 39 | 40 | public update(progress: number, heat: EngineHeat): void { 41 | if (progress > 0.5) progress = 1 - progress; 42 | 43 | this.updateTrunkHeat(heat); 44 | this.piston.setPosition(progress); 45 | // *will be finished coming soon 46 | // this.updateChamberPosition(progress); 47 | } 48 | 49 | private updateTrunkHeat(heat: EngineHeat): void { 50 | if(this.heatStage !== heat){ 51 | this.heatStage = heat; 52 | this.base.render.trunkUV = this.engineTexture.getTrunkUV(this.heatStage, this.directions[this.ConnectionSide].rotation); 53 | this.base.render.refresh(); 54 | } 55 | } 56 | 57 | private updateChamberPosition(progress: number): void { 58 | // progress : [0, .5] 59 | const realPos = 5 + -Math.ceil(10 * progress); 60 | this.base.render.chamberCoords = { 61 | x: this.coords.x * realPos, 62 | y: this.yOffset + this.coords.y * realPos, 63 | z: this.coords.z * realPos 64 | }; 65 | this.base.render.chamberSize = { 66 | x: 4 + (this.coords.x ? 2*Math.ceil(10 * progress) * Math.abs(this.coords.x): 6), 67 | y: 4 + (this.coords.y ? 2*Math.ceil(10 * progress) * Math.abs(this.coords.y): 6), 68 | z: 4 + (this.coords.z ? 2*Math.ceil(10 * progress) * Math.abs(this.coords.z): 6) 69 | }; 70 | this.base.render.refreshChamber(); 71 | } 72 | 73 | private rotateByMeta(): void { 74 | const data = this.directions[this.ConnectionSide]; 75 | this.createPiston(data.rotation, data.direction); 76 | } 77 | 78 | public destroy(): void { 79 | this.base.destroy(); 80 | this.piston.destroy(); 81 | } 82 | 83 | // Legacy, but it still work 84 | private createPiston(rotation: EngineRotation, direction: number): void { 85 | const coords = {x: 0, y: 0, z: 0}; 86 | 87 | switch (rotation){ 88 | case EngineRotation.X: 89 | coords.x = direction; 90 | break; 91 | case EngineRotation.Y: 92 | coords.y = direction; 93 | break; 94 | case EngineRotation.Z: 95 | coords.z = direction; 96 | break; 97 | }; 98 | 99 | this.coords = coords; 100 | 101 | this.setupBaseBoxes(coords); 102 | const baseRender = this.base.render; 103 | baseRender.baseUV = this.engineTexture.getBaseUV(rotation); 104 | 105 | this.setupTrunkBoxes(coords); 106 | baseRender.trunkUV = this.engineTexture.getTrunkUV(this.heatStage, rotation); 107 | baseRender.refresh(); 108 | 109 | // *will be finished coming soon 110 | // baseRender.chamberUV = this.engineTexture.getChamberUV(); 111 | // baseRender.refreshChamber(); 112 | 113 | this.setupPistonBoxes(coords); 114 | const pistonRender = this.piston.render; 115 | pistonRender.pistonUV = this.engineTexture.getBaseUV(rotation); 116 | pistonRender.refresh(); 117 | 118 | // piston Move Vector setup 119 | this.piston.direction = -direction; 120 | this.piston.rotation = rotation; 121 | } 122 | 123 | private setupBaseBoxes(coords: Vector): void { 124 | this.base.render.baseCoords = { 125 | x: coords.x * 6, 126 | y: this.yOffset + coords.y * 6, 127 | z: coords.z * 6 128 | } 129 | this.base.render.baseSize = { 130 | x: 4 + 12 * (1 - Math.abs(coords.x)), 131 | y: 4 + 12 * (1 - Math.abs(coords.y)), 132 | z: 4 + 12 * (1 - Math.abs(coords.z)) 133 | } 134 | } 135 | 136 | private setupTrunkBoxes(coords: Vector): void { 137 | this.base.render.trunkCoords = { 138 | x: -coords.x * .1, 139 | y: this.yOffset - coords.y * .1, 140 | z: -coords.z * .1 141 | } 142 | this.base.render.trunkSize = { 143 | x: 8 + 8 * (Math.abs(coords.x)), 144 | y: 8 + 8 * (Math.abs(coords.y)), 145 | z: 8 + 8 * (Math.abs(coords.z)) 146 | } 147 | } 148 | 149 | private setupPistonBoxes(coords: Vector): void { 150 | this.piston.render.pistonCoords = { 151 | x: coords.x * 2, 152 | y: this.yOffset + coords.y * 2, 153 | z: coords.z * 2 154 | }; 155 | this.piston.render.pistonSize = { 156 | x: 4 + 12 * (1 - Math.abs(coords.x)), 157 | y: 4 + 12 * (1 - Math.abs(coords.y)), 158 | z: 4 + 12 * (1 - Math.abs(coords.z)) 159 | } 160 | } 161 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/EngineBlock.ts: -------------------------------------------------------------------------------- 1 | const BlockTypeEngine: Block.SpecialType = { 2 | base: 1, 3 | destroytime: 1.5 4 | }; 5 | 6 | class EngineBlock { 7 | public readonly id: number; 8 | public readonly stringId: string; 9 | 10 | constructor(private readonly registryId: string) { 11 | this.stringId = "engine_" + this.registryId; 12 | this.registerBlock(); 13 | this.id = BlockID[this.stringId]; 14 | } 15 | 16 | private registerBlock(): void { 17 | IDRegistry.genBlockID(this.stringId); 18 | Block.createBlock(this.stringId, [ 19 | { name: this.stringId, texture: [["empty", 0]], inCreative: false }, 20 | { name: this.stringId, texture: [["empty", 0]], inCreative: true } 21 | ], BlockTypeEngine); 22 | } 23 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/EngineItem.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @deprecated 3 | */ 4 | class EngineItem { 5 | public readonly id: number; 6 | public readonly stringId: string; 7 | 8 | constructor(private readonly registryId: string, public readonly engineBlock: EngineBlock) { 9 | this.stringId = "engine_" + this.registryId; 10 | this.registerItem(); 11 | this.id = ItemID[this.stringId]; 12 | } 13 | private registerItem(): void { 14 | IDRegistry.genItemID(this.stringId); 15 | Item.createItem(this.stringId, this.stringId, { name: "engine_" + this.registryId }); 16 | } 17 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/animation/AnimationComponent.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class AnimationComponent { 3 | protected readonly animation; 4 | public readonly coords: Vector; 5 | 6 | constructor(pos: Vector, public render: EngineRender){ 7 | this.coords = {x: pos.x + .5, y: pos.y + 15 / 16, z: pos.z + .5}; 8 | this.animation = new Animation.Base(this.coords.x, this.coords.y, this.coords.z); 9 | this.animation.describe({render: this.render.getID()}); 10 | this.animation.load(); 11 | } 12 | 13 | public updateRender(render: EngineRender): void { 14 | this.render.stash(); 15 | this.render = render; 16 | this.animation.describe({render: this.render.getID()}); 17 | this.animation.refresh(); 18 | } 19 | 20 | public destroy(): void{ 21 | this.render.stash(); 22 | this.animation.destroy(); 23 | } 24 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/animation/BaseAnimation.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | class BaseAnimation extends AnimationComponent { 5 | public render: BaseRender; 6 | 7 | constructor(pos: Vector, engineTexture: EngineTexture){ 8 | const render = new BaseRender(engineTexture); 9 | super(pos, render); 10 | } 11 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/animation/PistonAnimation.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class PistonAnimation extends AnimationComponent { 3 | public render: PistonRender; 4 | 5 | public rotation: EngineRotation; 6 | public direction: number; 7 | 8 | constructor(pos: Vector, engineTexture: EngineTexture){ 9 | const render = new PistonRender(engineTexture); 10 | super(pos, render); 11 | const isInterpolationEnabled = __config__.getBool("animation_movement_interpolation"); 12 | this.animation.setInterpolationEnabled(isInterpolationEnabled); 13 | } 14 | 15 | public setPosition(pistonPosition: number): void { 16 | const move = { 17 | x: this.rotation === EngineRotation.X ? pistonPosition * this.direction : 0, 18 | y: this.rotation === EngineRotation.Y ? pistonPosition * -this.direction : 0, 19 | z: this.rotation === EngineRotation.Z ? pistonPosition * -this.direction : 0 20 | }// !dont touch -1 or fix root of evil 21 | this.animation.setPos(this.coords.x + move.x, this.coords.y + move.y, this.coords.z + move.z); 22 | } 23 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/model/EngineItemModel.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | class EngineItemModel { 6 | private model: BlockRenderer.Model; 7 | 8 | private baseModel: IEnginePartModel; 9 | private trunkModel: IEnginePartModel; 10 | private pistonModel: IEnginePartModel; 11 | private chamberModel: IEnginePartModel; 12 | 13 | constructor(private engineTexture: EngineTexture) { 14 | this.model = new BlockRenderer.Model(); 15 | this.setupModels(); 16 | 17 | for (const box of this.Boxes) { 18 | const { x1, y1, z1, x2, y2, z2, descr } = box; 19 | this.model.addBox(x1, y1, z1, x2, y2, z2, descr); 20 | } 21 | } 22 | 23 | private get Boxes(): ModelBox[] { 24 | return [ 25 | this.baseModel.requireModelBox(), 26 | this.trunkModel.requireModelBox(), 27 | this.pistonModel.requireModelBox(), 28 | this.chamberModel.requireModelBox() 29 | ] 30 | } 31 | 32 | get Model(): BlockRenderer.Model { 33 | return this.model; 34 | } 35 | 36 | private setupModels(): void { 37 | const texture = this.engineTexture.getItemModelTexture() 38 | this.baseModel = new EngineBaseModelPart(texture.BaseBoxTextureSet); 39 | this.trunkModel = new EngineTrunkModelPart(texture.TrunkBoxTextureSet); 40 | this.pistonModel = new EnginePistonModelPart(texture.PistonBoxTextureSet); 41 | this.chamberModel = new EngineChamberModelPart(texture.ChamberBoxTextureSet); 42 | } 43 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/model/EngineItemModelTexture.ts: -------------------------------------------------------------------------------- 1 | class EngineItemModelTexture { 2 | private trunkTextureName = "engine_trunk"; 3 | private chamberTextureName = "chamber"; 4 | constructor(private textureName: string) { } 5 | 6 | get BaseBoxTextureSet(): BlockRenderer.ModelTextureSet { 7 | return [ 8 | [this.textureName, 0], 9 | [this.textureName, 0], 10 | [this.textureName, 1], 11 | [this.textureName, 1], 12 | [this.textureName, 1], 13 | [this.textureName, 1] 14 | ] 15 | } 16 | 17 | get TrunkBoxTextureSet(): BlockRenderer.ModelTextureSet { 18 | return [ 19 | [this.trunkTextureName, 1], 20 | [this.trunkTextureName, 1], 21 | [this.trunkTextureName, 0], 22 | [this.trunkTextureName, 0], 23 | [this.trunkTextureName, 0], 24 | [this.trunkTextureName, 0] 25 | ] 26 | } 27 | 28 | get PistonBoxTextureSet(): BlockRenderer.ModelTextureSet { 29 | return [ 30 | [this.textureName, 0], 31 | [this.textureName, 0], 32 | [this.textureName, 2], 33 | [this.textureName, 2], 34 | [this.textureName, 2], 35 | [this.textureName, 2] 36 | ] 37 | } 38 | 39 | get ChamberBoxTextureSet(): BlockRenderer.ModelTextureSet { 40 | return [ 41 | [this.chamberTextureName, 0], 42 | [this.chamberTextureName, 0], 43 | [this.chamberTextureName, 0], 44 | [this.chamberTextureName, 0], 45 | [this.chamberTextureName, 0], 46 | [this.chamberTextureName, 0] 47 | ] 48 | } 49 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/model/IEnginePartModel.ts: -------------------------------------------------------------------------------- 1 | interface IEnginePartModel { 2 | requireModelBox(): ModelBox; 3 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/model/ModelBox.ts: -------------------------------------------------------------------------------- 1 | type ModelBox = { 2 | x1: number; 3 | y1: number; 4 | z1: number; 5 | x2: number; 6 | y2: number; 7 | z2: number; 8 | descr: BlockRenderer.ModelTextureSet; 9 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/model/parts/EngineBaseModelPart.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class EngineBaseModelPart implements IEnginePartModel { 4 | constructor(private textureSet: BlockRenderer.ModelTextureSet) { } 5 | 6 | public requireModelBox(): ModelBox { 7 | return { 8 | x1: 0, y1: 0, z1: 0, 9 | x2: 1, y2: .25, z2: 1, 10 | descr: this.textureSet 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/model/parts/EngineChamberModelPart.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class EngineChamberModelPart implements IEnginePartModel { 4 | constructor(private textureSet: BlockRenderer.ModelTextureSet) { } 5 | 6 | public requireModelBox(): ModelBox { 7 | return { 8 | x1: .125, y1: 0, z1: .125, 9 | x2: .875, y2: .5, z2: .875, 10 | descr: this.textureSet 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/model/parts/EnginePistonModelPart.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class EnginePistonModelPart implements IEnginePartModel { 4 | constructor(private textureSet: BlockRenderer.ModelTextureSet) { } 5 | 6 | public requireModelBox(): ModelBox { 7 | return { 8 | x1: 0, y1: .5, z1: 0, 9 | x2: 1, y2: .75, z2: 1, 10 | descr: this.textureSet 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/model/parts/EngineTrunkModelPart.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class EngineTrunkModelPart implements IEnginePartModel { 4 | constructor(private textureSet: BlockRenderer.ModelTextureSet) { } 5 | 6 | public requireModelBox(): ModelBox { 7 | return { 8 | x1: .25, y1: 0, z1: .25, 9 | x2: .75, y2: 1, z2: .75, 10 | descr: this.textureSet 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/recipe/EngineIngredients.ts: -------------------------------------------------------------------------------- 1 | class EngineIngredients { 2 | constructor(readonly gear: ItemInstance, readonly ingot: ItemInstance) { } 3 | } -------------------------------------------------------------------------------- /src/dev/core/engine/components/recipe/EngineRecipe.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class EngineRecipe { 3 | public readonly gear: ItemInstance; 4 | public readonly ingot: ItemInstance; 5 | 6 | constructor(ingredients: EngineIngredients) { 7 | this.gear = ingredients.gear; 8 | this.ingot = ingredients.ingot; 9 | } 10 | 11 | public registerFor(item: ItemInstance): void { 12 | Recipes.addShaped(item, this.Pattern, this.PatternData); 13 | } 14 | 15 | private get Pattern(): string[] { 16 | return [ 17 | "aaa", 18 | " b ", 19 | "oxo" 20 | ]; 21 | } 22 | 23 | private get PatternData(): (string | number)[] { 24 | return [ 25 | "x", VanillaBlockID.piston, -1, 26 | "a", this.ingot.id, this.ingot.data, 27 | "b", VanillaBlockID.glass, -1, 28 | "o", this.gear.id, this.gear.data 29 | ]; 30 | } 31 | } -------------------------------------------------------------------------------- /src/dev/core/engine/creative/CreativeEngine.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | // * only for engine order in creative tab 7 | /// 8 | class CreativeEngine extends BCEngine { 9 | 10 | public get engineType(): string { 11 | return "creative" 12 | } 13 | 14 | protected get texture(): EngineTexture { 15 | return EngineTextures.creative; 16 | } 17 | 18 | protected getRecipe(ingredients: EngineIngredients): EngineRecipe { 19 | return CreativeEngineRecipe.Recipe; 20 | } 21 | 22 | protected requireTileEntity() { 23 | return new BCCreativeEngineTileEntity(EngineTextures.creative); 24 | } 25 | 26 | protected getIngredientsForRecipe(): EngineIngredients { 27 | return null; 28 | } 29 | } 30 | const creativeEngine = new CreativeEngine(); -------------------------------------------------------------------------------- /src/dev/core/engine/creative/CreativeEngineRecipe.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class CreativeEngineRecipe extends EngineRecipe { 4 | private static staticRecipe: CreativeEngineRecipe = null; 5 | private static ingredients: EngineIngredients = new EngineIngredients({ id: 0, count: 0, data: 0 }, { id: 0, count: 0, data: 0 }); 6 | 7 | public static get Recipe(): CreativeEngineRecipe { 8 | if (!this.staticRecipe) { 9 | this.staticRecipe = new CreativeEngineRecipe(this.ingredients); 10 | } 11 | return this.staticRecipe; 12 | } 13 | 14 | public registerFor(item: ItemInstance): void { } 15 | } -------------------------------------------------------------------------------- /src/dev/core/engine/creative/CreativeEngineTileEntity.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class BCCreativeEngineTileEntity extends BCEngineTileEntity { 3 | public energyStage = EngineHeat.BLACK; 4 | 5 | constructor(protected texture: EngineTexture){ 6 | super(texture); 7 | this.defaultValues.powerMode = PowerMode.M2; 8 | this.client.getEngineTexture = (stage: EngineHeat) => { 9 | return EngineTextures.creative; 10 | }; 11 | this.client.getPistonSpeed = function(energyStage: EngineHeat) { 12 | return 0.02 * (this.powerModeIndex+1); 13 | } 14 | // @ts-ignore 15 | this.client._load = this.client.load; 16 | this.client.load = function(){ 17 | this._load(); 18 | this.powerModeIndex = 0; 19 | this.networkData.addOnDataChangedListener((networkData: SyncedNetworkData, isExternalChange) => { 20 | this.powerModeIndex = networkData.getInt("powerModeIndex"); 21 | }); 22 | } 23 | } 24 | 25 | public init(){ 26 | super.init(); 27 | this.syncPowerMode(); 28 | } 29 | 30 | public click(id: number, count: number, data: number) { 31 | if(id != ItemID.bc_wrench) return false; 32 | 33 | if(Entity.getSneaking(Player.get())){ 34 | this.data.energy = 0; 35 | let currentModeIndex = PowerModeOrder.indexOf(this.data.powerMode); 36 | this.data.powerMode = PowerModeOrder[++currentModeIndex % PowerModeOrder.length]; 37 | this.syncPowerMode(); 38 | Game.tipMessage(`Mode switched to ${this.data.powerMode}RF`); 39 | return true; 40 | } 41 | this.setOrientation(this.getConnectionSide(true)); 42 | return false; 43 | } 44 | 45 | private syncPowerMode(): void { 46 | this.networkData.putInt("powerModeIndex", PowerModeOrder.indexOf(this.data.powerMode)); 47 | this.networkData.sendChanges(); 48 | } 49 | 50 | protected computeEnergyStage(): EngineHeat { 51 | return EngineHeat.BLACK; 52 | } 53 | 54 | public updateHeat(): void {} 55 | 56 | public getPistonSpeed(): number { 57 | return 0.02 * (PowerModeOrder.indexOf(this.data.powerMode) + 1); 58 | } 59 | 60 | public engineUpdate(): void { 61 | super.engineUpdate(); 62 | 63 | if (this.isRedstonePowered) { 64 | this.addEnergy(this.getIdealOutput()); 65 | } 66 | } 67 | 68 | public isBurning(): boolean { 69 | return this.isRedstonePowered; 70 | } 71 | 72 | public getMaxEnergy(): number { 73 | return this.getIdealOutput(); 74 | } 75 | 76 | public getIdealOutput(): number { 77 | return this.data.powerMode; 78 | } 79 | } -------------------------------------------------------------------------------- /src/dev/core/engine/interface/IEngine.ts: -------------------------------------------------------------------------------- 1 | interface IEngine { 2 | canReceiveFromEngine(side: number): boolean 3 | 4 | receiveEnergyFromEngine(side: number, amount: number, simulate: boolean): number 5 | } -------------------------------------------------------------------------------- /src/dev/core/engine/interface/IHeatable.ts: -------------------------------------------------------------------------------- 1 | interface IHeatable { 2 | getMinHeatValue(): number 3 | 4 | getIdealHeatValue(): number 5 | 6 | getMaxHeatValue(): number 7 | 8 | getCurrentHeatValue(): number 9 | } -------------------------------------------------------------------------------- /src/dev/core/engine/model/EngineRotation.ts: -------------------------------------------------------------------------------- 1 | enum EngineRotation { 2 | X = 1, 3 | Y = 0, 4 | Z = 2 5 | } -------------------------------------------------------------------------------- /src/dev/core/engine/model/render/BaseRender.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class BaseRender extends EngineRender { 3 | protected boxes = [{ 4 | type: "box",// base 5 | uv: null, 6 | coords: null, 7 | size: null 8 | }, 9 | { 10 | type: "box",// trunk 11 | uv: null, 12 | coords: null, 13 | size: null 14 | }]; 15 | 16 | protected chamberBoxes = [{ 17 | type: "box",// chamber 18 | uv: null, 19 | coords: null, 20 | size: null 21 | }]; 22 | 23 | // Base 24 | public set baseCoords(value: Vector) { 25 | this.boxes[0].coords = value; 26 | } 27 | 28 | public set baseUV(value: Vector2) { 29 | this.boxes[0].uv = value; 30 | } 31 | 32 | public set baseSize(value: Vector) { 33 | this.boxes[0].size = value; 34 | } 35 | 36 | // Trunk 37 | public set trunkCoords(value: Vector) { 38 | this.boxes[1].coords = value; 39 | } 40 | 41 | public set trunkSize(value: Vector) { 42 | this.boxes[1].size = value; 43 | } 44 | 45 | public set trunkUV(value: Vector2) { 46 | this.boxes[1].uv = value; 47 | } 48 | 49 | // Chamber 50 | public set chamberCoords(value: Vector) { 51 | this.chamberBoxes[0].coords = value; 52 | } 53 | 54 | public set chamberSize(value: Vector) { 55 | this.chamberBoxes[0].size = value; 56 | } 57 | 58 | public set chamberUV(value: Vector2) { 59 | this.chamberBoxes[0].uv = value; 60 | } 61 | 62 | public refreshChamber(): void { 63 | this.render.setPart("head.chamber", this.chamberBoxes, this.engineTexture.size); 64 | }; 65 | 66 | protected getModelData(): Render.PartElement[] { 67 | return this.boxes; 68 | } 69 | } -------------------------------------------------------------------------------- /src/dev/core/engine/model/render/EngineRender.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | abstract class EngineRender { 4 | protected readonly render: Render; 5 | protected boxes = []; 6 | 7 | constructor(protected engineTexture: EngineTexture) { 8 | this.render = RenderManager.getRender() || new Render({ skin: this.engineTexture.name }); 9 | } 10 | 11 | public refresh(): void { 12 | this.render.setPart("head", this.getModelData(), this.engineTexture.size); 13 | } 14 | 15 | public stash(): void { 16 | RenderManager.store(this.render); 17 | } 18 | 19 | public getID(): number { 20 | return this.render.getId(); 21 | } 22 | 23 | protected getModelData(): Render.PartElement[] { 24 | return this.boxes; 25 | } 26 | } -------------------------------------------------------------------------------- /src/dev/core/engine/model/render/PistonRender.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class PistonRender extends EngineRender { 3 | protected boxes = [{ 4 | type: "box", 5 | uv: null, 6 | coords: null, 7 | size: null 8 | }]; 9 | 10 | public set pistonCoords(value: Vector) { 11 | this.boxes[0].coords = value; 12 | } 13 | 14 | public set pistonUV(value: Vector2) { 15 | this.boxes[0].uv = value; 16 | } 17 | 18 | public set pistonSize(value: Vector) { 19 | this.boxes[0].size = value; 20 | } 21 | 22 | protected getModelData(): Render.PartElement[] { 23 | return this.boxes; 24 | } 25 | } -------------------------------------------------------------------------------- /src/dev/core/engine/model/render/RenderManager.ts: -------------------------------------------------------------------------------- 1 | class RenderManager { 2 | private static renders = []; 3 | 4 | static getRender(groupName?: string) { 5 | return this.renders.pop(); 6 | } 7 | 8 | static store(render: Render): void { 9 | this.renders.push(render); 10 | } 11 | } -------------------------------------------------------------------------------- /src/dev/core/engine/model/texture/EngineTexture.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | interface Vector2 { 6 | x: number; 7 | y: number; 8 | } 9 | 10 | const STANDART_TEXTURE = "model/buildcraft_engine_atlas.png"; 11 | const STANDART_SIZE = { width: 512, height: 512 }; 12 | 13 | class EngineTexture { 14 | private engineItemModelTexture: EngineItemModelTexture; 15 | constructor(itemModelTexture: string, public readonly name: string, private readonly baseOffset, public readonly size: ITexture) { 16 | this.engineItemModelTexture = new EngineItemModelTexture(itemModelTexture); 17 | } 18 | 19 | public getTrunkUV(heat: EngineHeat, rotation: EngineRotation): Vector2 { 20 | return { x: 64 * rotation, y: 32 * HeatOrder.indexOf(heat) } 21 | } 22 | 23 | public getBaseUV(rotation: EngineRotation): Vector2 { 24 | return { x: this.baseOffset.x + 64 * rotation, y: this.baseOffset.y } 25 | } 26 | 27 | public getChamberUV(): Vector2 { 28 | return { x: 192, y: 0 } 29 | } 30 | 31 | public getItemModelTexture(): EngineItemModelTexture { 32 | return this.engineItemModelTexture; 33 | } 34 | } -------------------------------------------------------------------------------- /src/dev/core/engine/model/texture/ITexture.ts: -------------------------------------------------------------------------------- 1 | interface ITexture { 2 | width: number; 3 | height: number; 4 | } -------------------------------------------------------------------------------- /src/dev/core/engine/wood/WoodEngine.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | 8 | class WoodEngine extends BCEngine { 9 | public get engineType(): string { 10 | return "wooden" 11 | } 12 | 13 | protected get texture(): EngineTexture { 14 | return EngineTextures.wood; 15 | } 16 | 17 | protected requireTileEntity() { 18 | return new BCWoodEngineTileEntity(this.texture); 19 | } 20 | 21 | protected getIngredientsForRecipe(): EngineIngredients { 22 | return new EngineIngredients({ id: ItemID.gear_wood, count: 1, data: 0 }, { id: VanillaBlockID.planks, count: 1, data: -1 }); 23 | } 24 | } 25 | const woodenEngine = new WoodEngine(); -------------------------------------------------------------------------------- /src/dev/core/engine/wood/WoodEngineTileEntity.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | class BCWoodEngineTileEntity extends BCEngineTileEntity { 5 | private hasSent: boolean = false; 6 | 7 | constructor(protected texture: EngineTexture) { 8 | super(texture); 9 | this.client.getEngineTexture = (stage: EngineHeat) => { 10 | return EngineTextures.wood; 11 | }; 12 | this.client.getTrunkTexture = (stage: EngineHeat, progress: number) => { 13 | return stage == EngineHeat.RED && progress < 0.5 ? EngineHeat.ORANGE : stage; 14 | } 15 | this.client.getPistonSpeed = (energyStage: EngineHeat) => { 16 | switch (energyStage) { 17 | case EngineHeat.GREEN: 18 | return 0.02; 19 | case EngineHeat.ORANGE: 20 | return 0.04; 21 | case EngineHeat.RED: 22 | return 0.08; 23 | default: 24 | return 0.01; 25 | } 26 | } 27 | } 28 | 29 | protected computeEnergyStage(): EngineHeat { 30 | const energyLevel = this.getEnergyLevel(); 31 | if (energyLevel < 0.33) { 32 | return EngineHeat.BLUE; 33 | } else if (energyLevel < 0.66) { 34 | return EngineHeat.GREEN; 35 | } else if (energyLevel < 0.75) { 36 | return EngineHeat.ORANGE; 37 | } 38 | return EngineHeat.RED; 39 | } 40 | 41 | public getPistonSpeed(): number { 42 | return Math.max(0.08 * this.getHeatLevel(), 0.01); 43 | } 44 | 45 | public engineUpdate(): void { 46 | super.engineUpdate(); 47 | if (this.isRedstonePowered && World.getThreadTime() % 16 == 0) { 48 | this.addEnergy(10); 49 | } 50 | } 51 | 52 | protected sendPower(): void { 53 | if (this.progressPart == 2 && !this.hasSent) { 54 | this.hasSent = true; 55 | 56 | const tile = this.getEnergyProvider(this.getOrientation()); 57 | 58 | if (tile && tile.canReceiveEnergy(World.getInverseBlockSide(this.getOrientation()), "RF") && 59 | tile.canConnectRedstoneEngine && tile.canConnectRedstoneEngine()) { 60 | super.sendPower(); 61 | } else { 62 | this.data.energy = 0; 63 | } 64 | } else if (this.progressPart != 2) { 65 | this.hasSent = false; 66 | } 67 | } 68 | 69 | public isBurning(): boolean { 70 | return this.isRedstonePowered; 71 | } 72 | 73 | public getCurrentOutputLimit(): number { 74 | return 10; 75 | } 76 | 77 | public getMaxEnergy(): number { 78 | return 1000; 79 | } 80 | 81 | public getIdealOutput(): number { 82 | return 10; 83 | } 84 | 85 | public canConnectEnergy(from: number): boolean { 86 | return false; 87 | } 88 | 89 | public getEnergyStored(): number { 90 | return 0; 91 | } 92 | 93 | public getMaxEnergyStored(): number { 94 | return 0; 95 | } 96 | } -------------------------------------------------------------------------------- /src/dev/core/importLib.ts: -------------------------------------------------------------------------------- 1 | IMPORT("StorageInterface"); 2 | IMPORT("EnergyNet"); 3 | // you can see this files in 4 | // BuildCraft/lib/ 5 | // !only bundle folder should contain lib files -------------------------------------------------------------------------------- /src/dev/core/pipe/PipeSpeed.ts: -------------------------------------------------------------------------------- 1 | class PipeSpeed { 2 | constructor(private target: number, private delta: number) {} 3 | 4 | public get Target(): number { 5 | return this.target; 6 | } 7 | 8 | public get Delta(): number { 9 | return this.delta; 10 | } 11 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/abstract/BCPipe.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | abstract class BCPipe { 8 | protected block: PipeBlock; 9 | protected recipe: PipeRecipe; 10 | 11 | protected connector: PipeConnector; 12 | 13 | protected texture: PipeTexture; 14 | protected renderer: PipeRenderer; 15 | 16 | protected pipeSpeed: PipeSpeed = BCPipe.StandartPipeSpeed; 17 | protected static standartSpeed: PipeSpeed = new PipeSpeed(0.01, 0.02); 18 | 19 | constructor() { 20 | this.block = new PipeBlock(this.material, this.transportType, this.pipeTexture); 21 | this.renderer = new PipeRenderer(this.pipeConnector, this.pipeTexture, this.renderGroups.main); 22 | this.recipe = this.getRecipe(this.getIngredientForRecipe()); 23 | this.recipe.registerFor({ id: this.block.id, count: 1, data: 0 }); 24 | this.registerBlockToGroup(); 25 | this.renderer.enableRender(this.block.id, 0); 26 | PipeIdMap.assignIdAsClass(this.block.id, this); 27 | } 28 | 29 | /** 30 | * it a method because we need this in constructor 31 | */ 32 | protected getRecipe(ingredient: ItemInstance): PipeRecipe { 33 | return new PipeRecipe(ingredient); 34 | } 35 | 36 | /** 37 | * it a method because we need this in constructor 38 | */ 39 | protected abstract getIngredientForRecipe(): ItemInstance 40 | 41 | protected registerBlockToGroup(): void { 42 | const groups = this.renderGroups; 43 | groups.main.add(this.block.id, -1); 44 | if (groups.addition) 45 | groups.addition.add(this.block.id, -1); 46 | } 47 | 48 | protected get ICRenderGroup(): ICRender.Group { 49 | return null 50 | } 51 | 52 | public get pipeConnector(): PipeConnector { 53 | return null; 54 | } 55 | 56 | public get renderGroups(): RenderGroups { 57 | return { 58 | main: ICRender.getGroup("BCPipe") 59 | }; 60 | } 61 | 62 | protected get pipeTexture(): PipeTexture { 63 | return null; 64 | } 65 | 66 | protected get pipeRenderer(): PipeRenderer { 67 | return this.renderer; 68 | } 69 | 70 | public get material(): string { 71 | return null 72 | } 73 | 74 | public get transportType(): string { 75 | return null 76 | } 77 | 78 | public get PipeSpeed(): PipeSpeed { 79 | return this.pipeSpeed; 80 | } 81 | 82 | public static get StandartPipeSpeed(): PipeSpeed { 83 | return this.standartSpeed; 84 | } 85 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/abstract/PipeConnector.ts: -------------------------------------------------------------------------------- 1 | type ConnectionRule = { 2 | name: string; 3 | exclude: boolean; 4 | isANDrule: boolean; 5 | }; 6 | abstract class PipeConnector { 7 | abstract canPipesConnect(coords0: Vector, coords1: Vector): boolean; 8 | abstract canConnectToGroup(groupName: string): boolean; 9 | abstract getConnectionRules(): ConnectionRule[]; 10 | 11 | /** 12 | * For vanila block ID 13 | */ 14 | protected getBlacklistConnectedBlock(): Tile[] { 15 | return [ 16 | { id: VanillaTileID.ender_chest, data: -1 } 17 | ] 18 | } 19 | 20 | public hasBlacklistBlockID(id: number, data: number): boolean { 21 | for (const bl of this.getBlacklistConnectedBlock()) { 22 | if (id == bl.id && (bl.data < 0 || bl.data == data)) { 23 | return true; 24 | } 25 | } 26 | return false; 27 | } 28 | 29 | public canConnectToPipe(target: BCPipe): boolean { 30 | const targetGroups = target.renderGroups; 31 | for (const rule of this.getConnectionRules()) { 32 | if (rule.name == targetGroups.main.getName()) { 33 | if (rule.exclude) return false; 34 | } 35 | const secondary = targetGroups.addition; 36 | if (secondary && rule.name == secondary.getName()) { 37 | if (rule.exclude) return false; 38 | } 39 | } 40 | return true; 41 | } 42 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/components/PipeBlock.ts: -------------------------------------------------------------------------------- 1 | const BlockTypePipe: Block.SpecialType = { 2 | base: 1, 3 | destroytime: 0.2, 4 | explosionres: 0.5 5 | }; 6 | 7 | class PipeBlock { 8 | public readonly id: number; 9 | public readonly stringId: string; 10 | 11 | constructor(public readonly material: string, public readonly transportType: string, private texture: PipeTexture) { 12 | this.stringId = `pipe_${this.transportType}_${this.material}`; 13 | this.registerBlock(); 14 | this.id = BlockID[this.stringId]; 15 | this.registerShape(); 16 | } 17 | 18 | private registerBlock(): void { 19 | IDRegistry.genBlockID(this.stringId); 20 | Block.createBlock(this.stringId, 21 | [{ name: this.stringId, texture: [[this.texture.block.name, this.texture.block.data]], inCreative: true }], 22 | BlockTypePipe); 23 | } 24 | 25 | private registerShape(): void { 26 | Block.setBlockShape(this.id, { x: .25, y: .25, z: .25 }, { x: 0.75, y: 0.75, z: 0.75 }); 27 | } 28 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/components/PipeDoubleRecipe.ts: -------------------------------------------------------------------------------- 1 | class PipeDoubleRecipe extends PipeRecipe { 2 | constructor(private readonly ingredient0: ItemInstance, private readonly ingredient1: ItemInstance) { 3 | super(ingredient0); 4 | } 5 | 6 | protected get Pattern(): string[] { 7 | return [ 8 | "abc" 9 | ]; 10 | } 11 | 12 | protected get PatternData(): (string | number)[] { 13 | return [ 14 | "b", VanillaBlockID.glass, -1, 15 | "a", this.ingredient0.id, this.ingredient0.data, 16 | "c", this.ingredient1.id, this.ingredient1.data, 17 | ]; 18 | } 19 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/components/PipeIdMap.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class PipeIdMap { 3 | private static map = {}; 4 | 5 | public static assignIdAsClass(id: number, cls: BCPipe) { 6 | this.map[id] = cls; 7 | } 8 | 9 | public static getClassById(id: number): BCPipe | null { 10 | return this.map[id] || null; 11 | } 12 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/components/PipeRecipe.ts: -------------------------------------------------------------------------------- 1 | class PipeRecipe { 2 | constructor(private readonly ingredient: ItemInstance) { } 3 | 4 | public registerFor(item: ItemInstance): void { 5 | Recipes.addShaped(item, this.Pattern, this.PatternData); 6 | } 7 | 8 | protected get Pattern(): string[] { 9 | return [ 10 | "aba" 11 | ]; 12 | } 13 | 14 | protected get PatternData(): (string | number)[] { 15 | return [ 16 | "b", VanillaBlockID.glass, -1, 17 | "a", this.ingredient.id, this.ingredient.data 18 | ]; 19 | } 20 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/components/PipeRenderer.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class PipeRenderer { 3 | constructor(protected connector: PipeConnector, protected texture: PipeTexture, protected renderGroup: ICRender.Group) { } 4 | 5 | public readonly width = .5; 6 | 7 | public get standartICrender() { 8 | const render = new ICRender.Model(); 9 | return render; 10 | } 11 | 12 | public getICrenderAtCoords(coords: Vector) { 13 | 14 | } 15 | 16 | public enableRender(id: number, data: number): void { 17 | const render = this.standartModel; 18 | BlockRenderer.setStaticICRender(id, data, render); 19 | BlockRenderer.enableCoordMapping(id, data, render); 20 | } 21 | 22 | public getBoxes(width: number): any[] { 23 | return [ 24 | { side: [0, -1, 0], box: [0.5 - width / 2, 0, 0.5 - width / 2, 0.5 + width / 2, 0.5 - width / 2, 0.5 + width / 2] }, 25 | { side: [0, 1, 0], box: [0.5 - width / 2, 0.5 + width / 2, 0.5 - width / 2, 0.5 + width / 2, 1, 0.5 + width / 2] }, 26 | { side: [0, 0, -1], box: [0.5 - width / 2, 0.5 - width / 2, 0, 0.5 + width / 2, 0.5 + width / 2, 0.5 - width / 2] }, 27 | { side: [0, 0, 1], box: [0.5 - width / 2, 0.5 - width / 2, 0.5 + width / 2, 0.5 + width / 2, 0.5 + width / 2, 1] }, 28 | { side: [-1, 0, 0], box: [0, 0.5 - width / 2, 0.5 - width / 2, 0.5 - width / 2, 0.5 + width / 2, 0.5 + width / 2] }, 29 | { side: [1, 0, 0], box: [0.5 + width / 2, 0.5 - width / 2, 0.5 - width / 2, 1, 0.5 + width / 2, 0.5 + width / 2] } 30 | ] 31 | } 32 | 33 | public get standartModel(): ICRender.Model { 34 | const width = this.width; 35 | const render = new ICRender.Model(); 36 | const boxes = this.getBoxes(width); 37 | for (const box of boxes) { 38 | const renderModel = BlockRenderer.createModel(); 39 | const texture = this.texture.connection; 40 | 41 | let condition = ICRender.BLOCK(box.side[0], box.side[1], box.side[2], this.renderGroup, false); 42 | const groupRules = this.connector.getConnectionRules(); 43 | for (const rule of groupRules) { 44 | const newGroup = ICRender.getGroup(rule.name); 45 | const additionCondition = ICRender.BLOCK(box.side[0], box.side[1], box.side[2], newGroup, rule.exclude); 46 | if (rule.isANDrule) { 47 | condition = ICRender.AND(condition, additionCondition); 48 | } else { 49 | condition = ICRender.OR(condition, additionCondition); 50 | } 51 | } 52 | 53 | renderModel.addBox(box.box[0], box.box[1], box.box[2], box.box[3], 54 | box.box[4], box.box[5], texture.name, texture.data); 55 | render.addEntry(renderModel).setCondition(condition); 56 | } 57 | 58 | // standart box 59 | const model = BlockRenderer.createModel(); 60 | const p0 = 0.5 - width / 2; 61 | const p1 = 0.5 + width / 2; 62 | model.addBox(p0, p0, p0, p1, p1, p1, this.texture.block.name, this.texture.block.data); 63 | render.addEntry(model); 64 | return render; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/dev/core/pipe/components/PipeTexture.ts: -------------------------------------------------------------------------------- 1 | type TexturePair = { 2 | name: string 3 | data: number 4 | } 5 | class PipeTexture { 6 | constructor(public block: TexturePair, public connection: TexturePair, public containerConnection: TexturePair = connection){} 7 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/ItemMachines.ts: -------------------------------------------------------------------------------- 1 | /// 2 | let ITEM_MACHINES = [{ id: 54, data: -1 }]; 3 | 4 | const transportConnector = new TransportPipeConnector(); 5 | const basicRule = transportConnector.getConnectionRules()[0]; 6 | 7 | for (const instance of ITEM_MACHINES) { 8 | ICRender.getGroup(basicRule.name).add(instance.id, instance.data); 9 | } 10 | 11 | Callback.addCallback("PostLoaded", () => { 12 | // For StorageInterface containers 13 | // @ts-ignore 14 | for (const blockID in StorageInterface.data) { 15 | // @ts-ignore 16 | ICRender.getGroup(basicRule.name).add(blockID, -1); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /src/dev/core/pipe/item/abstract/BCTransportPipe.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | abstract class BCTransportPipe extends BCPipe { 4 | public get pipeConnector(): PipeConnector { 5 | if (!this.connector) this.connector = new TransportPipeConnector(); 6 | return this.connector; 7 | } 8 | 9 | public get renderGroups(): RenderGroups { 10 | return { 11 | main: ICRender.getGroup("BCTransportPipe") 12 | }; 13 | } 14 | 15 | public get transportType(): string { 16 | return "item" 17 | } 18 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/abstract/TransportPipeConnector.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class TransportPipeConnector extends PipeConnector { 3 | public canConnectToGroup(groupName: string): boolean { 4 | return groupName == "ItemMachine" 5 | } 6 | 7 | public canPipesConnect(coords0: Vector, coords1: Vector){ 8 | return false; 9 | } 10 | 11 | public getConnectionRules(): ConnectionRule[] { 12 | return [ 13 | {name: "ItemMachine", exclude: false, isANDrule: false} 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/cobble/CobblePipeConnector.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class CobblePipeConnector extends TransportPipeConnector { 3 | public getConnectionRules(): ConnectionRule[] { 4 | const old = super.getConnectionRules(); 5 | old.push({name: "BCPipeStone", exclude: true, isANDrule: true}); 6 | old.push({name: "BCPipeQuartz", exclude: true, isANDrule: true}); 7 | return old; 8 | } 9 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/cobble/PipeCobble.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class PipeCobble extends BCTransportPipe { 4 | public get material(): string { 5 | return "cobble" 6 | } 7 | 8 | public get pipeConnector(): PipeConnector { 9 | if (!this.connector) this.connector = new CobblePipeConnector(); 10 | return this.connector; 11 | } 12 | 13 | public get renderGroups(): RenderGroups { 14 | return { 15 | main: ICRender.getGroup("BCTransportPipe"), 16 | addition: ICRender.getGroup("BCPipeCobble") 17 | }; 18 | } 19 | 20 | protected get pipeTexture(): PipeTexture { 21 | const textureName = `pipe_${this.transportType}_${this.material}` 22 | if (!this.texture) this.texture = new PipeTexture({ name: textureName, data: 0 }, { name: textureName, data: 1 }); 23 | return this.texture; 24 | } 25 | 26 | protected getIngredientForRecipe(): ItemInstance { 27 | return { id: VanillaBlockID.cobblestone, count: 1, data: 0 } 28 | } 29 | } 30 | const cobblePipe = new PipeCobble(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/diamond/DiamondPipeGUI.ts: -------------------------------------------------------------------------------- 1 | const DIAMOND_PIPE_COLORS = [ 2 | "green", 3 | "yellow", 4 | "white", 5 | "black", 6 | "blue", 7 | "red" 8 | ]; 9 | const diamondPipeUIContext: UI.WindowContent = { 10 | standard: { 11 | header: { 12 | text: {text: "Diamond Transporting Pipe"} 13 | }, 14 | background: { 15 | standard: true, 16 | }, 17 | inventory: { 18 | standard: true 19 | } 20 | }, 21 | 22 | elements: { } 23 | }; 24 | const diamondPipeUI = new UI.StandartWindow(diamondPipeUIContext); 25 | 26 | for (let i = 0; i < 6; i++){ 27 | const color = DIAMOND_PIPE_COLORS[i]; 28 | for (let j = 0; j < 9; j++){ 29 | diamondPipeUI.content.elements["slot_" + i + "_" + j] = { 30 | type: "slot", 31 | bitmap: "diamond_pipe_slot_" + color, 32 | x: 370 + j * 65, y: 80 + i * 65 33 | }; 34 | }; 35 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/diamond/DiamondPipeRenderer.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class DiamondPipeRenderer extends PipeRenderer { 3 | 4 | constructor(protected connector: PipeConnector, protected texture: PipeTexture, protected renderGroup: ICRender.Group) { 5 | super(connector, texture, renderGroup); 6 | } 7 | 8 | public get standartModel(): ICRender.Model { 9 | const width = this.width; 10 | const render = new ICRender.Model(); 11 | const boxes = this.getBoxes(width); 12 | for (let i = 0; i < 6; i++) { 13 | const box = boxes[i]; 14 | const renderModel = BlockRenderer.createModel(); 15 | const texture = this.texture.connection; 16 | 17 | let condition = ICRender.BLOCK(box.side[0], box.side[1], box.side[2], this.renderGroup, false); 18 | const groupRules = this.connector.getConnectionRules(); 19 | for (const rule of groupRules) { 20 | const newGroup = ICRender.getGroup(rule.name); 21 | const additionCondition = ICRender.BLOCK(box.side[0], box.side[1], box.side[2], newGroup, rule.exclude); 22 | if (rule.isANDrule) { 23 | condition = ICRender.AND(condition, additionCondition); 24 | } else { 25 | condition = ICRender.OR(condition, additionCondition); 26 | } 27 | } 28 | 29 | renderModel.addBox(box.box[0], box.box[1], box.box[2], box.box[3], 30 | box.box[4], box.box[5], texture.name, i + 1); 31 | render.addEntry(renderModel).setCondition(condition); 32 | } 33 | 34 | // standart box 35 | const model = BlockRenderer.createModel(); 36 | const p0 = 0.5 - width / 2; 37 | const p1 = 0.5 + width / 2; 38 | model.addBox(p0, p0, p0, p1, p1, p1, this.texture.block.name, this.texture.block.data); 39 | render.addEntry(model); 40 | return render; 41 | } 42 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/diamond/DiamondPipeTileEntity.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class DiamondPipeTileEntity { 3 | public readonly useNetworkItemContainer = true; 4 | private container: any; 5 | constructor(protected renderer: PipeRenderer, protected texture: PipeTexture) { } 6 | 7 | // !TileEntity event 8 | public getScreenName = (player: number, coords: Vector) => "main"; 9 | 10 | // !TileEntity event 11 | public getScreenByName = (screenName: string) => diamondPipeUI; 12 | 13 | public canItemGoToSide(item: ItemInstance, index: number): boolean { 14 | let hasFilter = false; 15 | for (let i = 0; i < 9; i++) { 16 | const slot = this.container.getSlot("slot_" + index + "_" + i); 17 | if (slot.id == 0) continue; 18 | if (!hasFilter) hasFilter = true; 19 | if (slot.id == item.id && slot.data == item.data) return true; 20 | } 21 | return !hasFilter; 22 | } 23 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/diamond/PipeDiamond.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | 5 | class PipeDiamond extends BCTransportPipe { 6 | constructor() { 7 | super(); 8 | this.renderer = new DiamondPipeRenderer(this.pipeConnector, this.pipeTexture, this.renderGroups.main); 9 | this.renderer.enableRender(this.block.id, 0); 10 | TileEntity.registerPrototype(this.block.id, 11 | new DiamondPipeTileEntity(this.pipeRenderer, this.texture) 12 | ); 13 | 14 | StorageInterface.createInterface(this.block.id, { 15 | isValidInput: (item) => false 16 | }); 17 | } 18 | 19 | public get material(): string { 20 | return "diamond"; 21 | } 22 | 23 | protected get pipeTexture(): PipeTexture { 24 | const textre = `pipe_${this.transportType}_${this.material}`; 25 | if (!this.texture) { 26 | this.texture = new PipeTexture( 27 | { name: textre, data: 0 }, 28 | { name: textre, data: 1 } 29 | ); 30 | } 31 | return this.texture; 32 | } 33 | 34 | protected getIngredientForRecipe(): ItemInstance { 35 | return { id: VanillaItemID.diamond, count: 1, data: 0 } 36 | } 37 | } 38 | const diamondPipe = new PipeDiamond(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/gold/PipeGold.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class PipeGold extends BCTransportPipe { 3 | constructor() { 4 | super(); 5 | this.pipeSpeed = new PipeSpeed(0.25, 0.07); 6 | } 7 | 8 | public get material(): string { 9 | return "gold" 10 | } 11 | 12 | protected get pipeTexture(): PipeTexture { 13 | const textureName = `pipe_${this.transportType}_${this.material}` 14 | if (!this.texture) this.texture = new PipeTexture({ name: textureName, data: 0 }, { name: textureName, data: 1 }); 15 | return this.texture; 16 | } 17 | 18 | protected getIngredientForRecipe(): ItemInstance { 19 | return { id: VanillaItemID.gold_ingot, count: 1, data: 0 } 20 | } 21 | } 22 | const goldPipe = new PipeGold(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/iron/IronPipeClient.ts: -------------------------------------------------------------------------------- 1 | class IronPipeClient { 2 | private renderConnector: IronPipeRenderConnector 3 | public networkData: SyncedNetworkData; 4 | 5 | public readonly dimension: number; 6 | public x: number; 7 | public y: number; 8 | public z: number; 9 | 10 | constructor(private renderer: PipeRenderer, private texture: PipeTexture, private connector: PipeConnector) { } 11 | 12 | public load() { 13 | const id = BlockSource.getDefaultForDimension(this.dimension).getBlockId(this.x, this.y, this.z); 14 | const pipe = PipeIdMap.getClassById(id); 15 | this.renderConnector = new IronPipeRenderConnector(pipe, this, this.renderer, this.connector, this.texture); 16 | this.renderConnector.ConnectionSide = this.networkData.getInt("orientation"); 17 | this.networkData.addOnDataChangedListener((networkData, isExternalChange) => { 18 | this.renderConnector.ConnectionSide = networkData.getInt("orientation"); 19 | }); 20 | } 21 | 22 | public unload() { 23 | this.renderConnector.destroy(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/dev/core/pipe/item/iron/IronPipeRenderConnector.ts: -------------------------------------------------------------------------------- 1 | class IronPipeRenderConnector { 2 | constructor(public pipeClass: BCPipe, public coords: Vector, protected renderer: PipeRenderer, protected connector: PipeConnector, 3 | protected texture: PipeTexture) { } 4 | 5 | private side: number; 6 | 7 | public get ConnectionSide(): number { 8 | return this.side; 9 | } 10 | 11 | public set ConnectionSide(value: number) { 12 | this.side = value; 13 | this.updateConnections(); 14 | } 15 | 16 | public updateConnections() { 17 | const width = this.renderer.width; 18 | const render = new ICRender.Model(); 19 | const boxes = this.renderer.getBoxes(width); 20 | 21 | for (let i = 0; i < 6; i++) { 22 | const box = boxes[i]; 23 | const renderModel = BlockRenderer.createModel(); 24 | 25 | let condition = ICRender.BLOCK(box.side[0], box.side[1], box.side[2], this.pipeClass.renderGroups.main, false); 26 | const groupRules = this.connector.getConnectionRules(); 27 | for (const rule of groupRules) { 28 | const newGroup = ICRender.getGroup(rule.name); 29 | const additionCondition = ICRender.BLOCK(box.side[0], box.side[1], box.side[2], newGroup, rule.exclude); 30 | if (rule.isANDrule) { 31 | condition = ICRender.AND(condition, additionCondition); 32 | } else { 33 | condition = ICRender.OR(condition, additionCondition); 34 | } 35 | } 36 | let texture: TexturePair; 37 | if (this.ConnectionSide != i) { 38 | texture = this.texture.containerConnection; 39 | } else { 40 | texture = this.texture.connection; 41 | } 42 | 43 | renderModel.addBox(box.box[0], box.box[1], box.box[2], box.box[3], 44 | box.box[4], box.box[5], texture.name, texture.data); 45 | render.addEntry(renderModel).setCondition(condition); 46 | } 47 | 48 | // standart box 49 | const model = BlockRenderer.createModel(); 50 | const p0 = 0.5 - width / 2; 51 | const p1 = 0.5 + width / 2; 52 | model.addBox(p0, p0, p0, p1, p1, p1, this.texture.block.name, this.texture.block.data); 53 | render.addEntry(model); 54 | BlockRenderer.mapAtCoords(this.coords.x, this.coords.y, this.coords.z, render); 55 | } 56 | 57 | public destroy(): void { 58 | BlockRenderer.unmapAtCoords(this.coords.x, this.coords.y, this.coords.z); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/dev/core/pipe/item/iron/IronPipeTileEntity.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class IronPipeTileEntity implements TileEntity.TileEntityPrototype { 3 | private clientFactory: ClientFactory = new ClientFactory(IronPipeClient); 4 | 5 | protected data: any = {} 6 | 7 | public defaultValues: any = { 8 | connectionSide: -1 9 | } 10 | 11 | public x: number; 12 | public y: number; 13 | public z: number; 14 | 15 | public blockSource: BlockSource; 16 | public networkData: SyncedNetworkData; 17 | 18 | public client: IronPipeClient; 19 | 20 | 21 | constructor(protected renderer: PipeRenderer, protected pipeConnector: PipeConnector, protected texture: PipeTexture) { 22 | this.client = this.clientFactory.instantiate(renderer, texture, pipeConnector); 23 | } 24 | 25 | private changeOrientation() { 26 | // ? if connection side is null put < 0 to syncData 27 | this.networkData.putInt("orientation", this.data.connectionSide); 28 | this.networkData.sendChanges(); 29 | } 30 | 31 | // !TileEntity event 32 | public init(): void { 33 | this.checkConnection(); 34 | } 35 | 36 | // !TileEntity event 37 | public click(id, count, data) { 38 | if (id != ItemID.bc_wrench) return false; 39 | 40 | this.updateConnectionSide(true); 41 | return true; 42 | } 43 | 44 | private updateConnectionSide(findNext: boolean = false): void { 45 | this.data.connectionSide = this.getConnectionSide(findNext); 46 | this.changeOrientation(); 47 | } 48 | 49 | public canItemGoToSide(item: ItemInstance, index: number): boolean { 50 | return index == this.data.connectionSide; 51 | } 52 | 53 | /** @param findNext - use true value if you want to rerotate pipe like a wrench */ 54 | protected getConnectionSide(findNext: boolean = false): number { 55 | // * In common situation ends when i gets max in 5 index 56 | // * But if fhis function calling by wrench index can go beyound 57 | // * I think this code is poor, but maybe i fix it in future 58 | for (let t = 0; t < 12; t++) { 59 | const i = t % 6; 60 | if (findNext) { 61 | if (this.data.connectionSide == t) { 62 | findNext = false 63 | } 64 | continue; 65 | } 66 | const relCoords = World.getRelativeCoords(this.x, this.y, this.z, i); 67 | if (this.canConnectTo(relCoords)) return i; 68 | } 69 | // default value 70 | return -1; 71 | } 72 | 73 | public checkConnection(): void { 74 | if (this.data.connectionSide < 0){ 75 | this.updateConnectionSide(); 76 | } else { 77 | const coords = World.getRelativeCoords(this.x, this.y, this.z, this.data.connectionSide); 78 | if (!this.canConnectTo(coords)) { 79 | this.updateConnectionSide(); 80 | } else { 81 | this.changeOrientation(); 82 | } 83 | } 84 | } 85 | 86 | private canConnectTo(coords: Vector): boolean { 87 | const { x, y, z } = coords; 88 | const blockID = this.blockSource.getBlockId(x, y, z); 89 | const relativePipe = PipeIdMap.getClassById(blockID); 90 | if (relativePipe) { 91 | return this.pipeConnector.canConnectToPipe(relativePipe) 92 | } 93 | const container = World.getContainer(x, y, z, this.blockSource); 94 | return this.isValidContainer(container); 95 | } 96 | 97 | private isValidContainer(container): boolean { 98 | if (!container) return false; 99 | 100 | // ? if NativeTileEntity is NullObject 101 | if (container.getSlot(0) == null) return false; 102 | 103 | // ! container.slots contain not only slots. It containt saverID too. 104 | // ! container.slots.length = 1 means that container has 0 slots 105 | if (!container.slots || container.slots.length > 1) return true; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/dev/core/pipe/item/iron/PipeIron.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class PipeIron extends BCTransportPipe { 4 | constructor() { 5 | super(); 6 | TileEntity.registerPrototype(this.block.id, 7 | new IronPipeTileEntity(this.pipeRenderer, this.connector, this.texture) 8 | ); 9 | Block.registerNeighbourChangeFunctionForID(this.block.id, (coords, block, changeCoords, region: BlockSource) => { 10 | const tile = World.getTileEntity(coords.x, coords.y, coords.z, region); 11 | if (tile && TileEntity.isTileEntityLoaded(tile)) { 12 | tile.checkConnection(); 13 | } 14 | } 15 | ); 16 | } 17 | 18 | public get material(): string { 19 | return "iron" 20 | } 21 | 22 | protected get pipeTexture(): PipeTexture { 23 | const textre = `pipe_${this.transportType}_${this.material}`; 24 | if (!this.texture) { 25 | this.texture = new PipeTexture( 26 | { name: textre, data: 0 }, 27 | { name: textre, data: 1 }, 28 | { name: textre, data: 2 } 29 | ); 30 | } 31 | return this.texture; 32 | } 33 | 34 | protected getIngredientForRecipe(): ItemInstance { 35 | return { id: VanillaItemID.iron_ingot, count: 1, data: 0 } 36 | } 37 | } 38 | const ironPipe = new PipeIron(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/obsidian/AxisBoxes.ts: -------------------------------------------------------------------------------- 1 | type BoxPoints = { 2 | start: Vector; 3 | end: Vector 4 | } 5 | 6 | class AxisBoxes { 7 | 8 | public static get X(): BoxPoints { 9 | return { 10 | start: { 11 | x: 0, 12 | y: -1, 13 | z: -1 14 | }, 15 | end: { 16 | x: 1, 17 | y: 2, 18 | z: 2 19 | } 20 | } 21 | } 22 | 23 | public static get Y(): BoxPoints { 24 | return { 25 | start: { 26 | x: -1, 27 | y: 0, 28 | z: -1 29 | }, 30 | end: { 31 | x: 2, 32 | y: 1, 33 | z: 2 34 | } 35 | } 36 | } 37 | 38 | public static get Z(): BoxPoints { 39 | return { 40 | start: { 41 | x: -1, 42 | y: -1, 43 | z: 0 44 | }, 45 | end: { 46 | x: 2, 47 | y: 2, 48 | z: 1 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/obsidian/ObsidianPipeConnector.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class ObsidianPipeConnector extends TransportPipeConnector { 3 | public getConnectionRules(): ConnectionRule[] { 4 | const old = super.getConnectionRules(); 5 | old.push({name: "BCPipeObsidian", exclude: true, isANDrule: true}); 6 | return old; 7 | } 8 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/obsidian/ObsidianPipeItemAccelerator.ts: -------------------------------------------------------------------------------- 1 | /// 2 | const OBSIDIAN_PIPE_DROP_VELOCITY = +__config__.getNumber("obsidian_pipe_drop_velocity"); 3 | class ObsidianPipeItemAccelerator { 4 | constructor(private region: BlockSource, private coords: Vector) { } 5 | 6 | private side: number = null; 7 | 8 | public set ConnectionSide(value: number) { 9 | this.side = value; 10 | } 11 | 12 | public get ConnectionSide(): number { 13 | return this.side; 14 | } 15 | 16 | public accelerate(count: number): void { 17 | if (this.ConnectionSide === null || count <= 0) return; 18 | const target = this.coords; 19 | const side = this.ConnectionSide; 20 | const box = this.getMovedAxisBoxBySide(target, side); 21 | const entities = this.getItems(box, this.region); 22 | 23 | for (const entity of entities) { 24 | Entity.moveToTarget(entity, this.getMoveTarget(), {speed: OBSIDIAN_PIPE_DROP_VELOCITY}); 25 | return; 26 | } 27 | } 28 | 29 | private getItems(box: BoxPoints, region: BlockSource): number[] { 30 | const { x, y, z } = box.start; 31 | const end = box.end; 32 | return region.listEntitiesInAABB(x, y, z, end.x, end.y, end.z, 64, false); 33 | } 34 | 35 | private getMoveTarget(): Vector { 36 | const x = this.coords.x + .5; 37 | const y = this.coords.y + .5; 38 | const z = this.coords.z + .5; 39 | return { x, y, z }; 40 | } 41 | 42 | private getStandartBoxPoints(side: number): BoxPoints { 43 | switch (side) { 44 | case 0: 45 | case 1: 46 | return AxisBoxes.Y; 47 | case 2: 48 | case 3: 49 | return AxisBoxes.Z; 50 | case 4: 51 | case 5: 52 | return AxisBoxes.X; 53 | } 54 | } 55 | 56 | private getMovedAxisBoxBySide(target: Vector, side: number): BoxPoints { 57 | let box = this.getStandartBoxPoints(side); 58 | const movVector = this.getVectorBySide(side); 59 | box = { 60 | start: { 61 | x: target.x + movVector.x + box.start.x, 62 | y: target.y + movVector.y + box.start.y, 63 | z: target.z + movVector.z + box.start.z 64 | }, 65 | end: { 66 | x: target.x + movVector.x + box.end.x, 67 | y: target.y + movVector.y + box.end.y, 68 | z: target.z + movVector.z + box.end.z 69 | } 70 | }; 71 | 72 | return box; 73 | } 74 | 75 | private getVectorBySide(side: number): Vector { 76 | const invertedSide = World.getInverseBlockSide(side); 77 | return World.getRelativeCoords(0, 0, 0, invertedSide); 78 | } 79 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/obsidian/ObsidianPipeItemEjector.ts: -------------------------------------------------------------------------------- 1 | class ObsidianPipeItemEjector { 2 | constructor(private region: BlockSource, private coords: Vector) { } 3 | 4 | public set ConnectionSide(value: number) { 5 | this.side = value; 6 | } 7 | 8 | public get ConnectionSide(): number { 9 | return this.side; 10 | } 11 | 12 | private side: number = null; 13 | public collectEntities(maxCount: number): void { 14 | const boxEnd = { 15 | x: this.coords.x + 1, 16 | y: this.coords.y + 1, 17 | z: this.coords.z + 1 18 | }; 19 | 20 | const { x, y, z } = this.coords; 21 | const entitiesToCollect = this.region.listEntitiesInAABB(x, y, z, boxEnd.x, boxEnd.y, boxEnd.z, 64, false); 22 | for (const entity of entitiesToCollect) { 23 | if (!Entity.isExist(entity)) return; 24 | 25 | const item = Entity.getDroppedItem(entity); 26 | if (item.count <= maxCount) { 27 | const speed = this.getItemSpeed(entity); 28 | this.extractItem(item, speed); 29 | Entity.remove(entity); 30 | } 31 | } 32 | } 33 | 34 | private extractItem(item: ItemInstance, speed: number) : void { 35 | const offsetVector = World.getRelativeCoords(0, 0, 0, this.ConnectionSide); 36 | 37 | // ? should I add offsetDistance to config? 38 | const offsetDistance = +__config__.getNumber("travelingItem_offset_distance") ?? 0.01; 39 | 40 | const itemCoords = { 41 | x: this.coords.x + 0.5 + offsetDistance * offsetVector.x, 42 | y: this.coords.y + 0.5 + offsetDistance * offsetVector.y, 43 | z: this.coords.z + 0.5 + offsetDistance * offsetVector.z, 44 | }; 45 | const travelingItem = new TravelingItem(itemCoords, this.region.getDimension(), item, this.ConnectionSide, speed); 46 | } 47 | 48 | private getItemSpeed(entity: number): number { 49 | const distance = Entity.getDistanceToCoords(entity, this.coords); 50 | return Math.max(distance / 50, BCPipe.StandartPipeSpeed.Target); 51 | } 52 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/obsidian/ObsidianPipeTargetConnector.ts: -------------------------------------------------------------------------------- 1 | class ObsidianPipeTargetConnector { 2 | constructor(private region: BlockSource, private coords: Vector, private pipeConnector: PipeConnector) { } 3 | 4 | public getTargetSide(): number | null { 5 | let findedTarget = null; 6 | for (let side = 0; side < 6; side++) { 7 | const { x, y, z } = World.getRelativeCoords(this.coords.x, this.coords.y, this.coords.z, side); 8 | const targetPipe = PipeIdMap.getClassById(this.region.getBlockId(x, y, z)); 9 | const isContainer = this.isValidContainerAtCoords(this.region, x, y, z); 10 | let isValidPipe = false; 11 | if (targetPipe && this.pipeConnector.canConnectToPipe(targetPipe)) isValidPipe = true; 12 | 13 | if (isContainer || isValidPipe) { 14 | if (findedTarget == null) { 15 | findedTarget = side; 16 | } else { 17 | return null; 18 | } 19 | } 20 | } 21 | return findedTarget 22 | } 23 | 24 | private isValidContainerAtCoords(region: BlockSource, x: number, y: number, z: number): boolean { 25 | const container = World.getContainer(x, y, z, region) as UI.Container; 26 | if (!container) return false; 27 | // ! container.slots contain not only slots. It containt saverID too. 28 | // ! container.slots.length = 1 means that container has 0 slots 29 | if (!container.slots || container.slots.length > 1) return true; 30 | } 31 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/obsidian/ObsidianPipeTileEntity.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | class ObsidianPipeTileEntity implements TileEntity.TileEntityPrototype { 5 | constructor(protected pipeConnector: PipeConnector) { } 6 | 7 | // * it will be rewriten during runtime 8 | protected data: any = {} 9 | 10 | public defaultValues: any = {// * it will be rewriten during runtime 11 | connectionSide: null, 12 | energy: 0 13 | } 14 | 15 | public x: number; 16 | public y: number; 17 | public z: number; 18 | 19 | public blockSource: BlockSource; 20 | 21 | private targetConnector: ObsidianPipeTargetConnector; 22 | private ejector: ObsidianPipeItemEjector; 23 | private accelerator: ObsidianPipeItemAccelerator; 24 | 25 | // !TileEntity event 26 | public init(): void { 27 | const pipe = PipeIdMap.getClassById(this.blockSource.getBlockId(this.x, this.y, this.z)); 28 | this.targetConnector = new ObsidianPipeTargetConnector(this.blockSource, this, this.pipeConnector); 29 | this.ejector = new ObsidianPipeItemEjector(this.blockSource, this); 30 | this.accelerator = new ObsidianPipeItemAccelerator(this.blockSource, this); 31 | this.updateConnection(); 32 | } 33 | 34 | // !TileEntity event 35 | public tick(): void { 36 | if ((this.ejector && this.data.connectionSide !== null)) { 37 | this.ejector.collectEntities(this.maxEntitiesToCollect()); 38 | this.accelerator.accelerate(this.maxEntitiesToPull()); 39 | } 40 | this.data.energy = 0; 41 | } 42 | 43 | // !TileEntity event 44 | public destroy() { 45 | this.ejector = null; 46 | } 47 | 48 | // !EnergyNet event 49 | public energyReceive(type, amount, voltage): number { 50 | const storage = this.getMaxEnergyStored(); 51 | const readyToReceive = Math.min(storage - amount, this.getMaxEnergyReceive()); 52 | const received = Math.min(readyToReceive, amount); 53 | this.data.energy += received; 54 | return received; 55 | } 56 | 57 | public updateConnection(): void { 58 | this.data.connectionSide = this.targetConnector.getTargetSide(); 59 | this.ejector.ConnectionSide = this.data.connectionSide; 60 | this.accelerator.ConnectionSide = this.data.connectionSide; 61 | } 62 | 63 | private maxEntitiesToCollect(): number { 64 | return 64; 65 | } 66 | 67 | private maxEntitiesToPull(): number { 68 | return Math.floor(this.data.energy / 10); 69 | } 70 | 71 | public canConnectRedstoneEngine(): boolean { 72 | return true 73 | } 74 | 75 | public getMaxEnergyStored(): number { 76 | return 2560; 77 | } 78 | 79 | public getMaxEnergyReceive(): number { 80 | return 640; 81 | } 82 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/obsidian/PipeObsidian.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | class PipeObsidian extends BCTransportPipe { 5 | constructor() { 6 | super(); 7 | TileEntity.registerPrototype(this.block.id, 8 | new ObsidianPipeTileEntity(this.pipeConnector) 9 | ); 10 | EnergyTileRegistry.addEnergyTypeForId(this.block.id, RF); 11 | Block.registerNeighbourChangeFunctionForID(this.block.id, (coords, block, changeCoords, region: BlockSource) => { 12 | const tile = World.getTileEntity(coords.x, coords.y, coords.z, region); 13 | if (tile && tile.targetConnector) { 14 | tile.updateConnection(); 15 | } 16 | } 17 | ); 18 | } 19 | 20 | public get material(): string { 21 | return "obsidian" 22 | } 23 | 24 | public get pipeConnector(): PipeConnector { 25 | if (!this.connector) this.connector = new ObsidianPipeConnector(); 26 | return this.connector; 27 | } 28 | 29 | public get renderGroups(): RenderGroups { 30 | return { 31 | main: ICRender.getGroup("BCTransportPipe"), 32 | addition: ICRender.getGroup("BCPipeObsidian"), 33 | }; 34 | } 35 | 36 | protected get pipeTexture(): PipeTexture { 37 | const textureName = `pipe_${this.transportType}_${this.material}` 38 | if (!this.texture) this.texture = new PipeTexture({ name: textureName, data: 0 }, { name: textureName, data: 1 }); 39 | return this.texture; 40 | } 41 | 42 | protected getIngredientForRecipe(): ItemInstance { 43 | return { id: VanillaBlockID.obsidian, count: 1, data: 0 } 44 | } 45 | } 46 | const obsidianPipe = new PipeObsidian(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/quartz/PipeQuartz.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class PipeQuartz extends BCTransportPipe { 4 | constructor() { 5 | super(); 6 | this.pipeSpeed = new PipeSpeed(0.01, 0.002); 7 | } 8 | 9 | public get material(): string { 10 | return "quartz" 11 | } 12 | 13 | public get pipeConnector(): PipeConnector { 14 | if (!this.connector) this.connector = new QuartzPipeConnector(); 15 | return this.connector; 16 | } 17 | 18 | public get renderGroups(): RenderGroups { 19 | return { 20 | main: ICRender.getGroup("BCTransportPipe"), 21 | addition: ICRender.getGroup("BCPipeQuartz") 22 | }; 23 | } 24 | 25 | protected get pipeTexture(): PipeTexture { 26 | const textureName = `pipe_${this.transportType}_${this.material}` 27 | if (!this.texture) this.texture = new PipeTexture({ name: textureName, data: 0 }, { name: textureName, data: 1 }); 28 | return this.texture; 29 | } 30 | 31 | protected getIngredientForRecipe(): ItemInstance { 32 | return { id: VanillaItemID.quartz, count: 1, data: 0 } 33 | } 34 | } 35 | const quartzPipe = new PipeQuartz(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/quartz/QuartzPipeConnector.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class QuartzPipeConnector extends TransportPipeConnector { 3 | public getConnectionRules(): ConnectionRule[] { 4 | const old = super.getConnectionRules(); 5 | old.push({name: "BCPipeStone", exclude: true, isANDrule: true}); 6 | old.push({name: "BCPipeCobble", exclude: true, isANDrule: true}); 7 | return old; 8 | } 9 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/sandstone/PipeSandstone.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class PipeSandstone extends BCTransportPipe { 4 | public get material(): string { 5 | return "sandstone" 6 | } 7 | 8 | public get pipeConnector(): PipeConnector { 9 | if (!this.connector) this.connector = new SandstonePipeConnector(); 10 | return this.connector; 11 | } 12 | 13 | protected get pipeTexture(): PipeTexture { 14 | const textureName = `pipe_${this.transportType}_${this.material}` 15 | if (!this.texture) this.texture = new PipeTexture({ name: textureName, data: 0 }, { name: textureName, data: 1 }); 16 | return this.texture; 17 | } 18 | 19 | protected getIngredientForRecipe(): ItemInstance { 20 | return { id: VanillaBlockID.sandstone, count: 1, data: 0 } 21 | } 22 | } 23 | const sandstonePipe = new PipeSandstone(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/sandstone/SandstonePipeConnector.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class SandstonePipeConnector extends TransportPipeConnector { 4 | public getConnectionRules(): ConnectionRule[] { 5 | return []; 6 | } 7 | 8 | protected getBlacklistConnectedBlock(): Tile[] { 9 | return ITEM_MACHINES; 10 | } 11 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/stone/PipeStone.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | class PipeStone extends BCTransportPipe { 4 | public get material(): string { 5 | return "stone" 6 | } 7 | 8 | public get pipeConnector(): PipeConnector { 9 | if (!this.connector) this.connector = new StonePipeConnector(); 10 | return this.connector; 11 | } 12 | 13 | public get renderGroups(): RenderGroups { 14 | return { 15 | main: ICRender.getGroup("BCTransportPipe"), 16 | addition: ICRender.getGroup("BCPipeStone") 17 | }; 18 | } 19 | 20 | protected get pipeTexture(): PipeTexture { 21 | const textureName = `pipe_${this.transportType}_${this.material}` 22 | if (!this.texture) this.texture = new PipeTexture({ name: textureName, data: 0 }, { name: textureName, data: 1 }); 23 | return this.texture; 24 | } 25 | 26 | protected getIngredientForRecipe(): ItemInstance { 27 | return { id: VanillaBlockID.stone, count: 1, data: 0 } 28 | } 29 | } 30 | const stonePipe = new PipeStone(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/stone/StonePipeConnector.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class StonePipeConnector extends TransportPipeConnector { 3 | public getConnectionRules(): ConnectionRule[] { 4 | const old = super.getConnectionRules(); 5 | old.push({name: "BCPipeCobble", exclude: true, isANDrule: true}); 6 | old.push({name: "BCPipeQuartz", exclude: true, isANDrule: true}); 7 | return old; 8 | } 9 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/travelingItem/TravelingItem.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | const ITEM_DROP_VELOCITY = +__config__.getNumber("item_drop_velocity"); 6 | const ITEM_COOLDOWN_TIME = 100; 7 | const DESTROY_CHECK_FREQUENCY = 3; 8 | class TravelingItem { 9 | // ! its just a Updatable flag 10 | public remove: boolean = false; 11 | private readonly itemMover: TravelingItemMover; 12 | 13 | public blockSource: BlockSource; 14 | private networkEntity: NetworkEntity; 15 | 16 | private cooldown = 0; 17 | 18 | public static saverId = Saver.registerObjectSaver("TravelingItemSaver", { 19 | save(travelingItem: TravelingItem) { 20 | const dataToSave = { 21 | dimension: travelingItem.dimension, 22 | coords: travelingItem.itemMover.Coords, 23 | moveIndex: travelingItem.itemMover.MoveVectorIndex, 24 | moveSpeed: travelingItem.itemMover.MoveSpeed, 25 | targetSpeed: travelingItem.itemMover.PipeSpeed.Target, 26 | deltaSpeed: travelingItem.itemMover.PipeSpeed.Delta, 27 | progressPart: travelingItem.itemMover.ProgressPart, 28 | item: travelingItem.item, 29 | }; 30 | return dataToSave; 31 | }, 32 | 33 | read(scope) { 34 | const item = new TravelingItem( 35 | scope.coords, 36 | scope.dimension, 37 | scope.item, 38 | scope.moveIndex, 39 | scope.moveSpeed, 40 | new PipeSpeed(scope.targetSpeed, scope.deltaSpeed), 41 | scope.progressPart 42 | ); 43 | } 44 | }); 45 | 46 | constructor( 47 | coords: Vector, 48 | private dimension: number, 49 | private item: ItemInstance, 50 | moveVectorIndex: number, 51 | moveSpeed: number = null, 52 | pipeSpeed: PipeSpeed = BCPipe.StandartPipeSpeed, 53 | progressPart: number = 0 54 | ) { 55 | this.itemMover = new TravelingItemMover(coords, progressPart, moveVectorIndex, this.item, pipeSpeed, moveSpeed); 56 | Saver.registerObject(this, TravelingItem.saverId); 57 | Updatable.addUpdatable(this); 58 | } 59 | 60 | public get Coords(): Vector { 61 | return this.itemMover.Coords; 62 | } 63 | 64 | public get VisualItem(): { id, count, data } { 65 | return { 66 | id: this.item.id, 67 | count: this.item.count, 68 | data: this.item.data 69 | }; 70 | } 71 | 72 | public get MoveData(): TravelingItemMoveData { 73 | return { 74 | coordsFrom: this.itemMover.PrevCoords, 75 | vectorIndex: this.itemMover.MoveVectorIndex, 76 | time: this.itemMover.TravelTime 77 | } 78 | } 79 | 80 | // * We need this to pass this["update"] existing 81 | public update = () => { 82 | if (this.cooldown-- > 0) { 83 | return; 84 | } 85 | 86 | if (!this.blockSource) { 87 | this.blockSource = BlockSource.getDefaultForDimension(this.dimension); 88 | if (!this.blockSource) { 89 | this.cooldown = ITEM_COOLDOWN_TIME; 90 | return; 91 | } else { 92 | this.networkEntity = new NetworkEntity(TravelingItemNetworkType, this); 93 | this.updateMoveData(); 94 | } 95 | } 96 | 97 | const { x, y, z } = this.itemMover.AbsoluteCoords; 98 | /** 99 | * If an object moves in an unloaded chunk, 100 | * then it can exit its pipe network and fall into another 101 | * that is not connected to the past 102 | */ 103 | if (!this.blockSource.isChunkLoaded(Math.floor(x / 16), Math.floor(z / 16))) { 104 | this.cooldown = ITEM_COOLDOWN_TIME; 105 | return; 106 | } 107 | 108 | if (this.itemMover.hasReached()) { 109 | /* 110 | * checking for block destroy 111 | * I think this way is more convenient than array of travelingItems 112 | * and DestroyBlock check 113 | */ 114 | if (this.blockSource.getBlockId(x, y, z) == 0) { 115 | this.destroy(true); 116 | return; 117 | } 118 | const tileEntity = World.getTileEntity(x, y, z, this.blockSource); 119 | if (tileEntity?.__initialized === false) { 120 | this.cooldown = ITEM_COOLDOWN_TIME; 121 | return; 122 | } 123 | 124 | if (this.modifyByPipe()) { 125 | this.destroy(); 126 | return; 127 | } 128 | const storage = StorageInterface.getStorage(this.blockSource, x, y, z); 129 | if (this.itemMover.isValidStorage(storage, World.getInverseBlockSide(this.itemMover.MoveVectorIndex))) { 130 | const pushedCount = storage.addItem(this.item, World.getInverseBlockSide(this.itemMover.MoveVectorIndex)); 131 | 132 | if (pushedCount > 0) { 133 | this.destroy(); 134 | return; 135 | } 136 | } 137 | 138 | this.networkEntity.getClients().setupDistancePolicy(x, y, z, this.blockSource.getDimension(), 32); 139 | const findResult = this.itemMover.findNewMoveVector(this.blockSource); 140 | if (findResult > 0) { 141 | this.updateMoveData(); 142 | } else if (findResult < 0) { 143 | this.cooldown = ITEM_COOLDOWN_TIME; 144 | } else { 145 | this.destroy(true); 146 | return; 147 | } 148 | } 149 | 150 | this.itemMover.move(); 151 | }; 152 | 153 | /** 154 | * @returns {boolean} should destroy item 155 | */ 156 | private modifyByPipe(): boolean { 157 | const { x, y, z } = this.itemMover.AbsoluteCoords; 158 | const tile = World.getTileEntity(x, y, z, this.blockSource) 159 | if (!tile) return false; 160 | 161 | // ? modifyTravelingItem(item: TravelingItem): boolean 162 | return tile.modifyTravelingItem ? tile.modifyTravelingItem(this) : false; 163 | } 164 | 165 | private updateMoveData(): void { 166 | this.networkEntity.send("moveData", this.MoveData); 167 | } 168 | 169 | 170 | private destroy(drop: boolean = false): void { 171 | if (drop) this.drop(); 172 | this.remove = true; 173 | this.networkEntity.remove(); 174 | } 175 | 176 | private drop(): void { 177 | const { x, y, z } = this.itemMover.Coords; 178 | const { id, count, data, extra } = this.item; 179 | const entity = this.blockSource.spawnDroppedItem(x, y, z, id, count, data, extra || null); 180 | 181 | const speed = ITEM_DROP_VELOCITY; 182 | const velVec = this.itemMover.getVectorBySide(this.itemMover.MoveVectorIndex); 183 | Entity.addVelocity(entity, velVec.x * speed, velVec.y * speed, velVec.z * speed); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/dev/core/pipe/item/travelingItem/TravelingItemAnimation.ts: -------------------------------------------------------------------------------- 1 | /// 2 | const IS_INTERPOLATION_ENABLED = __config__.getBool( 3 | "animation_movement_interpolation" 4 | ); 5 | const AVERAGE_PING = +__config__.getNumber("relative_max_ping"); 6 | interface TimedVector extends Vector { 7 | time: number; 8 | } 9 | 10 | class TravelingItemAnimation implements Updatable { 11 | private readonly animation: any; 12 | private readonly randomOffset = Math.random() / 100; 13 | remove: boolean = false; 14 | 15 | private time: 0; 16 | private startPos: Vector; 17 | private targetPos1: TimedVector; 18 | private targetPos2: TimedVector; 19 | 20 | constructor(private coords: Vector, item: ItemInstance) { 21 | this.animation = new Animation.Item(coords.x, coords.y, coords.z); 22 | this.describe(item); 23 | this.animation.load(); 24 | this.animation.setInterpolationEnabled(IS_INTERPOLATION_ENABLED); 25 | } 26 | 27 | public get Coords(): Vector { 28 | return this.coords; 29 | } 30 | 31 | public update = () => { 32 | if (this.time < this.targetPos2.time) { 33 | if (this.time < this.targetPos1.time) { 34 | // go to targetPos1 35 | const progress = Math.min(this.time / this.targetPos1.time, 1); 36 | this.updateCoords( 37 | this.interpolateBetweenPositions( 38 | this.startPos, 39 | this.targetPos1, 40 | progress 41 | ) 42 | ); 43 | } else { 44 | // go to targetPos2 45 | const progress = Math.min(1, 46 | (this.time - this.targetPos1.time) / (this.targetPos2.time - this.targetPos1.time) 47 | ); 48 | this.updateCoords( 49 | this.interpolateBetweenPositions( 50 | this.targetPos1, 51 | this.targetPos2, 52 | progress 53 | ) 54 | ); 55 | } 56 | } 57 | this.time++; 58 | 59 | const { x, y, z } = this.Coords; 60 | this.animation.setPos(x, y, z); 61 | }; 62 | 63 | public updateMoveData(packet: TravelingItemMoveData): void { 64 | const moveVector = this.getVectorBySide(packet.vectorIndex); 65 | 66 | this.time = 0; 67 | this.startPos = this.Coords; 68 | 69 | const totalTime = Math.min( 70 | packet.time * 1.5, 71 | packet.time + AVERAGE_PING 72 | ); 73 | 74 | // axis is "x", "y" or "z" 75 | const axis = this.getAxisByIndex(packet.vectorIndex); 76 | const distance = Math.abs( 77 | packet.coordsFrom[axis] - this.startPos[axis] 78 | ); 79 | 80 | // dis1To2 is always 1 81 | const speed = (distance + 1) / totalTime; 82 | const time1 = distance / speed / 50; 83 | 84 | this.targetPos1 = { 85 | x: packet.coordsFrom.x, 86 | y: packet.coordsFrom.y, 87 | z: packet.coordsFrom.z, 88 | time: time1, 89 | }; 90 | 91 | const time2 = totalTime / 50; 92 | this.targetPos2 = { 93 | x: this.targetPos1.x + moveVector.x, 94 | y: this.targetPos1.y + moveVector.y, 95 | z: this.targetPos1.z + moveVector.z, 96 | time: time2, 97 | }; 98 | } 99 | 100 | /** 101 | * Thanks Zheka2304 102 | */ 103 | private interpolateBetweenPositions(pos1: Vector, pos2: Vector, f: number) { 104 | f = Math.min(Math.max(0, f), 1); 105 | return { 106 | x: pos1.x * (1 - f) + pos2.x * f, 107 | y: pos1.y * (1 - f) + pos2.y * f, 108 | z: pos1.z * (1 - f) + pos2.z * f, 109 | }; 110 | } 111 | 112 | private describe(item: ItemInstance): void { 113 | this.animation.describeItem({ 114 | id: Network.serverToLocalId(item.id), 115 | count: 1, 116 | data: item.data, 117 | notRandomize: true, 118 | size: 0.3, 119 | }); 120 | } 121 | 122 | public updateCoords(coords: Vector): void { 123 | // removing visual collisions 124 | this.coords = { 125 | x: coords.x + this.randomOffset, 126 | y: coords.y + this.randomOffset, 127 | z: coords.z + this.randomOffset, 128 | }; 129 | } 130 | 131 | // *Heh-heh cunning Nikolai won 132 | public getVectorBySide(side: number): Vector { 133 | return World.getRelativeCoords(0, 0, 0, side); 134 | } 135 | 136 | private getAxisByIndex(side: number): string { 137 | switch (side) { 138 | case 0: 139 | case 1: 140 | return "y"; 141 | case 2: 142 | case 3: 143 | return "z"; 144 | case 4: 145 | case 5: 146 | return "x"; 147 | } 148 | } 149 | 150 | public destroy(): void { 151 | this.animation.destroy(); 152 | this.remove = true; 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/dev/core/pipe/item/travelingItem/TravelingItemMoveData.ts: -------------------------------------------------------------------------------- 1 | type TravelingItemMoveData = { 2 | coordsFrom: Vector, 3 | vectorIndex: number, 4 | time: number 5 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/travelingItem/TravelingItemMover.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class TravelingItemMover { 3 | private coords: Vector; 4 | private prevCoords: Vector; 5 | 6 | private prevCoordsTime: number; 7 | private nextCoordsTime: number; 8 | 9 | constructor( 10 | initialCoords: Vector, 11 | private progressPart: number, 12 | private moveVectorIndex: number, 13 | private item: ItemInstance, 14 | private pipeSpeed: PipeSpeed = BCPipe.StandartPipeSpeed, 15 | private moveSpeed: number 16 | ) { 17 | this.coords = this.coordsToFixed(initialCoords); 18 | if (!this.moveSpeed) { 19 | this.moveSpeed = this.pipeSpeed.Target; 20 | } 21 | this.updateCoordsTime(); 22 | this.updatePrevCoords(); 23 | } 24 | 25 | public get Coords(): Vector { 26 | return this.coords; 27 | } 28 | 29 | public get PrevCoords(): Vector { 30 | return this.prevCoords; 31 | } 32 | 33 | public get NextCoords(): Vector { 34 | const prev = this.PrevCoords; 35 | const vec = this.getVectorBySide(this.MoveVectorIndex); 36 | prev.x += vec.x; 37 | prev.y += vec.y; 38 | prev.z += vec.z; 39 | return prev; 40 | } 41 | 42 | public get ProgressPart(): number { 43 | return this.progressPart; 44 | } 45 | 46 | public get Time(): number { 47 | return java.lang.System.currentTimeMillis(); 48 | } 49 | 50 | public get TravelTime(): number { 51 | return this.nextCoordsTime - this.prevCoordsTime; 52 | } 53 | 54 | public get PipeSpeed(): PipeSpeed { 55 | return this.pipeSpeed; 56 | } 57 | 58 | public set PipeSpeed(speed: PipeSpeed) { 59 | this.pipeSpeed = speed; 60 | } 61 | 62 | public get MoveSpeed(): number { 63 | return this.moveSpeed; 64 | } 65 | 66 | public get MoveVectorIndex(): number { 67 | return this.moveVectorIndex; 68 | } 69 | 70 | public get AbsoluteCoords(): Vector { 71 | const { x, y, z } = this.Coords; 72 | return { 73 | x: Math.floor(x), 74 | y: Math.floor(y), 75 | z: Math.floor(z), 76 | }; 77 | } 78 | 79 | public hasReached(): boolean { 80 | return this.Time >= this.nextCoordsTime; 81 | } 82 | 83 | public move(): void { 84 | if (this.moveSpeed <= 0 || this.moveVectorIndex == null) return; 85 | const moveVector = this.getVectorBySide(this.MoveVectorIndex); 86 | 87 | const moveTime = this.nextCoordsTime - this.prevCoordsTime; 88 | const timePassed = this.Time - this.prevCoordsTime; 89 | this.progressPart = Math.min(timePassed / moveTime, 1); 90 | 91 | const newCoords = { 92 | x: this.prevCoords.x + moveVector.x * this.ProgressPart, 93 | y: this.prevCoords.y + moveVector.y * this.ProgressPart, 94 | z: this.prevCoords.z + moveVector.z * this.ProgressPart 95 | }; 96 | 97 | this.coords = this.coordsToFixed(newCoords); 98 | } 99 | 100 | public findNewMoveVector(region: BlockSource): number { 101 | var relativePaths = this.getRelativePaths(region); 102 | if (relativePaths === null) { 103 | return -1; 104 | } 105 | const nextPipes = this.filterPaths(relativePaths, region); 106 | const keys = Object.keys(nextPipes); 107 | 108 | if (keys.length > 0) { 109 | const keyIndex = this.random(keys.length); 110 | this.moveVectorIndex = parseInt(keys[keyIndex]); 111 | // ? should I delete fitCoords? 112 | this.fitCoordsToCenter(); 113 | this.prevCoords = this.Coords; 114 | this.updateMoveSpeed(region); 115 | this.updateCoordsTime(); 116 | return 1; 117 | } 118 | 119 | return 0; 120 | } 121 | 122 | /** 123 | * @param progressPart use only saves reading 124 | */ 125 | private updateCoordsTime(progressPart: number = 0): void { 126 | const speedInMs = this.MoveSpeed / 50; 127 | const totalTimeInMs = 1 / speedInMs; 128 | this.prevCoordsTime = this.Time - totalTimeInMs * progressPart; 129 | this.nextCoordsTime = this.Time + totalTimeInMs * (1 - progressPart); 130 | } 131 | /** 132 | * use only saves reading 133 | */ 134 | private updatePrevCoords(): void { 135 | const moveVector = this.getVectorBySide(this.MoveVectorIndex); 136 | const relativePrevCoords = { 137 | x: this.Coords.x - moveVector.x * this.ProgressPart, 138 | y: this.Coords.y - moveVector.y * this.ProgressPart, 139 | z: this.Coords.z - moveVector.z * this.ProgressPart 140 | }; 141 | this.prevCoords = this.coordsToFixed(relativePrevCoords); 142 | } 143 | 144 | public updateMoveSpeed(region: BlockSource): void { 145 | // update pipeSpeed 146 | this.pipeSpeed = this.getClassOfCurrentPipe(region).PipeSpeed; 147 | 148 | if (this.MoveSpeed < this.PipeSpeed.Target) { 149 | this.moveSpeed += this.PipeSpeed.Delta; 150 | } else if (this.MoveSpeed > this.PipeSpeed.Target) { 151 | this.moveSpeed -= this.PipeSpeed.Delta; 152 | } 153 | } 154 | 155 | /** 156 | * @returns {object} which looks like {"sideIndex": pipeClass | container} or null if chunk unloaded 157 | */ 158 | private getRelativePaths(region: BlockSource): object | null { 159 | const targets = {}; 160 | for (let i = 0; i < 6; i++) { 161 | const backVectorIndex = World.getInverseBlockSide(this.moveVectorIndex); 162 | if (i != backVectorIndex) { 163 | const curX = this.AbsoluteCoords.x; 164 | const curY = this.AbsoluteCoords.y; 165 | const curZ = this.AbsoluteCoords.z; 166 | const { x, y, z } = World.getRelativeCoords(curX, curY, curZ, i); 167 | 168 | if (!region.isChunkLoadedAt(x, z)) return null; 169 | 170 | const pipeBlockID = region.getBlockId(x, y, z); 171 | const pipeBlockData = region.getBlockData(x, y, z); 172 | const relativePipeClass = PipeIdMap.getClassById(pipeBlockID); 173 | const currentConnector = this.getClassOfCurrentPipe(region)?.pipeConnector; 174 | if (relativePipeClass != null && currentConnector?.canConnectToPipe(relativePipeClass)) { 175 | targets[i] = relativePipeClass; 176 | continue; 177 | } 178 | 179 | let tile = TileEntity.getTileEntity(x, y, z, region); 180 | if (tile?.__initialized === false) return null; 181 | 182 | const storage = StorageInterface.getStorage(region, x, y, z); 183 | if (this.isValidStorage(storage, World.getInverseBlockSide(i)) && !currentConnector?.hasBlacklistBlockID(pipeBlockID, pipeBlockData)) { 184 | targets[i] = storage; 185 | } 186 | } 187 | } 188 | return targets; 189 | } 190 | 191 | public isValidStorage(storage: Storage, side: number): boolean { 192 | const slots = storage?.getInputSlots(side); 193 | if (!slots) return false; 194 | 195 | let trueSlotsLength = slots.length; 196 | if (trueSlotsLength > 0 && slots[0] == "_json_saver_id") { 197 | // ! tileEntity container has jsonSaverId in slots[0] 198 | trueSlotsLength -= 1; 199 | } 200 | return trueSlotsLength > 0; 201 | } 202 | 203 | /** 204 | * @param {object} is returnable from getRelativePaths 205 | */ 206 | private filterPaths(paths: object, region: BlockSource): object { 207 | const { x, y, z } = this.AbsoluteCoords; 208 | const tileEntity = World.getTileEntity(x, y, z, region); 209 | if (tileEntity && tileEntity.canItemGoToSide) { 210 | const keys = Object.keys(paths); 211 | for (const t in keys) { 212 | const index = keys[t]; 213 | // ? canItemGoToSide(item: ItemInstance, index: number): boolean 214 | if (!tileEntity.canItemGoToSide(this.item, index)) { 215 | delete paths[index]; 216 | } 217 | } 218 | } 219 | return paths; 220 | } 221 | 222 | private fitCoordsToCenter(): void { 223 | const absCoords = this.AbsoluteCoords; 224 | this.coords = { 225 | x: absCoords.x + .5, 226 | y: absCoords.y + .5, 227 | z: absCoords.z + .5 228 | }; 229 | } 230 | 231 | public getClassOfCurrentPipe(region: BlockSource): BCPipe | null { 232 | const { x, y, z } = this.AbsoluteCoords; 233 | const blockID = region.getBlockId(x, y, z); 234 | return PipeIdMap.getClassById(blockID); 235 | } 236 | 237 | public isInsidePipe(region: BlockSource): boolean { 238 | const { x, y, z } = this.Coords; 239 | const isChunkLoaded = region.isChunkLoaded(Math.floor(x / 16), Math.floor(z / 16)); 240 | return !isChunkLoaded || this.getClassOfCurrentPipe(region) != null; 241 | } 242 | 243 | private random(max: number): number { 244 | return Math.floor(Math.random() * max); 245 | } 246 | 247 | // *Heh-heh cunning Nikolai won 248 | public getVectorBySide(side: number): Vector { 249 | return World.getRelativeCoords(0, 0, 0, side); 250 | } 251 | 252 | public isInCoordsCenter(): boolean { 253 | const coords = this.Coords; 254 | const isInCenterByX = coords.x % 0.5 == 0 && coords.x % 1 != 0; 255 | const isInCenterByY = coords.y % 0.5 == 0 && coords.y % 1 != 0; 256 | const isInCenterByZ = coords.z % 0.5 == 0 && coords.z % 1 != 0; 257 | return isInCenterByX && isInCenterByY && isInCenterByZ; 258 | } 259 | 260 | private coordsToFixed(coords: Vector): Vector { 261 | return { 262 | x: Math.round(coords.x * 100) / 100, 263 | y: Math.round(coords.y * 100) / 100, 264 | z: Math.round(coords.z * 100) / 100, 265 | }; 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /src/dev/core/pipe/item/travelingItem/TravelingItemNetworkEntity.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | 5 | const TravelingItemNetworkType = new NetworkEntityType("bc.item") 6 | .setClientListSetupListener((list, target: TravelingItem, entity) => { 7 | const { x, y, z } = target.Coords; 8 | list.setupDistancePolicy(x, y, z, target.blockSource.getDimension(), 32); 9 | }) 10 | .setClientEntityAddedListener((entity, packet: { coords, item, moveData }) => { 11 | const target = new TravelingItemAnimation(packet.coords, packet.item); 12 | target.updateMoveData(packet.moveData); 13 | 14 | Updatable.addLocalUpdatable(target); 15 | return target; 16 | }) 17 | .setClientEntityRemovedListener((target: TravelingItemAnimation, entity) => { 18 | target.destroy(); 19 | }) 20 | .setClientAddPacketFactory((target: TravelingItem, entity, client) => { 21 | return { coords: target.Coords, item: target.VisualItem, moveData: target.MoveData } 22 | }) 23 | .addClientPacketListener("moveData", (target: TravelingItemAnimation, entity, packetData: TravelingItemMoveData) => { 24 | target.updateMoveData(packetData); 25 | }); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/void/PipeVoid.ts: -------------------------------------------------------------------------------- 1 | 2 | /// 3 | /// 4 | /// 5 | class PipeVoid extends BCTransportPipe { 6 | constructor() { 7 | super(); 8 | TileEntity.registerPrototype(this.block.id, 9 | new VoidPipeTileEntity() 10 | ); 11 | } 12 | 13 | public get material(): string { 14 | return "void" 15 | } 16 | 17 | protected get pipeTexture(): PipeTexture { 18 | const textureName = `pipe_${this.transportType}_${this.material}` 19 | if (!this.texture) this.texture = new PipeTexture({ name: textureName, data: 0 }, { name: textureName, data: 1 }); 20 | return this.texture; 21 | } 22 | 23 | protected getRecipe(ingredient: ItemInstance): PipeRecipe { 24 | const ingredients = this.Ingredients; 25 | return new PipeDoubleRecipe(ingredients[0], ingredients[1]); 26 | } 27 | 28 | protected get Ingredients(): ItemInstance[] { 29 | return [ 30 | { id: VanillaItemID.redstone, count: 1, data: 0 }, 31 | { id: VanillaItemID.dye, count: 1, data: 0 } 32 | ] 33 | } 34 | 35 | protected getIngredientForRecipe(): ItemInstance { 36 | return null 37 | } 38 | } 39 | const voidPipe = new PipeVoid(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/void/VoidPipeTileEntity.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class VoidPipeTileEntity { 3 | public modifyTravelingItem(travelingItem: TravelingItem): boolean { 4 | return true; 5 | } 6 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/wooden/PipeWooden.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | 5 | type RenderGroups = { 6 | main: ICRender.Group; 7 | addition?: ICRender.Group; 8 | }; 9 | 10 | class PipeWooden extends BCTransportPipe { 11 | constructor() { 12 | super(); 13 | TileEntity.registerPrototype(this.block.id, 14 | new WoodenPipeTileEntity(this.pipeRenderer, this.texture) 15 | ); 16 | EnergyTileRegistry.addEnergyTypeForId(this.block.id, RF); 17 | Block.registerNeighbourChangeFunctionForID(this.block.id, (coords, block, changeCoords, region: BlockSource) => { 18 | const tile = World.getTileEntity(coords.x, coords.y, coords.z, region); 19 | if (tile && tile.itemEjector) { 20 | tile.checkConnection(); 21 | } 22 | } 23 | ); 24 | } 25 | 26 | public get material(): string { 27 | return "wood"; 28 | } 29 | 30 | public get pipeConnector(): PipeConnector { 31 | if (!this.connector) this.connector = new WoodenPipeConnector(); 32 | return this.connector; 33 | } 34 | 35 | public get renderGroups(): RenderGroups { 36 | return { 37 | main: ICRender.getGroup("BCTransportPipe"), 38 | addition: ICRender.getGroup("BCPipeWooden"), 39 | }; 40 | } 41 | 42 | protected get pipeTexture(): PipeTexture { 43 | const textre = `pipe_${this.transportType}_${this.material}`; 44 | if (!this.texture) { 45 | this.texture = new PipeTexture( 46 | { name: textre, data: 0 }, 47 | { name: textre, data: 1 }, 48 | { name: textre, data: 2 } 49 | ); 50 | } 51 | return this.texture; 52 | } 53 | 54 | protected getIngredientForRecipe(): ItemInstance { 55 | return { id: VanillaBlockID.planks, count: 1, data: 0 } 56 | } 57 | } 58 | const woodPipe = new PipeWooden(); -------------------------------------------------------------------------------- /src/dev/core/pipe/item/wooden/WoodenPipeClient.ts: -------------------------------------------------------------------------------- 1 | class WoodenPipeClient { 2 | private storageConnector: WoodenPipeStorageConnector 3 | public networkData: SyncedNetworkData; 4 | 5 | public x: number; 6 | public y: number; 7 | public z: number; 8 | 9 | constructor(private renderer: PipeRenderer, private texture: PipeTexture) { } 10 | 11 | public load() { 12 | this.storageConnector = new WoodenPipeStorageConnector(this, this.renderer, this.texture); 13 | this.storageConnector.ConnectionSide = this.networkData.getInt("orientation"); 14 | this.networkData.addOnDataChangedListener((networkData, isExternalChange) => { 15 | this.storageConnector.ConnectionSide = networkData.getInt("orientation"); 16 | }); 17 | } 18 | 19 | public unload() { 20 | this.storageConnector.destroy(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/wooden/WoodenPipeConnector.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class WoodenPipeConnector extends TransportPipeConnector { 3 | public getConnectionRules(): ConnectionRule[] { 4 | const old = super.getConnectionRules(); 5 | old.push({name: "BCPipeWooden", exclude: true, isANDrule: true}); 6 | return old; 7 | } 8 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/wooden/WoodenPipeItemEjector.ts: -------------------------------------------------------------------------------- 1 | /// 2 | class WoodenPipeItemEjector { 3 | private side: number | null; 4 | private containerData: { source: Storage; slots } | null; 5 | constructor( 6 | public readonly region: BlockSource, 7 | public readonly x: number, 8 | public readonly y: number, 9 | public readonly z: number 10 | ) { } 11 | 12 | public set connectionSide(value: number) { 13 | this.side = value; 14 | if (value >= 0) { 15 | const coords = World.getRelativeCoords(this.x, this.y, this.z, this.connectionSide); 16 | // update to BlockSource 17 | const storage = StorageInterface.getStorage(this.region, coords.x, coords.y, coords.z); 18 | this.containerData = { 19 | source: storage, 20 | slots: storage.getOutputSlots(), 21 | }; 22 | } else { 23 | this.containerData = null; 24 | } 25 | } 26 | 27 | public get connectionSide(): number | null { 28 | return this.side; 29 | } 30 | 31 | public getExtractionTargetsCount(maxItems: number): number { 32 | if (!this.containerData) return -1; 33 | 34 | let id = 0; 35 | let data = null; 36 | let count = 0; 37 | 38 | for (const i of this.containerData.slots) { 39 | const slot = this.containerData.source.getSlot(i); 40 | 41 | if (slot.id == 0) continue; 42 | 43 | if (id == 0 && slot.id != 0) { 44 | id = slot.id; 45 | data = slot.data; 46 | } 47 | 48 | if (id == slot.id && data == slot.data && count < maxItems) { 49 | count = Math.min(count + slot.count, maxItems); 50 | } 51 | 52 | if (count == maxItems) break; 53 | } 54 | 55 | return count; 56 | } 57 | 58 | public extractItems(count: number): void { 59 | const item = this.getExtractionPack(this.containerData, count); 60 | const containerCoords = World.getRelativeCoords(this.x, this.y, this.z, this.connectionSide); 61 | const vectorIndex = World.getInverseBlockSide(this.connectionSide); 62 | const offsetVector = World.getRelativeCoords(0, 0, 0, vectorIndex); 63 | 64 | // ? should I add offsetDistance to config? 65 | const offsetDistance = +__config__.getNumber("travelingItem_offset_distance"); 66 | /* 67 | If you want to create items not on source block center 68 | change "travelingItem_offset_distance" in config 69 | */ 70 | 71 | const itemCoords = { 72 | x: containerCoords.x + 0.5 + offsetDistance * offsetVector.x, 73 | y: containerCoords.y + 0.5 + offsetDistance * offsetVector.y, 74 | z: containerCoords.z + 0.5 + offsetDistance * offsetVector.z, 75 | }; 76 | const travelingItem = new TravelingItem(itemCoords, this.region.getDimension(), item, vectorIndex); 77 | } 78 | 79 | public getExtractionPack(containerData: { source; slots }, count: number): ItemInstance { 80 | const gettedItem = { 81 | id: 0, 82 | count: 0, 83 | data: 0, 84 | extra: null, 85 | }; 86 | 87 | const { source, slots } = containerData; 88 | 89 | for (const i of slots) { 90 | const slot = source.getSlot(i); 91 | if (slot.id == 0) continue; 92 | 93 | if (gettedItem.extra != null) break; 94 | 95 | const needToAdd = count - gettedItem.count; 96 | if (needToAdd > 0) { 97 | // * MineExplorer thanks for StorageInterface 98 | StorageInterface.addItemToSlot(slot, gettedItem, needToAdd); 99 | source.setSlot(i, slot.id, slot.count, slot.data, slot.extra); 100 | } else break; 101 | } 102 | return gettedItem; 103 | } 104 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/wooden/WoodenPipeStorageConnector.ts: -------------------------------------------------------------------------------- 1 | class WoodenPipeStorageConnector { 2 | constructor(public coords: Vector, protected renderer: PipeRenderer, protected texture: PipeTexture) { } 3 | 4 | private side: number = null;// connected side index 5 | 6 | public set ConnectionSide(value: number) { 7 | this.side = value; 8 | this.renderConnections(); 9 | } 10 | 11 | public get ConnectionSide(): number { 12 | return this.side; 13 | } 14 | 15 | public renderConnections(): void { 16 | const boxes = this.renderer.getBoxes(this.renderer.width); 17 | const standartModel = this.renderer.standartModel; 18 | if (this.ConnectionSide >= 0) { 19 | for (let i = 0; i < 6; i++) { 20 | const box = boxes[i]; 21 | const renderModel = BlockRenderer.createModel(); 22 | 23 | if (i == this.ConnectionSide) { 24 | const textre = this.texture.containerConnection; 25 | renderModel.addBox(box.box[0], box.box[1], box.box[2], 26 | box.box[3], box.box[4], box.box[5], textre.name, textre.data); 27 | } 28 | standartModel.addEntry(renderModel); 29 | } 30 | } 31 | 32 | BlockRenderer.mapAtCoords(this.coords.x, this.coords.y, this.coords.z, standartModel); 33 | } 34 | 35 | public destroy(): void { 36 | BlockRenderer.unmapAtCoords(this.coords.x, this.coords.y, this.coords.z); 37 | } 38 | } -------------------------------------------------------------------------------- /src/dev/core/pipe/item/wooden/WoodenPipeTileEntity.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | class WoodenPipeTileEntity implements TileEntity.TileEntityPrototype { 5 | private clientFactory: ClientFactory = new ClientFactory(WoodenPipeClient); 6 | 7 | // * it will be rewriten during runtime 8 | protected data: any = {} 9 | 10 | public defaultValues: any = {// * it will be rewriten during runtime 11 | // ? I use -1 because we cant put null into java.int in SyncedData 12 | connectionSide: -1, 13 | energy: 0 14 | } 15 | 16 | // private storageConnector: WoodenPipeStorageConnector; 17 | private itemEjector: WoodenPipeItemEjector; 18 | 19 | public x: number; 20 | public y: number; 21 | public z: number; 22 | 23 | public blockSource: BlockSource; 24 | public networkData: SyncedNetworkData; 25 | 26 | private ticksSincePull: number = 0; 27 | 28 | public client: WoodenPipeClient; 29 | 30 | constructor(protected renderer: PipeRenderer, protected texture: PipeTexture) { 31 | this.client = this.clientFactory.instantiate(renderer, texture); 32 | } 33 | 34 | private changeOrientation() { 35 | this.itemEjector.connectionSide = this.data.connectionSide; 36 | // ? if connection side is null put < 0 to syncData 37 | this.networkData.putInt("orientation", this.data.connectionSide); 38 | this.networkData.sendChanges(); 39 | } 40 | 41 | // !TileEntity event 42 | public tick(): void { 43 | this.ticksSincePull++; 44 | 45 | if (this.shouldTick()) { 46 | const maxExtractable = this.maxExtractable(); 47 | const targets = this.itemEjector.getExtractionTargetsCount(maxExtractable); 48 | if (targets > 0) { 49 | // * EXTRACT 50 | this.itemEjector.extractItems(this.maxExtractable()); 51 | } 52 | 53 | this.data.energy = 0; 54 | this.ticksSincePull = 0; 55 | } 56 | } 57 | 58 | // !TileEntity event 59 | public init(): void { 60 | this.itemEjector = new WoodenPipeItemEjector(this.blockSource, this.x, this.y, this.z); 61 | this.checkConnection(); 62 | } 63 | 64 | // !TileEntity event 65 | public click(id, count, data) { 66 | if (id != ItemID.bc_wrench) return false; 67 | 68 | this.updateConnectionSide(true); 69 | return true; 70 | } 71 | 72 | // !EnergyNet event 73 | public energyReceive(type, amount, voltage): number { 74 | const storage = this.getMaxEnergyStored(); 75 | const readyToReceive = Math.min(storage - amount, this.getMaxEnergyReceive()); 76 | const received = Math.min(readyToReceive, amount); 77 | this.data.energy += received; 78 | return received; 79 | } 80 | 81 | private shouldTick(): boolean { 82 | if (this.ticksSincePull < 8) { 83 | return false; 84 | } else if (this.ticksSincePull < 16) { 85 | // !Check if we have just enough energy for the next stack. 86 | if (this.data.connectionSide <= 5) { 87 | const stackSize = this.itemEjector.getExtractionTargetsCount(this.maxExtractable()); 88 | 89 | if (stackSize > 0 && this.data.energy >= stackSize * 10) { 90 | return true; 91 | } 92 | } 93 | } 94 | return this.ticksSincePull >= 16 && this.data.energy >= 10; 95 | } 96 | 97 | public updateConnectionSide(findNext: boolean = false): void { 98 | this.data.connectionSide = this.getConnectionSide(findNext); 99 | this.changeOrientation(); 100 | } 101 | 102 | /** @param findNext - use true value if you want to rerotate pipe like a wrench */ 103 | protected getConnectionSide(findNext: boolean = false): number { 104 | // * In common situation ends when i gets max in 5 index 105 | // * But if fhis function calling by wrench index can go beyound 106 | // * I think this code is poor, but maybe i fix it in future 107 | for (let t = 0; t < 12; t++) { 108 | const i = t % 6; 109 | if (findNext) { 110 | if (this.data.connectionSide == t) { 111 | findNext = false 112 | } 113 | continue; 114 | } 115 | const { x, y, z } = World.getRelativeCoords(this.x, this.y, this.z, i); 116 | if (this.canConnectTo(x, y, z, this.blockSource, i)) return i; 117 | } 118 | // default value 119 | return -1; 120 | } 121 | 122 | public checkConnection(): void { 123 | if (this.data.connectionSide < 0) { 124 | this.updateConnectionSide(); 125 | } else { 126 | const { x, y, z } = World.getRelativeCoords(this.x, this.y, this.z, this.data.connectionSide); 127 | if (!this.canConnectTo(x, y, z, this.blockSource, this.data.connectionSide)) { 128 | this.updateConnectionSide(); 129 | } else { 130 | this.changeOrientation(); 131 | } 132 | } 133 | } 134 | 135 | public canConnectTo(x: number, y: number, z: number, region: BlockSource, side: number): boolean { 136 | const storage = StorageInterface.getStorage(region, x, y, z); 137 | const slots = storage?.getOutputSlots(side); 138 | if (!slots) return false; 139 | 140 | let trueSlotsLength = slots.length; 141 | if (trueSlotsLength > 0 && slots[0] == "_json_saver_id") { 142 | // ! tileEntity container has jsonSaverId in slots[0] 143 | trueSlotsLength -= 1; 144 | } 145 | return trueSlotsLength > 0; 146 | } 147 | 148 | private maxExtractable(): number { 149 | return Math.floor(this.data.energy / 10); 150 | } 151 | 152 | public canConnectRedstoneEngine(): boolean { 153 | return true 154 | } 155 | 156 | public getMaxEnergyStored(): number { 157 | return 2560; 158 | } 159 | 160 | public getMaxEnergyReceive(): number { 161 | return 80; 162 | } 163 | } -------------------------------------------------------------------------------- /src/dev/item/gears.ts: -------------------------------------------------------------------------------- 1 | IDRegistry.genItemID("gear_wood"); 2 | Item.createItem("gear_wood", "gear_wood", { name: "gear_wood" }); 3 | 4 | IDRegistry.genItemID("gear_stone"); 5 | Item.createItem("gear_stone", "gear_stone", { name: "gear_stone" }); 6 | 7 | IDRegistry.genItemID("gear_iron"); 8 | Item.createItem("gear_iron", "gear_iron", { name: "gear_iron" }); 9 | 10 | IDRegistry.genItemID("gear_gold"); 11 | Item.createItem("gear_gold", "gear_gold", { name: "gear_gold" }); 12 | 13 | IDRegistry.genItemID("gear_diamond"); 14 | Item.createItem("gear_diamond", "gear_diamond", { name: "gear_diamond" }); 15 | 16 | Recipes.addShaped({ id: ItemID.gear_wood, count: 1, data: 0 }, [ 17 | " x ", 18 | "x x", 19 | " x " 20 | ], ["x", 280, 0]); 21 | 22 | Recipes.addShaped({ id: ItemID.gear_stone, count: 1, data: 0 }, [ 23 | " x ", 24 | "xox", 25 | " x " 26 | ], ["x", 4, -1, "o", ItemID.gear_wood, 0]); 27 | 28 | Recipes.addShaped({ id: ItemID.gear_iron, count: 1, data: 0 }, [ 29 | " x ", 30 | "xox", 31 | " x " 32 | ], ["x", 265, 0, "o", ItemID.gear_stone, 0]); 33 | 34 | Recipes.addShaped({ id: ItemID.gear_gold, count: 1, data: 0 }, [ 35 | " x ", 36 | "xox", 37 | " x " 38 | ], ["x", 266, 0, "o", ItemID.gear_iron, 0]); 39 | 40 | Recipes.addShaped({ id: ItemID.gear_diamond, count: 1, data: 0 }, [ 41 | " x ", 42 | "xox", 43 | " x " 44 | ], ["x", 264, 0, "o", ItemID.gear_gold, 0]); 45 | 46 | 47 | Callback.addCallback("BC-ICore", (ICore) => { 48 | IDRegistry.genItemID("gear_tin"); 49 | Item.createItem("gear_tin", "Tin Gear", { name: "gear_tin" }); 50 | 51 | Recipes.addShaped({ id: ItemID.gear_tin, count: 1, data: 0 }, [ 52 | " x ", 53 | "xox", 54 | " x " 55 | ], ["x", ItemID.ingotTin, 0, "o", ItemID.gear_stone, 0]); 56 | }); 57 | -------------------------------------------------------------------------------- /src/dev/item/wrench.ts: -------------------------------------------------------------------------------- 1 | IDRegistry.genItemID("bc_wrench"); 2 | Item.createItem("bc_wrench", "bc_wrench", { name: "bc_wrench" }, { stack: 1 }); 3 | 4 | Callback.addCallback("PostLoaded", () => { 5 | Recipes.addShaped({ id: ItemID.bc_wrench, count: 1, data: 0 }, [ 6 | "x x", 7 | " o ", 8 | " x " 9 | ], ["x", VanillaItemID.iron_ingot, 0, "o", ItemID.gear_stone, 0]); 10 | }); 11 | -------------------------------------------------------------------------------- /src/dev/misc/Translations.ts: -------------------------------------------------------------------------------- 1 | Translation.addTranslation("engine_creative", { ru: "Двигатель для творческого режима", en: "Creative Engine", zh:"创造引擎", pt:"motor criativo"}); 2 | Translation.addTranslation("engine_wooden", { ru: "Двигатель на красном камне", en: "Wooden Engine", zh:"红石引擎", pt:"motor de madeira"}); 3 | Translation.addTranslation("pipe_item_cobble", { ru: "Булыжниковая транспортная труба", en: "Cobblestone Transport Pipe", zh:"圆石管道", pt:"tubo de transporte de pedregulho"}); 4 | Translation.addTranslation("pipe_item_stone", { ru: "Каменная транспортная труба", en: "Stone Transport Pipe", zh:"石头管道", pt:"tubo de transporte de pedra"}); 5 | Translation.addTranslation("pipe_item_sandstone", { ru: "Песчаниковая транспортная труба", en: "Sandstone Transport Pipe", zh:"沙石管道", pt:"tubo de transporte de arenito"}); 6 | Translation.addTranslation("pipe_item_quartz", { ru: "Кварцевая транспортная труба", en: "Quartz Transport Pipe", zh:"石英管道", pt:"tubo de transporte de quartzo"}); 7 | Translation.addTranslation("pipe_item_gold", { ru: "Золотая транспортная труба", en: "Golden Transport Pipe", zh:"金质管道", pt:"tubo de transporte de ouro"}); 8 | Translation.addTranslation("pipe_item_wood", { ru: "Деревянная транспортная труба", en: "Wooden Transport Pipe", zh:"木质管道", pt:"tubo de transporte de madeira"}); 9 | Translation.addTranslation("pipe_item_void", { ru: "Пустотная транспортная труба", en: "Void Transport Pipe", zh:"虚空管道", pt:"tubo de transporte de vazio"}); 10 | Translation.addTranslation("pipe_item_iron", { ru: "Железная транспортная труба", en: "Iron Transport Pipe", zh:"铁质管道", pt:"tubo de transporte de ferro"}); 11 | Translation.addTranslation("pipe_item_diamond", { ru: "Алмазная транспортная труба", en: "Diamond Transport Pipe", zh:"钻石管道", pt:"tubo de transporte de diamante"}); 12 | Translation.addTranslation("pipe_item_obsidian", { ru: "Обсидиановая транспортная труба", en: "Obsidian Transport Pipe", zh:"黑曜石管道", pt:"tubo de transporte de obsidiana"}); 13 | Translation.addTranslation("gear_diamond", { ru: "Алмазная шестерня", en: "Diamond Gear", zh:"钻石齿轮", pt:"engrenagem de diamante"}); 14 | Translation.addTranslation("gear_gold", { ru: "Золотая шестерня", en: "Gold Gear", zh:"金齿轮", pt:"engrenagem de ouro"}); 15 | Translation.addTranslation("gear_iron", { ru: "Железная шестерня", en: "Iron Gear", zh:"铁齿轮", pt:"engrenagem de ferro"}); 16 | Translation.addTranslation("gear_stone", { ru: "Каменная шестерня", en: "Stone Gear", zh:"石齿轮", pt:"engrenagem de pedra"}); 17 | Translation.addTranslation("gear_wood", { ru: "Деревянная шестерня", en: "Wood Gear", zh:"木齿轮", pt:"engrenagem de madeira"}); 18 | Translation.addTranslation("bc_wrench", { ru: "Гаечный ключ", en: "Wrench", zh:"扳手", pt:"chave inglesa"}); 19 | -------------------------------------------------------------------------------- /src/dev/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES5", 4 | "lib": [ 5 | "ESNext" 6 | ], 7 | "outFile": "C:\\Git_Projects\\BuildCraftProject\\toolchain\\build\\project\\sources\\main.js", 8 | "experimentalDecorators": true, 9 | "downlevelIteration": true, 10 | "allowJs": true 11 | }, 12 | "exclude": [ 13 | "**/node_modules/*", 14 | "dom", 15 | "webpack" 16 | ], 17 | "include": [ 18 | "core", 19 | "Header.ts", 20 | "item", 21 | "misc", 22 | "tsconfig.json", 23 | "core/ClientFactory.ts", 24 | "core/energy.ts", 25 | "core/engine", 26 | "core/importLib.ts", 27 | "core/pipe", 28 | "core/engine/abstract", 29 | "core/engine/components", 30 | "core/engine/creative", 31 | "core/engine/EngineHeat.ts", 32 | "core/engine/EngineTextures.ts", 33 | "core/engine/interface", 34 | "core/engine/model", 35 | "core/engine/PowerMode.ts", 36 | "core/engine/wood", 37 | "core/engine/abstract/BCEngine.ts", 38 | "core/engine/abstract/BCEngineTileEntity.ts", 39 | "core/engine/components/animation", 40 | "core/engine/components/EngineAnimation.ts", 41 | "core/engine/components/EngineBlock.ts", 42 | "core/engine/components/EngineItem.ts", 43 | "core/engine/components/model", 44 | "core/engine/components/recipe", 45 | "core/engine/components/animation/AnimationComponent.ts", 46 | "core/engine/components/animation/BaseAnimation.ts", 47 | "core/engine/components/animation/PistonAnimation.ts", 48 | "core/engine/components/model/EngineItemModel.ts", 49 | "core/engine/components/model/EngineItemModelTexture.ts", 50 | "core/engine/components/model/IEnginePartModel.ts", 51 | "core/engine/components/model/ModelBox.ts", 52 | "core/engine/components/model/parts", 53 | "core/engine/components/model/parts/EngineBaseModelPart.ts", 54 | "core/engine/components/model/parts/EngineChamberModelPart.ts", 55 | "core/engine/components/model/parts/EnginePistonModelPart.ts", 56 | "core/engine/components/model/parts/EngineTrunkModelPart.ts", 57 | "core/engine/components/recipe/EngineIngredients.ts", 58 | "core/engine/components/recipe/EngineRecipe.ts", 59 | "core/engine/creative/CreativeEngine.ts", 60 | "core/engine/creative/CreativeEngineRecipe.ts", 61 | "core/engine/creative/CreativeEngineTileEntity.ts", 62 | "core/engine/interface/IEngine.ts", 63 | "core/engine/interface/IHeatable.ts", 64 | "core/engine/model/EngineRotation.ts", 65 | "core/engine/model/render", 66 | "core/engine/model/texture", 67 | "core/engine/model/render/BaseRender.ts", 68 | "core/engine/model/render/EngineRender.ts", 69 | "core/engine/model/render/PistonRender.ts", 70 | "core/engine/model/render/RenderManager.ts", 71 | "core/engine/model/texture/EngineTexture.ts", 72 | "core/engine/model/texture/ITexture.ts", 73 | "core/engine/wood/WoodEngine.ts", 74 | "core/engine/wood/WoodEngineTileEntity.ts", 75 | "core/pipe/abstract", 76 | "core/pipe/components", 77 | "core/pipe/item", 78 | "core/pipe/PipeSpeed.ts", 79 | "core/pipe/abstract/BCPipe.ts", 80 | "core/pipe/abstract/PipeConnector.ts", 81 | "core/pipe/components/PipeBlock.ts", 82 | "core/pipe/components/PipeDoubleRecipe.ts", 83 | "core/pipe/components/PipeIdMap.ts", 84 | "core/pipe/components/PipeRecipe.ts", 85 | "core/pipe/components/PipeRenderer.ts", 86 | "core/pipe/components/PipeTexture.ts", 87 | "core/pipe/item/abstract", 88 | "core/pipe/item/cobble", 89 | "core/pipe/item/diamond", 90 | "core/pipe/item/gold", 91 | "core/pipe/item/iron", 92 | "core/pipe/item/ItemMachines.ts", 93 | "core/pipe/item/obsidian", 94 | "core/pipe/item/quartz", 95 | "core/pipe/item/sandstone", 96 | "core/pipe/item/stone", 97 | "core/pipe/item/travelingItem", 98 | "core/pipe/item/void", 99 | "core/pipe/item/wooden", 100 | "core/pipe/item/abstract/BCTransportPipe.ts", 101 | "core/pipe/item/abstract/TransportPipeConnector.ts", 102 | "core/pipe/item/cobble/CobblePipeConnector.ts", 103 | "core/pipe/item/cobble/PipeCobble.ts", 104 | "core/pipe/item/diamond/DiamondPipeGUI.ts", 105 | "core/pipe/item/diamond/DiamondPipeRenderer.ts", 106 | "core/pipe/item/diamond/DiamondPipeTileEntity.ts", 107 | "core/pipe/item/diamond/PipeDiamond.ts", 108 | "core/pipe/item/gold/PipeGold.ts", 109 | "core/pipe/item/iron/IronPipeClient.ts", 110 | "core/pipe/item/iron/IronPipeRenderConnector.ts", 111 | "core/pipe/item/iron/IronPipeTileEntity.ts", 112 | "core/pipe/item/iron/PipeIron.ts", 113 | "core/pipe/item/obsidian/AxisBoxes.ts", 114 | "core/pipe/item/obsidian/ObsidianPipeConnector.ts", 115 | "core/pipe/item/obsidian/ObsidianPipeItemAccelerator.ts", 116 | "core/pipe/item/obsidian/ObsidianPipeItemEjector.ts", 117 | "core/pipe/item/obsidian/ObsidianPipeTargetConnector.ts", 118 | "core/pipe/item/obsidian/ObsidianPipeTileEntity.ts", 119 | "core/pipe/item/obsidian/PipeObsidian.ts", 120 | "core/pipe/item/quartz/PipeQuartz.ts", 121 | "core/pipe/item/quartz/QuartzPipeConnector.ts", 122 | "core/pipe/item/sandstone/PipeSandstone.ts", 123 | "core/pipe/item/sandstone/SandstonePipeConnector.ts", 124 | "core/pipe/item/stone/PipeStone.ts", 125 | "core/pipe/item/stone/StonePipeConnector.ts", 126 | "core/pipe/item/travelingItem/TravelingItem.ts", 127 | "core/pipe/item/travelingItem/TravelingItemAnimation.ts", 128 | "core/pipe/item/travelingItem/TravelingItemMoveData.ts", 129 | "core/pipe/item/travelingItem/TravelingItemMover.ts", 130 | "core/pipe/item/travelingItem/TravelingItemNetworkEntity.ts", 131 | "core/pipe/item/void/PipeVoid.ts", 132 | "core/pipe/item/void/VoidPipeTileEntity.ts", 133 | "core/pipe/item/wooden/PipeWooden.ts", 134 | "core/pipe/item/wooden/WoodenPipeClient.ts", 135 | "core/pipe/item/wooden/WoodenPipeConnector.ts", 136 | "core/pipe/item/wooden/WoodenPipeItemEjector.ts", 137 | "core/pipe/item/wooden/WoodenPipeStorageConnector.ts", 138 | "core/pipe/item/wooden/WoodenPipeTileEntity.ts", 139 | "item/gears.ts", 140 | "item/wrench.ts", 141 | "misc/Translations.ts" 142 | ], 143 | "files": [ 144 | "C:\\Git_Projects\\BuildCraftProject\\toolchain\\declarations\\android-declarations.d.ts", 145 | "C:\\Git_Projects\\BuildCraftProject\\toolchain\\declarations\\android.d.ts", 146 | "C:\\Git_Projects\\BuildCraftProject\\toolchain\\declarations\\core-engine.d.ts", 147 | "C:\\Git_Projects\\BuildCraftProject\\toolchain\\declarations\\lib\\energy-net.d.ts", 148 | "C:\\Git_Projects\\BuildCraftProject\\toolchain\\declarations\\lib\\LiquidLib.d.ts", 149 | "C:\\Git_Projects\\BuildCraftProject\\toolchain\\declarations\\lib\\numbers.d.ts", 150 | "C:\\Git_Projects\\BuildCraftProject\\toolchain\\declarations\\lib\\StorageInterface.d.ts" 151 | ] 152 | } -------------------------------------------------------------------------------- /src/launcher.js: -------------------------------------------------------------------------------- 1 | ConfigureMultiplayer({ 2 | name: "buildcraft_pe", 3 | version: "1.0", 4 | isClientOnly: false 5 | }); 6 | Launch(); -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "max-line-length": { 5 | "options": [150] 6 | }, 7 | "quotemark": [true, "double"], 8 | "new-parens": true, 9 | "no-arg": true, 10 | "no-bitwise": true, 11 | "no-conditional-assignment": true, 12 | "no-consecutive-blank-lines": false, 13 | "no-reference": false, 14 | "triple-equals": false, 15 | "no-empty": false, 16 | "no-string-literal": false, 17 | "radix": false, 18 | "forin": false, 19 | "no-console": { 20 | "severity": "warning", 21 | "options": ["debug", "info", "log", "time", "timeEnd", "trace"] 22 | } 23 | } 24 | } --------------------------------------------------------------------------------