Implement main game as a mod
This commit is contained in:
+39
-59
@@ -1,5 +1,7 @@
|
||||
import { Container, ItemStack } from "$/common/inventory.ts";
|
||||
import { ScreenLayout } from "$/common/protocol.ts";
|
||||
import { EverythingRegistry, ItemRegistry } from "$/common/everything_registry.ts";
|
||||
import type { RecipeBook } from "$/common/mod_loader.ts";
|
||||
import type { GameServer } from "./game_server.ts";
|
||||
import type { ServerPlayer } from "./player.ts";
|
||||
import type { Tile } from "./world.ts";
|
||||
@@ -80,50 +82,6 @@ BLOCK_BEHAVIORS["bworld:chest"] = {
|
||||
|
||||
// furnace
|
||||
|
||||
export interface FurnaceRecipe {
|
||||
input: string;
|
||||
output: ItemStack;
|
||||
cook_time: number;
|
||||
}
|
||||
|
||||
export const FURNACE_RECIPES: FurnaceRecipe[] = [
|
||||
{
|
||||
input: "bworld:log",
|
||||
output: new ItemStack("bworld:coal", 1),
|
||||
cook_time: 100,
|
||||
},
|
||||
{
|
||||
input: "bworld:coal_ore",
|
||||
output: new ItemStack("bworld:coal", 1),
|
||||
cook_time: 100,
|
||||
},
|
||||
{
|
||||
input: "bworld:iron_ore",
|
||||
output: new ItemStack("bworld:iron_ingot", 1),
|
||||
cook_time: 200,
|
||||
},
|
||||
{
|
||||
input: "bworld:tin_ore",
|
||||
output: new ItemStack("bworld:tin_ingot", 1),
|
||||
cook_time: 200,
|
||||
},
|
||||
{
|
||||
input: "bworld:copper_ore",
|
||||
output: new ItemStack("bworld:copper_ingot", 1),
|
||||
cook_time: 200,
|
||||
},
|
||||
{
|
||||
input: "bworld:gold_ore",
|
||||
output: new ItemStack("bworld:gold_ingot", 1),
|
||||
cook_time: 200,
|
||||
},
|
||||
];
|
||||
|
||||
export const FUEL_VALUES: Record<string, number> = {
|
||||
"bworld:coal": 1000,
|
||||
"bworld:log": 100,
|
||||
};
|
||||
|
||||
interface FurnaceData {
|
||||
progress: number;
|
||||
progress_max: number;
|
||||
@@ -131,12 +89,17 @@ interface FurnaceData {
|
||||
fuel_max: number;
|
||||
}
|
||||
|
||||
function get_recipe(input?: ItemStack | undefined): FurnaceRecipe | undefined {
|
||||
interface FurnaceRecipe {
|
||||
output: { id: string; count: number };
|
||||
cook_time: number;
|
||||
}
|
||||
|
||||
function get_recipe(recipes: RecipeBook, input?: ItemStack | undefined): FurnaceRecipe | undefined {
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
|
||||
return FURNACE_RECIPES.find((r) => r.input === input.type_id);
|
||||
return recipes.furnace.get(input.type_id);
|
||||
}
|
||||
|
||||
function can_craft(container: Container, recipe?: FurnaceRecipe) {
|
||||
@@ -150,27 +113,27 @@ function can_craft(container: Container, recipe?: FurnaceRecipe) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (output.type_id !== recipe.output.type_id) {
|
||||
if (output.type_id !== recipe.output.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return output.amount < output.max_amount;
|
||||
}
|
||||
|
||||
function get_fuel_value(item?: ItemStack | undefined): number {
|
||||
function get_fuel_value(recipes: RecipeBook, item?: ItemStack | undefined): number {
|
||||
if (!item) {
|
||||
return 0;
|
||||
}
|
||||
return FUEL_VALUES[item.type_id] ?? 0;
|
||||
return recipes.fuel.get(item.type_id) ?? 0;
|
||||
}
|
||||
|
||||
function has_fuel(container: Container) {
|
||||
return get_fuel_value(container.get_item(1)) > 0;
|
||||
function has_fuel(recipes: RecipeBook, container: Container) {
|
||||
return get_fuel_value(recipes, container.get_item(1)) > 0;
|
||||
}
|
||||
|
||||
function consume_fuel(container: Container): number {
|
||||
function consume_fuel(recipes: RecipeBook, container: Container): number {
|
||||
const fuel = container.get_slot(1)!;
|
||||
const value = get_fuel_value(fuel.get_item());
|
||||
const value = get_fuel_value(recipes, fuel.get_item());
|
||||
|
||||
if (fuel.has_item()) {
|
||||
fuel.amount! -= 1;
|
||||
@@ -184,9 +147,9 @@ function craft(container: Container, recipe: FurnaceRecipe) {
|
||||
const output = container.get_item(2);
|
||||
|
||||
if (!output) {
|
||||
container.set_item(2, recipe.output.clone());
|
||||
container.set_item(2, new ItemStack(recipe.output.id, recipe.output.count));
|
||||
} else {
|
||||
output.amount += recipe.output.amount;
|
||||
output.amount += recipe.output.count;
|
||||
}
|
||||
|
||||
input.amount -= 1;
|
||||
@@ -241,12 +204,12 @@ BLOCK_BEHAVIORS["bworld:furnace"] = {
|
||||
on_break(_game, tile, player) {
|
||||
give_container_contents(tile, player);
|
||||
},
|
||||
on_tick(_game, tile) {
|
||||
on_tick(game, tile) {
|
||||
const data = tile.data as unknown as FurnaceData;
|
||||
const container = tile.containers.main;
|
||||
|
||||
const input = container.get_item(0);
|
||||
const recipe = get_recipe(input);
|
||||
const recipe = get_recipe(game.recipes, input);
|
||||
|
||||
// burn fuel
|
||||
if (data.fuel > 0) {
|
||||
@@ -259,8 +222,8 @@ BLOCK_BEHAVIORS["bworld:furnace"] = {
|
||||
}
|
||||
|
||||
// refuel
|
||||
if (data.fuel === 0 && has_fuel(container)) {
|
||||
data.fuel = consume_fuel(container);
|
||||
if (data.fuel === 0 && has_fuel(game.recipes, container)) {
|
||||
data.fuel = consume_fuel(game.recipes, container);
|
||||
data.fuel_max = data.fuel;
|
||||
}
|
||||
|
||||
@@ -276,3 +239,20 @@ BLOCK_BEHAVIORS["bworld:furnace"] = {
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// items that still need code, until they're components in mods/bworld (phase 2 in MODS.md)
|
||||
|
||||
export interface WateringCanData {
|
||||
water: number;
|
||||
max_water: number;
|
||||
}
|
||||
|
||||
export function add_base_item_hooks() {
|
||||
const watering_can = EverythingRegistry.get<ItemRegistry<WateringCanData>>("items", "bworld:watering_can");
|
||||
if (watering_can) {
|
||||
watering_can.on_create = (item) => {
|
||||
item.data = { water: 0, max_water: 32 };
|
||||
};
|
||||
watering_can.get_lore = (item) => `Water: ${item.data?.water}/${item.data?.max_water}`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user