producer supports output node push

efd/v1
Dominik Madarász 2022-10-17 18:28:40 +02:00
parent 3f6235e8a4
commit 6385ea4461
2 changed files with 106 additions and 40 deletions

View File

@ -1,14 +1,72 @@
static inline
asset_id FetchAssetAtPos(float x, float y) {
world_block_lookup lookup = world_block_from_realpos(x, y);
if (lookup.is_outer) {
return blocks_get_asset(lookup.bid);
}
return ASSET_INVALID;
}
static inline
bool CheckForNearbyBelt(Position *p, float *dx, float *dy) {
asset_id bid = ASSET_INVALID;
float o = WORLD_BLOCK_SIZE;
// up
bid = FetchAssetAtPos(p->x + 0, p->y - o);
{
debug_v2 a = {p->x, p->y};
debug_v2 b = {p->x, p->y-WORLD_BLOCK_SIZE};
debug_push_line(a, b, 0xFFFFFFFF);
}
if (bid == ASSET_BELT_UP) {
*dx = 0;
*dy = -o;
return true;
}
// down
bid = FetchAssetAtPos(p->x + 0, p->y + o);
if (bid == ASSET_BELT_DOWN) {
*dx = 0;
*dy = o;
return true;
}
// left
bid = FetchAssetAtPos(p->x - o, p->y + 0);
if (bid == ASSET_BELT_LEFT) {
*dx = -o;
*dy = 0;
return true;
}
// right
bid = FetchAssetAtPos(p->x + o, p->y + 0);
if (bid == ASSET_BELT_RIGHT) {
*dx = o;
*dy = 0;
return true;
}
return false;
}
void ProduceItems(ecs_iter_t *it) { void ProduceItems(ecs_iter_t *it) {
ItemContainer *storage = ecs_field(it, ItemContainer, 1); ItemContainer *storage = ecs_field(it, ItemContainer, 1);
Producer *producer = ecs_field(it, Producer, 2); Producer *producer = ecs_field(it, Producer, 2);
Position *p = ecs_field(it, Position, 3); Position *p = ecs_field(it, Position, 3);
Device *d = ecs_field(it, Device, 4); Device *d = ecs_field(it, Device, 4);
for (int i = 0; i < it->count; i++) { for (int i = 0; i < it->count; i++) {
float push_dx=0.0f, push_dy=0.0f;
bool has_output_node = CheckForNearbyBelt(&p[i], &push_dx, &push_dy);
for (int j = 0; j < ITEMS_CONTAINER_SIZE; j++) { for (int j = 0; j < ITEMS_CONTAINER_SIZE; j++) {
ecs_entity_t item_slot_ent = storage[i].items[j]; ecs_entity_t item_slot_ent = storage[i].items[j];
Item *item = item_get_data(item_slot_ent); Item *item = item_get_data(item_slot_ent);
const EnergySource *energy_source = 0; const EnergySource *energy_source = 0;
if ((energy_source = ecs_get_if(it->world, item_slot_ent, EnergySource))) { if ((energy_source = ecs_get_if(it->world, item_slot_ent, EnergySource))) {
if (energy_source->kind == d->asset) { if (energy_source->kind == d->asset) {
@ -18,13 +76,21 @@ void ProduceItems(ecs_iter_t *it) {
} }
continue; continue;
} }
// if (producer[i].energy_level <= 0.0f) continue; // if (producer[i].energy_level <= 0.0f) continue;
if (producer[i].process_time < game_time()) { if (producer[i].process_time < game_time()) {
if (producer[i].processed_item > 0) { if (producer[i].processed_item > 0) {
uint64_t e = item_spawn(producer[i].processed_item, 1); uint64_t e = item_spawn(producer[i].processed_item, 1);
entity_set_position(e, p[i].x, p[i].y);
producer[i].processed_item = 0; producer[i].processed_item = 0;
if (has_output_node) {
entity_set_position(e, p[i].x+push_dx, p[i].y+push_dy);
Velocity *e_vel = ecs_get_mut_ex(it->world, e, Velocity);
e_vel->x = push_dx;
e_vel->y = push_dy;
} else {
entity_set_position(e, p[i].x, p[i].y);
}
} else { } else {
const Ingredient *ing = 0; const Ingredient *ing = 0;
if ((ing = ecs_get_if(it->world, item_slot_ent, Ingredient))) { if ((ing = ecs_get_if(it->world, item_slot_ent, Ingredient))) {
@ -42,10 +108,10 @@ void ProduceItems(ecs_iter_t *it) {
} }
} }
} }
d[i].progress_active = (producer[i].processed_item > 0); d[i].progress_active = (producer[i].processed_item > 0);
d[i].progress_value = 1.0f-((producer[i].process_time - game_time()) / game_rules.furnace_cook_time); d[i].progress_value = 1.0f-((producer[i].process_time - game_time()) / game_rules.furnace_cook_time);
if (d[i].progress_active) { if (d[i].progress_active) {
entity_wake(it->entities[i]); entity_wake(it->entities[i]);
} }

View File

@ -5,10 +5,10 @@ void LeaveVehicle(ecs_iter_t *it) {
Input *in = ecs_field(it, Input, 1); Input *in = ecs_field(it, Input, 1);
IsInVehicle *vehp = ecs_field(it, IsInVehicle, 2); IsInVehicle *vehp = ecs_field(it, IsInVehicle, 2);
Velocity *v = ecs_field(it, Velocity, 3); Velocity *v = ecs_field(it, Velocity, 3);
for (int i = 0; i < it->count; i++) { for (int i = 0; i < it->count; i++) {
if (!in[i].use) continue; if (!in[i].use) continue;
Vehicle *veh = 0; Vehicle *veh = 0;
if ((veh = ecs_get_mut_if_ex(it->world, vehp->veh, Vehicle))) { if ((veh = ecs_get_mut_if_ex(it->world, vehp->veh, Vehicle))) {
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
@ -17,16 +17,16 @@ void LeaveVehicle(ecs_iter_t *it) {
break; break;
} }
} }
in[i].use = false; in[i].use = false;
ecs_remove(it->world, it->entities[i], IsInVehicle); ecs_remove(it->world, it->entities[i], IsInVehicle);
// NOTE(zaklaus): push passenger out // NOTE(zaklaus): push passenger out
{ {
float px = zpl_cos(veh->heading)*400.0f; float px = zpl_cos(veh->heading)*400.0f;
float py = zpl_sin(veh->heading)*400.0f; float py = zpl_sin(veh->heading)*400.0f;
v->x += py; v[i].x += py;
v->y -= px; v[i].y -= px;
} }
} else { } else {
ZPL_PANIC("unreachable code"); ZPL_PANIC("unreachable code");
@ -37,31 +37,31 @@ void LeaveVehicle(ecs_iter_t *it) {
void EnterVehicle(ecs_iter_t *it) { void EnterVehicle(ecs_iter_t *it) {
Input *in = ecs_field(it, Input, 1); Input *in = ecs_field(it, Input, 1);
Position *p = ecs_field(it, Position, 2); Position *p = ecs_field(it, Position, 2);
for (int i = 0; i < it->count; i++) { for (int i = 0; i < it->count; i++) {
if (!in[i].use) continue; if (!in[i].use) continue;
size_t ents_count; size_t ents_count;
int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 2); int64_t *ents = world_chunk_query_entities(it->entities[i], &ents_count, 2);
bool has_entered_veh = false; bool has_entered_veh = false;
for (size_t j = 0; j < ents_count; j++) { for (size_t j = 0; j < ents_count; j++) {
Vehicle *veh = 0; Vehicle *veh = 0;
if (has_entered_veh) break; if (has_entered_veh) break;
veh = ecs_get_mut_if_ex(it->world, ents[j], Vehicle); veh = ecs_get_mut_if_ex(it->world, ents[j], Vehicle);
if ((veh = ecs_get_mut_if_ex(it->world, ents[j], Vehicle))) { if ((veh = ecs_get_mut_if_ex(it->world, ents[j], Vehicle))) {
Position const* p2 = ecs_get(it->world, ents[j], Position); Position const* p2 = ecs_get(it->world, ents[j], Position);
float dx = p2->x - p[i].x; float dx = p2->x - p[i].x;
float dy = p2->y - p[i].y; float dy = p2->y - p[i].y;
float range = zpl_sqrt(dx*dx + dy*dy); float range = zpl_sqrt(dx*dx + dy*dy);
if (range <= game_rules.veh_enter_radius) { if (range <= game_rules.veh_enter_radius) {
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
if (veh->seats[k] != 0) continue; if (veh->seats[k] != 0) continue;
// NOTE(zaklaus): We can enter the vehicle, yay! // NOTE(zaklaus): We can enter the vehicle, yay!
veh->seats[k] = it->entities[i]; veh->seats[k] = it->entities[i];
ecs_set(it->world, it->entities[i], IsInVehicle, { ecs_set(it->world, it->entities[i], IsInVehicle, {
@ -82,27 +82,27 @@ void VehicleHandling(ecs_iter_t *it) {
Vehicle *veh = ecs_field(it, Vehicle, 1); Vehicle *veh = ecs_field(it, Vehicle, 1);
Position *p = ecs_field(it, Position, 2); Position *p = ecs_field(it, Position, 2);
Velocity *v = ecs_field(it, Velocity, 3); Velocity *v = ecs_field(it, Velocity, 3);
for (int i = 0; i < it->count; i++) { for (int i = 0; i < it->count; i++) {
Vehicle *car = &veh[i]; Vehicle *car = &veh[i];
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
// NOTE(zaklaus): Perform seat cleanup // NOTE(zaklaus): Perform seat cleanup
if (!world_entity_valid(veh[i].seats[j])) { if (!world_entity_valid(veh[i].seats[j])) {
veh[i].seats[j] = 0; veh[i].seats[j] = 0;
continue; continue;
} }
ecs_entity_t pe = veh[i].seats[j]; ecs_entity_t pe = veh[i].seats[j];
// NOTE(zaklaus): Handle driver input // NOTE(zaklaus): Handle driver input
if (j == 0) { if (j == 0) {
Input const* in = ecs_get(it->world, pe, Input); Input const* in = ecs_get(it->world, pe, Input);
car->force += zpl_lerp(0.0f, in->y * game_rules.vehicle_force, (zpl_sign(in->y) == zpl_sign(car->force) ? 1.0f : 3.0f) * game_rules.vehicle_accel*safe_dt(it)); car->force += zpl_lerp(0.0f, in->y * game_rules.vehicle_force, (zpl_sign(in->y) == zpl_sign(car->force) ? 1.0f : 3.0f) * game_rules.vehicle_accel*safe_dt(it));
if (in->sprint) { if (in->sprint) {
car->force = zpl_lerp(car->force, 0.0f, game_rules.vehicle_brake_force*safe_dt(it)); car->force = zpl_lerp(car->force, 0.0f, game_rules.vehicle_brake_force*safe_dt(it));
if (zpl_abs(car->force) < 5.5f) if (zpl_abs(car->force) < 5.5f)
car->force = 0.0f; car->force = 0.0f;
} }
@ -112,28 +112,28 @@ void VehicleHandling(ecs_iter_t *it) {
car->steer = zpl_clamp(car->steer, -60.0f, 60.0f); car->steer = zpl_clamp(car->steer, -60.0f, 60.0f);
} }
} }
car->force = zpl_clamp(car->force, car->reverse_speed, car->speed); car->force = zpl_clamp(car->force, car->reverse_speed, car->speed);
// NOTE(zaklaus): Vehicle physics // NOTE(zaklaus): Vehicle physics
float fr_x = p[i].x + (car->wheel_base/2.0f) * zpl_cos(car->heading); float fr_x = p[i].x + (car->wheel_base/2.0f) * zpl_cos(car->heading);
float fr_y = p[i].y + (car->wheel_base/2.0f) * zpl_sin(car->heading); float fr_y = p[i].y + (car->wheel_base/2.0f) * zpl_sin(car->heading);
float bk_x = p[i].x - (car->wheel_base/2.0f) * zpl_cos(car->heading); float bk_x = p[i].x - (car->wheel_base/2.0f) * zpl_cos(car->heading);
float bk_y = p[i].y - (car->wheel_base/2.0f) * zpl_sin(car->heading); float bk_y = p[i].y - (car->wheel_base/2.0f) * zpl_sin(car->heading);
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y); world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
float drag = zpl_clamp(blocks_get_drag(lookup.bid), 0.0f, 1.0f); float drag = zpl_clamp(blocks_get_drag(lookup.bid), 0.0f, 1.0f);
bk_x += car->force * drag * zpl_cos(car->heading) * safe_dt(it)*game_rules.vehicle_power; bk_x += car->force * drag * zpl_cos(car->heading) * safe_dt(it)*game_rules.vehicle_power;
bk_y += car->force * drag * zpl_sin(car->heading) * safe_dt(it)*game_rules.vehicle_power; bk_y += car->force * drag * zpl_sin(car->heading) * safe_dt(it)*game_rules.vehicle_power;
fr_x += car->force * drag * zpl_cos(car->heading + zpl_to_radians(car->steer)) * safe_dt(it)*game_rules.vehicle_power; fr_x += car->force * drag * zpl_cos(car->heading + zpl_to_radians(car->steer)) * safe_dt(it)*game_rules.vehicle_power;
fr_y += car->force * drag * zpl_sin(car->heading + zpl_to_radians(car->steer)) * safe_dt(it)*game_rules.vehicle_power; fr_y += car->force * drag * zpl_sin(car->heading + zpl_to_radians(car->steer)) * safe_dt(it)*game_rules.vehicle_power;
v[i].x += ((fr_x + bk_x) / 2.0f - p[i].x); v[i].x += ((fr_x + bk_x) / 2.0f - p[i].x);
v[i].y += ((fr_y + bk_y) / 2.0f - p[i].y); v[i].y += ((fr_y + bk_y) / 2.0f - p[i].y);
car->heading = zpl_arctan2(fr_y - bk_y, fr_x - bk_x); car->heading = zpl_arctan2(fr_y - bk_y, fr_x - bk_x);
float check_x = p[i].x+PHY_LOOKAHEAD(v[i].x); float check_x = p[i].x+PHY_LOOKAHEAD(v[i].x);
float check_y = p[i].y+PHY_LOOKAHEAD(v[i].y); float check_y = p[i].y+PHY_LOOKAHEAD(v[i].y);
world_block_lookup lookahead = world_block_from_realpos(check_x, check_y); world_block_lookup lookahead = world_block_from_realpos(check_x, check_y);
@ -146,11 +146,11 @@ void VehicleHandling(ecs_iter_t *it) {
car->force = 0.0f; car->force = 0.0f;
} }
} }
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
if (!world_entity_valid(veh[i].seats[j])) continue; if (!world_entity_valid(veh[i].seats[j])) continue;
ecs_entity_t pe = veh[i].seats[j]; ecs_entity_t pe = veh[i].seats[j];
// NOTE(zaklaus): Update passenger position // NOTE(zaklaus): Update passenger position
{ {
Velocity *v2 = ecs_get_mut_ex(it->world, pe, Velocity); Velocity *v2 = ecs_get_mut_ex(it->world, pe, Velocity);
@ -158,22 +158,22 @@ void VehicleHandling(ecs_iter_t *it) {
*v2 = v[i]; *v2 = v[i];
} }
} }
if (zpl_abs(car->force) > ENTITY_ACTION_VELOCITY_THRESHOLD) { if (zpl_abs(car->force) > ENTITY_ACTION_VELOCITY_THRESHOLD) {
entity_wake(it->entities[i]); entity_wake(it->entities[i]);
} }
{ {
debug_v2 b2 = {p[i].x + zpl_cos(car->heading)*(car->wheel_base), p[i].y + zpl_sin(car->heading)*(car->wheel_base)}; debug_v2 b2 = {p[i].x + zpl_cos(car->heading)*(car->wheel_base), p[i].y + zpl_sin(car->heading)*(car->wheel_base)};
debug_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF); debug_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF);
// NOTE(zaklaus): force // NOTE(zaklaus): force
{ {
float dx = zpl_cos(car->heading); float dx = zpl_cos(car->heading);
float dy = zpl_sin(car->heading); float dy = zpl_sin(car->heading);
debug_push_circle((debug_v2){p[i].x+dx*car->force, p[i].y+dy*car->force}, 5.0f, 0x00FF00FF); debug_push_circle((debug_v2){p[i].x+dx*car->force, p[i].y+dy*car->force}, 5.0f, 0x00FF00FF);
} }
// NOTE(zaklaus): steer // NOTE(zaklaus): steer
{ {
float dx = zpl_sin(car->heading); float dx = zpl_sin(car->heading);
@ -187,7 +187,7 @@ void VehicleHandling(ecs_iter_t *it) {
void ClearVehicle(ecs_iter_t *it) { void ClearVehicle(ecs_iter_t *it) {
Vehicle *veh = ecs_field(it, Vehicle, 1); Vehicle *veh = ecs_field(it, Vehicle, 1);
for (int i = 0; i < it->count; i++) { for (int i = 0; i < it->count; i++) {
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
if (world_entity_valid(veh[i].seats[k])) { if (world_entity_valid(veh[i].seats[k])) {