2022-07-10 10:37:19 -04:00
|
|
|
#include <libreborn/libreborn.h>
|
|
|
|
#include <symbols/minecraft.h>
|
|
|
|
|
|
|
|
#include <mods/feature/feature.h>
|
|
|
|
#include <mods/init/init.h>
|
|
|
|
#include <mods/misc/misc.h>
|
2024-02-07 19:00:55 -05:00
|
|
|
#include <mods/bucket/bucket.h>
|
2022-07-10 10:37:19 -04:00
|
|
|
|
|
|
|
// Items
|
2024-04-02 19:22:01 -04:00
|
|
|
static FoodItem *bucket = nullptr;
|
2022-07-10 10:37:19 -04:00
|
|
|
|
|
|
|
// Description And Texture
|
2024-02-07 06:47:46 +00:00
|
|
|
static std::string BucketItem_getDescriptionId(__attribute__((unused)) FoodItem *item, ItemInstance *item_instance) {
|
2024-05-17 02:52:55 -04:00
|
|
|
if (item_instance->auxiliary == Tile::water->id) {
|
2022-07-10 10:37:19 -04:00
|
|
|
return "item.bucketWater";
|
2024-05-17 02:52:55 -04:00
|
|
|
} else if (item_instance->auxiliary == Tile::lava->id) {
|
2022-07-10 10:37:19 -04:00
|
|
|
return "item.bucketLava";
|
2024-02-07 06:47:46 +00:00
|
|
|
} else if (item_instance->auxiliary == 1) {
|
|
|
|
return "item.bucketMilk";
|
2022-07-10 10:37:19 -04:00
|
|
|
} else {
|
|
|
|
return "item.bucket";
|
|
|
|
}
|
|
|
|
}
|
2024-02-07 06:47:46 +00:00
|
|
|
static int32_t BucketItem_getIcon(__attribute__((unused)) FoodItem *item, int32_t auxiliary) {
|
2024-05-17 02:52:55 -04:00
|
|
|
if (auxiliary == Tile::water->id) {
|
2022-07-10 10:37:19 -04:00
|
|
|
return 75;
|
2024-05-17 02:52:55 -04:00
|
|
|
} else if (auxiliary == Tile::lava->id) {
|
2022-07-10 10:37:19 -04:00
|
|
|
return 76;
|
2024-02-07 06:47:46 +00:00
|
|
|
} else if (auxiliary == 1) {
|
|
|
|
return 77;
|
2022-07-10 10:37:19 -04:00
|
|
|
} else {
|
|
|
|
return 74;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-07 06:47:46 +00:00
|
|
|
// Filling
|
|
|
|
static bool fill_bucket(ItemInstance *item_instance, Player *player, int new_auxiliary) {
|
|
|
|
bool success = false;
|
|
|
|
if (item_instance->count == 1) {
|
|
|
|
item_instance->auxiliary = new_auxiliary;
|
|
|
|
success = true;
|
|
|
|
} else {
|
|
|
|
ItemInstance new_item;
|
|
|
|
new_item.id = bucket->id;
|
|
|
|
new_item.count = 1;
|
|
|
|
new_item.auxiliary = new_auxiliary;
|
|
|
|
Inventory *inventory = player->inventory;
|
2024-05-15 05:02:19 -04:00
|
|
|
if (inventory->add(&new_item)) {
|
2024-02-07 06:47:46 +00:00
|
|
|
// Added To Inventory
|
|
|
|
success = true;
|
|
|
|
item_instance->count -= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-07-10 10:37:19 -04:00
|
|
|
// Use Bucket
|
2024-02-07 06:47:46 +00:00
|
|
|
static int32_t BucketItem_useOn(__attribute__((unused)) FoodItem *item, ItemInstance *item_instance, Player *player, Level *level, int32_t x, int32_t y, int32_t z, int32_t hit_side, __attribute__((unused)) float hit_x, __attribute__((unused)) float hit_y, __attribute__((unused)) float hit_z) {
|
|
|
|
if (item_instance->count < 1 || item_instance->auxiliary == 1) {
|
2022-07-10 10:37:19 -04:00
|
|
|
return 0;
|
2022-08-09 18:38:48 -04:00
|
|
|
} else if (item_instance->auxiliary == 0) {
|
2022-07-10 10:37:19 -04:00
|
|
|
// Empty Bucket
|
|
|
|
int32_t new_auxiliary = 0;
|
2024-05-15 05:02:19 -04:00
|
|
|
int32_t tile = level->getTile(x, y, z);
|
2024-05-17 02:52:55 -04:00
|
|
|
if (tile == Tile::calmWater->id) {
|
|
|
|
new_auxiliary = Tile::water->id;
|
|
|
|
} else if (tile == Tile::calmLava->id) {
|
|
|
|
new_auxiliary = Tile::lava->id;
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
|
|
|
if (new_auxiliary != 0) {
|
|
|
|
// Valid
|
2024-02-07 06:47:46 +00:00
|
|
|
if (fill_bucket(item_instance, player, new_auxiliary)) {
|
2024-05-15 05:02:19 -04:00
|
|
|
level->setTileAndData(x, y, z, 0, 0);
|
2022-07-10 10:37:19 -04:00
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Invalid
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Place
|
|
|
|
switch (hit_side) {
|
|
|
|
case 0: {
|
|
|
|
y -= 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1: {
|
|
|
|
y += 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2: {
|
|
|
|
z -= 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 3: {
|
|
|
|
z += 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 4: {
|
|
|
|
x -= 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 5: {
|
|
|
|
x += 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Get Current Tile
|
|
|
|
bool valid = false;
|
2024-05-15 05:02:19 -04:00
|
|
|
Material *material = level->getMaterial(x, y, z);
|
2024-04-02 19:22:01 -04:00
|
|
|
if (material != nullptr) {
|
2024-05-15 05:02:19 -04:00
|
|
|
valid = !material->isSolid();
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
2024-05-17 02:52:55 -04:00
|
|
|
if (item_instance->auxiliary != Tile::water->id && item_instance->auxiliary != Tile::lava->id) {
|
2022-07-29 22:13:03 -04:00
|
|
|
valid = false;
|
|
|
|
}
|
2022-07-10 10:37:19 -04:00
|
|
|
if (valid) {
|
2024-05-15 05:02:19 -04:00
|
|
|
level->setTileAndData(x, y, z, item_instance->auxiliary, 0);
|
2022-07-10 10:37:19 -04:00
|
|
|
item_instance->auxiliary = 0;
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-07 06:47:46 +00:00
|
|
|
static int BucketItem_getUseDuration(__attribute__((unused)) FoodItem *item, ItemInstance *item_instance) {
|
|
|
|
if (item_instance->auxiliary == 1) {
|
|
|
|
return 0x20;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ItemInstance BucketItem_useTimeDepleted(FoodItem *item, ItemInstance *item_instance, Level *level, Player *player) {
|
|
|
|
if (item_instance->auxiliary == 1) {
|
2024-04-03 03:19:12 -04:00
|
|
|
*item_instance = (*FoodItem_useTimeDepleted_vtable_addr)(item, item_instance, level, player);
|
2024-02-07 06:47:46 +00:00
|
|
|
// Set it to a empty bucket
|
|
|
|
item_instance->auxiliary = 0;
|
|
|
|
item_instance->count = 1;
|
|
|
|
}
|
|
|
|
return *item_instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int BucketItem_getUseAnimation(__attribute__((unused)) FoodItem *item) {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool BucketItem_isFood(__attribute__((unused)) FoodItem *item) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ItemInstance *BucketItem_use(FoodItem *item, ItemInstance *item_instance, __attribute__((unused)) Level *level, Player *player) {
|
|
|
|
if (item_instance->auxiliary == 1) {
|
|
|
|
return (*FoodItem_use_vtable_addr)(item, item_instance, level, player);
|
|
|
|
}
|
|
|
|
return item_instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ItemInstance *BucketItem_getCraftingRemainingItem(FoodItem *item, ItemInstance *item_instance) {
|
|
|
|
if (item_instance->auxiliary == 0) {
|
2024-04-02 19:22:01 -04:00
|
|
|
return nullptr;
|
2024-02-07 06:47:46 +00:00
|
|
|
}
|
2024-05-17 00:36:28 -04:00
|
|
|
ItemInstance *ret = new ItemInstance;
|
2024-02-07 06:47:46 +00:00
|
|
|
ret->id = item->id;
|
|
|
|
ret->count = item_instance->count;
|
|
|
|
ret->auxiliary = 0;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-07-10 10:37:19 -04:00
|
|
|
// Bucket VTable
|
2024-02-07 06:47:46 +00:00
|
|
|
CUSTOM_VTABLE(bucket, FoodItem) {
|
2024-01-31 22:13:20 -05:00
|
|
|
vtable->getDescriptionId = BucketItem_getDescriptionId;
|
|
|
|
vtable->getIcon = BucketItem_getIcon;
|
|
|
|
vtable->useOn = BucketItem_useOn;
|
2024-02-07 06:47:46 +00:00
|
|
|
vtable->getUseDuration = BucketItem_getUseDuration;
|
|
|
|
vtable->useTimeDepleted = BucketItem_useTimeDepleted;
|
|
|
|
vtable->getUseAnimation = BucketItem_getUseAnimation;
|
|
|
|
vtable->isFood = BucketItem_isFood;
|
|
|
|
vtable->use = BucketItem_use;
|
|
|
|
vtable->getCraftingRemainingItem = BucketItem_getCraftingRemainingItem;
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create Items
|
2024-02-07 06:47:46 +00:00
|
|
|
static FoodItem *create_bucket(int32_t id, int32_t texture_x, int32_t texture_y, std::string name) {
|
2022-07-10 10:37:19 -04:00
|
|
|
// Construct
|
2024-05-17 00:36:28 -04:00
|
|
|
FoodItem *item = new FoodItem;
|
2022-07-10 10:37:19 -04:00
|
|
|
ALLOC_CHECK(item);
|
2024-05-15 05:02:19 -04:00
|
|
|
Item_constructor((Item *) item, id); // FoodItem's Constructor Was Inlined
|
2022-07-10 10:37:19 -04:00
|
|
|
|
|
|
|
// Set VTable
|
2024-01-06 06:30:23 -05:00
|
|
|
item->vtable = get_bucket_vtable();
|
2022-07-10 10:37:19 -04:00
|
|
|
|
|
|
|
// Setup
|
2024-05-15 05:02:19 -04:00
|
|
|
item->setIcon(texture_x, texture_y);
|
|
|
|
item->setDescriptionId(&name);
|
2024-01-06 06:30:23 -05:00
|
|
|
item->is_stacked_by_data = 1;
|
|
|
|
item->category = 2;
|
|
|
|
item->max_damage = 0;
|
|
|
|
item->max_stack_size = 1;
|
2024-02-07 06:47:46 +00:00
|
|
|
item->nutrition = 0;
|
|
|
|
item->unknown_param_1 = 0.6;
|
|
|
|
item->meat = false;
|
2022-07-10 10:37:19 -04:00
|
|
|
|
|
|
|
// Return
|
|
|
|
return item;
|
|
|
|
}
|
2024-05-18 18:58:39 -04:00
|
|
|
static void Item_initItems_injection() {
|
2022-07-10 10:37:19 -04:00
|
|
|
bucket = create_bucket(69, 10, 4, "bucket");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change Max Stack Size Based On Auxiliary
|
2024-04-03 03:19:12 -04:00
|
|
|
static int32_t ItemInstance_getMaxStackSize_injection(ItemInstance_getMaxStackSize_t original, ItemInstance *item_instance) {
|
2024-01-06 06:30:23 -05:00
|
|
|
if (item_instance->id == bucket->id && item_instance->auxiliary == 0) {
|
2022-07-10 10:37:19 -04:00
|
|
|
// Custom Value
|
|
|
|
return 16;
|
|
|
|
} else {
|
|
|
|
// Call Original Method
|
2024-04-03 03:19:12 -04:00
|
|
|
return original(item_instance);
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-07 06:47:46 +00:00
|
|
|
// Milking
|
2024-04-03 03:19:12 -04:00
|
|
|
bool Cow_interact_injection(Cow_interact_t original, Cow *self, Player *player) {
|
2024-05-15 05:02:19 -04:00
|
|
|
ItemInstance *item = player->inventory->getSelected();
|
2024-02-07 06:47:46 +00:00
|
|
|
if (item && item->id == bucket->id && item->auxiliary == 0) {
|
|
|
|
// Fill with milk
|
|
|
|
fill_bucket(item, player, 1);
|
|
|
|
return true;
|
|
|
|
}
|
2024-04-03 03:19:12 -04:00
|
|
|
return original(self, player);
|
2024-02-07 06:47:46 +00:00
|
|
|
}
|
|
|
|
|
2022-07-10 10:37:19 -04:00
|
|
|
// Creative Inventory
|
2024-02-07 06:47:46 +00:00
|
|
|
static void inventory_add_item(FillingContainer *inventory, FoodItem *item, int32_t auxiliary) {
|
2022-07-10 10:37:19 -04:00
|
|
|
ItemInstance *item_instance = new ItemInstance;
|
|
|
|
ALLOC_CHECK(item_instance);
|
2024-05-15 05:02:19 -04:00
|
|
|
item_instance = item_instance->constructor_item_extra((Item *) item, 1, auxiliary);
|
|
|
|
inventory->addItem(item_instance);
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
2024-01-06 06:30:23 -05:00
|
|
|
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container) {
|
2022-07-10 10:37:19 -04:00
|
|
|
inventory_add_item(filling_container, bucket, 0);
|
2024-05-17 02:52:55 -04:00
|
|
|
inventory_add_item(filling_container, bucket, Tile::water->id);
|
|
|
|
inventory_add_item(filling_container, bucket, Tile::lava->id);
|
2024-02-07 06:47:46 +00:00
|
|
|
inventory_add_item(filling_container, bucket, 1);
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Make Liquids Selectable
|
|
|
|
static bool is_holding_bucket = false;
|
2024-01-06 06:30:23 -05:00
|
|
|
static HitResult Mob_pick_Level_clip_injection(Level *level, unsigned char *param_1, unsigned char *param_2, __attribute__((unused)) bool clip_liquids, bool param_3) {
|
2022-07-10 10:37:19 -04:00
|
|
|
// Call Original Method
|
2024-05-15 05:02:19 -04:00
|
|
|
return level->clip(param_1, param_2, is_holding_bucket, param_3);
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
2024-01-06 06:30:23 -05:00
|
|
|
static void handle_tick(Minecraft *minecraft) {
|
|
|
|
LocalPlayer *player = minecraft->player;
|
2024-04-02 19:22:01 -04:00
|
|
|
if (player != nullptr) {
|
2022-07-10 10:37:19 -04:00
|
|
|
// Get Selected Slot
|
2024-01-06 06:30:23 -05:00
|
|
|
int32_t selected_slot = misc_get_real_selected_slot((Player *) player);
|
|
|
|
Inventory *inventory = player->inventory;
|
2022-07-10 10:37:19 -04:00
|
|
|
|
|
|
|
// Get Item
|
2024-05-15 05:02:19 -04:00
|
|
|
ItemInstance *inventory_item = inventory->getItem(selected_slot);
|
2022-07-10 10:37:19 -04:00
|
|
|
// Check
|
2024-04-02 19:22:01 -04:00
|
|
|
is_holding_bucket = inventory_item != nullptr && inventory_item->id == bucket->id && inventory_item->auxiliary == 0;
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Prevent Breaking Liquid
|
|
|
|
static bool is_calm_liquid(int32_t id) {
|
2024-05-17 02:52:55 -04:00
|
|
|
if (id == Tile::calmWater->id) {
|
2022-07-10 10:37:19 -04:00
|
|
|
return true;
|
2024-05-17 02:52:55 -04:00
|
|
|
} else if (id == Tile::calmLava->id) {
|
2022-07-10 10:37:19 -04:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2024-04-03 03:19:12 -04:00
|
|
|
static void Minecraft_handleMouseDown_injection(Minecraft_handleMouseDown_t original, Minecraft *minecraft, int param_1, bool can_destroy) {
|
2022-07-10 10:37:19 -04:00
|
|
|
// Check
|
2024-01-06 06:30:23 -05:00
|
|
|
Level *level = minecraft->level;
|
2024-04-02 19:22:01 -04:00
|
|
|
if (level != nullptr) {
|
2024-01-06 06:30:23 -05:00
|
|
|
int32_t x = minecraft->hit_result.x;
|
|
|
|
int32_t y = minecraft->hit_result.y;
|
|
|
|
int32_t z = minecraft->hit_result.z;
|
2024-05-15 05:02:19 -04:00
|
|
|
int32_t tile = level->getTile(x, y, z);
|
2022-07-10 10:37:19 -04:00
|
|
|
if (is_calm_liquid(tile)) {
|
|
|
|
can_destroy = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Call Original Method
|
2024-04-03 03:19:12 -04:00
|
|
|
original(minecraft, param_1, can_destroy);
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Custom Crafting Recipes
|
2024-01-06 06:30:23 -05:00
|
|
|
static void Recipes_injection(Recipes *recipes) {
|
2022-07-10 10:37:19 -04:00
|
|
|
// Add
|
|
|
|
Recipes_Type type1 = {
|
|
|
|
.item = 0,
|
|
|
|
.tile = 0,
|
|
|
|
.instance = {
|
|
|
|
.count = 3,
|
|
|
|
.id = 265,
|
|
|
|
.auxiliary = 0
|
|
|
|
},
|
|
|
|
.letter = '#'
|
|
|
|
};
|
|
|
|
ItemInstance result = {
|
|
|
|
.count = 1,
|
2024-01-06 06:30:23 -05:00
|
|
|
.id = bucket->id,
|
2022-07-10 10:37:19 -04:00
|
|
|
.auxiliary = 0
|
|
|
|
};
|
2024-01-06 06:30:23 -05:00
|
|
|
std::string line1 = "# #";
|
|
|
|
std::string line2 = " # ";
|
|
|
|
std::vector<Recipes_Type> types = {type1};
|
2024-05-15 05:02:19 -04:00
|
|
|
recipes->addShapedRecipe_2(&result, &line1, &line2, &types);
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Custom Furnace Fuel
|
2024-04-03 03:19:12 -04:00
|
|
|
static int32_t FurnaceTileEntity_getBurnDuration_injection(FurnaceTileEntity_getBurnDuration_t original, ItemInstance *item_instance) {
|
2024-05-17 02:52:55 -04:00
|
|
|
if (item_instance->count > 0 && item_instance->id == bucket->id && item_instance->auxiliary == Tile::lava->id) {
|
2022-07-10 10:37:19 -04:00
|
|
|
return 20000;
|
|
|
|
} else {
|
|
|
|
// Call Original Method
|
2024-04-03 03:19:12 -04:00
|
|
|
return original(item_instance);
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
static void FurnaceTileEntity_tick_ItemInstance_setNull_injection(ItemInstance *item_instance) {
|
|
|
|
// Replace Lava Bucket With Empty Bucket When It Burns Out
|
2024-01-06 06:30:23 -05:00
|
|
|
if (item_instance->id == bucket->id) {
|
2022-07-10 10:37:19 -04:00
|
|
|
item_instance->auxiliary = 0;
|
|
|
|
} else {
|
|
|
|
// Original Behavior
|
|
|
|
item_instance->count = 0;
|
|
|
|
item_instance->id = 0;
|
|
|
|
item_instance->auxiliary = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-07 06:47:46 +00:00
|
|
|
// Add the bucket name to the language file
|
2024-05-18 18:58:39 -04:00
|
|
|
static void Language_injection() {
|
2024-05-17 02:52:55 -04:00
|
|
|
I18n::_strings.insert(std::make_pair("item.bucketMilk.name", "Milk Bucket"));
|
2024-02-07 06:47:46 +00:00
|
|
|
}
|
|
|
|
|
2022-07-10 10:37:19 -04:00
|
|
|
// Init
|
2024-02-07 06:47:46 +00:00
|
|
|
bool buckets_enabled = false;
|
2022-07-10 10:37:19 -04:00
|
|
|
void init_bucket() {
|
|
|
|
// Add Buckets
|
2024-02-07 06:47:46 +00:00
|
|
|
buckets_enabled = feature_has("Add Buckets", server_enabled);
|
|
|
|
if (buckets_enabled) {
|
2022-07-10 10:37:19 -04:00
|
|
|
// Add Items
|
|
|
|
misc_run_on_items_setup(Item_initItems_injection);
|
|
|
|
// Change Max Stack Size Based On Auxiliary
|
2024-04-03 03:19:12 -04:00
|
|
|
overwrite_calls(ItemInstance_getMaxStackSize, ItemInstance_getMaxStackSize_injection);
|
2024-02-07 06:47:46 +00:00
|
|
|
// Enable milking
|
2024-04-03 03:19:12 -04:00
|
|
|
overwrite_virtual_calls(Cow_interact, Cow_interact_injection);
|
2022-07-10 10:37:19 -04:00
|
|
|
// Creative Inventory
|
|
|
|
misc_run_on_creative_inventory_setup(Inventory_setupDefault_FillingContainer_addItem_call_injection);
|
|
|
|
// Make Liquids Selectable
|
|
|
|
overwrite_call((void *) 0x7f5b0, (void *) Mob_pick_Level_clip_injection);
|
|
|
|
misc_run_on_tick(handle_tick);
|
|
|
|
// Prevent Breaking Liquid
|
2024-04-03 03:19:12 -04:00
|
|
|
overwrite_calls(Minecraft_handleMouseDown, Minecraft_handleMouseDown_injection);
|
2022-07-10 10:37:19 -04:00
|
|
|
// Custom Crafting Recipes
|
|
|
|
misc_run_on_recipes_setup(Recipes_injection);
|
|
|
|
// Custom Furnace Fuel
|
2024-04-03 03:19:12 -04:00
|
|
|
overwrite_calls(FurnaceTileEntity_getBurnDuration, FurnaceTileEntity_getBurnDuration_injection);
|
2022-07-10 10:37:19 -04:00
|
|
|
overwrite_call((void *) 0xd351c, (void *) FurnaceTileEntity_tick_ItemInstance_setNull_injection);
|
2024-02-07 06:47:46 +00:00
|
|
|
// Language for milk
|
|
|
|
misc_run_on_language_setup(Language_injection);
|
2022-07-10 10:37:19 -04:00
|
|
|
}
|
|
|
|
}
|