gameplay: add block placing

This commit is contained in:
Lephenixnoir 2022-07-17 16:36:34 +01:00
parent eb8bf66f45
commit cc91261186
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
8 changed files with 44 additions and 6 deletions

View File

@ -2,6 +2,7 @@
cluster: " "
walkable: yes
breakability: Fluid
replaceable: yes
- name: "STONE"
cluster: "□□□□"

View File

@ -80,7 +80,7 @@ def convert_blockinfo(input, params):
for b in data:
# Make sure there are no typos in the fields
assert (f in ["name", "breakability", "toolKind",
"baseBreakDurationTicks", "walkable"] for f in b)
"baseBreakDurationTicks", "walkable", "replaceable"] for f in b)
# If a tool is specified, default to Breakability::ByTool
tk = b.get("toolKind", None)
@ -92,7 +92,8 @@ def convert_blockinfo(input, params):
o += mkToolKind(tk)
o += fxconv.u16(int(b.get("breakingTime", 20)))
o += mkBool(b.get("walkable", False))
o += bytes(3)
o += mkBool(b.get("replaceable", False))
o += bytes(2)
o += fxconv.sym("Nooncraft_blockInfoCount")
o += fxconv.u32(len(data))

View File

@ -49,6 +49,7 @@ struct BlockInfo
ToolKind toolKind;
int16_t baseBreakDurationTicks;
bool walkable;
bool replaceable;
};
namespace Nooncraft {

View File

@ -10,6 +10,22 @@ Item Game::handItem() const
return this->inventory[27 + this->hotbarCursor].item;
}
void Game::place()
{
ItemStack &stack = this->inventory[27 + this->hotbarCursor];
if(!stack.item.isBlock)
return;
if(!this->world->canPlaceAt(this->cursorPos))
return;
this->world->cellAt(this->cursorPos.x, this->cursorPos.y) =
stack.item.block;
if(--stack.qty == 0)
stack = ItemStack();
}
bool Game::movePlayerBy(WorldCoord dir, bool camera_follow)
{
WorldCoord candidatePos = this->playerPos + dir;
@ -157,6 +173,10 @@ bool Game::collectBrokenBlock(WorldCoord pos)
else if(block == BlockID(DIAMOND_ORE)) {
item.itemID = ItemID::DIAMOND;
}
else if(block == BlockID(STONE)) {
item.isBlock = true;
item.block = BlockID(COBBLESTONE);
}
else {
item.isBlock = true;
item.block = block;

View File

@ -19,6 +19,9 @@ struct Game
/* Info on the selected item */
Item handItem() const;
/* Place the hand block at the cursor position, if possible */
void place();
/* Current ticks spent damaging the pointed block, ≥ 0 when breaking */
int damageTicks;

View File

@ -180,10 +180,6 @@ int main(void)
if(ev.key == KEY_MENU)
runMainLoop = false;
if(ev.key == KEY_OPTN) {
if(game.world->canBreakBlock(game.cursorPos))
game.damageTicks = 0;
}
int digit = keycode_digit(ev.key);
if(digit >= 1 && digit <= 9 && !game.isBreakingBlock()) {
game.hotbarCursor = digit - 1;
@ -211,6 +207,14 @@ int main(void)
game.moveCursorBy(WorldCoord::Down);
}
if(keydown(KEY_OPTN) && !game.isBreakingBlock()) {
if(game.world->canBreakBlock(game.cursorPos))
game.damageTicks = 0;
}
if(keydown(KEY_VARS) && !game.isBreakingBlock()) {
game.place();
}
game.updateBlockBreaking();
}

View File

@ -227,6 +227,12 @@ bool World::canBreakBlock(WorldCoord p) const
&& info->breakability != Breakability::Unbreakable;
}
bool World::canPlaceAt(WorldCoord p) const
{
BlockInfo *info = this->blockInfoAt(p);
return info && info->replaceable;
}
namespace Nooncraft {
World *mkWorld(int width, int height)

View File

@ -125,6 +125,8 @@ struct World
BlockInfo *blockInfoAt(WorldCoord p) const;
bool canBreakBlock(WorldCoord p) const;
bool canPlaceAt(WorldCoord p) const;
};
namespace Nooncraft {