Water/Lava physics, plugins system

This commit is contained in:
JavaProphet 2017-01-05 00:13:32 -08:00
parent b5a946050e
commit 549e5dbc2a
10 changed files with 377 additions and 76 deletions

View File

@ -14,24 +14,24 @@
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1769467163" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GCCErrorParser" id="cdt.managedbuild.config.gnu.exe.debug.1769467163" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1769467163." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1649192409" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.753514033" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
<builder buildPath="${workspace_loc:/basin}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.1034178310" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
<toolChain errorParsers="" id="cdt.managedbuild.toolchain.gnu.exe.debug.1649192409" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.exe.debug.753514033" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
<builder buildPath="${workspace_loc:/basin}/Debug" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="cdt.managedbuild.target.gnu.builder.exe.debug.1034178310" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1610722987" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.18882949" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.8026142" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1625287618" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.287902410" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
<tool errorParsers="org.eclipse.cdt.core.GCCErrorParser" id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.287902410" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.85127222" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1202660524" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="gnu.c.compiler.option.dialect.std.1846139639" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
<option id="gnu.c.compiler.option.dialect.flags.767216746" name="Other dialect flags" superClass="gnu.c.compiler.option.dialect.flags" value="-std=gnu11" valueType="string"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.929664948" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1069626255" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
<tool errorParsers="org.eclipse.cdt.core.GLDErrorParser" id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1069626255" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
<option id="gnu.c.link.option.libs.627461760" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="pthread"/>
<listOptionValue builtIn="false" value="crypto"/>
@ -45,7 +45,7 @@
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.940105122" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.69795815" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
<tool errorParsers="org.eclipse.cdt.core.GASErrorParser" id="cdt.managedbuild.tool.gnu.assembler.exe.debug.69795815" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.161983121" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>

View File

@ -4,5 +4,5 @@
USER_OBJS :=
LIBS := -lpthread -lcrypto -lssl -lm -lz
LIBS := -lpthread -lcrypto -lssl -lm -lz -ldl

View File

@ -29,6 +29,7 @@ C_SRCS += \
../src/hashmap.c \
../src/profile.c \
../src/anticheat.c \
../src/plugin.c \
../src/xstring.c
OBJS += \
@ -61,6 +62,7 @@ OBJS += \
./src/hashmap.o \
./src/profile.o \
./src/anticheat.o \
./src/plugin.o \
./src/xstring.o
C_DEPS += \
@ -93,6 +95,7 @@ C_DEPS += \
./src/hashmap.d \
./src/profile.d \
./src/anticheat.d \
./src/plugin.d \
./src/xstring.d

View File

