From 6f2a75065212906621c90e4e13166df8aee6fd78 Mon Sep 17 00:00:00 2001 From: Protryon Date: Sat, 4 May 2019 19:38:57 -0700 Subject: [PATCH] entity refactoring --- include/basin/entity.h | 8 +- include/basin/entity_impl.h | 6 +- include/basin/game.h | 2 +- src/entity.c | 401 +++++++++++++++++------------------- src/game.c | 2 +- src/player.c | 4 +- src/player_packet.c | 12 +- 7 files changed, 206 insertions(+), 229 deletions(-) diff --git a/include/basin/entity.h b/include/basin/entity.h index 7e13166..ab3bad4 100644 --- a/include/basin/entity.h +++ b/include/basin/entity.h @@ -455,7 +455,7 @@ void entitymeta_read(struct entity* ent, uint8_t* meta, size_t size); void entitymeta_write(struct entity* entity, uint8_t** data, size_t* size, struct mempool* pool); -void updateMetadata(struct entity* ent); +void entity_broadcast_metadata(struct entity* entity); void entity_jump(struct entity* entity); @@ -471,12 +471,8 @@ double entity_dist_block(struct entity* ent1, double x, double y, double z); void entity_collision_bounding_box(struct entity* entity, struct boundingbox* bb); -int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float shrink); - -int tick_itemstack(struct world* world, struct entity* entity); +int entity_move(struct entity* entity, double* motionX, double* motionY, double* motionZ, float shrink); void tick_entity(struct world* world, struct entity* entity); -void freeEntity(struct entity* entity); - #endif /* BASIN_ENTITY_H_ */ diff --git a/include/basin/entity_impl.h b/include/basin/entity_impl.h index 87ea1b3..e82b46e 100644 --- a/include/basin/entity_impl.h +++ b/include/basin/entity_impl.h @@ -1,7 +1,11 @@ #ifndef BASIN_ENTITY_IMPL_H #define BASIN_ENTITY_IMPL_H -#include "entity_impl.h" +#include +#include +#include +#include +#include void onSpawned_minecart(struct world* world, struct entity* entity); diff --git a/include/basin/game.h b/include/basin/game.h index 84873b2..9b0d870 100644 --- a/include/basin/game.h +++ b/include/basin/game.h @@ -17,7 +17,7 @@ void player_openInventory(struct player* player, struct inventory* inv); float game_rand_float(); -void playSound(struct world* world, int32_t soundID, int32_t soundCategory, float x, float y, float z, float volume, float pitch); +void playSound(struct world* world, int32_t soundID, int32_t soundCategory, double x, double y, double z, float volume, float pitch); void dropPlayerItem(struct player* player, struct slot* drop); diff --git a/src/entity.c b/src/entity.c index aceb3b9..aef124c 100644 --- a/src/entity.c +++ b/src/entity.c @@ -450,46 +450,45 @@ void entitymeta_write(struct entity* entity, uint8_t** data, size_t* size, struc (*data)[(*size)++] = 0xFF; } -void updateMetadata(struct entity* ent) { - BEGIN_BROADCAST(ent->loadingPlayers) - struct packet* pkt = xmalloc(sizeof(struct packet)); - pkt->id = PKT_PLAY_CLIENT_ENTITYMETADATA; - pkt->data.play_client.entitymetadata.entity_id = ent->id; - entitymeta_write(ent, &pkt->data.play_client.entitymetadata.metadata.metadata, &pkt->data.play_client.entitymetadata.metadata.metadata_size); - add_queue(bc_player->outgoing_packets, pkt); - END_BROADCAST(ent->loadingPlayers) +void entity_broadcast_metadata(struct entity* entity) { + BEGIN_BROADCAST(entity->loadingPlayers) + struct packet* packet = packet_new(mempool_new(), PKT_PLAY_CLIENT_ENTITYMETADATA); + packet->data.play_client.entitymetadata.entity_id = entity->id; + entitymeta_write(entity, &packet->data.play_client.entitymetadata.metadata.metadata, &packet->data.play_client.entitymetadata.metadata.metadata_size, packet->pool); + queue_push(bc_player->outgoing_packets, packet); + END_BROADCAST(entity->loadingPlayers) } -int getSwingTime(struct entity* ent) { - for (size_t i = 0; i < ent->effect_count; i++) { - if (ent->effects[i].effectID == 3) { - return 6 - (1 + ent->effects[i].amplifier); - } else if (ent->effects[i].effectID == 4) { - return 6 + (1 + ent->effects[i].amplifier) * 2; +int entity_swing_time(struct entity* entity) { + for (size_t i = 0; i < entity->effect_count; i++) { + if (entity->effects[i].effectID == 3) { + return 6 - (1 + entity->effects[i].amplifier); + } else if (entity->effects[i].effectID == 4) { + return 6 + (1 + entity->effects[i].amplifier) * 2; } } return 6; } -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 world_get_block_guess(world, ch, x, y - 1, z); +block entity_adjustCollision(struct world* world, struct entity* entity, struct chunk* chunk, block block, int32_t x, int32_t y, int32_t z) { + if (block >> 4 == BLK_DOORIRON >> 4 || block >> 4 == BLK_DOOROAK >> 4 || block >> 4 == BLK_DOORSPRUCE >> 4 || block >> 4 == BLK_DOORBIRCH >> 4 || block >> 4 == BLK_DOORJUNGLE >> 4 || block >> 4 == BLK_DOORACACIA >> 4 || block >> 4 == BLK_DOORDARKOAK >> 4) { + if (block & 0b1000) return world_get_block_guess(world, chunk, x, y - 1, z); } - return b; + return block; } -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) { +void entity_adjustBoundingBox(struct world* world, struct entity* entity, struct chunk* ch, block block, 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 = world_get_block_guess(world, ch, x, y - 1, z); + if (block >> 4 == BLK_DOORIRON >> 4 || block >> 4 == BLK_DOOROAK >> 4 || block >> 4 == BLK_DOORSPRUCE >> 4 || block >> 4 == BLK_DOORBIRCH >> 4 || block >> 4 == BLK_DOORJUNGLE >> 4 || block >> 4 == BLK_DOORACACIA >> 4 || block >> 4 == BLK_DOORDARKOAK >> 4) { + block low_block = block; + block high_block = block; + if (block & 0b1000) { + low_block = world_get_block_guess(world, ch, x, y - 1, z); } else { - ub = world_get_block_guess(world, ch, x, y + 1, z); + high_block = world_get_block_guess(world, ch, x, y + 1, z); } - if ((lb & 0b0010) && (ub & 0b0001)) { - uint8_t face = lb & 0b0011; + if ((low_block & 0b0010) && (high_block & 0b0001)) { + uint8_t face = (uint8_t) (low_block & 0b0011); if (face == 3 || face == 1) { out->maxZ = 1. - in->maxZ; out->minZ = 1. - in->minZ; @@ -501,14 +500,14 @@ void entity_adjustBoundingBox(struct world* world, struct entity* ent, struct ch } } -int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float shrink) { +int entity_move(struct entity* entity, double* motionX, double* motionY, double* motionZ, float shrink) { if (entity->immovable) return 0; struct boundingbox obb; entity_collision_bounding_box(entity, &obb); if (entity->type == ENT_ARROW || entity->type == ENT_SPECTRALARROW || obb.minX == obb.maxX || obb.minZ == obb.maxZ || obb.minY == obb.maxY) { - entity->x += *mx; - entity->y += *my; - entity->z += *mz; + entity->x += *motionX; + entity->y += *motionY; + entity->z += *motionZ; return 0; } obb.minX += shrink; @@ -517,20 +516,20 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float obb.maxY -= shrink; obb.minZ += shrink; obb.maxZ -= shrink; - if (*mx < 0.) { - obb.minX += *mx; + if (*motionX < 0.) { + obb.minX += *motionX; } else { - obb.maxX += *mx; + obb.maxX += *motionX; } - if (*my < 0.) { - obb.minY += *my; + if (*motionY < 0.) { + obb.minY += *motionY; } else { - obb.maxY += *my; + obb.maxY += *motionY; } - if (*mz < 0.) { - obb.minZ += *mz; + if (*motionZ < 0.) { + obb.minZ += *motionZ; } else { - obb.maxZ += *mz; + obb.maxZ += *motionZ; } struct boundingbox pbb; entity_collision_bounding_box(entity, &pbb); @@ -540,7 +539,7 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float pbb.maxY -= shrink; pbb.minZ += shrink; pbb.maxZ -= shrink; - double ny = *my; + double ny = *motionY; struct chunk* ch = world_get_chunk(entity->world, (int32_t) entity->x / 16, (int32_t) entity->z / 16); for (int32_t x = (int32_t) floor(obb.minX); x < floor(obb.maxX + 1.); x++) { for (int32_t z = (int32_t) floor(obb.minZ); z < floor(obb.maxZ + 1.); z++) { @@ -580,7 +579,7 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float entity->y += ny; pbb.minY += ny; pbb.maxY += ny; - double nx = *mx; + double nx = *motionX; for (int32_t x = (int32_t) floor(obb.minX); x < floor(obb.maxX + 1.); x++) { for (int32_t z = (int32_t) floor(obb.minZ); z < floor(obb.maxZ + 1.); z++) { for (int32_t y = (int32_t) floor(obb.minY); y < floor(obb.maxY + 1.); y++) { @@ -619,7 +618,7 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float entity->x += nx; pbb.minX += nx; pbb.maxX += nx; - double nz = *mz; + double nz = *motionZ; for (int32_t x = (int32_t) floor(obb.minX); x < floor(obb.maxX + 1.); x++) { for (int32_t z = (int32_t) floor(obb.minZ); z < floor(obb.maxZ + 1.); z++) { for (int32_t y = (int32_t) floor(obb.minY); y < floor(obb.maxY + 1.); y++) { @@ -659,9 +658,9 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float entity->z += nz; pbb.minZ += nz; pbb.maxZ += nz; - entity->collidedHorizontally = *mx != nx || *mz != nz; - entity->collidedVertically = *my != ny; - entity->on_ground = entity->collidedVertically && *my < 0.; + entity->collidedHorizontally = *motionX != nx || *motionZ != nz; + entity->collidedVertically = *motionY != ny; + entity->on_ground = entity->collidedVertically && *motionY < 0.; int32_t bx = (int32_t) floor(entity->x); int32_t by = (int32_t) floor(entity->y - .20000000298023224); int32_t bz = (int32_t) floor(entity->z); @@ -674,77 +673,80 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float by--; } } - if (*mx != nx) *mx = 0.; - if (*mz != nz) *mz = 0.; - if (*my != ny) { + if (*motionX != nx) *motionX = 0.; + if (*motionZ != nz) *motionZ = 0.; + if (*motionY != ny) { if (lb != BLK_SLIME || entity->sneaking) { - *my = 0.; + *motionY = 0.; } else { - *my = -(*my); + *motionY = -(*motionY); } } - return ny != *my || nx != *mx || nz != *mz; + return ny != *motionY || nx != *motionX || nz != *motionZ; } -void applyVelocity(struct entity* entity, double x, double y, double z) { +void entity_apply_velocity(struct entity* entity, double x, double y, double z) { entity->motX += x; entity->motY += y; entity->motZ += z; - BEGIN_BROADCAST(entity->loadingPlayers) - struct packet* pkt = xmalloc(sizeof(struct packet)); - pkt->id = PKT_PLAY_CLIENT_ENTITYVELOCITY; - pkt->data.play_client.entityvelocity.entity_id = entity->id; - pkt->data.play_client.entityvelocity.velocity_x = (int16_t)(entity->motX * 8000.); - pkt->data.play_client.entityvelocity.velocity_y = (int16_t)(entity->motY * 8000.); - pkt->data.play_client.entityvelocity.velocity_z = (int16_t)(entity->motZ * 8000.); - add_queue(bc_player->outgoing_packets, pkt); - END_BROADCAST(entity->loadingPlayers) + BEGIN_BROADCAST(entity->loadingPlayers) { + struct packet* packet = packet_new(mempool_new(), PKT_PLAY_CLIENT_ENTITYVELOCITY); + packet->data.play_client.entityvelocity.entity_id = entity->id; + packet->data.play_client.entityvelocity.velocity_x = (int16_t) (entity->motX * 8000.); + packet->data.play_client.entityvelocity.velocity_y = (int16_t) (entity->motY * 8000.); + packet->data.play_client.entityvelocity.velocity_z = (int16_t) (entity->motZ * 8000.); + queue_push(bc_player->outgoing_packets, packet); + END_BROADCAST(entity->loadingPlayers) + } if (entity->type == ENT_PLAYER) { - struct packet* pkt = xmalloc(sizeof(struct packet)); - pkt->id = PKT_PLAY_CLIENT_ENTITYVELOCITY; - pkt->data.play_client.entityvelocity.entity_id = entity->id; - pkt->data.play_client.entityvelocity.velocity_x = (int16_t)(entity->motX * 8000.); - pkt->data.play_client.entityvelocity.velocity_y = (int16_t)(entity->motY * 8000.); - pkt->data.play_client.entityvelocity.velocity_z = (int16_t)(entity->motZ * 8000.); - add_queue(entity->data.player.player->outgoing_packets, pkt); + struct packet* packet = packet_new(mempool_new(), PKT_PLAY_CLIENT_ENTITYVELOCITY); + packet->data.play_client.entityvelocity.entity_id = entity->id; + packet->data.play_client.entityvelocity.velocity_x = (int16_t)(entity->motX * 8000.); + packet->data.play_client.entityvelocity.velocity_y = (int16_t)(entity->motY * 8000.); + packet->data.play_client.entityvelocity.velocity_z = (int16_t)(entity->motZ * 8000.); + queue_push(entity->data.player.player->outgoing_packets, packet); } } -void applyKnockback(struct entity* entity, float yaw, float strength) { - float kb_resistance = 0.; +void entity_apply_knockback(struct entity* entity, float yaw, float strength) { + float kb_resistance = 0f; if (game_rand_float() > kb_resistance) { - float xr = sinf(yaw / 360. * 2 * M_PI); - float zr = -cosf(yaw / 360. * 2 * M_PI); - float m = sqrtf(xr * xr + zr * zr); + float x_component = sinf((float) (yaw / 360f * 2f * M_PI)); + float z_component = -cosf((float) (yaw / 360f * 2f * M_PI)); + float m = sqrtf(x_component * x_component + z_component * z_component); entity->motX /= 2.; entity->motZ /= 2.; - entity->motX -= xr / m * strength; - entity->motZ -= zr / m * strength; + entity->motX -= x_component / m * strength; + entity->motZ -= z_component / m * strength; if (entity->on_ground) { entity->motY /= 2.; entity->motY += strength; if (entity->motY > .4) entity->motY = .4; } - applyVelocity(entity, 0., 0., 0.); + entity_apply_velocity(entity, 0., 0., 0.); } } int damageEntityWithItem(struct entity* attacked, struct entity* attacker, uint8_t slot_index, struct slot* item) { - if (attacked == NULL || attacked->invincibilityTicks > 0 || !entity_has_flag(entity_get_info(attacked->type), "livingbase") || attacked->health <= 0.) return 0; - if (attacked->type == ENT_PLAYER && attacked->data.player.player->gamemode == 1) return 0; - float damage = 1.; + if (attacked == NULL || attacked->invincibilityTicks > 0 || !hashset_has(attacked->info->flags, "livingbase") || attacked->health <= 0.) { + return 0; + } + if (attacked->type == ENT_PLAYER && attacked->data.player.player->gamemode == 1) { + return 0; + } + float damage = 1f; if (item != NULL) { - struct item_info* ii = getItemInfo(item->item); - if (ii != NULL) { - damage = ii->damage; + struct item_info* info = getItemInfo(item->item); + if (info != NULL) { + damage = info->damage; if (attacker->type == ENT_PLAYER) { - if (ii->onItemAttacked != NULL) { - damage = (*ii->onItemAttacked)(attacker->world, attacker->data.player.player, attacker->data.player.player->currentItem + 36, item, attacked); + if (info->onItemAttacked != NULL) { + damage = (*info->onItemAttacked)(attacker->world, attacker->data.player.player, (uint8_t) (attacker->data.player.player->currentItem + 36), item, attacked); } } } } - float knockback_strength = 1.; + float knockback_strength = 1f; if (attacker->sprinting) knockback_strength++; if (attacker->type == ENT_PLAYER) { struct player* player = attacker->data.player.player; @@ -755,15 +757,18 @@ int damageEntityWithItem(struct entity* attacked, struct entity* attacker, uint8 if (attacker->y > attacked->y && (attacker->last_y - attacker->y) > 0 && !attacker->on_ground && !attacker->sprinting) { // todo water/ladder damage *= 1.5; } - BEGIN_HASHMAP_ITERATION (plugins) - struct plugin* plugin = value; - if (plugin->onEntityAttacked != NULL) damage = (*plugin->onEntityAttacked)(attacker->world, attacker, slot_index, item, attacked, damage); - END_HASHMAP_ITERATION (plugins) - if (damage == 0.) return 0; + ITER_MAP(plugins) { + struct plugin* plugin = value; + if (plugin->onEntityAttacked != NULL) damage = (*plugin->onEntityAttacked)(attacker->world, attacker, slot_index, item, attacked, damage); + ITER_MAP_END(); + } + if (damage == 0.) { + return 0; + } damageEntity(attacked, damage, 1); //TODO: enchantment knockback_strength *= .2; - applyKnockback(attacked, attacker->yaw, knockback_strength); + entity_apply_knockback(attacked, attacker->yaw, knockback_strength); if (attacker->type == ENT_PLAYER) { attacker->data.player.player->foodExhaustion += .1; } @@ -771,7 +776,7 @@ int damageEntityWithItem(struct entity* attacked, struct entity* attacker, uint8 } int damageEntity(struct entity* attacked, float damage, int armorable) { - if (attacked == NULL || damage <= 0. || attacked->invincibilityTicks > 0 || !entity_has_flag(entity_get_info(attacked->type), "livingbase") || attacked->health <= 0.) return 0; + if (attacked == NULL || damage <= 0. || attacked->invincibilityTicks > 0 || !hashset_has(attacked->info->flags, "livingbase") || attacked->health <= 0.) return 0; float armor = 0; if (attacked->type == ENT_PLAYER) { struct player* player = attacked->data.player.player; @@ -787,10 +792,10 @@ int damageEntity(struct entity* attacked, float damage, int armorable) { } } if (armorable) { - float f = armor - damage / 2.; - if (f < armor * .2) f = armor * .2; - if (f > 20.) f = 20.; - damage *= 1. - (f) / 25.; + float mod = armor - damage / 2f; + if (mod < armor * .2) mod = armor * .2f; + if (mod > 20.) mod = 20f; + damage *= 1. - mod / 25.; } if (attacked->type == ENT_PLAYER) { struct player* player = attacked->data.player.player; @@ -798,9 +803,9 @@ int damageEntity(struct entity* attacked, float damage, int armorable) { if (armorable) for (int i = 5; i <= 8; i++) { struct slot* sl = inventory_get(player, player->inventory, i); if (sl != NULL) { - struct item_info* ii = getItemInfo(sl->item); - if (ii != NULL && ii->onEntityHitWhileWearing != NULL) { - damage = (*ii->onEntityHitWhileWearing)(player->world, player, i, sl, damage); + struct item_info* info = getItemInfo(sl->item); + if (info != NULL && info->onEntityHitWhileWearing != NULL) { + damage = (*info->onEntityHitWhileWearing)(player->world, player, i, sl, damage); } } } @@ -808,74 +813,68 @@ int damageEntity(struct entity* attacked, float damage, int armorable) { attacked->health -= damage; attacked->invincibilityTicks = 10; if (attacked->type == ENT_PLAYER) { - struct packet* pkt = xmalloc(sizeof(struct packet)); - pkt->id = PKT_PLAY_CLIENT_UPDATEHEALTH; - pkt->data.play_client.updatehealth.health = attacked->health; - pkt->data.play_client.updatehealth.food = attacked->data.player.player->food; - pkt->data.play_client.updatehealth.food_saturation = attacked->data.player.player->saturation; - add_queue(attacked->data.player.player->outgoing_packets, pkt); + struct packet* packet = packet_new(mempool_new(), PKT_PLAY_CLIENT_UPDATEHEALTH); + packet->data.play_client.updatehealth.health = attacked->health; + packet->data.play_client.updatehealth.food = attacked->data.player.player->food; + packet->data.play_client.updatehealth.food_saturation = attacked->data.player.player->saturation; + queue_push(attacked->data.player.player->outgoing_packets, packet); } if (attacked->health <= 0.) { if (attacked->type == ENT_PLAYER) { struct player* player = attacked->data.player.player; broadcastf("default", "%s died", player->name); for (size_t i = 0; i < player->inventory->slot_count; i++) { - struct slot* slot = inventory_get(player, player->inventory, i); + struct slot* slot = inventory_get(player, player->inventory, (int) i); if (slot != NULL) dropEntityItem_explode(player->entity, slot); - inventory_set_slot(player, player->inventory, i, 0, 0, 1); + inventory_set_slot(player, player->inventory, (int) i, 0, 1); } if (player->inventory_holding != NULL) { dropEntityItem_explode(player->entity, player->inventory_holding); - freeSlot(player->inventory_holding); - xfree(player->inventory_holding); player->inventory_holding = NULL; } - if (player->open_inventory != NULL) player_closeWindow(player, player->open_inventory->windowID); + if (player->open_inventory != NULL) { + player_closeWindow(player, (uint16_t) player->open_inventory->window); + } } else { - struct entity_info* ei = entity_get_info(attacked->type); - if (ei != NULL) for (size_t i = 0; i < ei->loot_count; i++) { - struct entity_loot* el = &ei->loots[i]; - int amt = el->amountMax == el->amountMin ? el->amountMax : (rand() % (el->amountMax - el->amountMin) + el->amountMin); - if (amt <= 0) continue; - struct slot it; - it.item = el->id; - it.count = amt; - it.damage = el->metaMax == el->metaMin ? el->metaMax : (rand() % (el->metaMax - el->metaMin) + el->metaMin); - it.nbt = NULL; - dropEntityItem_explode(attacked, &it); + struct entity_info* info = entity_get_info(attacked->type); + if (info != NULL) { + for (size_t i = 0; i < info->loot_count; i++) { + struct entity_loot* el = &info->loots[i]; + int amt = el->amountMax == el->amountMin ? el->amountMax : (rand() % (el->amountMax - el->amountMin) + el->amountMin); + if (amt <= 0) continue; + struct slot it; + it.item = el->id; + it.count = (unsigned char) amt; + it.damage = (int16_t) (el->metaMax == el->metaMin ? el->metaMax : (rand() % (el->metaMax - el->metaMin) + el->metaMin)); + it.nbt = NULL; + dropEntityItem_explode(attacked, &it); + } } } } - BEGIN_BROADCAST_DIST(attacked, 128.) - struct packet* pkt = xmalloc(sizeof(struct packet)); - pkt->id = PKT_PLAY_CLIENT_ANIMATION; - pkt->data.play_client.animation.entity_id = attacked->id; - pkt->data.play_client.animation.animation = 1; - add_queue(bc_player->outgoing_packets, pkt); + entity_animation(attacked, 1); if (attacked->health <= 0.) { - pkt = xmalloc(sizeof(struct packet)); - pkt->id = PKT_PLAY_CLIENT_ENTITYMETADATA; - pkt->data.play_client.entitymetadata.entity_id = attacked->id; - entitymeta_write(attacked, &pkt->data.play_client.entitymetadata.metadata.metadata, &pkt->data.play_client.entitymetadata.metadata.metadata_size); - add_queue(bc_player->outgoing_packets, pkt); + entity_broadcast_metadata(attacked); } - END_BROADCAST(attacked->world->players) - if (attacked->type == ENT_PLAYER) playSound(attacked->world, 316, 8, attacked->x, attacked->y, attacked->z, 1., 1.); + if (attacked->type == ENT_PLAYER) playSound(attacked->world, 316, 8, attacked->x, attacked->y, attacked->z, 1f, 1f); return 1; } void healEntity(struct entity* healed, float amount) { - if (healed == NULL || amount <= 0. || healed->health <= 0. || !entity_has_flag(entity_get_info(healed->type), "livingbase")) return; - float oh = healed->health; + if (healed == NULL || amount <= 0. || healed->health <= 0. || !hashset_has(healed->info->flags, "livingbase")) { + return; + } + float original_health = healed->health; healed->health += amount; - if (healed->health > healed->maxHealth) healed->health = 20.; - if (healed->type == ENT_PLAYER && oh != healed->health) { - struct packet* pkt = xmalloc(sizeof(struct packet)); - pkt->id = PKT_PLAY_CLIENT_UPDATEHEALTH; - pkt->data.play_client.updatehealth.health = healed->health; - pkt->data.play_client.updatehealth.food = healed->data.player.player->food; - pkt->data.play_client.updatehealth.food_saturation = healed->data.player.player->saturation; - add_queue(healed->data.player.player->outgoing_packets, pkt); + if (healed->health > healed->maxHealth) { + healed->health = 20f; + } + if (healed->type == ENT_PLAYER && original_health != healed->health) { + struct packet* packet = packet_new(mempool_new(), PKT_PLAY_CLIENT_UPDATEHEALTH); + packet->data.play_client.updatehealth.health = healed->health; + packet->data.play_client.updatehealth.food = healed->data.player.player->food; + packet->data.play_client.updatehealth.food_saturation = healed->data.player.player->saturation; + queue_push(healed->data.player.player->outgoing_packets, packet); } } @@ -914,7 +913,6 @@ int entity_inFluid(struct entity* entity, uint16_t blk, float ydown, int meta_ch return 0; } - int entity_inBlock(struct entity* ent, block blk) { // blk = 0 for any block struct boundingbox obb; entity_collision_bounding_box(ent, &obb); @@ -951,8 +949,10 @@ int entity_inBlock(struct entity* ent, block blk) { // blk = 0 for any block return 0; } -void pushOutOfBlocks(struct entity* ent) { - if (!entity_inBlock(ent, 0)) return; +void entity_push_out_of_blocks(struct entity* ent) { + if (!entity_inBlock(ent, 0)) { + return; + } struct boundingbox ebb; entity_collision_bounding_box(ent, &ebb); double x = ent->x; @@ -965,40 +965,40 @@ void pushOutOfBlocks(struct entity* ent) { double dy = y - (double) by; double dz = z - (double) bz; double ld = 100.; - float fbx = 0.; - float fby = 0.; - float fbz = 0.; + float fbx = 0f; + float fby = 0f; + float fbz = 0f; if (dx < ld && !isNormalCube(getBlockInfo(world_get_block(ent->world, bx - 1, by, bz)))) { ld = dx; - fbx = -1.; - fby = 0.; - fbz = 0.; + fbx = -1f; + fby = 0f; + fbz = 0f; } if ((1. - dx) < ld && !isNormalCube(getBlockInfo(world_get_block(ent->world, bx + 1, by, bz)))) { ld = 1. - dx; - fbx = 1.; - fby = 0.; - fbz = 0.; + fbx = 1f; + fby = 0f; + fbz = 0f; } if (dz < ld && !isNormalCube(getBlockInfo(world_get_block(ent->world, bx, by, bz - 1)))) { ld = dx; - fbx = 0.; - fby = 0.; - fbz = -1.; + fbx = 0f; + fby = 0f; + fbz = -1f; } if ((1. - dz) < ld && !isNormalCube(getBlockInfo(world_get_block(ent->world, bx, by, bz + 1)))) { ld = 1. - dz; - fbx = 0.; - fby = 0.; - fbz = 1.; + fbx = 0f; + fby = 0f; + fbz = 1f; } if ((1. - dy) < ld && !isNormalCube(getBlockInfo(world_get_block(ent->world, bx, by + 1, bz)))) { ld = 1. - dy; - fbx = 0.; - fby = 1.; - fbz = 0.; + fbx = 0f; + fby = 1f; + fbz = 0f; } - float mag = game_rand_float() * .2 + .1; + float mag = game_rand_float() * .2f + .1f; if (fbx == 0. && fbz == 0.) { ent->motX *= .75; ent->motY = mag * fby; @@ -1038,13 +1038,11 @@ void tick_entity(struct world* world, struct entity* entity) { } } if (entity->type > ENT_PLAYER) { - if (entity->motX != 0. || entity->motY != 0. || entity->motZ != 0.) moveEntity(entity, &entity->motX, &entity->motY, &entity->motZ, 0.); + if (entity->motX != 0. || entity->motY != 0. || entity->motZ != 0.) entity_move(entity, &entity->motX, &entity->motY, &entity->motZ, 0.); double gravity = 0.; - int ar = entity->type == ENT_ARROW || entity->type == ENT_SPECTRALARROW; + int is_arrow = entity->type == ENT_ARROW || entity->type == ENT_SPECTRALARROW; float friction = .98; - if (ar) { - //printf("ymot %f pit %f\n", entity->motY, entity->pitch); - //printf("af %.17f, %.17f --- %.17f, %.17f, %.17f\n", entity->yaw, entity->pitch, entity->motX, entity->motY, entity->motZ); + if (is_arrow) { friction = .99; if (entity->inWater) friction = .6; entity->motX *= friction; @@ -1052,8 +1050,8 @@ void tick_entity(struct world* world, struct entity* entity) { entity->motZ *= friction; } if (entity->type == ENT_ITEM) gravity = .04; - else if (ar) gravity = .05; - else if (entity_has_flag(entity_get_info(entity->type), "livingbase")) { + else if (is_arrow) gravity = .05; + else if (hashset_has(entity->info->flags, "livingbase")) { if (entity->inLava) { entity->motX *= .5; entity->motY *= .5; @@ -1072,7 +1070,7 @@ void tick_entity(struct world* world, struct entity* entity) { gravity = .04; } if (gravity != 0. && !entity->immovable) entity->motY -= gravity; - if (!ar) { + if (!is_arrow) { if (entity->on_ground) { struct block_info* bi = getBlockInfo(world_get_block(entity->world, (int32_t) floor(entity->x), (int32_t) floor(entity->y) - 1, (int32_t) floor(entity->z))); if (bi != NULL) friction = bi->slipperiness * .98; @@ -1086,28 +1084,27 @@ void tick_entity(struct world* world, struct entity* entity) { if (fabs(entity->motZ) < .0001) entity->motZ = 0.; if (entity->type == ENT_ITEM && entity->on_ground && entity->motX == 0. && entity->motY == 0. && entity->motZ == 0.) entity->motY *= -.5; } - if (entity->type == ENT_ITEM || entity->type == ENT_XPORB) pushOutOfBlocks(entity); - if (entity_has_flag(entity_get_info(entity->type), "livingbase")) { - entity->inWater = entity_inFluid(entity, BLK_WATER, .2, 0) || entity_inFluid(entity, BLK_WATER_1, .2, 0); - entity->inLava = entity_inFluid(entity, BLK_LAVA, .2, 0) || entity_inFluid(entity, BLK_LAVA_1, .2, 0); - if ((entity->inWater || entity->inLava) && entity->type == ENT_PLAYER) entity->data.player.player->llTick = tick_counter; + if (entity->type == ENT_ITEM || entity->type == ENT_XPORB) entity_push_out_of_blocks(entity); + if (hashset_has(entity->info->flags, "livingbase")) { + entity->inWater = (uint8_t) (entity_inFluid(entity, BLK_WATER, .2, 0) || entity_inFluid(entity, BLK_WATER_1, .2, 0)); + entity->inLava = (uint8_t) (entity_inFluid(entity, BLK_LAVA, .2, 0) || entity_inFluid(entity, BLK_LAVA_1, .2, 0)); //TODO: ladders if (entity->type == ENT_PLAYER && entity->data.player.player->gamemode == 1) goto bfd; if (entity->inLava) { - damageEntity(entity, 4., 1); -//TODO: fire + damageEntity(entity, 4f, 1); + //TODO: fire } if (!entity->on_ground) { - float dy = entity->last_y - entity->y; + double dy = entity->last_y - entity->y; if (dy > 0.) { entity->fallDistance += dy; } } else if (entity->fallDistance > 0.) { if (entity->fallDistance > 3. && !entity->inWater && !entity->inLava) { - damageEntity(entity, entity->fallDistance - 3., 0); - playSound(entity->world, 312, 8, entity->x, entity->y, entity->z, 1., 1.); + damageEntity(entity, entity->fallDistance - 3f, 0); + playSound(entity->world, 312, 8, entity->x, entity->y, entity->z, 1f, 1f); } - entity->fallDistance = 0.; + entity->fallDistance = 0f; } bfd: ; } @@ -1115,33 +1112,13 @@ void tick_entity(struct world* world, struct entity* entity) { double md = entity_distsq_block(entity, entity->last_x, entity->last_y, entity->last_z); double mp = (entity->yaw - entity->last_yaw) * (entity->yaw - entity->last_yaw) + (entity->pitch - entity->last_pitch) * (entity->pitch - entity->last_pitch); if (md > .001 || mp > .01) { - BEGIN_HASHMAP_ITERATION(entity->loadingPlayers); - player_send_entity_move(value, entity); - END_HASHMAP_ITERATION(entity->loadingPlayers); + pthread_rwlock_rdlock(&entity->loadingPlayers->rwlock); + ITER_MAP(entity->loadingPlayers) { + player_send_entity_move(value, entity); + ITER_MAP_END(); + } + pthread_rwlock_unlock(&entity->loadingPlayers->rwlock); } } - /*int32_t chunk_x = ((int32_t) entity->x) >> 4; - int32_t chunk_z = ((int32_t) entity->z) >> 4; - int32_t lcx = ((int32_t) entity->lx) >> 4; - int32_t lcz = ((int32_t) entity->lz) >> 4; - if (chunk_x != lcx || chunk_z != lcz) { - struct chunk* lch = getChunk(entity->world, lcx, lcz); - struct chunk* cch = world_get_chunk(entity->world, chunk_x, chunk_z); - put_hashmap(lch->entities, entity->id, NULL); - put_hashmap(cch->entities, entity->id, entity); - }*/ } -void freeEntity(struct entity* entity) { - del_hashmap(entity->loadingPlayers); - if (entity->type == ENT_ITEM) { - if (entity->data.itemstack.slot != NULL) { - freeSlot(entity->data.itemstack.slot); - xfree(entity->data.itemstack.slot); - } - } - if (entity->type == ENT_PAINTING) { - if (entity->data.painting.title != NULL) xfree(entity->data.painting.title); - } - xfree(entity); -} diff --git a/src/game.c b/src/game.c index a77956f..d26a7e1 100644 --- a/src/game.c +++ b/src/game.c @@ -209,7 +209,7 @@ void dropPlayerItem(struct player* player, struct slot* drop) { END_BROADCAST(player->world->players) } -void playSound(struct world* world, int32_t soundID, int32_t soundCategory, float x, float y, float z, float volume, float pitch) { +void playSound(struct world* world, int32_t soundID, int32_t soundCategory, double x, double y, double z, float volume, float pitch) { BEGIN_BROADCAST_DISTXYZ(x, y, z, world->players, 64.) struct packet* pkt = xmalloc(sizeof(struct packet)); pkt->id = PKT_PLAY_CLIENT_SOUNDEFFECT; diff --git a/src/player.c b/src/player.c index f5e544d..899612c 100644 --- a/src/player.c +++ b/src/player.c @@ -303,13 +303,13 @@ void player_tick(struct player* player) { player->itemUseDuration = 0; player->entity->usingItemMain = 0; player->entity->usingItemOff = 0; - updateMetadata(player->entity); + entity_broadcast_metadata(player->entity); } else if (ihi->maxUseDuration <= player->itemUseDuration) { if (ihi->onItemUse != NULL) (*ihi->onItemUse)(player->world, player, (uint8_t) (player->itemUseHand ? 45 : (36 + player->currentItem)), ihs, player->itemUseDuration); player->itemUseDuration = 0; player->entity->usingItemMain = 0; player->entity->usingItemOff = 0; - updateMetadata(player->entity); + entity_broadcast_metadata(player->entity); } else { if (ihi->onItemUseTick != NULL) (*ihi->onItemUseTick)(player->world, player, (uint8_t) (player->itemUseHand ? 45 : (36 + player->currentItem)), ihs, player->itemUseDuration); player->itemUseDuration++; diff --git a/src/player_packet.c b/src/player_packet.c index 1541c27..6652638 100644 --- a/src/player_packet.c +++ b/src/player_packet.c @@ -624,7 +624,7 @@ void player_packet_handle_playerposition(struct player* player, struct mempool* double moveX = packet->x - lastX; double moveY = packet->feet_y - lastY; double moveZ = packet->z - lastZ; - if (moveEntity(player->entity, &moveX, &moveY, &moveZ, .05)) { + if (entity_move(player->entity, &moveX, &moveY, &moveZ, .05)) { player_teleport(player, lastX, lastY, lastZ); } else { player->entity->last_x = lastX; @@ -660,7 +660,7 @@ void player_packet_handle_playerpositionandlook(struct player* player, struct me double moveX = packet->x - lastX; double moveY = packet->feet_y - lastY; double moveZ = packet->z - lastZ; - if (moveEntity(player->entity, &moveX, &moveY, &moveZ, .05)) { + if (entity_move(player->entity, &moveX, &moveY, &moveZ, .05)) { player_teleport(player, lastX, lastY, lastZ); } else { player->entity->last_x = lastX; @@ -861,13 +861,13 @@ void player_packet_handle_playerdigging(struct player* player, struct mempool* p player->itemUseDuration = 0; player->entity->usingItemMain = 0; player->entity->usingItemOff = 0; - updateMetadata(player->entity); + entity_broadcast_metadata(player->entity); } if (item_info != NULL && item_info->onItemUse != NULL) (*item_info->onItemUse)(player->world, player, player->itemUseHand ? 45 : (36 + player->currentItem), item_in_hand, player->itemUseDuration); player->entity->usingItemMain = 0; player->entity->usingItemOff = 0; player->itemUseDuration = 0; - updateMetadata(player->entity); + entity_broadcast_metadata(player->entity); } pthread_mutex_unlock(&player->inventory->mutex); } else if (packet->status == 6) { @@ -881,7 +881,7 @@ void player_packet_handle_entityaction(struct player* player, struct mempool* po else if (packet->action_id == 1) player->entity->sneaking = 0; else if (packet->action_id == 3) player->entity->sprinting = 1; else if (packet->action_id == 4) player->entity->sprinting = 0; - updateMetadata(player->entity); + entity_broadcast_metadata(player->entity); } void player_packet_handle_steervehicle(struct player* player, struct mempool* pool, struct pkt_play_server_steervehicle* packet) { @@ -1061,7 +1061,7 @@ void player_packet_handle_useitem(struct player* player, struct mempool* pool, s player->itemUseHand = (uint8_t) (packet->hand ? 1 : 0); player->entity->usingItemMain = !player->itemUseHand; player->entity->usingItemOff = player->itemUseHand; - updateMetadata(player->entity); + entity_broadcast_metadata(player->entity); } } }