eco2d/code/games/survival/src/system_mob.c

119 lines
2.9 KiB
C
Raw Normal View History

2023-01-31 17:41:01 +00:00
void MobDetectPlayers(ecs_iter_t *it) {
Position *p = ecs_field(it, Position, 1);
for (int i = 0; i < it->count; i++) {
float closest_ent_dist = ZPL_F32_MAX;
uint64_t closest_ent = 0;
ecs_iter_t pit = ecs_query_iter(world_ecs(), world_ecs_player());
while (ecs_query_next(&pit)) {
Position *p2 = ecs_field(&pit, Position, 2);
for (int j = 0; j < pit.count; j++) {
float dx = p2->x - p[j].x;
float dy = p2->y - p[j].y;
float range = (dx*dx + dy*dy);
if (range < closest_ent_dist)
closest_ent = pit.entities[j];
}
}
if (!closest_ent)
continue;
ecs_set(it->world, it->entities[i], MobHuntPlayer, { .plr = closest_ent });
}
}
2023-02-01 14:28:30 +00:00
void MobDetectPlayers1(ecs_iter_t *it) {
2023-02-02 12:24:16 +00:00
2023-02-01 14:28:30 +00:00
}
2023-01-31 17:41:01 +00:00
#define MOB_MOVEMENT_SPEED 300.0f
void MobMovement(ecs_iter_t *it) {
Velocity *v = ecs_field(it, Velocity, 1);
Position *p = ecs_field(it, Position, 2);
MobHuntPlayer *m = ecs_field(it, MobHuntPlayer, 3);
for (int i = 0; i < it->count; i++) {
const Position *p2 = ecs_get(it->world, m->plr, Position);
zpl_vec2 pos1 = { .x = p[i].x, .y = p[i].y };
zpl_vec2 pos2 = { .x = p2->x, .y = p2->y };
zpl_vec2 dir;
zpl_vec2_sub(&dir, pos2, pos1);
zpl_vec2_norm(&dir, dir);
v[i].x += dir.x*(MOB_MOVEMENT_SPEED*safe_dt(it));
v[i].y += dir.y*(MOB_MOVEMENT_SPEED*safe_dt(it));
entity_wake(it->entities[i]);
}
}
2023-02-03 10:22:15 +00:00
#define MOB_MELEE_DIST 8000.0f
#define MOB_MELEE_DMG 8.5f
2023-01-31 17:41:01 +00:00
#define MOB_ATK_DELAY 10
#define MOB_DESPAWN_TIMER 20*60*5
2023-01-31 17:41:01 +00:00
void MobMeleeAtk(ecs_iter_t *it) {
Position *p = ecs_field(it, Position, 1);
Mob *mob = ecs_field(it, Mob, 2);
MobHuntPlayer *m = ecs_field(it, MobHuntPlayer, 3);
for (int i = 0; i < it->count; i++) {
if (mob[i].atk_delay > 0) {
TICK_VAR(mob[i].atk_delay);
continue;
}
const Position *p2 = ecs_get(it->world, m->plr, Position);
float dx = p2->x - p[i].x;
float dy = p2->y - p[i].y;
float range = (dx*dx + dy*dy);
if (range < MOB_MELEE_DIST) {
Health *health = ecs_get_mut(it->world, m->plr, Health);
2023-02-03 06:28:17 +00:00
health->dmg += MOB_MELEE_DMG;
2023-02-03 10:22:15 +00:00
mob[i].atk_delay = MOB_ATK_DELAY;
2023-01-31 17:41:01 +00:00
}
}
2023-02-03 06:28:17 +00:00
}
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);
2023-02-03 06:28:17 +00:00
for (int i = 0; i < it->count; 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);
2023-02-03 08:54:16 +00:00
pkt_code_send(0, 0, (pkt_send_code){
.code = SURV_CODE_SHOW_NOTIF,
.data = "mob died"
});
2023-02-03 06:28:17 +00:00
}
}
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) {
}