@ -610,62 +610,188 @@ void tree_addHangingVine(struct world* world, struct chunk* chunk, block b, int3
}
}
int tree_checkAndPlaceLeaf(struct world* world, struct chunk* chunk, block b, int32_t x, int32_t y, int32_t z) {
struct block_info* bi = getBlockInfo(getBlockWorld_guess(world, chunk, x, y, z));
if (bi == NULL || streq_nocase(bi->material->name, "air") || streq_nocase(bi->material->name, "leaves")) {
setBlockWorld_guess(world, chunk, b, x, y, z);
return 1;
}
return 0;
}
void randomTick_sapling(struct world* world, struct chunk* chunk, block blk, int32_t x, int32_t y, int32_t z) {
uint8_t lwu = getLightWorld(world, x, y + 1, z, 1);
if (lwu >= 9 && rand() % 7 == 0) {
if ((blk & 0x8) == 0x8) {
uint8_t type = blk & 0x7;
if (type == 0 || type == 2 || type == 3) { //oak
block log = BLK_LOG_OAK;
block leaf = BLK_LEAVES_OAK_2;
if (type == 2) {
log = BLK_LOG_BIRCH;
leaf = BLK_LEAVES_BIRCH_2;
} else if (type == 3) {
log = BLK_LOG_JUNGLE;
leaf = BLK_LEAVES_JUNGLE_2;
block log = BLK_LOG_OAK;
block leaf = BLK_LEAVES_OAK_2;
if (type == 1) {
log = BLK_LOG_SPRUCE;
leaf = BLK_LEAVES_SPRUCE_2;
} else if (type == 2) {
log = BLK_LOG_BIRCH;
leaf = BLK_LEAVES_BIRCH_2;
} else if (type == 3) {
log = BLK_LOG_JUNGLE;
leaf = BLK_LEAVES_JUNGLE_2;
} else if (type == 4) {
log = BLK_LOG_ACACIA_1;
leaf = BLK_LEAVES_ACACIA_2;
} else if (type == 5) {
log = BLK_LOG_BIG_OAK_1;
leaf = BLK_LEAVES_BIG_OAK_2;
}
uint8_t biome = getBiome(world, x, z);
uint8_t vines = type == 0 && (biome == BIOME_SWAMPLAND || biome == BIOME_SWAMPLANDM);
uint8_t cocoa = type == 3;
int big = type == 0 && rand() % 10 == 0;
if (!big) {
uint8_t height = 0;
if (type == 0) height = rand() % 3 + 4;
else if (type == 1) height = 6 + rand() % 4;
else if (type == 2) height = rand() % 3 + 5;
else if (type == 3) height = 3 + rand() % 10;
else if (type == 4) height = 5 + rand() % 6;
if (y < 1 || y + height + 1 > 256) return;
for (int ty = y; ty <= y + height + 1; ty++) {
if (ty < 0 || ty >= 256) return;
int width = 1;
if (ty == y) width = 0;
if (ty >= y + 1 + height - 2) width = 2;
for (int tx = x - width; tx <= x + width; tx++) {
for (int tz = z - width; tz <= z + width; tz++) {
if (!tree_canGrowInto(getBlockWorld_guess(world, chunk, tx, ty, tz))) return;
}
}
}
uint8_t biome = getBiome(world, x, z);
uint8_t vines = type == 0 && (biome == BIOME_SWAMPLAND || biome == BIOME_SWAMPLANDM);
uint8_t cocoa = type == 3;
int big = type == 0 && rand() % 10 == 0;
if (!big) {
uint8_t height = rand() % 3;
if (type == 0) height += 4;
else if (type == 2) height += 5;
else if (type == 3) height += 3 + rand() % 7;
if (y < 1 || y + height + 1 > 256) return;
for (int ty = y; ty <= y + height + 1; ty++) {
if (ty < 0 || ty >= 256) return;
int width = 1;
if (ty == y) width = 0;
if (ty >= y + 1 + height - 2) width = 2;
for (int tx = x - width; tx <= x + width; tx++) {
for (int tz = z - width; tz <= z + width; tz++) {
if (!tree_canGrowInto(getBlockWorld_guess(world, chunk, tx, ty, tz))) return;
block down = getBlockWorld_guess(world, chunk, x, y - 1, z);
if ((down != BLK_GRASS && down != BLK_DIRT && down != BLK_FARMLAND) || y >= 256 - height - 1) return;
if (down == BLK_FARMLAND && type == 4) return;
setBlockWorld_guess(world, chunk, BLK_DIRT, x, y - 1, z);
if (type == 4) {
int k2 = height - rand() % 4 - 1;
int l2 = 3 - rand() % 3;
int i3 = x;
int j1 = z;
int k1 = 0;
int rx = rand() % 4;
int ox = 0;
int oz = 0;
if (rx == 0) ox++;
else if (rx == 1) ox--;
else if (rx == 2) oz++;
else if (rx == 3) oz--;
for (int l1 = 0; l1 < height; l1++) {
int i2 = y + l1;
if (l1 >= k2 && l2 > 0) {
i3 += ox;
j1 += oz;
l2--;
}
struct block_info* bi = getBlockInfo(getBlockWorld_guess(world, chunk, i3, i2, j1));
if (bi != NULL && (streq_nocase(bi->material->name, "air") || streq_nocase(bi->material->name, "leaves") || streq_nocase(bi->material->name, "vine") || streq_nocase(bi->material->name, "plants"))) {
setBlockWorld_guess(world, chunk, log, i3, i2, j1);
k1 = i2;
}
}
for (int j3 = -3; j3 <= 3; j3++) {
for (int i4 = -3; i4 <= +3; i4++) {
if (abs(j3) != 3 || abs(i4) != 3) {
tree_checkAndPlaceLeaf(world, chunk, leaf, i3 + j3, k1, j1 + i4);
}
if (abs(j3) <= 1 || abs(i4) <= 1) {
tree_checkAndPlaceLeaf(world, chunk, leaf, i3 + j3, k1 + 1, j1 + i4);
}
}
}
block down = getBlockWorld_guess(world, chunk, x, y - 1, z);
if ((down != BLK_GRASS && down != BLK_DIRT && down != BLK_FARMLAND) || y >= 256 - height - 1) return;
setBlockWorld_guess(world, chunk, BLK_DIRT, x, y - 1, z);
for (int ty = y - 3 + height; ty <= y + height; ty++) {
int dist_from_top = ty - y - height;
int width = 1 - dist_from_top / 2;
for (int tx = x - width; tx <= x + width; tx++) {
int tx2 = tx - x;
for (int tz = z - width; tz <= z + width; tz++) {
int tz2 = tz - z;
if (abs(tx2) != width || abs(tz2) != width || (rand() % 2 == 0 && dist_from_top != 0)) {
struct block_info* bi = getBlockInfo(getBlockWorld_guess(world, chunk, tx, ty, tz));
if (bi != NULL && (streq_nocase(bi->material->name, "air") || streq_nocase(bi->material->name, "leaves") || streq_nocase(bi->material->name, "vine"))) {
setBlockWorld_guess(world, chunk, leaf, tx, ty, tz);
tree_checkAndPlaceLeaf(world, chunk, leaf, i3 - 2, k1 + 1, j1);
tree_checkAndPlaceLeaf(world, chunk, leaf, i3 + 2, k1 + 1, j1);
tree_checkAndPlaceLeaf(world, chunk, leaf, i3, k1 + 1, j1 - 2);
tree_checkAndPlaceLeaf(world, chunk, leaf, i3, k1 + 1, j1 + 1);
i3 = x;
j1 = z;
int nrx = rand() % 4;
if (rx == nrx) return;
rx = nrx;
ox = 0;
oz = 0;
if (rx == 0) ox++;
else if (rx == 1) ox--;
else if (rx == 2) oz++;
else if (rx == 3) oz--;
int l3 = k2 - rand() % 2 - 1;
int k4 = 1 + rand() % 3;
k1 = 0;
for (int l4 = l3; l4 < height && k4 > 0; k4--) {
if (l4 >= 1) {
int j2 = y + l4;
i3 += ox;
j1 += oz;
if (tree_checkAndPlaceLeaf(world, chunk, log, i3, j2, j1)) {
k1 = j2;
}
}
l4++;
}
if (k1 > 0) {
for (int i5 = -2; i5 <= 2; i5++) {
for (int k5 = -2; k5 <= 2; k5++) {
if (abs(i5) != 2 || abs(k5) != 2) tree_checkAndPlaceLeaf(world, chunk, leaf, i3 + i5, k1, j1 + k5);
if (abs(i5) <= 1 && abs(k5) <= 1) tree_checkAndPlaceLeaf(world, chunk, leaf, i3 + i5, k1 + 1, j1 + k5);
}
}
}
} else if (type == 1) {
int32_t j = 1 + rand() % 2;
int k = height - j;
int l = 2 + rand() % 2;
int i3 = rand() % 2;
int j3 = 1;
int k3 = 0;
for (int l3 = 0; l3 <= k; l3++) {
int yoff = y + height - l3;
for (int i2 = x - i3; i2 <= x + i3; i2++) {
int xoff = i2 - x;
for (int k2 = z - i3; k2 <= z + i3; k2++) {
int zoff = k2 - z;
if (abs(xoff) != i3 || abs(zoff) != i3 || i3 <= 0) {
struct block_info* bi = getBlockInfo(getBlockWorld_guess(world, chunk, i2, yoff, k2));
if (bi == NULL || !bi->fullCube) {
setBlockWorld_guess(world, chunk, leaf, i2, yoff, k2);
}
}
}
}
if (i3 >= j3) {
i3 = j3;
k3 = 1;
j3++;
if (j3 > l) {
j3 = l;
}
} else {
i3++;
}
}
for (int th = 0; th < height; th++) {
} else for (int ty = y - 3 + height; ty <= y + height; ty++) {
int dist_from_top = ty - y - height;
int width = 1 - dist_from_top / 2;
for (int tx = x - width; tx <= x + width; tx++) {
int tx2 = tx - x;
for (int tz = z - width; tz <= z + width; tz++) {
int tz2 = tz - z;
if (abs(tx2) != width || abs(tz2) != width || (rand() % 2 == 0 && dist_from_top != 0)) {
struct block_info* bi = getBlockInfo(getBlockWorld_guess(world, chunk, tx, ty, tz));
if (bi != NULL && (streq_nocase(bi->material->name, "air") || streq_nocase(bi->material->name, "leaves") || streq_nocase(bi->material->name, "vine"))) {
setBlockWorld_guess(world, chunk, leaf, tx, ty, tz);
}
}
}
}
}
if (type != 4) {
for (int th = 0; th < height - (type == 1 ? (rand() % 3) : 0); th++) {
struct block_info* bi = getBlockInfo(getBlockWorld_guess(world, chunk, x, y + th, z));
if (bi != NULL && (streq_nocase(bi->material->name, "air") || streq_nocase(bi->material->name, "leaves") || streq_nocase(bi->material->name, "vine") || streq_nocase(bi->material->name, "plants"))) {
setBlockWorld_guess(world, chunk, log, x, y + th, z);
@ -701,18 +827,8 @@ void randomTick_sapling(struct world* world, struct chunk* chunk, block blk, int
}
}
}
} else {
}
} else if (type == 1) { // spruce
} else if (type == 2) { // birch
} else if (type == 3) { // jungle
} else if (type == 4) { // acacia
} else if (type == 5) { // darkoak
} else {
}
} else {
@ -732,10 +848,123 @@ block onBlockPlaced_log(struct player* player, struct world* world, block blk, i
}
void onBlockInteract_fencegate(struct world* world, block blk, int32_t x, int32_t y, int32_t z, struct player* player, uint8_t face, float curPosX, float curPosY, float curPosZ) {
blk ^= (block)0b0100; // toggle opened bit
blk ^= (block) 0b0100; // toggle opened bit
setBlockWorld_guess(world, NULL, blk, x, y, z);
}
int fluid_getDepth(int water, block b) {
uint16_t ba = b >> 4;
if (water && (ba != BLK_WATER >> 4 && ba != BLK_WATER_1 >> 4)) return -1;
else if (!water && (ba != BLK_LAVA >> 4 && ba != BLK_LAVA_1 >> 4)) return -1;
return b & 0x0f;
}
int fluid_checkAdjacentBlock(int water, struct world* world, struct chunk* ch, int32_t x, uint8_t y, int32_t z, int cmin, int* adj) {
block b = getBlockWorld_guess(world, ch, x, y, z);
int m = fluid_getDepth(water, b);
if (m < 0) return cmin;
else {
if (m == 0) (*adj)++;
if (m >= 8) m = 0;
return cmin >= 0 && m >= cmin ? cmin : m;
}
}
int fluid_isUnblocked(int water, block b, struct block_info* bi) {
uint16_t ba = b >> 4;
if (ba == BLK_DOOROAK >> 4 || ba == BLK_DOORIRON >> 4 || ba == BLK_SIGN >> 4 || ba == BLK_LADDER >> 4 || ba == BLK_REEDS >> 4) return 0;
if (bi == NULL) return 0;
if (!streq_nocase(bi->material->name, "portal") && !streq_nocase(bi->material->name, "structure_void") ? bi->material->blocksMovement : 1) return 0;
return 1;
}
int fluid_canFlowInto(int water, block b) {
struct block_info* bi = getBlockInfo(b);
if (bi == NULL) return 1;
if (!((water ? !streq_nocase(bi->material->name, "water") : 1) && !streq_nocase(bi->material->name, "lava"))) return 0;
return fluid_isUnblocked(water, b, bi);
}
void fluid_doFlowInto(int water, struct world* world, struct chunk* ch, int32_t x, uint8_t y, int32_t z, int level, block b) {
// potentially triggerMixEffects
struct block_info* bi = getBlockInfo(b);
if (bi != NULL && !streq_nocase(bi->material->name, "air") && !streq_nocase(bi->material->name, "lava")) {
dropBlockDrops(world, b, NULL, x, y, z);
}
setBlockWorld_guess(world, ch, (water ? BLK_WATER : BLK_LAVA) | level, x, y, z);
}
void onBlockUpdate_fluid(struct world* world, block blk, int32_t x, int32_t y, int32_t z) {
struct chunk* ch = getChunk(world, x >> 4, z >> 4);
if (ch == NULL) return;
int level = blk & 0x0f;
int resistance = 1;
if (((blk >> 4) == (BLK_LAVA >> 4) || (blk >> 4) == (BLK_LAVA_1 >> 4)) && world->dimension != -1) resistance++;
int adjSource = 0;
int water = (blk >> 4) == (BLK_WATER >> 4) || (blk >> 4) == (BLK_WATER_1 >> 4);
int tickRate = water ? 5 : (world->dimension == -1 ? 10 : 30);
if (level > 0) {
int l = -100;
l = fluid_checkAdjacentBlock(water, world, ch, x + 1, y, z, l, &adjSource);
l = fluid_checkAdjacentBlock(water, world, ch, x - 1, y, z, l, &adjSource);
l = fluid_checkAdjacentBlock(water, world, ch, x, y, z + 1, l, &adjSource);
l = fluid_checkAdjacentBlock(water, world, ch, x, y, z - 1, l, &adjSource);
int i1 = l + resistance;
if (i1 >= 8 || l < 0) i1 = -1;
int ha = fluid_getDepth(water, getBlockWorld_guess(world, ch, x, y + 1, z));
if (ha >= 0) {
if (ha >= 8) i1 = ha;
else i1 = ha + 8;
}
if (adjSource >= 2 && water) {
block below = getBlockWorld_guess(world, ch, x, y - 1, z);
if ((below >> 4) == (BLK_WATER >> 4) || (below >> 4) == (BLK_WATER_1 >> 4)) {
i1 = 0;
} else {
struct block_info* bi = getBlockInfo(below);
if (bi != NULL && bi->material->solid) i1 = 0;
}
}
if (!water && level < 8 && i1 < 8 && i1 > level && rand() % 4 > 0) {
tickRate *= 4;
}
if (i1 == level) {
// set static
} else {
level = i1;
if (i1 < 0) setBlockWorld_guess(world, ch, 0, x, y, z);
else {
setBlockWorld_guess(world, ch, (blk & ~0x0f) | i1, x, y, z);
}
}
} else {
//set static
}
block down = getBlockWorld_guess(world, ch, x, y - 1, z);
if (fluid_canFlowInto(water, down)) {
if (!water && ((down >> 4) == (BLK_WATER >> 4) || (down >> 4) == (BLK_WATER_1 >> 4))) {
setBlockWorld_guess(world, ch, BLK_STONE, x, y - 1, z);
//trigger mix effects
return;
}
fluid_doFlowInto(water, world, ch, x, y - 1, z, level >= 8 ? level : (level + 8), down);
} else if (level >= 0) {
if (level == 0 || !fluid_isUnblocked(water, down, getBlockInfo(down))) {
int k1 = level + resistance;
if (level >= 8) k1 = 1;
if (k1 >= 8) return;
block b = getBlockWorld_guess(world, ch, x + 1, y, z);
if (fluid_canFlowInto(water, b)) fluid_doFlowInto(water, world, ch, x + 1, y, z, k1, b);
b = getBlockWorld_guess(world, ch, x - 1, y, z);
if (fluid_canFlowInto(water, b)) fluid_doFlowInto(water, world, ch, x - 1, y, z, k1, b);
b = getBlockWorld_guess(world, ch, x, y, z + 1);
if (fluid_canFlowInto(water, b)) fluid_doFlowInto(water, world, ch, x, y, z + 1, k1, b);
b = getBlockWorld_guess(world, ch, x, y, z - 1);
if (fluid_canFlowInto(water, b)) fluid_doFlowInto(water, world, ch, x, y, z - 1, k1, b);
}
}
}
//
struct block_info* getBlockInfo(block b) {
@ -1067,4 +1296,8 @@ void init_blocks() {
tmp->onBlockUpdate = &onBlockUpdate_checkPlace;
for (block b = BLK_FENCEGATE; b < BLK_FENCEGATE + 16; b++)
getBlockInfo(b)->onBlockInteract = &onBlockInteract_fencegate;
getBlockInfo(BLK_WATER)->onBlockUpdate = &onBlockUpdate_fluid;
getBlockInfo(BLK_WATER_1)->onBlockUpdate = &onBlockUpdate_fluid;
getBlockInfo(BLK_LAVA)->onBlockUpdate = &onBlockUpdate_fluid;
getBlockInfo(BLK_LAVA_1)->onBlockUpdate = &onBlockUpdate_fluid;
}

View File

@ -402,8 +402,11 @@
#define BLK_THINSTAINEDGLASS_BLACK 2575
#define BLK_LEAVES_ACACIA 2576
#define BLK_LEAVES_BIG_OAK 2577
#define BLK_LEAVES_ACACIA_1 2580
#define BLK_LEAVES_BIG_OAK_1 2581
#define BLK_LEAVES_ACACIA_2 2584
#define BLK_LEAVES_BIG_OAK_2 2585
#define BLK_LEAVES_ACACIA_3 2588
#define BLK_LEAVES_BIG_OAK_3 2589
#define BLK_LOG_ACACIA_1 2592
#define BLK_LOG_BIG_OAK_1 2593

View File

@ -75,6 +75,46 @@ int onItemInteract_reeds(struct world* world, struct player* player, uint8_t slo
return 0;
}
int onItemInteract_bucket(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, uint8_t y, int32_t z, uint8_t face) {
if (slot == NULL) return 0;
offsetCoordByFace(&x, &y, &z, face);
block b = getBlockWorld(world, x, y, z);
struct block_info* bi = getBlockInfo(b);
if (bi == NULL) return 0;
uint16_t ba = b >> 4;
if (slot->item == ITM_BUCKETWATER) {
if (b != 0 && !bi->material->replacable && ba != BLK_WATER >> 4 && ba != BLK_WATER_1 >> 4) return 0;
setBlockWorld(world, BLK_WATER, x, y, z);
if (player->gamemode != 1) {
slot->item = ITM_BUCKET;
setSlot(player, player->inventory, slot_index, slot, 1, 1);
}
} else if (slot->item == ITM_BUCKETLAVA) {
if (b != 0 && !bi->material->replacable && ba != BLK_LAVA >> 4 && ba != BLK_LAVA_1 >> 4) return 0;
setBlockWorld(world, BLK_LAVA, x, y, z);
if (player->gamemode != 1) {
slot->item = ITM_BUCKET;
setSlot(player, player->inventory, slot_index, slot, 1, 1);
}
} else if (slot->item == ITM_BUCKET) {
if ((b & 0x0f) != 0) return 0;
if (ba == BLK_WATER >> 4 || ba == BLK_WATER_1 >> 4) {
setBlockWorld(world, 0, x, y, z);
if (player->gamemode != 1) {
slot->item = ITM_BUCKETWATER;
setSlot(player, player->inventory, slot_index, slot, 1, 1);
}
} else if (ba == BLK_LAVA >> 4 || ba == BLK_LAVA_1 >> 4) {
setBlockWorld(world, 0, x, y, z);
if (player->gamemode != 1) {
slot->item = ITM_BUCKETLAVA;
setSlot(player, player->inventory, slot_index, slot, 1, 1);
}
}
}
return 0;
}
int onItemInteract_bonemeal(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, uint8_t y, int32_t z, uint8_t face) {
if (slot == NULL) return 0;
block b = getBlockWorld(world, x, y, z);
@ -327,6 +367,10 @@ void init_items() {
getItemInfo(ITM_SHOVELIRON)->onItemInteract = &onItemInteract_shovel;
getItemInfo(ITM_SHOVELDIAMOND)->onItemInteract = &onItemInteract_shovel;
getItemInfo(ITM_REEDS)->onItemInteract = &onItemInteract_reeds;
getItemInfo(ITM_BUCKET)->onItemInteract = &onItemInteract_bucket;
getItemInfo(ITM_BUCKETWATER)->onItemInteract = &onItemInteract_bucket;
getItemInfo(ITM_BUCKETLAVA)->onItemInteract = &onItemInteract_bucket;
}
void add_item(item id, struct item_info* info) {

View File

@ -135,11 +135,12 @@ int __recurJSON(struct json_object* cur, size_t* i, char* json) {
size_t sl = strlen(json);
int cs = 0;
struct json_object* nchild = NULL;
char ck = cur->type == JSON_OBJECT ? '}' : ']';
for (; *i < sl; (*i)++) {
if (cs == 0) {
if (json[*i] == '{') cs = 1;
} else if (cs == 1) {
if (json[*i] == '}') break;
if (json[*i] == ck) break;
else if (json[*i] == '\"') {
nchild = xmalloc(sizeof(struct json_object));
memset(nchild, 0, sizeof(struct json_object));
@ -170,7 +171,7 @@ int __recurJSON(struct json_object* cur, size_t* i, char* json) {
cs = 4;
} else if (cs == 4) {
if (json[*i] == ',') cs = 1;
else if (json[*i] == '}') break;
else if (json[*i] == ck) break;
}
}
if (nchild != NULL) {
@ -181,12 +182,13 @@ int __recurJSON(struct json_object* cur, size_t* i, char* json) {
}
ssize_t parseJSON(struct json_object* root, char* json) {
if (strlen(json) < 2 || json[0] != '{') {
if (strlen(json) < 2 || (json[0] != '{' && json[0] != '[')) {
memset(root, 0, sizeof(struct json_object));
errno = EINVAL;
return -1;
}
root->name = NULL;
root->type = JSON_OBJECT;
root->type = json[0] == '{' ? JSON_OBJECT : JSON_ARRAY;
root->children = NULL;
root->child_count = 0;
root->data.string = NULL;

View File

@ -41,6 +41,7 @@
#include "command.h"
#include "queue.h"
#include "profile.h"
#include "plugin.h"
void main_tick() {
pthread_cond_broadcast (&glob_tick_cond);
@ -201,6 +202,8 @@ int main(int argc, char* argv[]) {
printf("Smelting Initialized\n");
init_base_commands();
printf("Commands Initialized\n");
init_plugins();
printf("Plugins Initialized\n");
for (int i = 0; i < servsl; i++) {
struct cnode* serv = servs[i];
const char* bind_mode = getConfigValue(serv, "bind-mode");

View File

@ -462,11 +462,13 @@ uint8_t getLightChunk(struct chunk* chunk, uint8_t x, uint8_t y, uint8_t z, uint
}
uint8_t getLightWorld_guess(struct world* world, struct chunk* ch, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return 0;
if ((x >> 4) == ch->x && ((z >> 4) == ch->z)) return getLightChunk(ch, x & 0x0f, y, z & 0x0f, world->skylightSubtracted);
else return getLightWorld(world, x, y, z, 0);
}
uint8_t getLightWorld(struct world* world, int32_t x, int32_t y, int32_t z, uint8_t checkNeighbors) {
if (y < 0 || y > 255) return 0;
struct chunk* chunk = getChunk(world, x >> 4, z >> 4);
if (chunk == NULL) return 15;
if (checkNeighbors) {
@ -486,18 +488,20 @@ uint8_t getLightWorld(struct world* world, int32_t x, int32_t y, int32_t z, uint
}
}
block getBlockWorld(struct world* world, int32_t x, uint8_t y, int32_t z) {
block getBlockWorld(struct world* world, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return 0;
struct chunk* chunk = getChunk(world, x >> 4, z >> 4);
if (chunk == NULL) return 0;
return getBlockChunk(chunk, x & 0x0f, y, z & 0x0f);
}
block getBlockWorld_guess(struct world* world, struct chunk* ch, int32_t x, uint8_t y, int32_t z) {
block getBlockWorld_guess(struct world* world, struct chunk* ch, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return 0;
if ((x >> 4) == ch->x && ((z >> 4) == ch->z)) return getBlockChunk(ch, x & 0x0f, y, z & 0x0f);
else return getBlockWorld(world, x, y, z);
}
struct tile_entity* getTileEntityChunk(struct chunk* chunk, int32_t x, uint8_t y, int32_t z) { // TODO: optimize
struct tile_entity* getTileEntityChunk(struct chunk* chunk, int32_t x, int32_t y, int32_t z) { // TODO: optimize
if (y > 255 || y < 0) return NULL;
for (size_t i = 0; i < chunk->tileEntities->size; i++) {
struct tile_entity* te = (struct tile_entity*) chunk->tileEntities->data[i];
@ -545,13 +549,15 @@ void disableTileEntityTickable(struct world* world, struct tile_entity* te) {
rem_collection(chunk->tileEntitiesTickable, te);
}
struct tile_entity* getTileEntityWorld(struct world* world, int32_t x, uint8_t y, int32_t z) {
struct tile_entity* getTileEntityWorld(struct world* world, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return NULL;
struct chunk* chunk = getChunk(world, x >> 4, z >> 4);
if (chunk == NULL) return NULL;
return getTileEntityChunk(chunk, x, y, z);
}
void setTileEntityWorld(struct world* world, int32_t x, uint8_t y, int32_t z, struct tile_entity* te) {
void setTileEntityWorld(struct world* world, int32_t x, int32_t y, int32_t z, struct tile_entity* te) {
if (y < 0 || y > 255) return;
struct chunk* chunk = getChunk(world, x >> 4, z >> 4);
if (chunk == NULL) return;
setTileEntityChunk(chunk, te);
@ -680,18 +686,21 @@ void setBlockChunk(struct chunk* chunk, block blk, uint8_t x, uint8_t y, uint8_t
}
void setBlockWorld(struct world* world, block blk, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return;
struct chunk* ch = getChunk(world, x >> 4, z >> 4);
if (ch == NULL) return;
setBlockWorld_guess(world, ch, blk, x, y, z);
}
void setBlockWorld_noupdate(struct world* world, block blk, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return;
struct chunk* ch = getChunk(world, x >> 4, z >> 4);
if (ch == NULL) return;
setBlockWorld_guess_noupdate(world, ch, blk, x, y, z);
}
void setBlockWorld_guess(struct world* world, struct chunk* chunk, block blk, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return;
if (chunk == NULL || (x >> 4) != chunk->x || ((z >> 4) != chunk->z)) {
chunk = getChunk(world, x >> 4, z >> 4);
}
@ -719,6 +728,7 @@ void setBlockWorld_guess(struct world* world, struct chunk* chunk, block blk, in
}
void setBlockWorld_guess_noupdate(struct world* world, struct chunk* chunk, block blk, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return;
if (chunk == NULL || (x >> 4) != chunk->x || ((z >> 4) != chunk->z)) {
chunk = getChunk(world, x >> 4, z >> 4);
}
@ -962,6 +972,7 @@ void spawnPlayer(struct world* world, struct player* player) {
struct subworld* sw = xmalloc(sizeof(struct subworld));
sw->world = world;
sw->players = new_hashmap(1, 1);
sw->defunct = 0;
player->subworld = sw;
put_hashmap(world->subworlds, (uint64_t) sw, sw);
pthread_t swt;
@ -1017,12 +1028,14 @@ struct entity* getEntity(struct world* world, int32_t id) {
}
void updateBlockWorld_guess(struct world* world, struct chunk* ch, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return;
block b = getBlockWorld_guess(world, ch, x, y, z);
struct block_info* bi = getBlockInfo(b);
if (bi != NULL && bi->onBlockUpdate != NULL) bi->onBlockUpdate(world, b, x, y, z);
}
void updateBlockWorld(struct world* world, int32_t x, int32_t y, int32_t z) {
if (y < 0 || y > 255) return;
block b = getBlockWorld(world, x, y, z);
struct block_info* bi = getBlockInfo(b);
if (bi != NULL && bi->onBlockUpdate != NULL) bi->onBlockUpdate(world, b, x, y, z);

View File

@ -197,9 +197,9 @@ int getBiome(struct world* world, int32_t x, int32_t z);
block getBlockChunk(struct chunk* chunk, uint8_t x, uint8_t y, uint8_t z);
block getBlockWorld(struct world* world, int32_t x, uint8_t y, int32_t z);
block getBlockWorld(struct world* world, int32_t x, int32_t y, int32_t z);
block getBlockWorld_guess(struct world* world, struct chunk* ch, int32_t x, uint8_t y, int32_t z);
block getBlockWorld_guess(struct world* world, struct chunk* ch, int32_t x, int32_t y, int32_t z);
struct chunk* newChunk(int16_t x, int16_t z);
@ -215,13 +215,13 @@ void setBlockWorld(struct world* world, block blk, int32_t x, int32_t y, int32_t
void setBlockWorld_guess(struct world* world, struct chunk* chunk, block blk, int32_t x, int32_t y, int32_t z);
struct tile_entity* getTileEntityChunk(struct chunk* chunk, int32_t x, uint8_t y, int32_t z);
struct tile_entity* getTileEntityChunk(struct chunk* chunk, int32_t x, int32_t y, int32_t z);
void setTileEntityChunk(struct chunk* chunk, struct tile_entity* te);
struct tile_entity* getTileEntityWorld(struct world* world, int32_t x, uint8_t y, int32_t z);
struct tile_entity* getTileEntityWorld(struct world* world, int32_t x, int32_t y, int32_t z);
void setTileEntityWorld(struct world* world, int32_t x, uint8_t y, int32_t z, struct tile_entity* te);
void setTileEntityWorld(struct world* world, int32_t x, int32_t y, int32_t z, struct tile_entity* te);
void enableTileEntityTickable(struct world* world, struct tile_entity* te);