mirror of https://github.com/basinserver/basin/
fix door bugs
This commit is contained in:
parent
50d2ba4607
commit
93b6a94125
|
@ -28,6 +28,16 @@
|
|||
struct collection* block_infos;
|
||||
struct collection* block_materials;
|
||||
|
||||
uint8_t getFaceFromPlayer(struct player* player) {
|
||||
uint32_t h = (uint32_t) floor(player->entity->yaw / 90. + .5) & 3;
|
||||
uint8_t f = 0;
|
||||
if (h == 0) f = SOUTH;
|
||||
else if (h == 1) f = WEST;
|
||||
else if (h == 2) f = NORTH;
|
||||
else if (h == 3) f = EAST;
|
||||
return f;
|
||||
}
|
||||
|
||||
void onBlockUpdate_checkPlace(struct world* world, block blk, int32_t x, int32_t y, int32_t z) {
|
||||
struct block_info* bi = getBlockInfo(blk);
|
||||
if (bi != NULL && bi->canBePlaced != NULL && !(*bi->canBePlaced)(world, blk, x, y, z)) {
|
||||
|
@ -110,12 +120,7 @@ int canBePlaced_torch(struct world* world, block blk, int32_t x, int32_t y, int3
|
|||
}
|
||||
|
||||
block onBlockPlacedPlayer_lever(struct player* player, struct world* world, block blk, int32_t x, int32_t y, int32_t z, uint8_t face) {
|
||||
uint32_t h = (uint32_t) floor(player->entity->yaw / 90. + .5) & 3;
|
||||
uint8_t f = 0;
|
||||
if (h == 0) f = SOUTH;
|
||||
else if (h == 1) f = WEST;
|
||||
else if (h == 2) f = NORTH;
|
||||
else if (h == 3) f = EAST;
|
||||
uint8_t f = getFaceFromPlayer(player);
|
||||
if (face == NORTH) return blk | 0x04;
|
||||
else if (face == SOUTH) return blk | 0x03;
|
||||
else if (face == EAST) return blk | 0x01;
|
||||
|
|
|
@ -510,6 +510,8 @@ struct block_info* getBlockInfo(block b);
|
|||
|
||||
struct block_info* getBlockInfoLoose(block b);
|
||||
|
||||
uint8_t getFaceFromPlayer(struct player* player);
|
||||
|
||||
item getItemFromName(const char* name);
|
||||
|
||||
struct block_info {
|
||||
|
|
|
@ -858,13 +858,36 @@ int getSwingTime(struct entity* ent) {
|
|||
return 6;
|
||||
}
|
||||
|
||||
block entity_adjustCollision(struct world* world, struct chunk* ch, block b, int32_t x, int32_t y, int32_t z) {
|
||||
block entity_adjustCollision(struct world* world, struct entity* ent, struct chunk* ch, block b, int32_t x, int32_t y, int32_t z) {
|
||||
if (b >> 4 == BLK_DOORIRON >> 4 || b >> 4 == BLK_DOOROAK >> 4 || b >> 4 == BLK_DOORSPRUCE >> 4 || b >> 4 == BLK_DOORBIRCH >> 4 || b >> 4 == BLK_DOORJUNGLE >> 4 || b >> 4 == BLK_DOORACACIA >> 4 || b >> 4 == BLK_DOORDARKOAK >> 4) {
|
||||
if (b & 0b1000) return getBlockWorld_guess(world, ch, x, y - 1, z);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void entity_adjustBoundingBox(struct world* world, struct entity* ent, struct chunk* ch, block b, int32_t x, int32_t y, int32_t z, struct boundingbox* in, struct boundingbox* out) {
|
||||
memcpy(in, out, sizeof(struct boundingbox));
|
||||
if (b >> 4 == BLK_DOORIRON >> 4 || b >> 4 == BLK_DOOROAK >> 4 || b >> 4 == BLK_DOORSPRUCE >> 4 || b >> 4 == BLK_DOORBIRCH >> 4 || b >> 4 == BLK_DOORJUNGLE >> 4 || b >> 4 == BLK_DOORACACIA >> 4 || b >> 4 == BLK_DOORDARKOAK >> 4) {
|
||||
block lb = b;
|
||||
block ub = b;
|
||||
if (b & 0b1000) {
|
||||
lb = getBlockWorld_guess(world, ch, x, y - 1, z);
|
||||
} else {
|
||||
ub = getBlockWorld_guess(world, ch, x, y + 1, z);
|
||||
}
|
||||
if ((lb & 0b0010) && (ub & 0b0001)) {
|
||||
uint8_t face = lb & 0b0011;
|
||||
if (face == 3 || face == 1) {
|
||||
out->maxZ = 1. - in->maxZ;
|
||||
out->minZ = 1. - in->minZ;
|
||||
} else {
|
||||
out->maxX = 1. - in->maxX;
|
||||
out->minX = 1. - in->minX;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float shrink) {
|
||||
if (entity->immovable) return 0;
|
||||
struct boundingbox obb;
|
||||
|
@ -911,11 +934,14 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float
|
|||
for (int32_t y = floor(obb.minY); y < floor(obb.maxY + 1.); y++) {
|
||||
block b = getBlockWorld_guess(entity->world, ch, x, y, z);
|
||||
if (b == 0) continue;
|
||||
b = entity_adjustCollision(entity->world, ch, b, x, y, z);
|
||||
b = entity_adjustCollision(entity->world, entity, ch, b, x, y, z);
|
||||
struct block_info* bi = getBlockInfo(b);
|
||||
if (bi == NULL) continue;
|
||||
for (size_t i = 0; i < bi->boundingBox_count; i++) {
|
||||
struct boundingbox* bb = &bi->boundingBoxes[i];
|
||||
struct boundingbox* bbx = &bi->boundingBoxes[i];
|
||||
struct boundingbox bbd;
|
||||
struct boundingbox* bb = &bbd;
|
||||
entity_adjustBoundingBox(entity->world, entity, ch, b, x, y, z, bbx, &bbd);
|
||||
// if (!bi->fullCube) {
|
||||
// for (double *d = (double *) &bi->boundingBoxes[0], idx = 0; idx < 6; idx++, d++)
|
||||
// printf("%f ", *d);
|
||||
|
@ -952,11 +978,14 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float
|
|||
for (int32_t y = floor(obb.minY); y < floor(obb.maxY + 1.); y++) {
|
||||
block b = getBlockWorld_guess(entity->world, ch, x, y, z);
|
||||
if (b == 0) continue;
|
||||
b = entity_adjustCollision(entity->world, ch, b, x, y, z);
|
||||
b = entity_adjustCollision(entity->world, entity, ch, b, x, y, z);
|
||||
struct block_info* bi = getBlockInfo(b);
|
||||
if (bi == NULL) continue;
|
||||
for (size_t i = 0; i < bi->boundingBox_count; i++) {
|
||||
struct boundingbox* bb = &bi->boundingBoxes[i];
|
||||
struct boundingbox* bbx = &bi->boundingBoxes[i];
|
||||
struct boundingbox bbd;
|
||||
struct boundingbox* bb = &bbd;
|
||||
entity_adjustBoundingBox(entity->world, entity, ch, b, x, y, z, bbx, &bbd);
|
||||
if (bb != NULL && bb->minX != bb->maxX && bb->minY != bb->maxY && bb->minZ != bb->maxZ) {
|
||||
if (bb->maxX + x > obb.minX && bb->minX + x < obb.maxX ? (bb->maxY + y > obb.minY && bb->minY + y < obb.maxY ? bb->maxZ + z > obb.minZ && bb->minZ + z < obb.maxZ : 0) : 0) {
|
||||
if (pbb.maxY > bb->minY + y && pbb.minY < bb->maxY + y && pbb.maxZ > bb->minZ + z && pbb.minZ < bb->maxZ + z) {
|
||||
|
@ -988,11 +1017,14 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float
|
|||
for (int32_t y = floor(obb.minY); y < floor(obb.maxY + 1.); y++) {
|
||||
block b = getBlockWorld_guess(entity->world, ch, x, y, z);
|
||||
if (b == 0) continue;
|
||||
b = entity_adjustCollision(entity->world, ch, b, x, y, z);
|
||||
b = entity_adjustCollision(entity->world, entity, ch, b, x, y, z);
|
||||
struct block_info* bi = getBlockInfo(b);
|
||||
if (bi == NULL) continue;
|
||||
for (size_t i = 0; i < bi->boundingBox_count; i++) {
|
||||
struct boundingbox* bb = &bi->boundingBoxes[i];
|
||||
struct boundingbox* bbx = &bi->boundingBoxes[i];
|
||||
struct boundingbox bbd;
|
||||
struct boundingbox* bb = &bbd;
|
||||
entity_adjustBoundingBox(entity->world, entity, ch, b, x, y, z, bbx, &bbd);
|
||||
if (bb != NULL && bb->minX != bb->maxX && bb->minY != bb->maxY && bb->minZ != bb->maxZ) {
|
||||
if (bb->maxX + x > obb.minX && bb->minX + x < obb.maxX ? (bb->maxY + y > obb.minY && bb->minY + y < obb.maxY ? bb->maxZ + z > obb.minZ && bb->minZ + z < obb.maxZ : 0) : 0) {
|
||||
if (pbb.maxX > bb->minX + x && pbb.minX < bb->maxX + x && pbb.maxY > bb->minY + y && pbb.minY < bb->maxY + y) {
|
||||
|
|
|
@ -198,7 +198,7 @@ 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, int32_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, float cx, float cy, float cz) {
|
||||
if (face != YP) return 0;
|
||||
if (!getBlockInfo(getBlockWorld(world, x, y, z))->material->replacable) offsetCoordByFace(&x, &y, &z, face);
|
||||
block pre = getBlockWorld(world, x, y, z);
|
||||
|
@ -206,15 +206,19 @@ int onItemInteract_door(struct world* world, struct player* player, uint8_t slot
|
|||
block b = BLK_DOOROAK;
|
||||
if (slot->item == ITM_DOORSPRUCE) b = BLK_DOORSPRUCE;
|
||||
else if (slot->item == ITM_DOORBIRCH) b = BLK_DOORBIRCH;
|
||||
else if (slot->item == ITM_DOORJUNGLE) b = ITM_DOORJUNGLE;
|
||||
else if (slot->item == ITM_DOORACACIA) b = ITM_DOORACACIA;
|
||||
else if (slot->item == ITM_DOORDARKOAK) b = ITM_DOORDARKOAK;
|
||||
else if (slot->item == ITM_DOORIRON) b = ITM_DOORIRON;
|
||||
else if (slot->item == ITM_DOORJUNGLE) b = BLK_DOORJUNGLE;
|
||||
else if (slot->item == ITM_DOORACACIA) b = BLK_DOORACACIA;
|
||||
else if (slot->item == ITM_DOORDARKOAK) b = BLK_DOORDARKOAK;
|
||||
else if (slot->item == ITM_DOORIRON) b = BLK_DOORIRON;
|
||||
block b2 = b;
|
||||
uint32_t h = (uint32_t) floor(player->entity->yaw / 90. + .5) & 3;
|
||||
if (h == 0) b |= 1;
|
||||
else if (h == 1) b |= 2;
|
||||
else if (h == 2) b |= 3;
|
||||
else if (h == 2) b |= 3; // should fold into "f" below
|
||||
uint8_t f = getFaceFromPlayer(player);
|
||||
if ((f == XN && cz < .5) || (f == XP && cz > .5) || (f == ZN && cx > .5) || (f == ZP && cx < .5)) {
|
||||
b2 |= 0x01;
|
||||
}
|
||||
b2 |= 0b1000;
|
||||
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)) {
|
||||
|
|
|
@ -264,7 +264,7 @@ 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, int32_t y, int32_t z, uint8_t face); // in-world usage, called after onItemUse
|
||||
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, float cx, float cy, float cz); // 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
|
||||
|
|
|
@ -468,7 +468,7 @@ void player_receive_packet(struct player* player, struct packet* inp) {
|
|||
struct item_info* ii = getItemInfo(ci->item);
|
||||
if (ii != NULL && ii->onItemInteract != NULL) {
|
||||
pthread_mutex_unlock(&player->inventory->mut);
|
||||
if ((*ii->onItemInteract)(player->world, player, player->currentItem + 36, ci, x, y, z, face)) goto pbp_cont;
|
||||
if ((*ii->onItemInteract)(player->world, player, player->currentItem + 36, ci, x, y, z, face, inp->data.play_server.playerblockplacement.cursor_position_x, inp->data.play_server.playerblockplacement.cursor_position_y, inp->data.play_server.playerblockplacement.cursor_position_z)) goto pbp_cont;
|
||||
pthread_mutex_lock(&player->inventory->mut);
|
||||
ci = getSlot(player, player->inventory, 36 + player->currentItem);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue