Skip to content

Commit

Permalink
Added seeds and wheat. You can grow wheat but it's quite clunky atm.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unarelith committed Jul 5, 2020
1 parent 084a002 commit 14e23dc
Show file tree
Hide file tree
Showing 36 changed files with 173 additions and 47 deletions.
32 changes: 26 additions & 6 deletions docs/lua-api-block.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,26 @@ name = "Cobblestone"

This label is the name that will appear everywhere in the game.

### `tick_probability`

Probability to call the `on_tick` function when `tick_randomly` is enabled.

Example:
```lua
tick_probability = 0.5 -- 50%
```

### `tick_randomly`

Whether or not the block `on_tick` function is executed randomly.

See also `tick_probability`.

Example:
```lua
tick_randomly = true
```

### `tiles`

This field can be either a single string, or a table of strings.
Expand Down Expand Up @@ -243,8 +263,8 @@ Useful for flora, tallgrass, mushrooms, etc...
Parameters:
- `pos` (`ivec3`): position of the block
- `player` (`Player`): player that activated the block
- `world` (`World`): instance of the `ServerWorld`
- `player` (`ServerPlayer`): player that activated the block
- `world` (`ServerWorld`): instance of the world
- `client` (`Client`): client that activated the block
- `server` (`Server`): current server
- `screen_width` (`u16`): width of the screen
Expand All @@ -256,20 +276,20 @@ Parameters:
Parameters:
- `pos` (`ivec3`): position of the block
- `world` (`World`): instance of `ServerWorld`
- `world` (`ServerWorld`): instance of the world
### `on_block_placed`
Parameters:
- `pos` (`ivec3`): position of the block
- `world` (`World`): instance of `ServerWorld`
- `world` (`ServerWorld`): instance of the world
### `on_tick`
Parameters:
- `pos` (`ivec3`): position of the block
- `chunk` (`Chunk`): current chunk
- `world` (`World`): instance of the `ServerWorld`
- `chunk` (`ServerChunk`): current chunk
- `world` (`ServerWorld`): instance of the world
47 changes: 45 additions & 2 deletions mods/default/blocks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ mod:block {
id = "dandelion",
name = "Dandelion",
tiles = "dandelion.png",
hardness = 0.05,
hardness = 0,
draw_type = "xshape",
bounding_box = {0.25, 0.25, 0.0, 0.5, 0.5, 0.5},
}
Expand All @@ -159,7 +159,7 @@ mod:block {
name = "Grass",
tiles = "grass.png",
color_multiplier = {129, 191, 91, 255},
hardness = 0.05,
hardness = 0,
draw_type = "xshape",
}

Expand Down Expand Up @@ -352,6 +352,49 @@ mod:block {
bounding_box = {0, 0, 0, 1, 1, 15 / 16},
}

mod:block {
id = "seeds",
name = "Seeds",
tiles = "wheat_stage_0.png",
alt_tiles = "wheat_stage_7.png",
draw_type = "xshape",
inventory_image = "seeds_wheat.png",
hardness = 0,

tick_randomly = true,
tick_probability = 0.01,

on_block_placed = function(pos, world)
world:add_block_data(pos.x, pos.y, pos.z, 0, 0)
end,

on_tick = function(pos, chunk, world)
local data = world:get_block_data(pos.x, pos.y, pos.z)
if not data then return end

local growth_stage = data.meta:get_int("growth_stage") or 0
if growth_stage < 7 then
data.use_alt_tiles = true
data.meta:set_int("growth_stage", 7)
end
end,

on_block_activated = function(pos, player, world, client, server, screen_width, screen_height, gui_scale)
local data = world:get_block_data(pos.x, pos.y, pos.z)
if not data then return end

local growth_stage = data.meta:get_int("growth_stage") or 0
if growth_stage >= 7 then
data.use_alt_tiles = false
data.meta:set_int("growth_stage", 0)

-- FIXME: It should drop the item if 'default:use_item_drops' is enabled
local item_stack = ItemStack.new("default:wheat", 1)
mods["default"]:give_item_stack(player, item_stack)
end
end
}

dofile("blocks/workbench.lua")
dofile("blocks/furnace.lua")
dofile("blocks/door.lua")
Expand Down
13 changes: 13 additions & 0 deletions mods/default/items.lua
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,16 @@ mod:item {
end
end
}

