Recipes API
This commit is contained in:
parent
329f92c0a4
commit
699d83c61b
@ -3,6 +3,7 @@ This is an example of a mod that cane be built using the modding SDK.
|
||||
|
||||
* **Expanded Creative Mod**: This specific mod adds even more items and blocks to the Creative Inventory. It was originally by [@Bigjango13](https://github.com/bigjango13).
|
||||
* **Chat Commands Mod**: This specific mod makes an chat message starting with a ``/`` handled by the MCPI API.
|
||||
* **Recipes Mod**: This specific mod demos custom recipes.
|
||||
|
||||
## The SDK
|
||||
The modding SDK is a collection of exported CMake targets that allows anyone to create their own MCPI mod!
|
||||
|
14
example-mods/recipes/.gitignore
vendored
Normal file
14
example-mods/recipes/.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
out
|
||||
debian/tmp
|
||||
.vscode
|
||||
build*
|
||||
CMakeLists.txt.user
|
||||
*.autosave
|
||||
AppImageBuilder.yml
|
||||
appimage-builder-cache
|
||||
appimage-build
|
||||
AppDir
|
||||
*.zsync
|
||||
*.AppImage
|
||||
core*
|
||||
qemu_*
|
15
example-mods/recipes/CMakeLists.txt
Normal file
15
example-mods/recipes/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.16.0)
|
||||
|
||||
# Build For ARM
|
||||
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||
|
||||
# Start Project
|
||||
project(recipes)
|
||||
|
||||
# Include SDK
|
||||
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cmake")
|
||||
|
||||
# Build
|
||||
add_library(recipes SHARED recipes.cpp)
|
||||
target_link_libraries(recipes mods-headers reborn-util symbols misc)
|
52
example-mods/recipes/recipes.cpp
Normal file
52
example-mods/recipes/recipes.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
// Headers
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
#include <mods/misc/misc.h>
|
||||
|
||||
// Custom Crafting Recipes
|
||||
static void Recipes_injection(unsigned char *recipes) {
|
||||
// Add
|
||||
Recipes_Type type1 = {
|
||||
.item = 0,
|
||||
.tile = 0,
|
||||
.instance = {
|
||||
.count = 1,
|
||||
.id = 12,
|
||||
.auxiliary = 0
|
||||
},
|
||||
.letter = 'a'
|
||||
};
|
||||
Recipes_Type type2 = {
|
||||
.item = 0,
|
||||
.tile = 0,
|
||||
.instance = {
|
||||
.count = 1,
|
||||
.id = 13,
|
||||
.auxiliary = 0
|
||||
},
|
||||
.letter = 'b'
|
||||
};
|
||||
ItemInstance result = {
|
||||
.count = 1,
|
||||
.id = 344,
|
||||
.auxiliary = 0
|
||||
};
|
||||
(*Recipes_addShapelessRecipe)(recipes, result, {type1, type2});
|
||||
}
|
||||
|
||||
// Custom Furnace Recipes
|
||||
static void FurnaceRecipes_injection(unsigned char *recipes) {
|
||||
// Add
|
||||
(*FurnaceRecipes_addFurnaceRecipe)(recipes, 49, {.count = 1, .id = 246, .auxiliary = 0});
|
||||
}
|
||||
|
||||
// Init
|
||||
__attribute__((constructor)) static void init_recipes() {
|
||||
// Log
|
||||
INFO("Loading Custom Recipes");
|
||||
|
||||
// Setup
|
||||
misc_run_on_recipes_setup(Recipes_injection);
|
||||
misc_run_on_furnace_recipes_setup(FurnaceRecipes_injection);
|
||||
}
|
@ -157,6 +157,11 @@ static void use_shader(GLuint program) {
|
||||
|
||||
// Array Pointer Drawing
|
||||
GL_FUNC(glDrawArrays, void, (GLenum mode, GLint first, GLsizei count));
|
||||
#define lazy_uniform(name) \
|
||||
static GLint name##_handle = -1; \
|
||||
if (name##_handle == -1) { \
|
||||
name##_handle = real_glGetUniformLocation()(program, #name); \
|
||||
}
|
||||
void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
// Verify
|
||||
if (gl_state.array_pointers.vertex.size != 3 || !gl_state.array_pointers.vertex.enabled || gl_state.array_pointers.vertex.type != GL_FLOAT) {
|
||||
@ -178,30 +183,30 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
use_shader(program);
|
||||
|
||||
// Projection Matrix
|
||||
GLint u_projection_handle = real_glGetUniformLocation()(program, "u_projection");
|
||||
lazy_uniform(u_projection);
|
||||
matrix_t *p = &gl_state.matrix_stacks.projection.stack[gl_state.matrix_stacks.projection.i];
|
||||
real_glUniformMatrix4fv()(u_projection_handle, 1, 0, (GLfloat *) &p->data[0][0]);
|
||||
|
||||
// Model View Matrix
|
||||
GLint u_model_view_handle = real_glGetUniformLocation()(program, "u_model_view");
|
||||
lazy_uniform(u_model_view);
|
||||
p = &gl_state.matrix_stacks.model_view.stack[gl_state.matrix_stacks.model_view.i];
|
||||
real_glUniformMatrix4fv()(u_model_view_handle, 1, 0, (GLfloat *) &p->data[0][0]);
|
||||
|
||||
// Has Texture
|
||||
GLint u_has_texture_handle = real_glGetUniformLocation()(program, "u_has_texture"); \
|
||||
lazy_uniform(u_has_texture); \
|
||||
real_glUniform1i()(u_has_texture_handle, use_texture); \
|
||||
|
||||
// Texture Matrix
|
||||
GLint u_texture_handle = real_glGetUniformLocation()(program, "u_texture");
|
||||
lazy_uniform(u_texture);
|
||||
p = &gl_state.matrix_stacks.texture.stack[gl_state.matrix_stacks.texture.i];
|
||||
real_glUniformMatrix4fv()(u_texture_handle, 1, 0, (GLfloat *) &p->data[0][0]);
|
||||
|
||||
// Texture Unit
|
||||
GLint u_texture_unit_handle = real_glGetUniformLocation()(program, "u_texture_unit");
|
||||
lazy_uniform(u_texture_unit);
|
||||
real_glUniform1i()(u_texture_unit_handle, 0);
|
||||
|
||||
// Alpha Test
|
||||
GLint u_alpha_test_handle = real_glGetUniformLocation()(program, "u_alpha_test");
|
||||
lazy_uniform(u_alpha_test);
|
||||
real_glUniform1i()(u_alpha_test_handle, gl_state.alpha_test);
|
||||
|
||||
// Color
|
||||
@ -214,16 +219,16 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
}
|
||||
|
||||
// Fog
|
||||
GLint u_fog_handle = real_glGetUniformLocation()(program, "u_fog");
|
||||
lazy_uniform(u_fog);
|
||||
real_glUniform1i()(u_fog_handle, gl_state.fog.enabled);
|
||||
if (gl_state.fog.enabled) {
|
||||
GLint u_fog_color_handle = real_glGetUniformLocation()(program, "u_fog_color");
|
||||
lazy_uniform(u_fog_color);
|
||||
real_glUniform4f()(u_fog_color_handle, gl_state.fog.color[0], gl_state.fog.color[1], gl_state.fog.color[2], gl_state.fog.color[3]);
|
||||
GLint u_fog_is_linear_handle = real_glGetUniformLocation()(program, "u_fog_is_linear");
|
||||
lazy_uniform(u_fog_is_linear);
|
||||
real_glUniform1i()(u_fog_is_linear_handle, gl_state.fog.mode == GL_LINEAR);
|
||||
GLint u_fog_start_handle = real_glGetUniformLocation()(program, "u_fog_start");
|
||||
lazy_uniform(u_fog_start);
|
||||
real_glUniform1f()(u_fog_start_handle, gl_state.fog.start);
|
||||
GLint u_fog_end_handle = real_glGetUniformLocation()(program, "u_fog_end");
|
||||
lazy_uniform(u_fog_end);
|
||||
real_glUniform1f()(u_fog_end_handle, gl_state.fog.end);
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ endif()
|
||||
add_library(death SHARED src/death/death.cpp)
|
||||
target_link_libraries(death mods-headers reborn-patch symbols feature)
|
||||
|
||||
add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp src/misc/logging.cpp)
|
||||
add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp src/misc/logging.cpp src/misc/api.cpp)
|
||||
target_link_libraries(misc mods-headers reborn-patch symbols media-layer-core feature GLESv1_CM)
|
||||
|
||||
add_library(options SHARED src/options/options.c src/options/options.cpp)
|
||||
|
@ -4,9 +4,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*misc_update_function_t)(unsigned char *minecraft);
|
||||
void misc_run_on_update(misc_update_function_t function);
|
||||
void misc_run_on_tick(misc_update_function_t function);
|
||||
typedef void (*misc_update_function_t)(unsigned char *obj);
|
||||
void misc_run_on_update(misc_update_function_t function); // obj == Minecraft *
|
||||
void misc_run_on_tick(misc_update_function_t function); // obj == Minecraft *
|
||||
void misc_run_on_recipes_setup(misc_update_function_t function); // obj == Recipes *
|
||||
void misc_run_on_furnace_recipes_setup(misc_update_function_t function); // obj == FurnaceRecipes *
|
||||
|
||||
void Level_saveLevelData_injection(unsigned char *level);
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <mods/init/init.h>
|
||||
#include <mods/feature/feature.h>
|
||||
#include <mods/misc/misc.h>
|
||||
#include <mods/creative/creative.h>
|
||||
|
||||
#ifndef MCPI_SERVER_MODE
|
||||
|
100
mods/src/misc/api.cpp
Normal file
100
mods/src/misc/api.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include <vector>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include <mods/misc/misc.h>
|
||||
#include "misc-internal.h"
|
||||
|
||||
// Run Functions On Update
|
||||
static std::vector<misc_update_function_t> &get_misc_update_functions() {
|
||||
static std::vector<misc_update_function_t> functions;
|
||||
return functions;
|
||||
}
|
||||
void misc_run_on_update(misc_update_function_t function) {
|
||||
get_misc_update_functions().push_back(function);
|
||||
}
|
||||
// Handle Custom Update Behavior
|
||||
static void Minecraft_update_injection(unsigned char *minecraft) {
|
||||
// Call Original Method
|
||||
(*Minecraft_update)(minecraft);
|
||||
|
||||
// Run Functions
|
||||
for (misc_update_function_t function : get_misc_update_functions()) {
|
||||
(*function)(minecraft);
|
||||
}
|
||||
}
|
||||
|
||||
// Run Functions On Tick
|
||||
static std::vector<misc_update_function_t> &get_misc_tick_functions() {
|
||||
static std::vector<misc_update_function_t> functions;
|
||||
return functions;
|
||||
}
|
||||
void misc_run_on_tick(misc_update_function_t function) {
|
||||
get_misc_tick_functions().push_back(function);
|
||||
}
|
||||
// Handle Custom Tick Behavior
|
||||
static void Minecraft_tick_injection(unsigned char *minecraft, int32_t param_1, int32_t param_2) {
|
||||
// Call Original Method
|
||||
(*Minecraft_tick)(minecraft, param_1, param_2);
|
||||
|
||||
// Run Functions
|
||||
for (misc_update_function_t function : get_misc_tick_functions()) {
|
||||
(*function)(minecraft);
|
||||
}
|
||||
}
|
||||
|
||||
// Run Functions On Recipes Setup
|
||||
static std::vector<misc_update_function_t> &get_misc_recipes_setup_functions() {
|
||||
static std::vector<misc_update_function_t> functions;
|
||||
return functions;
|
||||
}
|
||||
void misc_run_on_recipes_setup(misc_update_function_t function) {
|
||||
get_misc_recipes_setup_functions().push_back(function);
|
||||
}
|
||||
// Handle Custom Recipes Setup Behavior
|
||||
static unsigned char *Recipes_injection(unsigned char *recipes) {
|
||||
// Call Original Method
|
||||
(*Recipes)(recipes);
|
||||
|
||||
// Run Functions
|
||||
for (misc_update_function_t function : get_misc_recipes_setup_functions()) {
|
||||
(*function)(recipes);
|
||||
}
|
||||
|
||||
// Return
|
||||
return recipes;
|
||||
}
|
||||
|
||||
// Run Functions On Furnace Recipes Setup
|
||||
static std::vector<misc_update_function_t> &get_misc_furnace_recipes_setup_functions() {
|
||||
static std::vector<misc_update_function_t> functions;
|
||||
return functions;
|
||||
}
|
||||
void misc_run_on_furnace_recipes_setup(misc_update_function_t function) {
|
||||
get_misc_furnace_recipes_setup_functions().push_back(function);
|
||||
}
|
||||
// Handle Custom Furnace Recipes Setup Behavior
|
||||
static unsigned char *FurnaceRecipes_injection(unsigned char *recipes) {
|
||||
// Call Original Method
|
||||
(*FurnaceRecipes)(recipes);
|
||||
|
||||
// Run Functions
|
||||
for (misc_update_function_t function : get_misc_furnace_recipes_setup_functions()) {
|
||||
(*function)(recipes);
|
||||
}
|
||||
|
||||
// Return
|
||||
return recipes;
|
||||
}
|
||||
|
||||
// Init
|
||||
void _init_misc_api() {
|
||||
// Handle Custom Update Behavior
|
||||
overwrite_calls((void *) Minecraft_update, (void *) Minecraft_update_injection);
|
||||
// Handle Custom Tick Behavior
|
||||
overwrite_calls((void *) Minecraft_tick, (void *) Minecraft_tick_injection);
|
||||
// Handle Custom Recipe Setup Behavior
|
||||
overwrite_calls((void *) Recipes, (void *) Recipes_injection);
|
||||
overwrite_calls((void *) FurnaceRecipes, (void *) FurnaceRecipes_injection);
|
||||
}
|
@ -6,6 +6,7 @@ extern "C" {
|
||||
|
||||
__attribute__((visibility("internal"))) void _init_misc_cpp();
|
||||
__attribute__((visibility("internal"))) void _init_misc_logging();
|
||||
__attribute__((visibility("internal"))) void _init_misc_api();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -258,4 +258,5 @@ void init_misc() {
|
||||
// Init C++ And Logging
|
||||
_init_misc_cpp();
|
||||
_init_misc_logging();
|
||||
_init_misc_api();
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <streambuf>
|
||||
#include <vector>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -26,44 +25,6 @@ static AppPlatform_readAssetFile_return_value AppPlatform_readAssetFile_injectio
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Run Functions On Update
|
||||
static std::vector<misc_update_function_t> &get_misc_update_functions() {
|
||||
static std::vector<misc_update_function_t> functions;
|
||||
return functions;
|
||||
}
|
||||
void misc_run_on_update(misc_update_function_t function) {
|
||||
get_misc_update_functions().push_back(function);
|
||||
}
|
||||
// Handle Custom Update Behavior
|
||||
static void Minecraft_update_injection(unsigned char *minecraft) {
|
||||
// Call Original Method
|
||||
(*Minecraft_update)(minecraft);
|
||||
|
||||
// Run Functions
|
||||
for (misc_update_function_t function : get_misc_update_functions()) {
|
||||
(*function)(minecraft);
|
||||
}
|
||||
}
|
||||
|
||||
// Run Functions On Update
|
||||
static std::vector<misc_update_function_t> &get_misc_tick_functions() {
|
||||
static std::vector<misc_update_function_t> functions;
|
||||
return functions;
|
||||
}
|
||||
void misc_run_on_tick(misc_update_function_t function) {
|
||||
get_misc_tick_functions().push_back(function);
|
||||
}
|
||||
// Handle Custom Tick Behavior
|
||||
static void Minecraft_tick_injection(unsigned char *minecraft, int32_t param_1, int32_t param_2) {
|
||||
// Call Original Method
|
||||
(*Minecraft_tick)(minecraft, param_1, param_2);
|
||||
|
||||
// Run Functions
|
||||
for (misc_update_function_t function : get_misc_tick_functions()) {
|
||||
(*function)(minecraft);
|
||||
}
|
||||
}
|
||||
|
||||
// Add Missing Buttons To Pause Menu
|
||||
static void PauseScreen_init_injection(unsigned char *screen) {
|
||||
// Call Original Method
|
||||
@ -105,11 +66,6 @@ void _init_misc_cpp() {
|
||||
overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection);
|
||||
}
|
||||
|
||||
// Handle Custom Update Behavior
|
||||
overwrite_calls((void *) Minecraft_update, (void *) Minecraft_update_injection);
|
||||
// Handle Custom Tick Behavior
|
||||
overwrite_calls((void *) Minecraft_tick, (void *) Minecraft_tick_injection);
|
||||
|
||||
// Fix Pause Menu
|
||||
if (feature_has("Fix Pause Menu", server_disabled)) {
|
||||
// Add Missing Buttons To Pause Menu
|
||||
|
@ -722,6 +722,23 @@ static SoundEngine_update_t SoundEngine_update = (SoundEngine_update_t) 0x67778;
|
||||
static uint32_t SoundEngine_minecraft_property_offset = 0xa08; // Minecraft *
|
||||
static uint32_t SoundEngine_options_property_offset = 0x4; // Options *
|
||||
|
||||
// Recipes
|
||||
|
||||
// If there are multiple item IDs, the priority order is: "item" > "tile" > "instance"
|
||||
typedef struct {
|
||||
unsigned char *item;
|
||||
unsigned char *tile;
|
||||
ItemInstance instance;
|
||||
char letter;
|
||||
} Recipes_Type;
|
||||
|
||||
typedef unsigned char *(*Recipes_t)(unsigned char *recipes);
|
||||
static Recipes_t Recipes = (Recipes_t) 0x9cabc;
|
||||
|
||||
// FurnaceRecipes
|
||||
|
||||
static Recipes_t FurnaceRecipes = (Recipes_t) 0xa0778;
|
||||
|
||||
// Method That Require C++ Types
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -848,6 +865,16 @@ static OptionsPane_unknown_toggle_creating_function_t OptionsPane_unknown_toggle
|
||||
typedef void (*Textures_loadAndBindTexture_t)(unsigned char *textures, std::string const& name);
|
||||
static Textures_loadAndBindTexture_t Textures_loadAndBindTexture = (Textures_loadAndBindTexture_t) 0x539cc;
|
||||
|
||||
// Recipes
|
||||
|
||||
typedef void (*Recipes_addShapelessRecipe_t)(unsigned char *recipes, ItemInstance const& result, std::vector<Recipes_Type> const& param_2);
|
||||
static Recipes_addShapelessRecipe_t Recipes_addShapelessRecipe = (Recipes_addShapelessRecipe_t) 0x9c3dc;
|
||||
|
||||
// FurnaceRecipes
|
||||
|
||||
typedef void (*FurnaceRecipes_addFurnaceRecipe_t)(unsigned char *recipes, int32_t input_item_id, ItemInstance const& result);
|
||||
static FurnaceRecipes_addFurnaceRecipe_t FurnaceRecipes_addFurnaceRecipe = (FurnaceRecipes_addFurnaceRecipe_t) 0xa0714;
|
||||
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
Loading…
Reference in New Issue
Block a user