forked from EXTERNAL/bareiron
implement block mining conditions
This commit is contained in:
@@ -1,6 +1,16 @@
|
|||||||
const fs = require("fs/promises");
|
const fs = require("fs/promises");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
|
// Overrides for block-to-item conversion
|
||||||
|
const blockToItemOverrides = {
|
||||||
|
"grass_block": "dirt",
|
||||||
|
"stone": "cobblestone"
|
||||||
|
};
|
||||||
|
|
||||||
|
const biomes = [
|
||||||
|
"plains"
|
||||||
|
];
|
||||||
|
|
||||||
// Extract item and block data from registry dump
|
// Extract item and block data from registry dump
|
||||||
async function extractItemsAndBlocks () {
|
async function extractItemsAndBlocks () {
|
||||||
|
|
||||||
@@ -48,12 +58,13 @@ async function extractItemsAndBlocks () {
|
|||||||
const exceptions = [ "air", "water", "lava" ];
|
const exceptions = [ "air", "water", "lava" ];
|
||||||
|
|
||||||
// While we're at it, map block IDs to item IDs
|
// While we're at it, map block IDs to item IDs
|
||||||
const mapping = [];
|
const mapping = [], mappingWithOverrides = [];
|
||||||
|
|
||||||
for (const block in blocks) {
|
for (const block in blocks) {
|
||||||
if (!(block in items) && !exceptions.includes(block)) continue;
|
if (!(block in items) && !exceptions.includes(block)) continue;
|
||||||
palette[block] = blocks[block];
|
palette[block] = blocks[block];
|
||||||
mapping.push(items[block] || 0);
|
mapping.push(items[block] || 0);
|
||||||
|
mappingWithOverrides.push(items[blockToItemOverrides[block]] || items[block] || 0);
|
||||||
if (mapping.length === 256) break;
|
if (mapping.length === 256) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +75,7 @@ async function extractItemsAndBlocks () {
|
|||||||
blockRegistry[block.replace("minecraft:", "")] = blockRegistrySource[block].protocol_id;
|
blockRegistry[block.replace("minecraft:", "")] = blockRegistrySource[block].protocol_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { blocks, items, palette, mapping, blockRegistry };
|
return { blocks, items, palette, mapping, mappingWithOverrides, blockRegistry };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,10 +217,6 @@ const requiredRegistries = [
|
|||||||
"damage_type"
|
"damage_type"
|
||||||
];
|
];
|
||||||
|
|
||||||
const biomes = [
|
|
||||||
"plains"
|
|
||||||
];
|
|
||||||
|
|
||||||
async function convert () {
|
async function convert () {
|
||||||
|
|
||||||
const inputPath = __dirname + "/notchian/generated/data/minecraft";
|
const inputPath = __dirname + "/notchian/generated/data/minecraft";
|
||||||
@@ -276,7 +283,7 @@ ${toCArray(tagBuffer)}
|
|||||||
// Block palette
|
// Block palette
|
||||||
uint16_t block_palette[] = { ${Object.values(itemsAndBlocks.palette).join(", ")} };
|
uint16_t block_palette[] = { ${Object.values(itemsAndBlocks.palette).join(", ")} };
|
||||||
// Block-to-item mapping
|
// Block-to-item mapping
|
||||||
uint16_t B_to_I[] = { ${itemsAndBlocks.mapping.join(", ")} };
|
uint16_t B_to_I[] = { ${itemsAndBlocks.mappingWithOverrides.join(", ")} };
|
||||||
// Item-to-block mapping
|
// Item-to-block mapping
|
||||||
uint8_t I_to_B (uint16_t item) {
|
uint8_t I_to_B (uint16_t item) {
|
||||||
switch (item) {
|
switch (item) {
|
||||||
|
8
main.c
8
main.c
@@ -282,6 +282,14 @@ int main () {
|
|||||||
sc_keepAlive(client_fd);
|
sc_keepAlive(client_fd);
|
||||||
sc_updateTime(client_fd, world_time += 200);
|
sc_updateTime(client_fd, world_time += 200);
|
||||||
clock_gettime(CLOCK_REALTIME, &keepalive_last);
|
clock_gettime(CLOCK_REALTIME, &keepalive_last);
|
||||||
|
/**
|
||||||
|
* If the RNG seed ever hits 0, it'll never generate anything
|
||||||
|
* else. This is because the fast_rand function uses a simple
|
||||||
|
* XORshift. This isn't a common concern, so we only check for
|
||||||
|
* this periodically. If it does become zero, we reset it to
|
||||||
|
* the world seed as a good-enough fallback.
|
||||||
|
*/
|
||||||
|
if (rng_seed == 0) rng_seed = world_seed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@ ssize_t recv_count;
|
|||||||
uint8_t recv_buffer[256] = {0};
|
uint8_t recv_buffer[256] = {0};
|
||||||
|
|
||||||
uint32_t world_seed = 0xA103DE6C;
|
uint32_t world_seed = 0xA103DE6C;
|
||||||
|
uint32_t rng_seed = 0xE2B9419;
|
||||||
|
|
||||||
BlockChange block_changes[20000];
|
BlockChange block_changes[20000];
|
||||||
int block_changes_count = 0;
|
int block_changes_count = 0;
|
||||||
|
@@ -22,6 +22,7 @@ extern ssize_t recv_count;
|
|||||||
extern uint8_t recv_buffer[256];
|
extern uint8_t recv_buffer[256];
|
||||||
|
|
||||||
extern uint32_t world_seed;
|
extern uint32_t world_seed;
|
||||||
|
extern uint32_t rng_seed;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
@@ -386,14 +386,7 @@ int cs_playerAction (int client_fd) {
|
|||||||
// block was mined in survival
|
// block was mined in survival
|
||||||
|
|
||||||
uint8_t block = getBlockAt(x, y, z);
|
uint8_t block = getBlockAt(x, y, z);
|
||||||
uint16_t item, tmp;
|
uint16_t tmp, item = getMiningResult(client_fd, block);
|
||||||
|
|
||||||
if (block == B_oak_leaves) {
|
|
||||||
if (sequence % 200 < 2) item = I_apple;
|
|
||||||
else if (sequence % 50 < 2) item = I_stick;
|
|
||||||
else if (sequence % 40 < 2) item = I_oak_sapling;
|
|
||||||
else item = 0;
|
|
||||||
} else item = B_to_I[block];
|
|
||||||
|
|
||||||
makeBlockChange(x, y, z, 0);
|
makeBlockChange(x, y, z, 0);
|
||||||
|
|
||||||
|
46
src/tools.c
46
src/tools.c
@@ -5,6 +5,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
#include "registries.h"
|
||||||
#include "varnum.h"
|
#include "varnum.h"
|
||||||
#include "packets.h"
|
#include "packets.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
@@ -102,6 +103,13 @@ void readString (int client_fd) {
|
|||||||
recv_buffer[recv_count] = '\0';
|
recv_buffer[recv_count] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t fast_rand () {
|
||||||
|
rng_seed ^= rng_seed << 13;
|
||||||
|
rng_seed ^= rng_seed >> 17;
|
||||||
|
rng_seed ^= rng_seed << 5;
|
||||||
|
return rng_seed;
|
||||||
|
}
|
||||||
|
|
||||||
int client_states[MAX_PLAYERS * 2];
|
int client_states[MAX_PLAYERS * 2];
|
||||||
|
|
||||||
void setClientState (int client_fd, int new_state) {
|
void setClientState (int client_fd, int new_state) {
|
||||||
@@ -275,3 +283,41 @@ void makeBlockChange (short x, short y, short z, uint8_t block) {
|
|||||||
block_changes_count ++;
|
block_changes_count ++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the result of mining a block, taking into account the block type and tools
|
||||||
|
// Probability numbers obtained with this formula: N = floor(P * 32 ^ 2)
|
||||||
|
uint16_t getMiningResult (int client_fd, uint8_t block) {
|
||||||
|
|
||||||
|
switch (block) {
|
||||||
|
|
||||||
|
case B_oak_leaves:
|
||||||
|
uint32_t r = fast_rand();
|
||||||
|
printf("fast_rand: %u, in distribution: %.3f\n", r, (float)r / (4294967295.0f));
|
||||||
|
if (r < 21474836) return I_apple; // 0.5%
|
||||||
|
if (r < 85899345) return I_stick; // 2%
|
||||||
|
if (r < 214748364) return I_oak_sapling; // 5%
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_stone:
|
||||||
|
case B_cobblestone:
|
||||||
|
// Check if player is holding a pickaxe
|
||||||
|
PlayerData *player;
|
||||||
|
if (getPlayerData(client_fd, &player)) return 0;
|
||||||
|
uint16_t held_item = player->inventory_items[player->hotbar];
|
||||||
|
if (
|
||||||
|
held_item != I_wooden_pickaxe &&
|
||||||
|
held_item != I_stone_pickaxe &&
|
||||||
|
held_item != I_iron_pickaxe &&
|
||||||
|
held_item != I_golden_pickaxe &&
|
||||||
|
held_item != I_diamond_pickaxe &&
|
||||||
|
held_item != I_netherite_pickaxe
|
||||||
|
) return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_to_I[block];
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -25,6 +25,8 @@ double readDouble (int client_fd);
|
|||||||
|
|
||||||
void readString (int client_fd);
|
void readString (int client_fd);
|
||||||
|
|
||||||
|
uint32_t fast_rand ();
|
||||||
|
|
||||||
extern int client_states[MAX_PLAYERS * 2];
|
extern int client_states[MAX_PLAYERS * 2];
|
||||||
|
|
||||||
void setClientState (int client_fd, int new_state);
|
void setClientState (int client_fd, int new_state);
|
||||||
@@ -42,4 +44,6 @@ uint8_t clientSlotToServerSlot (int window_id, uint8_t slot);
|
|||||||
uint8_t getBlockChange (short x, short y, short z);
|
uint8_t getBlockChange (short x, short y, short z);
|
||||||
void makeBlockChange (short x, short y, short z, uint8_t block);
|
void makeBlockChange (short x, short y, short z, uint8_t block);
|
||||||
|
|
||||||
|
uint16_t getMiningResult (int client_fd, uint8_t block);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user