mod:item {
id = "wheat",
name = "Wheat",
tiles = "wheat.png",
}

mod:item {
id = "bread",
name = "Bread",
tiles = "bread.png",
}

11 changes: 11 additions & 0 deletions mods/default/recipes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -635,3 +635,14 @@ mod:crafting_recipe {
keys = {["#"] = "default:oak_planks"}
}

-- Bread
mod:crafting_recipe {
result = {
id = "default:bread",
amount = 1
},
pattern = {
"###",
},
keys = {["#"] = "default:wheat"}
}
Binary file added mods/default/textures/blocks/wheat_stage_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/blocks/wheat_stage_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/blocks/wheat_stage_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/blocks/wheat_stage_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/blocks/wheat_stage_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/blocks/wheat_stage_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/blocks/wheat_stage_6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/blocks/wheat_stage_7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/items/bread.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/items/seeds_wheat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added mods/default/textures/items/wheat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion source/client/world/ChunkBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,10 @@ inline void ChunkBuilder::addFace(s8f x, s8f y, s8f z, s8f f, const ClientChunk
}

inline void ChunkBuilder::addCross(s8f x, s8f y, s8f z, const ClientChunk &chunk, const Block &block, const glm::vec3 *const vertexPos[nCrossFaces][nVertsPerFace]) {
const gk::FloatRect &blockTexCoords = m_textureAtlas.getTexCoords(block.tiles().getTextureForFace(0));
const BlockData *blockData = chunk.getBlockData(x, y, z);
const std::string &texture = block.tiles().getTextureForFace(0, blockData ? blockData->useAltTiles : false);
const gk::FloatRect &blockTexCoords = m_textureAtlas.getTexCoords(texture);

float faceTexCoords[nVertsPerFace][nCoordsPerUV] = {
{blockTexCoords.x, blockTexCoords.y + blockTexCoords.sizeY},
{blockTexCoords.x + blockTexCoords.sizeX, blockTexCoords.y + blockTexCoords.sizeY},
Expand Down
1 change: 1 addition & 0 deletions source/common/inventory/ItemStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const Item &ItemStack::item() const {
// Please update 'docs/lua-api-cpp.md' if you change this
void ItemStack::initUsertype(sol::state &lua) {
lua.new_usertype<ItemStack>("ItemStack",
sol::constructors<ItemStack(const std::string &, u16)>(),
"amount", &ItemStack::amount,
"item", &ItemStack::item
);
Expand Down
9 changes: 0 additions & 9 deletions source/common/world/Chunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,6 @@ void Chunk::setBlock(int x, int y, int z, u16 type) {
if ((m_data[z][y][x] & 0xffff) == type) return;

const Block &block = Registry::getInstance().getBlock(type);
if (block.canUpdate()) {
addTickingBlock(x, y, z, block);
}
else {
auto it = m_tickingBlocks.find(gk::Vector3i{x, y, z});
if (it != m_tickingBlocks.end())
m_tickingBlocks.erase(it);
}

if (block.isLightSource())
m_lightmap.addTorchlight(x, y, z, 14);
else {
Expand Down
3 changes: 0 additions & 3 deletions source/common/world/Chunk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ class Chunk : public gk::NonCopyable {
bool areAllNeighboursLoaded() const;
bool areAllNeighboursInitialized() const;

void addTickingBlock(int x, int y, int z, const Block &block) { m_tickingBlocks.emplace(gk::Vector3i{x, y, z}, block); }

bool hasChanged() const { return m_hasChanged; }
void setChanged(bool hasChanged) { m_hasChanged = hasChanged; }

Expand Down Expand Up @@ -126,7 +124,6 @@ class Chunk : public gk::NonCopyable {
std::atomic_bool m_hasLightChanged{false};
std::atomic_bool m_isInitialized{false};

std::unordered_map<gk::Vector3i, const Block&> m_tickingBlocks;
std::unordered_map<gk::Vector3i, std::unique_ptr<BlockData>> m_blockData;
};

Expand Down
2 changes: 2 additions & 0 deletions source/server/lua/loader/LuaBlockLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ inline void LuaBlockLoader::loadProperties(ServerBlock &block, const sol::table
block.setRotatable(table["is_rotatable"].get_or(false));
block.setInventoryImage(table["inventory_image"].get_or<std::string>(""));
block.setFogDepth(table["fog_depth"].get_or<float>(0));
block.setTickRandomly(table["tick_randomly"].get_or(false));
block.setTickProbability(table["tick_probability"].get_or(0.f));

if (block.fogDepth()) {
sol::optional<sol::table> fogColor = table["fog_color"];
Expand Down
29 changes: 18 additions & 11 deletions source/server/world/ServerBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@
#include "ServerBlock.hpp"
#include "ServerCommandHandler.hpp"
#include "ServerPlayer.hpp"
#include "ServerWorld.hpp"
#include "World.hpp"

void ServerBlock::onTick(const glm::ivec3 &pos, Chunk &chunk, World &world, ServerCommandHandler &server) const {
try {
if (m_onTick && m_onTickEnabled) {
void ServerBlock::onTick(const glm::ivec3 &pos, ServerChunk &chunk, ServerWorld &world, ServerCommandHandler &server) const {
if (m_onTickEnabled && m_onTick) {
try {
m_onTick(pos, chunk, world);

BlockData *blockData = world.getBlockData(pos.x, pos.y, pos.z);
Expand All @@ -47,18 +48,24 @@ void ServerBlock::onTick(const glm::ivec3 &pos, Chunk &chunk, World &world, Serv
}
}
}
}
catch (const sol::error &e) {
m_onTickEnabled = false;
gkError() << e.what();
gkError() << "Block stopped ticking at (" << pos.x << ", " << pos.y << ", " << pos.z << ")";
catch (const sol::error &e) {
m_onTickEnabled = false;
gkError() << e.what();
gkError() << "Block stopped ticking at (" << pos.x << ", " << pos.y << ", " << pos.z << ")";
}
}
}

bool ServerBlock::onBlockActivated(const glm::ivec3 &pos, Player &player, World &world, ClientInfo &client, ServerCommandHandler &server, u16 screenWidth, u16 screenHeight, u8 guiScale) const {
bool ServerBlock::onBlockActivated(const glm::ivec3 &pos, ServerPlayer &player, ServerWorld &world, ClientInfo &client, ServerCommandHandler &server, u16 screenWidth, u16 screenHeight, u8 guiScale) const {
try {
if (m_onBlockActivated) {
m_onBlockActivated(pos, player, world, client, server, screenWidth, screenHeight, guiScale);

// FIXME: Check if data changed before sending
BlockData *blockData = world.getBlockData(pos.x, pos.y, pos.z);
if (blockData)
server.sendBlockDataUpdate(pos.x, pos.y, pos.z, blockData);

return true;
}
}
Expand All @@ -69,7 +76,7 @@ bool ServerBlock::onBlockActivated(const glm::ivec3 &pos, Player &player, World
return false;
}

void ServerBlock::onBlockPlaced(const glm::ivec3 &pos, World &world) const {
void ServerBlock::onBlockPlaced(const glm::ivec3 &pos, ServerWorld &world) const {
try {
if (m_onBlockPlaced) {
m_onBlockPlaced(pos, world);
Expand All @@ -80,7 +87,7 @@ void ServerBlock::onBlockPlaced(const glm::ivec3 &pos, World &world) const {
}
}

void ServerBlock::onBlockDestroyed(const glm::ivec3 &pos, World &world) const {
void ServerBlock::onBlockDestroyed(const glm::ivec3 &pos, ServerWorld &world) const {
try {
if (m_onBlockDestroyed) {
m_onBlockDestroyed(pos, world);
Expand Down
19 changes: 15 additions & 4 deletions source/server/world/ServerBlock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,20 @@
#include "Block.hpp"

class ClientInfo;
class ServerChunk;
class ServerCommandHandler;
class ServerPlayer;
class ServerWorld;

class ServerBlock : public Block {
public:
ServerBlock(u32 id, const TilesDef &tiles, const std::string &name, const std::string &label)
: Block(id, tiles, name, label) {}

void onTick(const glm::ivec3 &, Chunk &, World &, ServerCommandHandler &) const;
bool onBlockActivated(const glm::ivec3 &pos, Player &player, World &world, ClientInfo &client, ServerCommandHandler &server, u16 screenWidth, u16 screenHeight, u8 guiScale) const;
void onBlockPlaced(const glm::ivec3 &pos, World &world) const;
void onBlockDestroyed(const glm::ivec3 &pos, World &world) const;
void onTick(const glm::ivec3 &pos, ServerChunk &chunk, ServerWorld &world, ServerCommandHandler &server) const;
bool onBlockActivated(const glm::ivec3 &pos, ServerPlayer &player, ServerWorld &world, ClientInfo &client, ServerCommandHandler &server, u16 screenWidth, u16 screenHeight, u8 guiScale) const;
void onBlockPlaced(const glm::ivec3 &pos, ServerWorld &world) const;
void onBlockDestroyed(const glm::ivec3 &pos, ServerWorld &world) const;

bool canUpdate() const { return m_onTick.valid(); }

Expand All @@ -50,6 +52,12 @@ class ServerBlock : public Block {
void setOnBlockPlaced(const sol::protected_function &function) { m_onBlockPlaced = function; }
void setOnBlockDestroyed(const sol::protected_function &function) { m_onBlockDestroyed = function; }

bool isTickingRandomly() const { return m_isTickingRandomly; }
void setTickRandomly(bool isTickingRandomly) { m_isTickingRandomly = isTickingRandomly; }

float tickProbability() const { return m_tickProbability; }
void setTickProbability(float tickProbability) { m_tickProbability = tickProbability; }

static void initUsertype(sol::state &lua);

private:
Expand All @@ -59,6 +67,9 @@ class ServerBlock : public Block {
sol::unsafe_function m_onBlockDestroyed;

mutable bool m_onTickEnabled = true;

bool m_isTickingRandomly = false;
float m_tickProbability = 0.f;
};

#endif // SERVERBLOCK_HPP_
33 changes: 24 additions & 9 deletions source/server/world/ServerChunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include "ServerCommandHandler.hpp"
#include "World.hpp"

ServerChunk::ServerChunk(s32 x, s32 y, s32 z, World &world) : Chunk(x, y, z, world) {
m_random.seed(std::time(nullptr));
}

void ServerChunk::updateLights() {
if (m_lightmap.updateLights() || m_hasChanged) {
m_isSent = false;
Expand All @@ -39,28 +43,39 @@ void ServerChunk::updateLights() {

void ServerChunk::onBlockPlaced(int x, int y, int z, const Block &block) {
const ServerBlock &serverBlock = (ServerBlock &)block;
serverBlock.onBlockPlaced(glm::ivec3{x + m_x * CHUNK_WIDTH, y + m_y * CHUNK_DEPTH, z + m_z * CHUNK_HEIGHT}, m_world);
if (block.canUpdate()) {
addTickingBlock(x, y, z, serverBlock);
}
else {
auto it = m_tickingBlocks.find(gk::Vector3i{x, y, z});
if (it != m_tickingBlocks.end())
m_tickingBlocks.erase(it);
}

serverBlock.onBlockPlaced(glm::ivec3{x + m_x * CHUNK_WIDTH, y + m_y * CHUNK_DEPTH, z + m_z * CHUNK_HEIGHT}, (ServerWorld &)m_world);

m_hasBeenModified = true;
}

void ServerChunk::onBlockDestroyed(int x, int y, int z, const Block &block) {
const ServerBlock &serverBlock = (ServerBlock &)block;
serverBlock.onBlockDestroyed(glm::ivec3{x + m_x * CHUNK_WIDTH, y + m_y * CHUNK_DEPTH, z + m_z * CHUNK_HEIGHT}, m_world);
serverBlock.onBlockDestroyed(glm::ivec3{x + m_x * CHUNK_WIDTH, y + m_y * CHUNK_DEPTH, z + m_z * CHUNK_HEIGHT}, (ServerWorld &)m_world);

m_hasBeenModified = true;
}

void ServerChunk::tick(World &world, ServerCommandHandler &server) {
if (!m_tickingBlocks.empty()) {
for (auto &it : m_tickingBlocks) {
((ServerBlock &)it.second).onTick(
glm::ivec3{
it.first.x + m_x * width,
it.first.y + m_y * depth,
it.first.z + m_z * height
},
*this, world, server);
if (!it.second.isTickingRandomly() || m_random.get<bool>(it.second.tickProbability())) {
it.second.onTick(
glm::ivec3{
it.first.x + m_x * width,
it.first.y + m_y * depth,
it.first.z + m_z * height
},
*this, (ServerWorld &)world, server);
}
}
}
}
Expand Down
Loading

0 comments on commit 14e23dc

Please sign in to comment.