render mobs via spritesheet + blood splatters

master
Dominik Madarász 2023-07-25 22:18:19 +02:00
parent 9c669407fc
commit d864661e65
6 changed files with 49 additions and 19 deletions

View File

@ -241,6 +241,7 @@ typedef struct { char _unused; } SeeksCompanion;
// survival comps
typedef struct {
uint8_t atk_delay;
uint16_t despawn_timer;
} Mob;
typedef struct {
uint64_t plr;

View File

@ -66,15 +66,15 @@ uint64_t craftbench_spawn(void) {
//------------------------------------------------------------------------
uint64_t creature_spawn(void) {
ecs_entity_t e = entity_spawn(EKIND_DEMO_NPC);
Creature *c = ecs_get_mut(world_ecs(), e, Creature);
c->hunger_satisfied = 0;
c->mating_satisfied = rand() % 1800;
c->life_remaining = 500 + rand() % 5200;
return (uint64_t)e;
}
ecs_entity_t e = entity_spawn(EKIND_DEMO_NPC);
Creature *c = ecs_get_mut(world_ecs(), e, Creature);
c->hunger_satisfied = 0;
c->mating_satisfied = rand() % 1800;
c->life_remaining = 500 + rand() % 5200;
return (uint64_t)e;
}
//------------------------------------------------------------------------
@ -127,6 +127,7 @@ uint64_t mob_spawn(void) {
ecs_add(world_ecs(), e, Mob);
ecs_set(world_ecs(), e, Health, { 60, 60, 0 });
ecs_set(world_ecs(), e, PhysicsBody, { .kind = PHYS_AABB, .mass = 1.0f });
ecs_set(world_ecs(), e, Sprite, { .frame = 101 + (rand()%3) });
return (uint64_t)e;
}

View File

@ -46,7 +46,7 @@ static inline bool BlockCollisionIslandTest(Position *p, librg_chunk ch_p) {
collision_island islands[16];
uint8_t num_islands = world_chunk_collision_islands(ch_p, islands);
for (uint8_t i = 0; i < num_islands; i++) {
#if 1
#if 0
{
zpl_printf("px %f py %f minx %f miny %f\n", p->x, p->y, islands[i].minx, islands[i].miny);
debug_v2 a = {islands[i].minx, islands[i].miny};

View File

@ -15,16 +15,17 @@ static ecs_query_t *ecs_mobpos_query = NULL;
#include "system_weapon.c"
void mob_systems(ecs_world_t *ecs) {
ECS_SYSTEM_TICKED_EX(ecs, MobDetectPlayers, EcsPostUpdate, 100.0f, components.Position, components.Mob);
ECS_SYSTEM(ecs, MobMovement, EcsPostUpdate, components.Velocity, components.Position, components.MobHuntPlayer);
ECS_SYSTEM_TICKED(ecs, MobMeleeAtk, EcsPostUpdate, components.Position, components.Mob, components.MobHuntPlayer, components.MobMelee);
ECS_SYSTEM_TICKED_EX(ecs, MobDetectPlayers, EcsPostUpdate, 100.0f, components.Position, components.Mob, !components.Dead);
ECS_SYSTEM(ecs, MobMovement, EcsPostUpdate, components.Velocity, components.Position, components.MobHuntPlayer, !components.Dead);
ECS_SYSTEM_TICKED(ecs, MobMeleeAtk, EcsPostUpdate, components.Position, components.Mob, components.MobHuntPlayer, components.MobMelee, !components.Dead);
ECS_SYSTEM_TICKED(ecs, MobDespawnDead, EcsPostUpdate, components.Mob, components.Dead);
//NOTE(DavoSK): weapons
ecs_mobpos_query = ecs_query_new(world_ecs(), "components.Mob, components.Position, components.Health, components.Velocity");
ecs_mobpos_query = ecs_query_new(world_ecs(), "components.Mob, components.Position, components.Health, components.Velocity, !components.Dead");
ECS_SYSTEM_TICKED(ecs, WeaponKnifeMechanic, EcsPostUpdate, components.WeaponKnife, components.Position, components.Input, !components.Dead);
ECS_SYSTEM_TICKED(ecs, WeaponProjectileHit, EcsPostUpdate, components.WeaponProjectile, components.Position, components.Rotation);
ECS_SYSTEM_TICKED(ecs, WeaponProjectileExpire, EcsPostUpdate, components.WeaponProjectile, components.Position);
ECS_OBSERVER(ecs, MobOnDead, EcsOnAdd, components.Mob, components.Dead);
ECS_OBSERVER(ecs, MobOnDead, EcsOnAdd, components.Mob, components.Sprite, components.Velocity, components.Dead);
}
void game_input() {

View File

@ -88,10 +88,12 @@ void renderer_draw_entry(uint64_t key, entity_view *data, game_world_render_entr
float x = data->x;
float y = data->y;
//DrawCircleEco(x, y, size, ColorAlpha(PINK, data->tran_time));
DrawTextureRec(GetSpriteTexture2D(assets_find(ASSET_MOB)), ASSET_SRC_RECT(), (Vector2){data->x-(WORLD_BLOCK_SIZE/2), data->y-(WORLD_BLOCK_SIZE/2)}, ColorAlpha(WHITE, data->tran_time));
// DrawTextureRec(GetSpriteTexture2D(assets_find(data->frame)), ASSET_SRC_RECT(), (Vector2){data->x-(WORLD_BLOCK_SIZE/2), data->y-(WORLD_BLOCK_SIZE/2)}, ColorAlpha(WHITE, data->tran_time));
DrawSpriteEco(&main_sprite_sheet, data->frame, x, y, 0.0f, 2.0f, WHITE);
float health = (data->hp / data->max_hp);
if (health < 1.0f) {
if (health > 0.0f && health < 1.0f) {
DrawRectangleEco(x-32, y-48, 64, 8, ColorAlpha(BLACK, data->tran_time));
DrawRectangleEco(x-32, y-48, 64*health, 8, ColorAlpha(RED, data->tran_time));
}

View File

@ -56,6 +56,7 @@ void MobMovement(ecs_iter_t *it) {
#define MOB_MELEE_DIST 8000.0f
#define MOB_MELEE_DMG 8.5f
#define MOB_ATK_DELAY 10
#define MOB_DESPAWN_TIMER 20*60*5
void MobMeleeAtk(ecs_iter_t *it) {
Position *p = ecs_field(it, Position, 1);
@ -82,12 +83,36 @@ void MobMeleeAtk(ecs_iter_t *it) {
}
void MobOnDead(ecs_iter_t *it) {
Mob *mob = ecs_field(it, Mob, 1);
Sprite *spr = ecs_field(it, Sprite, 2);
Velocity *v = ecs_field(it, Velocity, 3);
for (int i = 0; i < it->count; i++) {
entity_despawn(it->entities[i]);
mob[i].despawn_timer = MOB_DESPAWN_TIMER;
spr[i].frame = 3 + (rand()%5);
v[i] = (Velocity){0.0f, 0.0f};
ecs_remove(it->world, it->entities[i], PhysicsBody);
pkt_code_send(0, 0, (pkt_send_code){
.code = SURV_CODE_SHOW_NOTIF,
.data = "mob died"
});
}
}
}
void MobDespawnDead(ecs_iter_t *it) {
Mob *mob = ecs_field(it, Mob, 1);
for (int i = 0; i < it->count; i++) {
if (mob[i].despawn_timer > 0) {
TICK_VAR(mob[i].despawn_timer);
continue;
}
entity_despawn(it->entities[i]);
}
}
void MobSpawner(ecs_iter_t *it) {
}