From 11549eb324aff7669b73f5b7bce4f89a2410c3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Thu, 2 Feb 2023 14:17:53 +0100 Subject: [PATCH 1/2] send notification from server --- code/foundation/src/gui/notifications.c | 17 ++++- code/foundation/src/models/components.h | 3 + code/foundation/src/packets/pkt_send_notif.c | 35 +++++++++ code/foundation/src/packets/pkt_send_notif.h | 14 ++++ code/foundation/src/pkt/packet.c | 4 +- code/foundation/src/pkt/packet.h | 3 +- .../src/systems/modules/system_health.c | 76 +++++++++++++++++++ code/foundation/src/systems/systems.c | 74 +++++------------- code/games/minimal/src/platform.c | 1 + code/games/survival/src/platform.c | 11 --- 10 files changed, 165 insertions(+), 73 deletions(-) create mode 100644 code/foundation/src/packets/pkt_send_notif.c create mode 100644 code/foundation/src/packets/pkt_send_notif.h create mode 100644 code/foundation/src/systems/modules/system_health.c diff --git a/code/foundation/src/gui/notifications.c b/code/foundation/src/gui/notifications.c index 93c1559..b04e5e6 100644 --- a/code/foundation/src/gui/notifications.c +++ b/code/foundation/src/gui/notifications.c @@ -1,23 +1,30 @@ #define MAX_NOTIFICATIONS_ON_SCREEN 5 typedef struct { - const char *title; - const char *text; + zpl_string title; + zpl_string text; } notification; static notification *notifications = 0; static bool show_notification_list = 0; -void notification_push(const char* title, const char* text) { +void notification_push(const char* title1, const char* text1) { if (!notifications) { zpl_array_init(notifications, zpl_heap()); } + zpl_string title = zpl_string_make(zpl_heap(), title1); + zpl_string text = zpl_string_make(zpl_heap(), text1); + zpl_array_append(notifications, ((notification) { title, text })); } void notification_clear(void) { + for (zpl_isize i = 0; i < zpl_array_count(notifications); i++) { + zpl_string_free(notifications[i].title); + zpl_string_free(notifications[i].text); + } zpl_array_clear(notifications); } @@ -53,6 +60,8 @@ void notification_draw(void) { nk_label_wrap(game_ui, notif->text); if (nk_button_label(game_ui, "OK")) { + zpl_string_free(notifications[i].title); + zpl_string_free(notifications[i].text); zpl_array_remove_at(notifications, i); } nk_tree_pop(game_ui); @@ -77,6 +86,8 @@ void notification_draw(void) { nk_label_wrap(game_ui, notif->text); if (nk_button_label(game_ui, "OK")) { + zpl_string_free(notifications[i].title); + zpl_string_free(notifications[i].text); zpl_array_remove_at(notifications, i); --i; } } diff --git a/code/foundation/src/models/components.h b/code/foundation/src/models/components.h index d7661cd..4e1cfeb 100644 --- a/code/foundation/src/models/components.h +++ b/code/foundation/src/models/components.h @@ -100,6 +100,8 @@ typedef struct { float max_hp; } Health; +typedef struct { char _unused; } Dead; + typedef struct { float amt; } HealthRegen; @@ -241,6 +243,7 @@ typedef struct { X(Input)\ X(ClientInfo)\ X(Health)\ + X(Dead)\ X(HealthRegen)\ X(HealDelay)\ X(HealthDecreased)\ diff --git a/code/foundation/src/packets/pkt_send_notif.c b/code/foundation/src/packets/pkt_send_notif.c new file mode 100644 index 0000000..f405106 --- /dev/null +++ b/code/foundation/src/packets/pkt_send_notif.c @@ -0,0 +1,35 @@ +#include "packets/pkt_send_notif.h" +#include "pkt/packet.h" +#include "world/world.h" +#include "core/game.h" +#include "world/entity_view.h" +#include "core/camera.h" +#include "models/prefabs/player.h" + +#include "models/components.h" +#include "systems/systems.h" + +// client +#include "gui/notifications.h" + +pkt_desc pkt_send_notification_desc[] = { + { PKT_ARRAY(pkt_send_notification, title) }, + { PKT_ARRAY(pkt_send_notification, text) }, + { PKT_END }, +}; + +size_t pkt_notification_send(uint64_t peer_id, uint16_t view_id, const char *title, const char *text) { + pkt_send_notification table = { 0 }; + zpl_strncpy(table.title, title, sizeof(table.title)); + zpl_strncpy(table.text, text, sizeof(table.text)); + return pkt_world_write(MSG_ID_SEND_NOTIFICATION, pkt_table_encode(pkt_send_notification_desc, PKT_STRUCT_PTR(&table)), 1, view_id, (void*)peer_id, 0); +} + +int32_t pkt_send_notification_handler(pkt_header *header) { + pkt_send_notification table; + PKT_IF(pkt_msg_decode(header, pkt_send_notification_desc, pkt_pack_desc_args(pkt_send_notification_desc), PKT_STRUCT_PTR(&table))); + + notification_push(table.title, table.text); + + return 0; +} diff --git a/code/foundation/src/packets/pkt_send_notif.h b/code/foundation/src/packets/pkt_send_notif.h new file mode 100644 index 0000000..3220084 --- /dev/null +++ b/code/foundation/src/packets/pkt_send_notif.h @@ -0,0 +1,14 @@ +#pragma once +#include "platform/system.h" +#include "pkt/packet_utils.h" + +typedef struct { + char title[64]; + char text[1024]; +} pkt_send_notification; + +size_t pkt_notification_send(uint64_t peer_id, uint16_t view_id, const char *title, const char *text); +extern pkt_desc pkt_send_notification_desc[]; + +PKT_HANDLER_PROC(pkt_send_notification_handler); + diff --git a/code/foundation/src/pkt/packet.c b/code/foundation/src/pkt/packet.c index 61533cb..9223b2b 100644 --- a/code/foundation/src/pkt/packet.c +++ b/code/foundation/src/pkt/packet.c @@ -8,6 +8,7 @@ #include "packets/pkt_01_welcome.h" #include "packets/pkt_send_keystate.h" #include "packets/pkt_send_librg_update.h" +#include "packets/pkt_send_notif.h" #include "packets/pkt_switch_viewer.h" #define PKT_HEADER_ELEMENTS 3 @@ -18,7 +19,8 @@ pkt_handler pkt_handlers[] = { {.id = MSG_ID_LIBRG_UPDATE, .handler = pkt_send_librg_update_handler}, {.id = MSG_ID_SEND_KEYSTATE, .handler = pkt_send_keystate_handler}, {.id = MSG_ID_SEND_BLOCKPOS, .handler = pkt_send_blockpos_handler}, - {.id = MSG_ID_SWITCH_VIEWER, .handler = pkt_switch_viewer_handler}, + {.id = MSG_ID_SWITCH_VIEWER, .handler = pkt_switch_viewer_handler}, + {.id = MSG_ID_SEND_NOTIFICATION, .handler = pkt_send_notification_handler}, }; uint8_t pkt_buffer[PKT_BUFSIZ]; diff --git a/code/foundation/src/pkt/packet.h b/code/foundation/src/pkt/packet.h index 5100875..956bada 100644 --- a/code/foundation/src/pkt/packet.h +++ b/code/foundation/src/pkt/packet.h @@ -9,7 +9,8 @@ typedef enum { MSG_ID_LIBRG_UPDATE, MSG_ID_SEND_KEYSTATE, MSG_ID_SEND_BLOCKPOS, - MSG_ID_SWITCH_VIEWER, + MSG_ID_SWITCH_VIEWER, + MSG_ID_SEND_NOTIFICATION, MSG_NEXT_FREE_ID, MAX_PACKETS = 256, } pkt_messages; diff --git a/code/foundation/src/systems/modules/system_health.c b/code/foundation/src/systems/modules/system_health.c new file mode 100644 index 0000000..2d3d5bc --- /dev/null +++ b/code/foundation/src/systems/modules/system_health.c @@ -0,0 +1,76 @@ +#define HAZARD_BLOCK_DMG 5.0f + +void HurtOnHazardBlock(ecs_iter_t *it) { + Position *p = ecs_field(it, Position, 1); + Health *h = ecs_field(it, Health, 2); + + for (int i = 0; i < it->count; i++) { + world_block_lookup l = world_block_from_realpos(p[i].x, p[i].y); + if (blocks_get_flags(l.bid) & BLOCK_FLAG_HAZARD) { + h->hp -= HAZARD_BLOCK_DMG; + h->hp = zpl_max(0.0f, h->hp); + ecs_add(it->world, it->entities[i], HealthDecreased); + } + } +} + +//#define HP_REGEN_PAIN_COOLDOWN 5.0f + +void RegenerateHP(ecs_iter_t *it) { + Health *h = ecs_field(it, Health, 1); + HealthRegen *r = ecs_field(it, HealthRegen, 2); + + for (int i = 0; i < it->count; i++) { + // TODO delay regen on hurt + if (h[i].hp < h[i].max_hp) { + h[i].hp += r->amt; + h[i].hp = zpl_min(h[i].max_hp, h[i].hp); + entity_wake(it->entities[i]); + } + } +} + +void OnHealthChangePutDelay(ecs_iter_t *it) { + for (int i = 0; i < it->count; i++) { + ecs_set(it->world, it->entities[i], HealDelay, { .delay = 10 }); + ecs_remove(it->world, it->entities[i], HealthDecreased); + } +} + +void OnHealthChangeCheckDead(ecs_iter_t *it) { + for (int i = 0; i < it->count; i++) { + const Health *hp = ecs_get(it->world, it->entities[i], Health); + + if (hp && hp->hp <= 0.0f) { + ecs_add(it->world, it->entities[i], Dead); + } + } +} + +void OnDead(ecs_iter_t *it) { + for (int i = 0; i < it->count; i++) { + const ClientInfo *ci = ecs_get(it->world, it->entities[i], ClientInfo); + Input *pi = ecs_get_mut_if_ex(it->world, it->entities[i], Input); + + if (ci) { + pkt_notification_send(0, 0, "Someone died!", zpl_bprintf("Player %d has died!", it->entities[i])); + } + + if (pi) { + pi->is_blocked = 1; + } + } +} + +void TickDownHealDelay(ecs_iter_t *it) { + HealDelay *h = ecs_field(it, HealDelay, 1); + + for (int i = 0; i < it->count; i++) { + --h[i].delay; + + if (h[i].delay == 0) { + ecs_remove(it->world, it->entities[i], HealDelay); + } + } +} + diff --git a/code/foundation/src/systems/systems.c b/code/foundation/src/systems/systems.c index bbcc563..12bd7cf 100644 --- a/code/foundation/src/systems/systems.c +++ b/code/foundation/src/systems/systems.c @@ -8,6 +8,8 @@ #include "core/game.h" #include "core/rules.h" +#include "packets/pkt_send_notif.h" + ZPL_DIAGNOSTIC_PUSH_WARNLEVEL(0) #define CUTE_C2_IMPLEMENTATION #include "tinyc2.h" @@ -22,6 +24,7 @@ ecs_query_t *ecs_rigidbodies = 0; ecs_entity_t ecs_timer = 0; #include "modules/system_onfoot.c" +#include "modules/system_health.c" #include "modules/system_demo.c" #include "modules/system_vehicle.c" #include "modules/system_items.c" @@ -263,57 +266,6 @@ void IntegratePositions(ecs_iter_t *it) { } } -#define HAZARD_BLOCK_DMG 5.0f - -void HurtOnHazardBlock(ecs_iter_t *it) { - Position *p = ecs_field(it, Position, 1); - Health *h = ecs_field(it, Health, 2); - - for (int i = 0; i < it->count; i++) { - world_block_lookup l = world_block_from_realpos(p[i].x, p[i].y); - if (blocks_get_flags(l.bid) & BLOCK_FLAG_HAZARD) { - h->hp -= HAZARD_BLOCK_DMG; - h->hp = zpl_max(0.0f, h->hp); - ecs_add(it->world, it->entities[i], HealthDecreased); - } - } -} - -//#define HP_REGEN_PAIN_COOLDOWN 5.0f - -void RegenerateHP(ecs_iter_t *it) { - Health *h = ecs_field(it, Health, 1); - HealthRegen *r = ecs_field(it, HealthRegen, 2); - - for (int i = 0; i < it->count; i++) { - // TODO delay regen on hurt - if (h[i].hp < h[i].max_hp) { - h[i].hp += r->amt; - h[i].hp = zpl_min(h[i].max_hp, h[i].hp); - entity_wake(it->entities[i]); - } - } -} - -void OnHealthChangePutDelay(ecs_iter_t *it) { - for (int i = 0; i < it->count; i++) { - ecs_set(it->world, it->entities[i], HealDelay, { .delay = 10 }); - ecs_remove(it->world, it->entities[i], HealthDecreased); - } -} - -void TickDownHealDelay(ecs_iter_t *it) { - HealDelay *h = ecs_field(it, HealDelay, 1); - - for (int i = 0; i < it->count; i++) { - --h[i].delay; - - if (h[i].delay == 0) { - ecs_remove(it->world, it->entities[i], HealDelay); - } - } -} - void ResetActivators(ecs_iter_t *it) { Input *in = ecs_field(it, Input, 1); @@ -399,25 +351,29 @@ void SystemsImport(ecs_world_t *ecs) { ecs_rigidbodies = ecs_query_new(ecs, "components.Position, components.Velocity, components.PhysicsBody"); ECS_SYSTEM(ecs, EnableWorldEdit, EcsOnLoad); - ECS_SYSTEM(ecs, MovementImpulse, EcsOnLoad, components.Input, components.Velocity, components.Position, !components.IsInVehicle); - ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnLoad, components.Velocity, components.DemoNPC); - ECS_SYSTEM(ecs, ApplyWorldDragOnVelocity, EcsOnUpdate, components.Position, components.Velocity); + // health ECS_SYSTEM_TICKED_EX(ecs, HurtOnHazardBlock, EcsOnUpdate, 20.0f, components.Position, components.Health); ECS_SYSTEM_TICKED_EX(ecs, RegenerateHP, EcsOnUpdate, 40.0f, components.Health, components.HealthRegen, !components.HealDelay); ECS_SYSTEM_TICKED_EX(ecs, TickDownHealDelay, EcsOnUpdate, 20.0f, components.HealDelay); - ECS_SYSTEM(ecs, VehicleHandling, EcsOnUpdate, components.Vehicle, components.Position, components.Velocity); - ECS_OBSERVER(ecs, OnHealthChangePutDelay, EcsOnAdd, components.HealthDecreased); + ECS_OBSERVER(ecs, OnHealthChangeCheckDead, EcsOnAdd, components.HealthDecreased); + ECS_OBSERVER(ecs, OnDead, EcsOnAdd, components.Dead); + // collisions and movement physics + ECS_SYSTEM(ecs, ApplyWorldDragOnVelocity, EcsOnUpdate, components.Position, components.Velocity); + ECS_SYSTEM(ecs, VehicleHandling, EcsOnUpdate, components.Vehicle, components.Position, components.Velocity); ECS_SYSTEM(ecs, BodyCollisions, EcsOnUpdate, components.Position, components.Velocity, components.PhysicsBody); ECS_SYSTEM(ecs, BlockCollisions, EcsOnValidate, components.Position, components.Velocity); ECS_SYSTEM(ecs, IntegratePositions, EcsOnValidate, components.Position, components.Velocity); + // vehicles ECS_SYSTEM(ecs, EnterVehicle, EcsPostUpdate, components.Input, components.Position, !components.IsInVehicle); ECS_SYSTEM(ecs, LeaveVehicle, EcsPostUpdate, components.Input, components.IsInVehicle, components.Velocity); - ECS_SYSTEM(ecs, PlayerClosestInteractable, EcsPostUpdate, components.Input); + // player interaction + ECS_SYSTEM(ecs, MovementImpulse, EcsOnLoad, components.Input, components.Velocity, components.Position, !components.IsInVehicle); + ECS_SYSTEM(ecs, PlayerClosestInteractable, EcsPostUpdate, components.Input); ECS_SYSTEM(ecs, PickItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle); ECS_SYSTEM(ecs, DropItem, EcsPostUpdate, components.Input, components.Position, components.Inventory, !components.IsInVehicle); ECS_SYSTEM(ecs, SwapItems, EcsPostUpdate, components.Input, components.Inventory); @@ -426,18 +382,22 @@ void SystemsImport(ecs_world_t *ecs) { ECS_SYSTEM(ecs, CraftItem, EcsPostUpdate, components.Input, !components.IsInVehicle); ECS_SYSTEM(ecs, InspectContainers, EcsPostUpdate, components.Input, !components.IsInVehicle); + // logistics and production ECS_SYSTEM_TICKED(ecs, HarvestIntoContainers, EcsPostUpdate, components.ItemContainer, components.Position, !components.BlockHarvest); ECS_SYSTEM_TICKED(ecs, ProduceItems, EcsPostUpdate, components.ItemContainer, components.Producer, components.Position, components.Device); ECS_SYSTEM_TICKED_EX(ecs, PushItemsOnNodes, EcsPostUpdate, 20, components.ItemContainer, components.Position, components.Device, components.ItemRouter); ECS_SYSTEM_TICKED(ecs, BuildBlueprints, EcsPostUpdate, components.Blueprint, components.Device, components.Position); + // demo creature sim ECS_SYSTEM_TICKED(ecs, CreatureCheckNeeds, EcsPostUpdate, components.Creature); ECS_SYSTEM_TICKED(ecs, CreatureSeekFood, EcsPostUpdate, components.Creature, components.Position, components.Velocity, components.SeeksFood, !components.SeeksCompanion); ECS_SYSTEM_TICKED(ecs, CreatureSeekCompanion, EcsPostUpdate, components.Creature, components.Position, components.Velocity, components.SeeksCompanion, !components.SeeksFood); ECS_SYSTEM(ecs, CreatureRoamAround, EcsPostUpdate, components.Velocity, components.Creature, !components.SeeksFood, !components.SeeksCompanion); + // player input reset ECS_SYSTEM(ecs, ResetActivators, EcsPostUpdate, components.Input); + // cleanup systems ECS_SYSTEM(ecs, ClearVehicle, EcsUnSet, components.Vehicle); ECS_SYSTEM(ecs, ThrowItemsOut, EcsUnSet, components.ItemContainer, components.Position); diff --git a/code/games/minimal/src/platform.c b/code/games/minimal/src/platform.c index 5d06551..6e06546 100644 --- a/code/games/minimal/src/platform.c +++ b/code/games/minimal/src/platform.c @@ -102,6 +102,7 @@ void platform_render() { } debug_draw(); + notification_draw(); game_draw_ui(); } EndDrawing(); diff --git a/code/games/survival/src/platform.c b/code/games/survival/src/platform.c index b17265a..6970200 100644 --- a/code/games/survival/src/platform.c +++ b/code/games/survival/src/platform.c @@ -98,17 +98,6 @@ void platform_render() { game_world_view_active_entity_map(do_entity_fadeinout); } - // HACK run once when player is dead - { - static char done = 0; - camera cam = camera_get(); - entity_view *e = game_world_view_active_get_entity(cam.ent_id); - if (e && e->hp <= 0.0f && !done) { - done = 1; - notification_push("DEAD", "YOU ARE DEAD!"); - } - } - assets_frame(); BeginDrawing(); From 91f005b4bb8022c7b0f897f365f90be0661dfe29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Thu, 2 Feb 2023 15:40:48 +0100 Subject: [PATCH 2/2] Add support for sprite rendering --- code/foundation/src/models/components.h | 6 ++++++ code/foundation/src/systems/modules/system_health.c | 3 +-- code/foundation/src/world/entity_view.c | 7 ++++++- code/foundation/src/world/entity_view.h | 6 ++++++ code/foundation/src/world/world.c | 6 ++++++ code/games/minimal/src/renderer.c | 6 ++++++ code/games/sandbox/src/renderer.c | 6 ++++++ code/games/survival/src/renderer.c | 6 ++++++ 8 files changed, 43 insertions(+), 3 deletions(-) diff --git a/code/foundation/src/models/components.h b/code/foundation/src/models/components.h index 4e1cfeb..7629496 100644 --- a/code/foundation/src/models/components.h +++ b/code/foundation/src/models/components.h @@ -142,6 +142,11 @@ typedef struct { float durability; // 1.0 - 0.0 (0.0 = broken), we can only ever merge items of the same durability } Item; +typedef struct { + int spritesheet; + int frame; +} Sprite; + typedef struct { char _unused; } BlockHarvest; @@ -266,6 +271,7 @@ typedef struct { X(Creature)\ X(SeeksFood)\ X(SeeksCompanion)\ + X(Sprite)\ X(StreamInfo) #define X(comp) extern ECS_COMPONENT_DECLARE(comp); diff --git a/code/foundation/src/systems/modules/system_health.c b/code/foundation/src/systems/modules/system_health.c index 2d3d5bc..609da21 100644 --- a/code/foundation/src/systems/modules/system_health.c +++ b/code/foundation/src/systems/modules/system_health.c @@ -66,11 +66,10 @@ void TickDownHealDelay(ecs_iter_t *it) { HealDelay *h = ecs_field(it, HealDelay, 1); for (int i = 0; i < it->count; i++) { - --h[i].delay; + TICK_VAR(h[i].delay); if (h[i].delay == 0) { ecs_remove(it->world, it->entities[i], HealDelay); } } } - diff --git a/code/foundation/src/world/entity_view.c b/code/foundation/src/world/entity_view.c index 31b9404..b7fe255 100644 --- a/code/foundation/src/world/entity_view.c +++ b/code/foundation/src/world/entity_view.c @@ -44,8 +44,13 @@ pkt_desc pkt_entity_view_desc[] = { { PKT_UINT(entity_view, asset) }, { PKT_UINT(entity_view, progress_active) }, { PKT_UINT(entity_view, is_producer) }, + { PKT_HALF(entity_view, progress_value) }, - + + { PKT_KEEP_IF(entity_view, kind, EKIND_SPRITE, 2) }, + { PKT_UINT(entity_view, spritesheet) }, + { PKT_UINT(entity_view, frame) }, + { PKT_KEEP_IF(entity_view, has_items, true, 3) }, { PKT_UINT(entity_view, has_items) }, { PKT_UINT(entity_view, selected_item) }, diff --git a/code/foundation/src/world/entity_view.h b/code/foundation/src/world/entity_view.h index 1d2d54a..1d3cbcc 100644 --- a/code/foundation/src/world/entity_view.h +++ b/code/foundation/src/world/entity_view.h @@ -13,6 +13,8 @@ X(EKIND_PLAYER)\ X(EKIND_ITEM)\ X(EKIND_DEVICE)\ + X(EKIND_SPRITE)\ + X(EKIND_WEAPON)\ X(EKIND_VEHICLE)\ X(EKIND_DEMO_NPC)\ X(EKIND_MONSTER)\ @@ -78,6 +80,10 @@ typedef struct entity_view { bool is_producer; uint32_t progress_active; float progress_value; + + // sprite index + int spritesheet; + int frame; // NOTE(zaklaus): inventory uint8_t has_items; diff --git a/code/foundation/src/world/world.c b/code/foundation/src/world/world.c index 589b219..5c16c3f 100644 --- a/code/foundation/src/world/world.c +++ b/code/foundation/src/world/world.c @@ -76,6 +76,12 @@ entity_view* world_build_entity_view(int64_t e) { view.is_producer = ecs_get(world_ecs(), e, Producer) != 0; } + if (ecs_get(world_ecs(), e, Sprite)) { + Sprite const* spr = ecs_get(world_ecs(), e, Sprite); + view.spritesheet = spr->spritesheet; + view.frame = spr->frame; + } + view.inside_vehicle = ecs_get(world_ecs(), e, IsInVehicle) != 0 ? true : false; Inventory* inv = 0; diff --git a/code/games/minimal/src/renderer.c b/code/games/minimal/src/renderer.c index f7b732a..8ad3c89 100644 --- a/code/games/minimal/src/renderer.c +++ b/code/games/minimal/src/renderer.c @@ -69,6 +69,12 @@ void renderer_draw_entry(uint64_t key, entity_view *data, game_world_render_entr Color color = data->veh_kind == 0 ? RED : data->veh_kind == 1 ? GREEN : BLUE; DrawRectanglePro((Rectangle){x,y,w,h}, (Vector2){w/2.0f,h/2.0f}, zpl_to_degrees(data->heading), ColorAlpha(color, data->tran_time)); }break; + case EKIND_SPRITE: + case EKIND_WEAPON: { + float x = data->x - 32.f; + float y = data->y - 32.f; + DrawTexturePro(GetSpriteTexture2D(assets_find(data->asset)), ASSET_SRC_RECT(), ASSET_DST_RECT(x,y), (Vector2){0.5f,0.5f}, 0.0f, ALPHA(WHITE)); + } break; case EKIND_DEVICE:{ float x = data->x - 32.f; float y = data->y - 32.f; diff --git a/code/games/sandbox/src/renderer.c b/code/games/sandbox/src/renderer.c index 5a92fff..cda568b 100644 --- a/code/games/sandbox/src/renderer.c +++ b/code/games/sandbox/src/renderer.c @@ -72,6 +72,12 @@ void renderer_draw_entry(uint64_t key, entity_view *data, game_world_render_entr Color color = data->veh_kind == 0 ? RED : data->veh_kind == 1 ? GREEN : BLUE; DrawRectanglePro((Rectangle){x,y,w,h}, (Vector2){w/2.0f,h/2.0f}, zpl_to_degrees(data->heading), ColorAlpha(color, data->tran_time)); }break; + case EKIND_SPRITE: + case EKIND_WEAPON: { + float x = data->x - 32.f; + float y = data->y - 32.f; + DrawTexturePro(GetSpriteTexture2D(assets_find(data->asset)), ASSET_SRC_RECT(), ASSET_DST_RECT(x,y), (Vector2){0.5f,0.5f}, 0.0f, ALPHA(WHITE)); + } break; case EKIND_DEVICE:{ Texture2D tex = GetSpriteTexture2D(assets_find(data->asset)); float x = data->x - tex.width/2; diff --git a/code/games/survival/src/renderer.c b/code/games/survival/src/renderer.c index 3182403..7601e62 100644 --- a/code/games/survival/src/renderer.c +++ b/code/games/survival/src/renderer.c @@ -57,6 +57,12 @@ void renderer_draw_entry(uint64_t key, entity_view *data, game_world_render_entr Color color = data->veh_kind == 0 ? RED : data->veh_kind == 1 ? GREEN : BLUE; DrawRectanglePro((Rectangle){x,y,w,h}, (Vector2){w/2.0f,h/2.0f}, zpl_to_degrees(data->heading), ColorAlpha(color, data->tran_time)); }break; + case EKIND_SPRITE: + case EKIND_WEAPON: { + float x = data->x; + float y = data->y; + DrawSpriteEco(&main_sprite_sheet, data->frame, x, y, 0.0f, 2.0f, WHITE); + } break; case EKIND_DEVICE:{ float x = data->x - 32.f; float y = data->y - 32.f;