more entity refactoring

This commit is contained in:
Protryon 2019-05-04 18:39:56 -07:00
parent 5b505f29ec
commit f3fdc82399
7 changed files with 195 additions and 218 deletions

View File

@ -10,6 +10,8 @@
#include <basin/world.h>
#include <basin/item.h>
#include <avuna/hash.h>
#include <avuna/pmem.h>
#include <stdint.h>
#include <stdlib.h>
@ -138,8 +140,7 @@ struct entity_info {
float maxHealth;
float width;
float height;
char** flags;
size_t flag_count;
struct hashset* flags;
uint32_t spawn_packet;
int32_t spawn_packet_id;
struct entity_loot* loots;
@ -154,15 +155,13 @@ struct entity_info {
void (*onInteract)(struct world* world, struct entity* entity, struct player* interacter, struct slot* item, int16_t slot_index);
};
void swingArm(struct entity* entity);
struct mempool* entities_pool;
struct list* entity_infos;
struct hashmap* entity_infos_by_name;
void init_entities();
uint32_t getIDFromEntityDataName(const char* dataname);
struct entity_info* getEntityInfo(uint32_t id);
struct entity_info* entity_get_info(uint32_t id);
struct potioneffect {
char effectID;
@ -171,8 +170,6 @@ struct potioneffect {
char particles;
};
int hasFlag(struct entity_info* ei, char* flag);
union entity_data {
struct entity_player {
struct player* player;
@ -397,6 +394,7 @@ union entity_data {
struct entity {
struct mempool* pool;
struct entity_info* info;
int32_t id;
double x;
double y;
@ -445,19 +443,21 @@ struct entity {
struct entity* entity_new(struct world* world, int32_t id, double x, double y, double z, uint32_t type, float yaw, float pitch);
void entity_animation(struct entity* entity, int animation_id);
int damageEntityWithItem(struct entity* attacked, struct entity* attacker, uint8_t slot_index, struct slot* item);
int damageEntity(struct entity* attacked, float damage, int armorable);
void healEntity(struct entity* healed, float amount);
void readMetadata(struct entity* ent, unsigned char* meta, size_t size);
void entitymeta_read(struct entity* ent, unsigned char* meta, size_t size);
void writeMetadata(struct entity* ent, unsigned char** data, size_t* size);
void updateMetadata(struct entity* ent);
void jump(struct entity* entity);
void entity_jump(struct entity* entity);
int entity_inFluid(struct entity* entity, uint16_t blk, float ydown, int meta_check);
@ -469,7 +469,7 @@ double entity_distsq_block(struct entity* ent1, double x, double y, double z);
double entity_dist_block(struct entity* ent1, double x, double y, double z);
void getEntityCollision(struct entity* ent, struct boundingbox* bb);
void entity_collision_bounding_box(struct entity* entity, struct boundingbox* bb);
int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float shrink);

View File

@ -93,7 +93,7 @@ void lookHelper_tick(struct entity* entity) {
if (entity->ai == NULL || entity->ai->lookHelper_speedPitch == 0. || entity->ai->lookHelper_speedYaw == 0.) return;
double dx = entity->ai->lookHelper_x - entity->x;
struct boundingbox bb;
getEntityCollision(entity, &bb);
entity_collision_bounding_box(entity, &bb);
double dy = entity->ai->lookHelper_y - entity->y - ((bb.maxY - bb.minY) * .9); // TODO: real eye height
double dz = entity->ai->lookHelper_z - entity->z;
double horiz_dist = sqrt(dx * dx + dz * dz);
@ -234,7 +234,7 @@ int32_t ai_attackmelee(struct world* world, struct entity* entity, struct aitask
entity->ai->lookHelper_speedPitch = 30.;
entity->ai->lookHelper_x = entity->attacking->x;
struct boundingbox bb;
getEntityCollision(entity->attacking, &bb);
entity_collision_bounding_box(entity->attacking, &bb);
entity->ai->lookHelper_y = entity->attacking->y + ((bb.maxY - bb.minY) * .9); // TODO: real eye height
entity->ai->lookHelper_z = entity->attacking->z;
double dist = entity_distsq(entity->attacking, entity);
@ -249,12 +249,12 @@ int32_t ai_attackmelee(struct world* world, struct entity* entity, struct aitask
//TODO: set path
}
if (--amd->attackTick <= 0) amd->attackTick = 0;
struct entity_info* ei = getEntityInfo(entity->type);
struct entity_info* ei2 = getEntityInfo(entity->attacking->type);
struct entity_info* ei = entity_get_info(entity->type);
struct entity_info* ei2 = entity_get_info(entity->attacking->type);
float reach = ei->width * 2. * ei->width * 2. + ei2->width;
if (dist <= reach && amd->attackTick <= 0) {
amd->attackTick = 20;
swingArm(entity);
entity_animation(entity);
damageEntityWithItem(entity->attacking, entity, -1, NULL);
}
return 0;
@ -426,7 +426,7 @@ int32_t ai_skeletonriders(struct world* world, struct entity* entity, struct ait
int32_t ai_swimming(struct world* world, struct entity* entity, struct aitask* ai) {
//if (game_rand_float() < .8) {
jump(entity);
entity_jump(entity);
//}
return 0;
}
@ -475,9 +475,9 @@ int32_t ai_zombieattack(struct world* world, struct entity* entity, struct aitas
int ai_shouldattackmelee(struct world* world, struct entity* entity, struct aitask* ai) {
if (entity->attacking == NULL || entity->attacking->health <= 0. || (entity->type == ENT_PLAYER && (entity->data.player.player->gamemode == 1 || entity->data.player.player->gamemode == 3))) return 0;
struct entity_info* ei = getEntityInfo(entity->type);
struct entity_info* ei2 = getEntityInfo(entity->attacking->type);
if (ei == NULL || ei2 == NULL || !hasFlag(ei2, "livingbase")) return 0;
struct entity_info* ei = entity_get_info(entity->type);
struct entity_info* ei2 = entity_get_info(entity->attacking->type);
if (ei == NULL || ei2 == NULL || !entity_has_flag(ei2, "livingbase")) return 0;
return entity->attacking != NULL;
//float reach = ei->width * 2. * ei->width * 2. + ei2->width;
//return reach >= entity_distsq(entity->attacking, entity);
@ -602,14 +602,14 @@ int ai_shouldnearestattackabletarget(struct world* world, struct entity* entity,
struct entity* ce = NULL;
BEGIN_HASHMAP_ITERATION(world->entities)
struct entity* ie = value;
if (!hasFlag(getEntityInfo(ie->type), "livingbase") || ie == entity) continue;
if (!entity_has_flag(entity_get_info(ie->type), "livingbase") || ie == entity) continue;
double dsq = entity_distsq(entity, value);
if (ie->type == ENT_PLAYER) {
struct player* pl = ie->data.player.player;
if (pl->gamemode == 1 || pl->gamemode == 3 || pl->invulnerable) continue;
int sk = hasFlag(getEntityInfo(entity->type), "skeleton");
int zo = hasFlag(getEntityInfo(entity->type), "zombie");
int cr = hasFlag(getEntityInfo(entity->type), "creeper");
int sk = entity_has_flag(entity_get_info(entity->type), "skeleton");
int zo = entity_has_flag(entity_get_info(entity->type), "zombie");
int cr = entity_has_flag(entity_get_info(entity->type), "creeper");
if (sk || zo || cr) {
struct slot* hs = inventory_get(pl, pl->inventory, 5);
if (hs != NULL) {

View File

@ -27,26 +27,15 @@
#include <unistd.h>
#include <math.h>
struct entity_info* getEntityInfo(uint32_t id) {
struct entity_info* entity_get_info(uint32_t id) {
if (id < 0 || id > entity_infos->size) return NULL;
return entity_infos->data[id];
}
void swingArm(struct entity* entity) {
BEGIN_BROADCAST_DIST(entity, CHUNK_VIEW_DISTANCE * 16.)
struct packet* pkt = xmalloc(sizeof(struct packet));
pkt->id = PKT_PLAY_CLIENT_ANIMATION;
pkt->data.play_client.animation.entity_id = entity->id;
pkt->data.play_client.animation.animation = 0;
add_queue(bc_player->outgoing_packets, pkt);
END_BROADCAST(entity->world->players)
}
struct mempool* entities_pool;
void init_entities() {
entities_pool = mempool_new();
entity_infos = list_thread_new(64, entities_pool);
entity_infos = list_new(64, entities_pool);
entity_infos_by_name = hashmap_thread_new(64, entities_pool);
char* json_file = (char*) read_file_fully(entities_pool, "smelting.json", NULL);
if (json_file == NULL) {
errlog(delog, "Error reading entity information: %s\n", strerror(errno));
@ -120,15 +109,14 @@ void init_entities() {
if (tmp == NULL || tmp->type != JSON_ARRAY) {
goto entity_error;
}
info->flag_count = tmp->children_list->size;
info->flags = pmalloc(entities_pool, info->flag_count * sizeof(char*));
info->flags = hashset_new(8, entities_pool);
size_t flag_index = 0;
ITER_LLIST(tmp->children_list, flag_value) {
struct json_object* flag_json = flag_value;
if (flag_json == NULL || flag_json->type != JSON_STRING) {
goto entity_error;
}
info->flags[flag_index] = str_dup(str_tolower(str_trim(flag_json->data.string)), 0, entities_pool);
hashset_add(info->flags, str_dup(str_tolower(str_trim(flag_json->data.string)), 0, entities_pool));
++flag_index;
ITER_LLIST_END();
}
@ -150,54 +138,57 @@ void init_entities() {
if (tmp == NULL || tmp->type != JSON_STRING) goto entity_error;
info->dataname = str_dup(tmp->data.string, 0, entities_pool);
list_set(entity_infos, id, info);
hashmap_put(entity_infos_by_name, str_tolower(str_dup(info->dataname, 0, entities_pool)), info);
continue;
entity_error: ;
printf("[WARNING] Error Loading Entity \"%s\"! Skipped.\n", child_json->name);
ITER_LLIST_END();
}
pfree(json->pool);
getEntityInfo(ENT_ZOMBIE)->onAITick = &ai_handletasks;
getEntityInfo(ENT_ZOMBIE)->initAI = &initai_zombie;
getEntityInfo(ENT_FALLINGBLOCK)->onTick = &onTick_fallingblock;
getEntityInfo(ENT_PRIMEDTNT)->onTick = &onTick_tnt;
getEntityInfo(ENT_ITEM)->onTick = &tick_itemstack;
getEntityInfo(ENT_ARROW)->onTick = &tick_arrow;
getEntityInfo(ENT_SPECTRALARROW)->onTick = &tick_arrow;
getEntityInfo(ENT_COW)->onInteract = &onInteract_cow;
getEntityInfo(ENT_MUSHROOMCOW)->onInteract = &onInteract_mooshroom;
getEntityInfo(ENT_MINECARTRIDEABLE)->onSpawned = &onSpawned_minecart;
getEntityInfo(ENT_MINECARTCHEST)->onSpawned = &onSpawned_minecart;
getEntityInfo(ENT_MINECARTFURNACE)->onSpawned = &onSpawned_minecart;
getEntityInfo(ENT_MINECARTTNT)->onSpawned = &onSpawned_minecart;
getEntityInfo(ENT_MINECARTSPAWNER)->onSpawned = &onSpawned_minecart;
getEntityInfo(ENT_MINECARTHOPPER)->onSpawned = &onSpawned_minecart;
getEntityInfo(ENT_MINECARTCOMMANDBLOCK)->onSpawned = &onSpawned_minecart;
entity_get_info(ENT_ZOMBIE)->onAITick = &ai_handletasks;
entity_get_info(ENT_ZOMBIE)->initAI = &initai_zombie;
entity_get_info(ENT_FALLINGBLOCK)->onTick = &onTick_fallingblock;
entity_get_info(ENT_PRIMEDTNT)->onTick = &onTick_tnt;
entity_get_info(ENT_ITEM)->onTick = &tick_itemstack;
entity_get_info(ENT_ARROW)->onTick = &tick_arrow;
entity_get_info(ENT_SPECTRALARROW)->onTick = &tick_arrow;
entity_get_info(ENT_COW)->onInteract = &onInteract_cow;
entity_get_info(ENT_MUSHROOMCOW)->onInteract = &onInteract_mooshroom;
entity_get_info(ENT_MINECARTRIDEABLE)->onSpawned = &onSpawned_minecart;
entity_get_info(ENT_MINECARTCHEST)->onSpawned = &onSpawned_minecart;
entity_get_info(ENT_MINECARTFURNACE)->onSpawned = &onSpawned_minecart;
entity_get_info(ENT_MINECARTTNT)->onSpawned = &onSpawned_minecart;
entity_get_info(ENT_MINECARTSPAWNER)->onSpawned = &onSpawned_minecart;
entity_get_info(ENT_MINECARTHOPPER)->onSpawned = &onSpawned_minecart;
entity_get_info(ENT_MINECARTCOMMANDBLOCK)->onSpawned = &onSpawned_minecart;
}
uint32_t getIDFromEntityDataName(const char* dataname) {
for (size_t i = 0; i < entity_infos->size; i++) {
struct entity_info* ei = entity_infos->data[i];
if (ei == NULL) continue;
if (streq_nocase(ei->dataname, dataname)) return i;
void entity_animation(struct entity* entity, int animation_id) { // 0 to swing arm
BEGIN_BROADCAST_DIST(entity, CHUNK_VIEW_DISTANCE * 16.) {
struct packet* packet = packet_new(mempool_new(), PKT_PLAY_CLIENT_ANIMATION);
packet->data.play_client.animation.entity_id = entity->id;
packet->data.play_client.animation.animation = animation_id;
queue_push(bc_player->outgoing_packets, packet);
END_BROADCAST(entity->world->players);
}
return -1;
}
void getEntityCollision(struct entity* ent, struct boundingbox* bb) {
struct entity_info* ei = getEntityInfo(ent->type);
bb->minX = ent->x - ei->width / 2;
bb->maxX = ent->x + ei->width / 2;
bb->minZ = ent->z - ei->width / 2;
bb->maxZ = ent->z + ei->width / 2;
bb->minY = ent->y;
bb->maxY = ent->y + ei->height;
void entity_collision_bounding_box(struct entity* entity, struct boundingbox* bb) {
//TODO: plugin hook here?
bb->minX = entity->x - entity->info->width / 2;
bb->maxX = entity->x + entity->info->width / 2;
bb->minZ = entity->z - entity->info->width / 2;
bb->maxZ = entity->z + entity->info->width / 2;
bb->minY = entity->y;
bb->maxY = entity->y + entity->info->height;
}
void jump(struct entity* entity) {
void entity_jump(struct entity* entity) {
//TODO: plugin hook here?
//TODO: some entities may jump/swim diferently
if (entity->inWater || entity->inLava) entity->motY += .04;
else if (entity->on_ground) {
entity->motY = .42;
//entity sprinting jump?
}
}
@ -207,7 +198,8 @@ struct entity* entity_new(struct world* world, int32_t id, double x, double y, d
struct entity* entity = pcalloc(pool, sizeof(struct entity));
entity->pool = pool;
entity->world = world;
struct entity_info* info = getEntityInfo(type);
struct entity_info* info = entity_get_info(type);
entity->info = info;
entity->id = id;
entity->type = type;
entity->last_x = entity->x = x;
@ -238,71 +230,153 @@ double entity_dist_block(struct entity* ent1, double x, double y, double z) {
return sqrt((ent1->x - x) * (ent1->x - x) + (ent1->y - y) * (ent1->y - y) + (ent1->z - z) * (ent1->z - z));
}
struct packet* getEntityPropertiesPacket(struct entity* entity) {
struct packet* pkt = xmalloc(sizeof(struct packet));
pkt->id = PKT_PLAY_CLIENT_ENTITYPROPERTIES;
pkt->data.play_client.entityproperties.entity_id = entity->id;
pkt->data.play_client.entityproperties.number_of_properties = 0;
if (entity->type == ENT_PLAYER) {
}
return pkt;
}
void handleMetaByte(struct entity* ent, int index, signed char b) {
void entitymeta_handle_byte(struct entity* ent, int index, uint8_t b) {
if (index == 0) {
ent->sneaking = b & 0x02 ? 1 : 0;
ent->sprinting = b & 0x08 ? 1 : 0;
ent->usingItemMain = b & 0x10 ? 1 : 0;
ent->usingItemOff = 0;
} else if (hasFlag(getEntityInfo(ent->type), "living") && index == 6) {
} else if (hashset_has(ent->info->flags, "living") && index == 6) {
ent->usingItemMain = b & 0x01;
ent->usingItemOff = (b & 0x02) ? 1 : 0;
}
}
void handleMetaVarInt(struct entity* ent, int index, int32_t i) {
void entitymeta_handle_varint(struct entity* ent, int index, int32_t i) {
if ((ent->type == ENT_SKELETON || ent->type == ENT_SLIME || ent->type == ENT_LAVASLIME || ent->type == ENT_GUARDIAN) && index == 11) {
ent->subtype = i;
}
}
void handleMetaFloat(struct entity* ent, int index, float f) {
void entitymeta_handle_float(struct entity* ent, int index, float f) {
}
void handleMetaString(struct entity* ent, int index, char* str) {
void entitymeta_handle_string(struct entity* ent, int index, char* str) {
xfree(str);
}
void handleMetaSlot(struct entity* ent, int index, struct slot* slot) {
void entitymeta_handle_slot(struct entity* ent, int index, struct slot* slot) {
if (ent->type == ENT_ITEM && index == 6) {
ent->data.itemstack.slot = slot;
}
}
void handleMetaVector(struct entity* ent, int index, float f1, float f2, float f3) {
void entitymeta_handle_vector(struct entity* ent, int index, float f1, float f2, float f3) {
}
void handleMetaPosition(struct entity* ent, int index, struct encpos* pos) {
void entitymeta_handle_encpos(struct entity* ent, int index, struct encpos* pos) {
}
void handleMetaUUID(struct entity* ent, int index, struct uuid* pos) {
void entitymeta_handle_uuid(struct entity* ent, int index, struct uuid* pos) {
}
int hasFlag(struct entity_info* ei, char* flag) {
for (size_t i = 0; i < ei->flag_count; i++)
if (streq_nocase(ei->flags[i], flag)) return 1;
return 0;
void entitymeta_read(struct entity* ent, uint8_t* meta, size_t size) {
struct mempool* pool = mempool_new();
while (size > 0) {
uint8_t index = meta[0];
meta++;
size--;
if (index == 0xff || size == 0) break;
uint8_t type = meta[0];
meta++;
size--;
if (type == 0 || type == 6) {
if (size == 0) break;
uint8_t b = meta[0];
meta++;
size--;
entitymeta_handle_byte(ent, index, b);
} else if (type == 1 || type == 10 || type == 12) {
if ((type == 10 || type == 12) && size == 0) break;
int32_t vi = 0;
int r = readVarInt(&vi, meta, size);
meta += r;
size -= r;
entitymeta_handle_varint(ent, index, vi);
} else if (type == 2) {
if (size < 4) break;
float f = 0.;
memcpy(&f, meta, 4);
meta += 4;
size -= 4;
swapEndian(&f, 4);
entitymeta_handle_float(ent, index, f);
} else if (type == 3 || type == 4) {
char* str = NULL;
int r = readString(pool, &str, meta, size);
meta += r;
size -= r;
entitymeta_handle_string(ent, index, str);
} else if (type == 5) {
struct slot slot;
int r = readSlot(pool, &slot, meta, size);
meta += r;
size -= r;
entitymeta_handle_slot(ent, index, &slot);
} else if (type == 7) {
if (size < 12) break;
float f1 = 0.;
float f2 = 0.;
float f3 = 0.;
memcpy(&f1, meta, 4);
meta += 4;
size -= 4;
memcpy(&f2, meta, 4);
meta += 4;
size -= 4;
memcpy(&f3, meta, 4);
meta += 4;
size -= 4;
swapEndian(&f1, 4);
swapEndian(&f2, 4);
swapEndian(&f3, 4);
entitymeta_handle_vector(ent, index, f1, f2, f3);
} else if (type == 8) {
struct encpos pos;
if (size < sizeof(struct encpos)) break;
memcpy(&pos, meta, sizeof(struct encpos));
meta += sizeof(struct encpos);
size -= sizeof(struct encpos);
entitymeta_handle_encpos(ent, index, &pos);
} else if (type == 9) {
if (size == 0) break;
signed char b = meta[0];
meta++;
size--;
if (b) {
struct encpos pos;
if (size < sizeof(struct encpos)) break;
memcpy(&pos, meta, sizeof(struct encpos));
meta += sizeof(struct encpos);
size -= sizeof(struct encpos);
entitymeta_handle_encpos(ent, index, &pos);
}
} else if (type == 11) {
if (size == 0) break;
signed char b = meta[0];
meta++;
size--;
if (b) {
struct uuid uuid;
if (size < sizeof(struct uuid)) break;
memcpy(&uuid, meta, sizeof(struct uuid));
meta += sizeof(struct uuid);
size -= sizeof(struct uuid);
entitymeta_handle_uuid(ent, index, &uuid);
}
}
}
pfree(pool);
}
int entity_inFluid(struct entity* entity, uint16_t blk, float ydown, int meta_check) {
struct boundingbox pbb;
getEntityCollision(entity, &pbb);
entity_collision_bounding_box(entity, &pbb);
if (pbb.minX == pbb.maxX || pbb.minZ == pbb.maxZ || pbb.minY == pbb.maxY) return 0;
pbb.minX += .001;
pbb.minY += .001;
@ -342,7 +416,7 @@ void outputMetaByte(struct entity* ent, unsigned char** loc, size_t* size) {
(*loc)[*size] = ent->sneaking ? 0x02 : 0;
(*loc)[*size] |= ent->sprinting ? 0x08 : 0;
(*loc)[(*size)++] |= (ent->usingItemMain || ent->usingItemOff) ? 0x08 : 0;
if (hasFlag(getEntityInfo(ent->type), "livingbase")) {
if (entity_has_flag(entity_get_info(ent->type), "livingbase")) {
(*loc)[(*size)++] = 6;
(*loc)[(*size)++] = 0;
(*loc)[*size] = ent->usingItemMain ? 0x01 : 0;
@ -361,7 +435,7 @@ void outputMetaVarInt(struct entity* ent, unsigned char** loc, size_t* size) {
}
void outputMetaFloat(struct entity* ent, unsigned char** loc, size_t* size) {
if (hasFlag(getEntityInfo(ent->type), "livingbase")) {
if (entity_has_flag(entity_get_info(ent->type), "livingbase")) {
*loc = xrealloc(*loc, *size + 6);
(*loc)[(*size)++] = 7;
(*loc)[(*size)++] = 2;
@ -396,103 +470,6 @@ void outputMetaUUID(struct entity* ent, unsigned char** loc, size_t* size) {
}
void readMetadata(struct entity* ent, unsigned char* meta, size_t size) {
while (size > 0) {
unsigned char index = meta[0];
meta++;
size--;
if (index == 0xff || size == 0) break;
unsigned char type = meta[0];
meta++;
size--;
if (type == 0 || type == 6) {
if (size == 0) break;
signed char b = meta[0];
meta++;
size--;
handleMetaByte(ent, index, b);
} else if (type == 1 || type == 10 || type == 12) {
if ((type == 10 || type == 12) && size == 0) break;
int32_t vi = 0;
int r = readVarInt(&vi, meta, size);
meta += r;
size -= r;
handleMetaVarInt(ent, index, vi);
} else if (type == 2) {
if (size < 4) break;
float f = 0.;
memcpy(&f, meta, 4);
meta += 4;
size -= 4;
swapEndian(&f, 4);
handleMetaFloat(ent, index, f);
} else if (type == 3 || type == 4) {
char* str = NULL;
int r = readString(&str, meta, size);
meta += r;
size -= r;
handleMetaString(ent, index, str);
} else if (type == 5) {
struct slot slot;
int r = readSlot(&slot, meta, size);
meta += r;
size -= r;
handleMetaSlot(ent, index, &slot);
} else if (type == 7) {
if (size < 12) break;
float f1 = 0.;
float f2 = 0.;
float f3 = 0.;
memcpy(&f1, meta, 4);
meta += 4;
size -= 4;
memcpy(&f2, meta, 4);
meta += 4;
size -= 4;
memcpy(&f3, meta, 4);
meta += 4;
size -= 4;
swapEndian(&f1, 4);
swapEndian(&f2, 4);
swapEndian(&f3, 4);
handleMetaVector(ent, index, f1, f2, f3);
} else if (type == 8) {
struct encpos pos;
if (size < sizeof(struct encpos)) break;
memcpy(&pos, meta, sizeof(struct encpos));
meta += sizeof(struct encpos);
size -= sizeof(struct encpos);
handleMetaPosition(ent, index, &pos);
} else if (type == 9) {
if (size == 0) break;
signed char b = meta[0];
meta++;
size--;
if (b) {
struct encpos pos;
if (size < sizeof(struct encpos)) break;
memcpy(&pos, meta, sizeof(struct encpos));
meta += sizeof(struct encpos);
size -= sizeof(struct encpos);
handleMetaPosition(ent, index, &pos);
}
} else if (type == 11) {
if (size == 0) break;
signed char b = meta[0];
meta++;
size--;
if (b) {
struct uuid uuid;
if (size < sizeof(struct uuid)) break;
memcpy(&uuid, meta, sizeof(struct uuid));
meta += sizeof(struct uuid);
size -= sizeof(struct uuid);
handleMetaUUID(ent, index, &uuid);
}
}
}
}
void writeMetadata(struct entity* ent, unsigned char** data, size_t* size) {
*data = NULL;
*size = 0;
@ -562,7 +539,7 @@ void entity_adjustBoundingBox(struct world* world, struct entity* ent, struct ch
int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float shrink) {
if (entity->immovable) return 0;
struct boundingbox obb;
getEntityCollision(entity, &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;
@ -591,7 +568,7 @@ int moveEntity(struct entity* entity, double* mx, double* my, double* mz, float
obb.maxZ += *mz;
}
struct boundingbox pbb;
getEntityCollision(entity, &pbb);
entity_collision_bounding_box(entity, &pbb);
pbb.minX += shrink;
pbb.maxX -= shrink;
pbb.minY += shrink;
@ -788,7 +765,7 @@ void applyKnockback(struct entity* entity, float yaw, float strength) {
}
int damageEntityWithItem(struct entity* attacked, struct entity* attacker, uint8_t slot_index, struct slot* item) {
if (attacked == NULL || attacked->invincibilityTicks > 0 || !hasFlag(getEntityInfo(attacked->type), "livingbase") || attacked->health <= 0.) return 0;
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 (item != NULL) {
@ -829,7 +806,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 || !hasFlag(getEntityInfo(attacked->type), "livingbase") || attacked->health <= 0.) return 0;
if (attacked == NULL || damage <= 0. || attacked->invincibilityTicks > 0 || !entity_has_flag(entity_get_info(attacked->type), "livingbase") || attacked->health <= 0.) return 0;
float armor = 0;
if (attacked->type == ENT_PLAYER) {
struct player* player = attacked->data.player.player;
@ -890,7 +867,7 @@ int damageEntity(struct entity* attacked, float damage, int armorable) {
}
if (player->open_inventory != NULL) player_closeWindow(player, player->open_inventory->windowID);
} else {
struct entity_info* ei = getEntityInfo(attacked->type);
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);
@ -923,7 +900,7 @@ int damageEntity(struct entity* attacked, float damage, int armorable) {
}
void healEntity(struct entity* healed, float amount) {
if (healed == NULL || amount <= 0. || healed->health <= 0. || !hasFlag(getEntityInfo(healed->type), "livingbase")) return;
if (healed == NULL || amount <= 0. || healed->health <= 0. || !entity_has_flag(entity_get_info(healed->type), "livingbase")) return;
float oh = healed->health;
healed->health += amount;
if (healed->health > healed->maxHealth) healed->health = 20.;
@ -939,7 +916,7 @@ void healEntity(struct entity* healed, float amount) {
int entity_inBlock(struct entity* ent, block blk) { // blk = 0 for any block
struct boundingbox obb;
getEntityCollision(ent, &obb);
entity_collision_bounding_box(ent, &obb);
if (obb.minX == obb.maxX || obb.minY == obb.maxY || obb.minZ == obb.maxZ) return 0;
obb.minX += .01;
obb.minY += .01;
@ -976,7 +953,7 @@ int entity_inBlock(struct entity* ent, block blk) { // blk = 0 for any block
void pushOutOfBlocks(struct entity* ent) {
if (!entity_inBlock(ent, 0)) return;
struct boundingbox ebb;
getEntityCollision(ent, &ebb);
entity_collision_bounding_box(ent, &ebb);
double x = ent->x;
double y = (ebb.maxY + ebb.minY) / 2.;
double z = ent->z;
@ -1046,7 +1023,7 @@ void tick_entity(struct world* world, struct entity* entity) {
}
entity->age++;
if (entity->invincibilityTicks > 0) entity->invincibilityTicks--;
struct entity_info* ei = getEntityInfo(entity->type);
struct entity_info* ei = entity_get_info(entity->type);
if (entity->ai != NULL) {
if (ei != NULL && ei->onAITick != NULL) ei->onAITick(world, entity);
lookHelper_tick(entity);
@ -1075,7 +1052,7 @@ void tick_entity(struct world* world, struct entity* entity) {
}
if (entity->type == ENT_ITEM) gravity = .04;
else if (ar) gravity = .05;
else if (hasFlag(getEntityInfo(entity->type), "livingbase")) {
else if (entity_has_flag(entity_get_info(entity->type), "livingbase")) {
if (entity->inLava) {
entity->motX *= .5;
entity->motY *= .5;
@ -1109,7 +1086,7 @@ void tick_entity(struct world* world, struct entity* entity) {
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 (hasFlag(getEntityInfo(entity->type), "livingbase")) {
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;

View File

@ -56,7 +56,7 @@ void game_load_player(struct player* to, struct player* from) {
void game_load_entity(struct player* to, struct entity* from) {
struct entity_info* info = getEntityInfo(from->type);
struct entity_info* info = entity_get_info(from->type);
uint32_t packet_type = info->spawn_packet;
int8_t entitity_type_id = (int8_t) info->spawn_packet_id;
if (packet_type == PKT_PLAY_CLIENT_SPAWNOBJECT) {

View File

@ -396,13 +396,13 @@ void player_tick(struct player* player) {
int player_onGround(struct player* player) {
struct entity* entity = player->entity;
struct boundingbox obb;
getEntityCollision(entity, &obb);
entity_collision_bounding_box(entity, &obb);
if (obb.minX == obb.maxX || obb.minZ == obb.maxZ || obb.minY == obb.maxY) {
return 0;
}
obb.minY += -.08;
struct boundingbox pbb;
getEntityCollision(entity, &pbb);
entity_collision_bounding_box(entity, &pbb);
double ny = -.08;
for (int32_t x = floor(obb.minX); x < floor(obb.maxX + 1.); x++) {
for (int32_t z = floor(obb.minZ); z < floor(obb.maxZ + 1.); z++) {

View File

@ -591,7 +591,7 @@ void player_packet_handle_useentity(struct player* player, struct mempool* pool,
struct entity* entity = world_get_entity(player->world, packet->target);
if (packet->type == 0) {
if (entity != NULL && entity != player->entity && entity->health > 0. && entity->world == player->world && entity_dist(entity, player->entity) < 4.) {
struct entity_info* info = getEntityInfo(entity->type);
struct entity_info* info = entity_get_info(entity->type);
if (info != NULL && info->onInteract != NULL) {
pthread_mutex_lock(&player->inventory->mutex);
(*info->onInteract)(player->world, entity, player, inventory_get(player, player->inventory, 36 + player->currentItem), (int16_t) (36 + player->currentItem));
@ -995,8 +995,8 @@ void player_packet_handle_playerblockplacement(struct player* player, struct mem
// TODO: localize entity information!
ITER_MAP (player->world->entities) {
struct entity* ent = (struct entity*) value;
if (ent == NULL || entity_distsq_block(ent, x, y, z) > 8. * 8. || !hasFlag(getEntityInfo(ent->type), "livingbase")) continue;
getEntityCollision(ent, &entity_bounds);
if (ent == NULL || entity_distsq_block(ent, x, y, z) > 8. * 8. || !entity_has_flag(entity_get_info(ent->type), "livingbase")) continue;
entity_collision_bounding_box(ent, &entity_bounds);
entity_bounds.minX += .01;
entity_bounds.minY += .01;
entity_bounds.minZ += .01;

View File

@ -1025,7 +1025,7 @@ void world_spawn_entity(struct world* world, struct entity* entity) {
entity->attackers = hashmap_new(4, entity->pool);
}
hashmap_putint(world->entities, entity->id, entity);
struct entity_info* info = getEntityInfo(entity->type);
struct entity_info* info = entity_get_info(entity->type);
if (info != NULL) {
if (info->initAI != NULL) {
entity->ai = pcalloc(entity->pool, sizeof(struct aicontext));