From 23a8c3a413fabb5ee0ee56aea2ca63ef24b61fe3 Mon Sep 17 00:00:00 2001 From: javaprophet Date: Sun, 10 Sep 2017 10:49:42 -0700 Subject: [PATCH] fix some door/bed updates --- basin/Debug/blocks.json | 192 ---------------------------------------- basin/src/block.c | 70 ++++++++++++--- basin/src/item.c | 96 +++++++++++++++----- basin/src/item.h | 6 +- basin/src/player.c | 3 +- 5 files changed, 140 insertions(+), 227 deletions(-) diff --git a/basin/Debug/blocks.json b/basin/Debug/blocks.json index d406294..02c0332 100644 --- a/basin/Debug/blocks.json +++ b/basin/Debug/blocks.json @@ -1887,198 +1887,6 @@ "lightOpacity": 0, "lightEmission": 0 }, - "bed_6": { - "id": 424, - "collision": { - "0": { - "minX": 0.0, - "maxX": 1.0, - "minY": 0.0, - "maxY": 0.5625, - "minZ": 0.0, - "maxZ": 1.0 - } - }, - "dropItem": 0, - "dropDamage": 0, - "dropAmountMin": 1, - "dropAmountMax": 1, - "hardness": 0.2, - "material": "cloth", - "slipperiness": 0.6, - "isFullCube": false, - "canProvidePower": false, - "lightOpacity": 0, - "lightEmission": 0 - }, - "bed_7": { - "id": 425, - "collision": { - "0": { - "minX": 0.0, - "maxX": 1.0, - "minY": 0.0, - "maxY": 0.5625, - "minZ": 0.0, - "maxZ": 1.0 - } - }, - "dropItem": 0, - "dropDamage": 0, - "dropAmountMin": 1, - "dropAmountMax": 1, - "hardness": 0.2, - "material": "cloth", - "slipperiness": 0.6, - "isFullCube": false, - "canProvidePower": false, - "lightOpacity": 0, - "lightEmission": 0 - }, - "bed_8": { - "id": 426, - "collision": { - "0": { - "minX": 0.0, - "maxX": 1.0, - "minY": 0.0, - "maxY": 0.5625, - "minZ": 0.0, - "maxZ": 1.0 - } - }, - "dropItem": 0, - "dropDamage": 0, - "dropAmountMin": 1, - "dropAmountMax": 1, - "hardness": 0.2, - "material": "cloth", - "slipperiness": 0.6, - "isFullCube": false, - "canProvidePower": false, - "lightOpacity": 0, - "lightEmission": 0 - }, - "bed_9": { - "id": 427, - "collision": { - "0": { - "minX": 0.0, - "maxX": 1.0, - "minY": 0.0, - "maxY": 0.5625, - "minZ": 0.0, - "maxZ": 1.0 - } - }, - "dropItem": 0, - "dropDamage": 0, - "dropAmountMin": 1, - "dropAmountMax": 1, - "hardness": 0.2, - "material": "cloth", - "slipperiness": 0.6, - "isFullCube": false, - "canProvidePower": false, - "lightOpacity": 0, - "lightEmission": 0 - }, - "bed_10": { - "id": 428, - "collision": { - "0": { - "minX": 0.0, - "maxX": 1.0, - "minY": 0.0, - "maxY": 0.5625, - "minZ": 0.0, - "maxZ": 1.0 - } - }, - "dropItem": 0, - "dropDamage": 0, - "dropAmountMin": 1, - "dropAmountMax": 1, - "hardness": 0.2, - "material": "cloth", - "slipperiness": 0.6, - "isFullCube": false, - "canProvidePower": false, - "lightOpacity": 0, - "lightEmission": 0 - }, - "bed_11": { - "id": 429, - "collision": { - "0": { - "minX": 0.0, - "maxX": 1.0, - "minY": 0.0, - "maxY": 0.5625, - "minZ": 0.0, - "maxZ": 1.0 - } - }, - "dropItem": 0, - "dropDamage": 0, - "dropAmountMin": 1, - "dropAmountMax": 1, - "hardness": 0.2, - "material": "cloth", - "slipperiness": 0.6, - "isFullCube": false, - "canProvidePower": false, - "lightOpacity": 0, - "lightEmission": 0 - }, - "bed_12": { - "id": 430, - "collision": { - "0": { - "minX": 0.0, - "maxX": 1.0, - "minY": 0.0, - "maxY": 0.5625, - "minZ": 0.0, - "maxZ": 1.0 - } - }, - "dropItem": 0, - "dropDamage": 0, - "dropAmountMin": 1, - "dropAmountMax": 1, - "hardness": 0.2, - "material": "cloth", - "slipperiness": 0.6, - "isFullCube": false, - "canProvidePower": false, - "lightOpacity": 0, - "lightEmission": 0 - }, - "bed_13": { - "id": 431, - "collision": { - "0": { - "minX": 0.0, - "maxX": 1.0, - "minY": 0.0, - "maxY": 0.5625, - "minZ": 0.0, - "maxZ": 1.0 - } - }, - "dropItem": 0, - "dropDamage": 0, - "dropAmountMin": 1, - "dropAmountMax": 1, - "hardness": 0.2, - "material": "cloth", - "slipperiness": 0.6, - "isFullCube": false, - "canProvidePower": false, - "lightOpacity": 0, - "lightEmission": 0 - }, "goldenrail": { "id": 432, "collision": { diff --git a/basin/src/block.c b/basin/src/block.c index 5c5b3da..1d21197 100644 --- a/basin/src/block.c +++ b/basin/src/block.c @@ -27,10 +27,56 @@ struct collection* block_infos; struct collection* block_materials; +int canBePlaced_bed(struct world* world, block blk, int32_t x, int32_t y, int32_t z) { + block b = getBlockWorld(world, x, y - 1, z); + struct block_info* bi = getBlockInfo(b); + return isNormalCube(bi); +} + +void onBlockUpdate_bed(struct world* world, block blk, int32_t x, int32_t y, int32_t z) { + block b = getBlockWorld(world, x, y - 1, z); + struct block_info* bi = getBlockInfo(b); + if (!isNormalCube(bi)) goto delete; + int facing = blk & 0b0011; + int head = blk & 0b1000; + uint8_t rf = 0; + if (facing == 0) rf = SOUTH; + else if (facing == 1) rf = WEST; + else if (facing == 2) rf = NORTH; + else if (facing == 3) rf = EAST; + if (head) { + if (rf == SOUTH) rf = NORTH; + else if (rf == NORTH) rf = SOUTH; + else if (rf == EAST) rf = WEST; + else if (rf == WEST) rf = EAST; + } + int32_t ox = x; + int32_t oy = y; + int32_t oz = z; + offsetCoordByFace(&ox, &oy, &oz, rf); + b = getBlockWorld(world, ox, oy, oz); + if (b >> 4 == blk >> 4) return; + delete:; + setBlockWorld(world, 0, x, y, z); + if (head) dropBlockDrops(world, blk, NULL, x, y, z); +} + int canBePlaced_door(struct world* world, block blk, int32_t x, int32_t y, int32_t z) { block b = getBlockWorld(world, x, y - 1, z); struct block_info* bi = getBlockInfo(b); - return b >> 4 == blk >> 4 || isNormalCube(bi); + return (b >> 4 == blk >> 4 && !(b & 0b1000) && (blk & 0b1000)) || isNormalCube(bi); +} + +void onBlockUpdate_door(struct world* world, block blk, int32_t x, int32_t y, int32_t z) { + block b = getBlockWorld(world, x, y - 1, z); + struct block_info* bi = getBlockInfo(b); + int upper = blk & 0b1000; + if (!upper && !isNormalCube(bi)) goto delete; + b = getBlockWorld(world, x, y + (upper ? -1 : 1), z); + if (b >> 4 == blk >> 4) return; + delete:; + setBlockWorld(world, 0, x, y, z); + if (!upper) dropBlockDrops(world, blk, NULL, x, y, z); } void onBlockInteract_woodendoor(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) { @@ -95,7 +141,7 @@ void onBlockInteract_chest(struct world* world, block blk, int32_t x, int32_t y, onBlockPlaced_chest(world, blk, x, y, z, 0); te = getTileEntityWorld(world, x, y, z); } - //TODO: impl locks, loot +//TODO: impl locks, loot player_openInventory(player, te->data.chest.inv); BEGIN_BROADCAST_DIST(player->entity, 128.) struct packet* pkt = xmalloc(sizeof(struct packet)); @@ -128,7 +174,7 @@ void onBlockInteract_furnace(struct world* world, block blk, int32_t x, int32_t onBlockPlaced_furnace(world, blk, x, y, z, 0); te = getTileEntityWorld(world, x, y, z); } - //TODO: impl locks, loot +//TODO: impl locks, loot player_openInventory(player, te->data.furnace.inv); struct packet* pkt = xmalloc(sizeof(struct packet)); pkt->id = PKT_PLAY_CLIENT_WINDOWPROPERTY; @@ -1584,41 +1630,45 @@ void init_blocks() { tmp = getBlockInfo(b); tmp->onBlockInteract = &onBlockInteract_woodendoor; tmp->canBePlaced = &canBePlaced_door; - tmp->onBlockUpdate = &onBlockUpdate_checkPlace; + tmp->onBlockUpdate = &onBlockUpdate_door; } for (block b = BLK_DOORSPRUCE; b < BLK_DOORSPRUCE + 16; b++) { tmp = getBlockInfo(b); tmp->onBlockInteract = &onBlockInteract_woodendoor; tmp->canBePlaced = &canBePlaced_door; - tmp->onBlockUpdate = &onBlockUpdate_checkPlace; + tmp->onBlockUpdate = &onBlockUpdate_door; } for (block b = BLK_DOORBIRCH; b < BLK_DOORBIRCH + 16; b++) { tmp = getBlockInfo(b); tmp->onBlockInteract = &onBlockInteract_woodendoor; tmp->canBePlaced = &canBePlaced_door; - tmp->onBlockUpdate = &onBlockUpdate_checkPlace; + tmp->onBlockUpdate = &onBlockUpdate_door; } for (block b = BLK_DOORJUNGLE; b < BLK_DOORJUNGLE + 16; b++) { tmp = getBlockInfo(b); tmp->onBlockInteract = &onBlockInteract_woodendoor; tmp->canBePlaced = &canBePlaced_door; - tmp->onBlockUpdate = &onBlockUpdate_checkPlace; + tmp->onBlockUpdate = &onBlockUpdate_door; } for (block b = BLK_DOORACACIA; b < BLK_DOORACACIA + 16; b++) { tmp = getBlockInfo(b); tmp->onBlockInteract = &onBlockInteract_woodendoor; tmp->canBePlaced = &canBePlaced_door; - tmp->onBlockUpdate = &onBlockUpdate_checkPlace; + tmp->onBlockUpdate = &onBlockUpdate_door; } for (block b = BLK_DOORDARKOAK; b < BLK_DOORDARKOAK + 16; b++) { tmp = getBlockInfo(b); tmp->onBlockInteract = &onBlockInteract_woodendoor; tmp->canBePlaced = &canBePlaced_door; - tmp->onBlockUpdate = &onBlockUpdate_checkPlace; + tmp->onBlockUpdate = &onBlockUpdate_door; } for (block b = BLK_DOORIRON; b < BLK_DOORIRON + 16; b++) { tmp = getBlockInfo(b); tmp->canBePlaced = &canBePlaced_door; - tmp->onBlockUpdate = &onBlockUpdate_checkPlace; + tmp->onBlockUpdate = &onBlockUpdate_door; } + tmp = getBlockInfo(BLK_BED); + tmp->canBePlaced = &canBePlaced_bed; + tmp->onBlockUpdate = &onBlockUpdate_bed; + } diff --git a/basin/src/item.c b/basin/src/item.c index 1628db6..3b7bde3 100644 --- a/basin/src/item.c +++ b/basin/src/item.c @@ -19,7 +19,52 @@ #include "game.h" #include "player.h" -int onItemInteract_painting(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) { +int onItemInteract_bed(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { + if (face != YP) return 0; + if (!getBlockInfo(getBlockWorld(world, x, y, z))->material->replacable) offsetCoordByFace(&x, &y, &z, face); + uint32_t h = (uint32_t) floor(player->entity->yaw / 90. + .5) & 3; + uint8_t rf = 0; + if (h == 0) rf = SOUTH; + else if (h == 1) rf = WEST; + else if (h == 2) rf = NORTH; + else if (h == 3) rf = EAST; + int32_t x2 = x; + int32_t y2 = y; + int32_t z2 = z; + offsetCoordByFace(&x2, &y2, &z2, rf); + block pre = getBlockWorld(world, x, y, z); + block pre2 = getBlockWorld(world, x2, y2, z2); + block b = BLK_BED | h; + block b2 = b; + b2 |= 0b1000; + if (canPlayerPlaceBlock(player, b, x, y, z, face) && !setBlockWorld_noupdate(player->world, b, x, y, z)) { + if (!canPlayerPlaceBlock(player, b2, x2, y2, z2, face) || setBlockWorld(player->world, b2, x2, y2, z2)) { + setBlockWorld(player->world, pre, x, y, z); + setBlockWorld(player->world, pre2, x2, y2, z2); + setSlot(player, player->inventory, 36 + player->currentItem, slot, 1, 1); + return 0; + } else if (player->gamemode != 1) { + if (--slot->itemCount <= 0) { + slot = NULL; + } + setSlot(player, player->inventory, 36 + player->currentItem, slot, 1, 1); + } + updateBlockWorld_guess(world, NULL, x, y, z); + updateBlockWorld_guess(world, NULL, x + 1, y, z); + updateBlockWorld_guess(world, NULL, x - 1, y, z); + updateBlockWorld_guess(world, NULL, x, y + 1, z); + updateBlockWorld_guess(world, NULL, x, y - 1, z); + updateBlockWorld_guess(world, NULL, x, y, z + 1); + updateBlockWorld_guess(world, NULL, x, y, z - 1); + } else { + setBlockWorld(player->world, pre, x, y, z); + setBlockWorld(player->world, pre2, x2, y2, z2); + setSlot(player, player->inventory, 36 + player->currentItem, slot, 1, 1); + } + return 0; +} + +int onItemInteract_painting(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { int32_t ox = x; int32_t oy = y; int32_t oz = z; @@ -135,7 +180,7 @@ int onItemInteract_painting(struct world* world, struct player* player, uint8_t } -int onItemInteract_minecart(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) { +int onItemInteract_minecart(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { block b = getBlockWorld(world, x, y, z); if (b >> 4 != BLK_RAIL >> 4 && b >> 4 != BLK_ACTIVATORRAIL >> 4 && b >> 4 != BLK_GOLDENRAIL >> 4 && b >> 4 != BLK_DETECTORRAIL >> 4) return 0; double dy = 0.; @@ -153,9 +198,9 @@ int onItemInteract_minecart(struct world* world, struct player* player, uint8_t } -int onItemInteract_door(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) { +int onItemInteract_door(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { if (face != YP) return 0; - offsetCoordByFace(&x, &y, &z, face); + if (!getBlockInfo(getBlockWorld(world, x, y, z))->material->replacable) offsetCoordByFace(&x, &y, &z, face); block pre = getBlockWorld(world, x, y, z); block pre2 = getBlockWorld(world, x, y + 1, z); block b = BLK_DOOROAK; @@ -171,17 +216,25 @@ int onItemInteract_door(struct world* world, struct player* player, uint8_t slot else if (h == 1) b |= 2; else if (h == 2) b |= 3; b2 |= 0b1000; - if (canPlayerPlaceBlock(player, b, x, y, z, face) && !setBlockWorld(player->world, b, x, y, z)) { + if (canPlayerPlaceBlock(player, b, x, y, z, face) && !setBlockWorld_noupdate(player->world, b, x, y, z)) { if (!canPlayerPlaceBlock(player, b2, x, y + 1, z, face) || setBlockWorld(player->world, b2, x, y + 1, z)) { setBlockWorld(player->world, pre, x, y, z); setBlockWorld(player->world, pre2, x, y + 1, z); setSlot(player, player->inventory, 36 + player->currentItem, slot, 1, 1); + return 0; } else if (player->gamemode != 1) { if (--slot->itemCount <= 0) { slot = NULL; } setSlot(player, player->inventory, 36 + player->currentItem, slot, 1, 1); } + updateBlockWorld_guess(world, NULL, x, y, z); + updateBlockWorld_guess(world, NULL, x + 1, y, z); + updateBlockWorld_guess(world, NULL, x - 1, y, z); + updateBlockWorld_guess(world, NULL, x, y + 1, z); + updateBlockWorld_guess(world, NULL, x, y - 1, z); + updateBlockWorld_guess(world, NULL, x, y, z + 1); + updateBlockWorld_guess(world, NULL, x, y, z - 1); } else { setBlockWorld(player->world, pre, x, y, z); setBlockWorld(player->world, pre2, x, y + 1, z); @@ -190,8 +243,8 @@ int onItemInteract_door(struct world* world, struct player* player, uint8_t slot return 0; } -int onItemInteract_itemblock(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) { - offsetCoordByFace(&x, &y, &z, face); +int onItemInteract_itemblock(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { + if (!getBlockInfo(getBlockWorld(world, x, y, z))->material->replacable) offsetCoordByFace(&x, &y, &z, face); block pre = getBlockWorld(world, x, y, z); block b = pre; if (slot->item == ITM_STRING) { @@ -228,7 +281,7 @@ int onItemInteract_itemblock(struct world* world, struct player* player, uint8_t return 0; } -int onItemBreakBlock_tool(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, uint8_t y, int32_t z) { +int onItemBreakBlock_tool(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z) { if (slot == NULL) return 0; struct item_info* ii = getItemInfo(slot->item); if (ii == NULL) return 0; @@ -250,7 +303,7 @@ float onItemAttacked_tool(struct world* world, struct player* player, uint8_t sl return ii->damage; } -void offsetCoordByFace(int32_t* x, uint8_t* y, int32_t* z, uint8_t face) { +void offsetCoordByFace(int32_t* x, int32_t* y, int32_t* z, uint8_t face) { if (face == YN) (*y)--; else if (face == YP) (*y)++; else if (face == ZN) (*z)--; @@ -259,7 +312,7 @@ void offsetCoordByFace(int32_t* x, uint8_t* y, int32_t* z, uint8_t face) { else if (face == XP) (*x)++; } -int onItemInteract_flintandsteel(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) { +int onItemInteract_flintandsteel(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { if (slot == NULL) return 0; offsetCoordByFace(&x, &y, &z, face); if (getBlockWorld(world, x, y, z) != 0) return 0; @@ -274,10 +327,10 @@ int onItemInteract_flintandsteel(struct world* world, struct player* player, uin return 0; } -int onItemInteract_spawnegg(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) { +int onItemInteract_spawnegg(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { if (slot == NULL || slot->nbt == NULL) return 0; //TODO: mob spawners - offsetCoordByFace(&x, &y, &z, face); + if (getBlockInfo(getBlockWorld(world, x, y, z))->boundingBox_count > 0) offsetCoordByFace(&x, &y, &z, face); //if (getBlockWorld(world, x, y, z) != 0) return 0; struct item_info* ii = getItemInfo(slot->item); if (ii == NULL) return 0; @@ -295,9 +348,9 @@ int onItemInteract_spawnegg(struct world* world, struct player* player, uint8_t return 0; } -int onItemInteract_reeds(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) { +int onItemInteract_reeds(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { if (slot == NULL) return 0; - offsetCoordByFace(&x, &y, &z, face); + if (!getBlockInfo(getBlockWorld(world, x, y, z))->material->replacable) offsetCoordByFace(&x, &y, &z, face); if (!canPlayerPlaceBlock(player, BLK_REEDS, x, y, z, face)) return 0; if (getBlockWorld(world, x, y, z) != 0) return 0; if (!canBePlaced_reeds(world, BLK_REEDS, x, y, z)) return 0; @@ -311,9 +364,9 @@ 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) { +int onItemInteract_bucket(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { if (slot == NULL) return 0; - offsetCoordByFace(&x, &y, &z, face); + if (!getBlockInfo(getBlockWorld(world, x, y, z))->material->replacable) offsetCoordByFace(&x, &y, &z, face); block b = getBlockWorld(world, x, y, z); struct block_info* bi = getBlockInfo(b); if (bi == NULL) return 0; @@ -353,7 +406,7 @@ int onItemInteract_bucket(struct world* world, struct player* player, uint8_t sl 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) { +int onItemInteract_bonemeal(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { if (slot == NULL) return 0; if (!canPlayerPlaceBlock(player, ITM_DYEPOWDER_BLACK, x, y, z, face)) return 0; block b = getBlockWorld(world, x, y, z); @@ -409,9 +462,9 @@ int onItemInteract_bonemeal(struct world* world, struct player* player, uint8_t return 0; } -int onItemInteract_seeds(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) { +int onItemInteract_seeds(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { if (slot == NULL) return 0; - offsetCoordByFace(&x, &y, &z, face); + if (!getBlockInfo(getBlockWorld(world, x, y, z))->material->replacable) offsetCoordByFace(&x, &y, &z, face); if (!canPlayerPlaceBlock(player, ITM_DYEPOWDER_BLACK, x, y, z, face)) return 0; block b = getBlockWorld(world, x, y, z); if (slot->item == ITM_DYEPOWDER_BLACK) { @@ -438,7 +491,7 @@ int onItemInteract_seeds(struct world* world, struct player* player, uint8_t slo return 0; } -int onItemInteract_hoe(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) { +int onItemInteract_hoe(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { if (slot == NULL) return 0; struct item_info* ii = getItemInfo(slot->item); if (ii == NULL) return 0; @@ -454,7 +507,7 @@ int onItemInteract_hoe(struct world* world, struct player* player, uint8_t slot_ return 0; } -int onItemInteract_shovel(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) { +int onItemInteract_shovel(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face) { if (slot == NULL) return 0; struct item_info* ii = getItemInfo(slot->item); if (ii == NULL) return 0; @@ -761,6 +814,7 @@ void init_items() { getItemInfo(ITM_MINECARTHOPPER)->onItemInteract = &onItemInteract_minecart; getItemInfo(ITM_MINECARTCOMMANDBLOCK)->onItemInteract = &onItemInteract_minecart; getItemInfo(ITM_PAINTING)->onItemInteract = &onItemInteract_painting; + getItemInfo(ITM_BED)->onItemInteract = &onItemInteract_bed; init_food(ITM_APPLE, 4, 0.3, 0); init_food(ITM_MUSHROOMSTEW, 6, 0.6, 0); init_food(ITM_BREAD, 5, 0.6, 0); diff --git a/basin/src/item.h b/basin/src/item.h index 3717ef2..671148f 100644 --- a/basin/src/item.h +++ b/basin/src/item.h @@ -18,7 +18,7 @@ typedef int16_t item; #include "inventory.h" #include "tools.h" -void offsetCoordByFace(int32_t* x, uint8_t* y, int32_t* z, uint8_t face); +void offsetCoordByFace(int32_t* x, int32_t* y, int32_t* z, uint8_t face); #define YN 0 #define YP 1 @@ -264,8 +264,8 @@ struct item_info { int (*canUseItem)(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot); void (*onItemUseTick)(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t ticksElapsed); // not in-world usage, nor called on last tick. ticksElapsed==0 on start., -1 on cancel void (*onItemUse)(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, uint32_t ticks); // not in-world usage, when called with long use items, full duration not guaranteed - int (*onItemInteract)(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); // in-world usage, called after onItemUse - int (*onItemBreakBlock)(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, uint8_t y, int32_t z); // in-world usage + int (*onItemInteract)(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z, uint8_t face); // in-world usage, called after onItemUse + int (*onItemBreakBlock)(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, int32_t x, int32_t y, int32_t z); // in-world usage float (*onItemAttacked)(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, struct entity* entity); // entity may be NULL float (*onEntityHitWhileWearing)(struct world* world, struct player* player, uint8_t slot_index, struct slot* slot, float damage); // only called for armor/shields void* callback_arg; diff --git a/basin/src/player.c b/basin/src/player.c index 60ed73e..e95a6af 100644 --- a/basin/src/player.c +++ b/basin/src/player.c @@ -1605,5 +1605,6 @@ int canPlayerPlaceBlock(struct player* player, block blk, int32_t x, int32_t y, if (bi != NULL && bi->canBePlaced != NULL && !(*bi->canBePlaced)(player->world, tbb, x, y, z)) { return 0; } - return 1; + block b = getBlockWorld(player->world, x, y, z); + return b == 0 || getBlockInfo(b)->material->replacable; }