Compare commits
127 Commits
possible3d
...
master
Author | SHA1 | Date |
---|---|---|
Dominik Madarász | 2d593809d7 | |
Dominik Madarász | 23645ed32a | |
Dominik Madarász | 29d9b9306d | |
Dominik Madarász | 6e09c09037 | |
Dominik Madarász | b348400c1a | |
Dominik Madarász | a9ea1e9335 | |
Dominik Madarász | e2e6ef9185 | |
Dominik Madarász | 3fba1bc1d4 | |
Dominik Madarász | e43b167435 | |
Dominik Madarász | a9efa0f01c | |
Dominik Madarász | 213710e922 | |
Dominik Madarász | d864661e65 | |
Dominik Madarász | 9c669407fc | |
Dominik Madarász | a1d576fe8a | |
Dominik Madarász | 200d0a1e6d | |
Dominik Madarász | 00f0a672f8 | |
Dominik Madarász | 4a07e4ff4c | |
Dominik Madarász | c022b104d0 | |
Dominik Madarász | a9898527ee | |
Dominik Madarász | e302d1c865 | |
Dominik Madarász | eccaa14bda | |
Dominik Madarász | 94c49e770b | |
Dominik Madarász | 3e4814222e | |
Dominik Madarász | 410d6e5f11 | |
DavoSK | cf200e8bf5 | |
DavoSK | ea9b201a08 | |
DavoSK | c21cb39140 | |
DavoSK | 3a9196d19a | |
DavoSK | 98b9f3431e | |
Dominik Madarász | d15e7da7cc | |
DavoSK | 7356168b6f | |
DavoSK | 1631e9199b | |
Dominik Madarász | 7ed35706fc | |
DavoSK | e89cd75388 | |
DavoSK | f89b35a856 | |
Dominik Madarász | 8c288dc193 | |
Dominik Madarász | fc9997d4db | |
DavoSK | 5473ca3c46 | |
DavoSK | 698d3d2089 | |
Dominik Madarász | 78c05fd9da | |
DavoSK | f6d5c76d1b | |
Dominik Madarász | e8934ac2f3 | |
DavoSK | 755f7e7a86 | |
DavoSK | 1f451f10be | |
Dominik Madarász | 91f005b4bb | |
Dominik Madarász | 11549eb324 | |
Dominik Madarász | 65766d8748 | |
Dominik Madarász | 0760d1809d | |
Dominik Madarász | 6e6243e9df | |
Dominik Madarász | 89fea143d3 | |
Dominik Madarász | 5aa90fc5af | |
DavoSK | bdd43143f8 | |
Dominik Madarász | f35c9b8a1c | |
Dominik Madarász | 6e0e747756 | |
DavoSK | b578ceffef | |
Dominik Madarász | 3f5d999d44 | |
Dominik Madarász | 719b002989 | |
Dominik Madarász | 4d1a90d5cb | |
Dominik Madarász | 36a4a010c8 | |
Dominik Madarász | 1c68c73028 | |
Dominik Madarász | 4fd2856a25 | |
Dominik Madarász | 391106417b | |
Dominik Madarász | a31f4f6f25 | |
Dominik Madarász | 3174b8a3c3 | |
Dominik Madarász | 267a60af32 | |
Dominik Madarász | 0e614b53a5 | |
Dominik Madarász | d0edc058eb | |
Dominik Madarász | 3165d21f2b | |
Dominik Madarász | 701c15fde1 | |
Dominik Madarász | 82a8bbdaf8 | |
Dominik Madarász | 847289c6de | |
Dominik Madarász | 341040abc2 | |
Dominik Madarász | b9e29dd7ab | |
Dominik Madarász | c8b21e86b5 | |
Dominik Madarász | 31cf65ad50 | |
Dominik Madarász | ba78e5360e | |
Dominik Madarász | f24ab7dc04 | |
Dominik Madarász | d51d88002d | |
Dominik Madarász | 553afd44d0 | |
Dominik Madarász | 72005402cf | |
Dominik Madarász | d00ce4ec80 | |
Dominik Madarász | f0ccac8e0c | |
Dominik Madarász | e15cdab4ff | |
Vladyslav Hrytsenko | 4ae83ebdbb | |
Dominik Madarász | a3a75af9b5 | |
Vladyslav Hrytsenko | 4c778d24ec | |
Dominik Madarász | 5e8e760098 | |
Dominik Madarász | 7ecc5cd0d7 | |
Vladyslav Hrytsenko | 80d8620ee1 | |
Dominik Madarász | d3e1f595e5 | |
Vladyslav Hrytsenko | 8eec4ac470 | |
Dominik Madarász | ee7ff6a6c3 | |
Dominik Madarász | f99cbc8018 | |
Dominik Madarász | 3a008427f6 | |
Vladyslav Hrytsenko | 0740d0a85b | |
Dominik Madarász | 9e368527a3 | |
Dominik Madarász | 70bb456a43 | |
Dominik Madarász | 3d104313f8 | |
Dominik Madarász | e732949856 | |
Dominik Madarász | 339bb56dc7 | |
Dominik Madarász | 4cb85f069f | |
Dominik Madarász | 6385ea4461 | |
Dominik Madarász | 3f6235e8a4 | |
Dominik Madarász | 0d58d5f315 | |
Dominik Madarász | 06f408f09f | |
Dominik Madarász | 20d35ad653 | |
Dominik Madarász | 79caba208f | |
Dominik Madarász | 437aea7df5 | |
Dominik Madarász | 0f12724700 | |
Dominik Madarász | 3f30bb5079 | |
Dominik Madarász | ec6d489526 | |
Dominik Madarász | bdd774fd50 | |
Dominik Madarász | 746ec9b00d | |
Dominik Madarász | 143bf1bffa | |
Dominik Madarász | a824731a15 | |
Dominik Madarász | 93612f5462 | |
Dominik Madarász | 71dc349e4e | |
Dominik Madarász | 026a1e01c7 | |
Dominik Madarász | 2527a40231 | |
Dominik Madarász | b12c321488 | |
Dominik Madarász | f9906ca1dd | |
Dominik Madarász | fe497ae71b | |
Dominik Madarász | 2d09fd90cd | |
Dominik Madarász | 671445d4a7 | |
Dominik Madarász | 174e5a0452 | |
Dominik Madarász | 50967aa046 | |
Dominik Madarász | a7622ceeec |
|
@ -0,0 +1,22 @@
|
|||
name: Build web and deploy
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
BUTLER_API_KEY: ${{ secrets.BUTLER_KEY }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up emsdk
|
||||
run: web/setup.sh
|
||||
|
||||
- name: Build and deploy eco2d
|
||||
run: web/deploy.sh
|
|
@ -1,6 +1,6 @@
|
|||
build
|
||||
build_rel
|
||||
build_web
|
||||
build.*
|
||||
build_*
|
||||
emsdk
|
||||
deploy_web
|
||||
run_web
|
||||
|
@ -20,3 +20,7 @@ GTAGS
|
|||
pkg
|
||||
pkg.zip
|
||||
eco2d.zip
|
||||
eco2d.db
|
||||
eco2d.sublime-workspace
|
||||
|
||||
.cache
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"version": 2,
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "vs2022-debug",
|
||||
"displayName": "Visual Studio Community 2022 Release - x86_amd64 - Debug",
|
||||
"configurePreset": "vs2022",
|
||||
"configuration": "Debug"
|
||||
}
|
||||
]
|
||||
}
|
12
README.md
|
@ -1,6 +1,6 @@
|
|||
<div align="center">
|
||||
<a href="https://zaklaus.itch.io/eco2d"><img src="https://user-images.githubusercontent.com/2182108/111983468-d5593e80-8b12-11eb-9c59-8c78ecc0504e.png" alt="eco2d" /></a>
|
||||
</div>
|
||||
<h1>
|
||||
eco2d
|
||||
</h1>
|
||||
|
||||
<br />
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
|||
</div>
|
||||
|
||||
# Introduction
|
||||
zpl.eco2d is a small framework/game engine made out of curiosity. It attempts to bridge several libraries to create a playable sandbox with ease of extensibility and with performance in mind. The goal is not to make a generic 2D game engine but to build a game prototype that anyone can use to build various experiments.
|
||||
eco2d is a experimental set of games made out of curiosity. It attempts to bridge several libraries to create a playable sandbox with ease of extensibility and with performance in mind. The goal is not to make a generic 2D game engine but to build a game prototype that anyone can use to build various experiments.
|
||||
|
||||
The game runs on top of [raylib](https://raylib.com/) technologies and makes use of the [zpl](https://zpl.pw/) ecosystem alongside the **cwpack** library for data serialization. The game logic and lifecycle are maintained using [flecs](https://github.com/SanderMertens/flecs/) library and its suite of tools that help us improve the development efficiency.
|
||||
|
||||
|
@ -31,7 +31,7 @@ It was built with networked game sessions in mind from the ground up and therefo
|
|||
* Networked game (UDP) - networked sessions benefit from the use of [enet](https://github.com/zpl-c/enet/) library.
|
||||
* Local Only sessions - Data is streamed via local buffers.
|
||||
|
||||
In both cases, the game engine does not differentiate between these two options and makes the concept of Server <>client infrastructure entirely abstract. As a result, gameplay logic is only tied to living entities, where the entity might represent a networked client / local controller.
|
||||
In both cases, the game engine does not differentiate between these two options and makes the concept of Server<>client infrastructure entirely abstract. As a result, gameplay logic is only tied to living entities, where the entity might represent a networked client / local controller.
|
||||
|
||||
All data is transferred via packets fully automated by our serialization rule system, which uses the **cwpack** library in the background.
|
||||
|
||||
|
@ -90,7 +90,7 @@ build\eco2d.exe -?
|
|||
```
|
||||
|
||||
# License
|
||||
zpl.eco2d code is licensed under the BSD 3-Clause license, as seen [here](LICENSE).
|
||||
eco2d code is licensed under the BSD 3-Clause license, as seen [here](LICENSE).
|
||||
|
||||
Assets under the **art** folder are released into [Public Domain](https://creativecommons.org/share-your-work/public-domain/cc0/) unless otherwise stated.
|
||||
|
||||
|
|
After Width: | Height: | Size: 474 B |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 430 B |
BIN
art/gen/coal.png
Before Width: | Height: | Size: 824 B After Width: | Height: | Size: 452 B |
After Width: | Height: | Size: 559 B |
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 652 B |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 901 B |
After Width: | Height: | Size: 422 B |
After Width: | Height: | Size: 553 B |
After Width: | Height: | Size: 366 B |
After Width: | Height: | Size: 528 B |
After Width: | Height: | Size: 423 B |
After Width: | Height: | Size: 382 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 588 B |
After Width: | Height: | Size: 1.4 MiB |
After Width: | Height: | Size: 592 B |
After Width: | Height: | Size: 581 B |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 156 B |
BIN
art/gen/wood.png
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 278 B |
|
@ -0,0 +1,28 @@
|
|||
-- typedef enum {
|
||||
-- BLOCK_FLAG_COLLISION = (1 << 1),
|
||||
-- BLOCK_FLAG_HAZARD = (1 << 2),
|
||||
-- BLOCK_FLAG_ESSENTIAL = (1 << 3),
|
||||
-- BLOCK_FLAG_DESTROY_ON_COLLISION = (1 << 4),
|
||||
-- BLOCK_FLAG_ENTITY = (1 << 5),
|
||||
-- } block_flags;
|
||||
|
||||
INSERT INTO blocks (kind, flags, drag, friction, bounce, velx, vely) VALUES
|
||||
(asset('EMPTY'), NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('GROUND'), NULL, 1.0, 1.0, NULL, NULL, NULL),
|
||||
(asset('DIRT'), NULL, 2.1, 1.0, NULL, NULL, NULL),
|
||||
(asset('WALL'), (1<<1), 1.0, 1.0, 1.0, NULL, NULL),
|
||||
(asset('HILL'), (1<<1), 1.0, 1.0, NULL, NULL, NULL),
|
||||
(asset('HILL_SNOW'), (1<<1), 1.0, 1.0, NULL, NULL, NULL),
|
||||
(asset('WATER'), 0, 0.11, 1.0, NULL, NULL, NULL),
|
||||
(asset('LAVA'), (1<<2), 6.2, 4.0, NULL, NULL, NULL),
|
||||
(asset('FENCE'), (1<<1), 1.0, 1.0, 1.0, NULL, NULL),
|
||||
(asset('WOOD'), (1<<1), 1.0, 1.0, 0.0, NULL, NULL),
|
||||
(asset('TREE'), (1<<1)|(1<<4), 1.0, 1.0, 0.0, NULL, NULL),
|
||||
(asset('CHEST'), (1<<5), NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('FURNACE'), (1<<5), NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('TEST_TALL'), (1<<1), NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('BELT_LEFT'), NULL, 1.0, 1.0, NULL, -150.0, NULL),
|
||||
(asset('BELT_RIGHT'), NULL, 1.0, 1.0, NULL, 150.0, NULL),
|
||||
(asset('BELT_UP'), NULL, 1.0, 1.0, NULL, NULL, -150.0),
|
||||
(asset('BELT_DOWN'), NULL, 1.0, 1.0, NULL, NULL, 150.0);
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
-- typedef enum {
|
||||
-- // NOTE(zaklaus): hardcoded fields for placement ops
|
||||
-- UKIND_DELETE,
|
||||
-- UKIND_PLACE,
|
||||
-- UKIND_PLACE_ITEM,
|
||||
-- UKIND_PLACE_ITEM_DATA,
|
||||
-- UKIND_END_PLACE,
|
||||
--
|
||||
-- // NOTE(zaklaus): the rest of possible actions
|
||||
-- UKIND_HOLD,
|
||||
-- UKIND_PROXY,
|
||||
-- } item_usage;
|
||||
--
|
||||
-- typedef enum {
|
||||
-- UDATA_NONE,
|
||||
-- UDATA_ENERGY_SOURCE,
|
||||
-- } item_attachment;
|
||||
|
||||
INSERT INTO items (kind, usage, attachment, max_quantity, place_kind, directional,
|
||||
proxy_id, place_item_id, producer, energy_level, blueprint_w, blueprint_h, blueprint_plan)
|
||||
VALUES
|
||||
(0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('FENCE'), 5, 0, 64, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('COAL'), 5, 1, 64, NULL, NULL, NULL, NULL, asset('FURNACE'), 15.0, NULL, NULL, NULL),
|
||||
(asset('WOOD'), 1, 0, 64, asset('WOOD'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('TREE'), 1, 0, 64, asset('TREE'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('TEST_TALL'), 1, 0, 64, asset('TEST_TALL'), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('BELT'), 1, 0, 999, asset('BELT'), 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('BELT_LEFT'), 6, 0, NULL, NULL, NULL, asset('BELT'), NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('BELT_RIGHT'), 6, 0, NULL, NULL, NULL, asset('BELT'), NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('BELT_UP'), 6, 0, NULL, NULL, NULL, asset('BELT'), NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('BELT_DOWN'), 6, 0, NULL, NULL, NULL, asset('BELT'), NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('CHEST'), 2, 0, 32, NULL, NULL, NULL, asset('CHEST'), NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('CRAFTBENCH'), 2, 0, 32, NULL, NULL, NULL, asset('CRAFTBENCH'), NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('FURNACE'), 2, 0, 32, NULL, NULL, NULL, asset('FURNACE'), NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('SPLITTER'), 2, 0, 32, NULL, NULL, NULL, asset('SPLITTER'), NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('ASSEMBLER'), 2, 0, 32, NULL, NULL, NULL, asset('ASSEMBLER'), NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('CREATURE'), 2, 0, 32, NULL, NULL, NULL, asset('CREATURE'), NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('IRON_ORE'), 5, 0, 64, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('IRON_INGOT'), 5, 0, 64, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('IRON_PLATES'), 5, 0, 64, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('SCREWS'), 5, 0, 64, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('LOG'), 5, 0, 64, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
(asset('PLANK'), 5, 0, 64, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
|
||||
-- (asset('BLUEPRINT_DEMO_HOUSE'), 3, 0, 1, NULL, NULL, NULL, asset('BLUEPRINT'), NULL, NULL, 4, 4, ''),
|
||||
(asset('CREATURE_FOOD'), 5, 0, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
|
@ -0,0 +1 @@
|
|||
Only modify these for eco2d game specifically!
|
|
@ -0,0 +1,18 @@
|
|||
INSERT INTO recipes (product, product_qty, process_ticks, producer) VALUES
|
||||
(asset('IRON_PLATES'), 4, 20, asset('FURNACE')),
|
||||
(asset('SCREWS'), 8, 40, asset('CRAFTBENCH')),
|
||||
(asset('BELT'), 1, 120, asset('ASSEMBLER'));
|
||||
|
||||
INSERT INTO reagents (asset_id, qty) VALUES
|
||||
(asset('IRON_ORE'), 1),
|
||||
(asset('IRON_PLATES'), 1),
|
||||
(asset('FENCE'), 1),
|
||||
(asset('SCREWS'), 4),
|
||||
(asset('IRON_PLATES'), 2);
|
||||
|
||||
INSERT INTO recipe_reagents (recipe_id, reagent_id) VALUES
|
||||
(1, 1),
|
||||
(2, 2),
|
||||
(3, 3),
|
||||
(3, 4),
|
||||
(3, 5);
|
|
@ -0,0 +1,42 @@
|
|||
INSERT INTO resources (asset, kind) VALUES
|
||||
(asset('EMPTY'), 0),
|
||||
(asset('BLANK'), 0),
|
||||
(asset('BLOCK_FRAME'), 0),
|
||||
(asset('BUILDMODE_HIGHLIGHT'), 0),
|
||||
(asset('COAL'), 0),
|
||||
(asset('IRON_ORE'), 0),
|
||||
(asset('IRON_INGOT'), 0),
|
||||
(asset('IRON_PLATES'), 0),
|
||||
(asset('SCREWS'), 0),
|
||||
(asset('LOG'), 0),
|
||||
(asset('PLANK'), 0),
|
||||
(asset('CHEST'), 0),
|
||||
(asset('CREATURE'), 0),
|
||||
(asset('CREATURE_FOOD'), 0),
|
||||
(asset('FURNACE'), 0),
|
||||
(asset('SPLITTER'), 0),
|
||||
(asset('ASSEMBLER'), 0),
|
||||
(asset('CRAFTBENCH'), 0),
|
||||
(asset('BLUEPRINT'), 0),
|
||||
(asset('BLUEPRINT_DEMO_HOUSE'), 0),
|
||||
(asset('MOB'), 0),
|
||||
(asset('PLAYER'), 0),
|
||||
(asset('FENCE'), 0),
|
||||
(asset('DEV'), 0),
|
||||
(asset('GROUND'), 0),
|
||||
(asset('DIRT'), 0),
|
||||
(asset('WATER'), 2),
|
||||
(asset('LAVA'), 0),
|
||||
(asset('WALL'), 0),
|
||||
(asset('HILL'), 0),
|
||||
(asset('HILL_SNOW'), 0),
|
||||
(asset('HOLE'), 0),
|
||||
(asset('WOOD'), 0),
|
||||
(asset('TEST_TALL'), 0),
|
||||
(asset('TREE'), 0),
|
||||
(asset('BELT'), 0),
|
||||
(asset('BELT_LEFT'), 0),
|
||||
(asset('BELT_RIGHT'), 0),
|
||||
(asset('BELT_UP'), 0),
|
||||
(asset('BELT_DOWN'), 0);
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
CREATE TABLE assets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name VARCHAR(255) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE resources (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
asset INTEGER NOT NULL,
|
||||
kind INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE blocks (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
kind INTEGER NOT NULL,
|
||||
flags INTEGER DEFAULT 0,
|
||||
drag REAL,
|
||||
friction REAL,
|
||||
bounce REAL,
|
||||
velx REAL,
|
||||
vely REAL,
|
||||
FOREIGN KEY (kind) REFERENCES assets(id)
|
||||
);
|
||||
|
||||
CREATE TABLE items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
kind INTEGER NOT NULL,
|
||||
usage INTEGER,
|
||||
attachment INTEGER,
|
||||
max_quantity INTEGER,
|
||||
has_storage BOOLEAN,
|
||||
|
||||
place_kind INTEGER,
|
||||
directional BOOLEAN,
|
||||
|
||||
proxy_id INTEGER,
|
||||
|
||||
place_item_id INTEGER,
|
||||
|
||||
producer INTEGER,
|
||||
energy_level REAL,
|
||||
|
||||
blueprint_w INTEGER,
|
||||
blueprint_h INTEGER,
|
||||
blueprint_plan TEXT,
|
||||
|
||||
FOREIGN KEY (kind) REFERENCES assets(id)
|
||||
);
|
||||
|
||||
CREATE TABLE reagents (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
asset_id INTEGER NOT NULL,
|
||||
qty INTEGER NOT NULL,
|
||||
FOREIGN KEY (asset_id) REFERENCES assets(id)
|
||||
);
|
||||
|
||||
CREATE TABLE recipes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
product INTEGER NOT NULL,
|
||||
product_qty INTEGER NOT NULL,
|
||||
process_ticks INTEGER NOT NULL,
|
||||
producer INTEGER NOT NULL,
|
||||
FOREIGN KEY (product) REFERENCES assets(id),
|
||||
FOREIGN KEY (producer) REFERENCES assets(id)
|
||||
);
|
||||
|
||||
CREATE TABLE recipe_reagents (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
recipe_id INTEGER NOT NULL,
|
||||
reagent_id INTEGER NOT NULL,
|
||||
FOREIGN KEY (recipe_id) REFERENCES recipes(id),
|
||||
FOREIGN KEY (reagent_id) REFERENCES reagents(id)
|
||||
);
|
After Width: | Height: | Size: 24 KiB |
|
@ -0,0 +1,3 @@
|
|||
@echo off
|
||||
call win\setup_cl_generic.bat amd64
|
||||
cmake --build build && build\eco2d
|
|
@ -7,25 +7,25 @@ add_library(eco2d-foundation STATIC
|
|||
|
||||
src/platform/signal_handling.c
|
||||
src/platform/profiler.c
|
||||
src/platform/input.c
|
||||
|
||||
src/models/database.c
|
||||
src/models/assets.c
|
||||
src/models/components.c
|
||||
src/models/components.c
|
||||
src/models/items.c
|
||||
src/models/entity.c
|
||||
src/models/device.c
|
||||
src/models/crafting.c
|
||||
|
||||
src/models/prefabs/player.c
|
||||
src/models/prefabs/vehicle.c
|
||||
src/models/prefabs/storage.c
|
||||
src/models/prefabs/furnace.c
|
||||
src/models/prefabs/blueprint.c
|
||||
|
||||
src/pkt/packet.c
|
||||
|
||||
src/gen/texgen_fallback.c
|
||||
|
||||
src/debug/debug_ui.c
|
||||
src/debug/debug_draw.c
|
||||
src/dev/debug_ui.c
|
||||
src/dev/debug_draw.c
|
||||
|
||||
src/utils/options.c
|
||||
src/utils/compress.c
|
||||
|
@ -46,6 +46,6 @@ add_library(eco2d-foundation STATIC
|
|||
|
||||
target_compile_definitions(eco2d-foundation PRIVATE CLIENT)
|
||||
include_directories(src ../modules ../../art/gen)
|
||||
target_link_libraries(eco2d-foundation raylib cwpack flecs-bundle vendors-bundle)
|
||||
target_link_libraries(eco2d-foundation raylib raylib_nuklear cwpack flecs-bundle vendors-bundle)
|
||||
|
||||
link_system_libs(eco2d-foundation)
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
#pragma once
|
||||
|
||||
#define ASSET_INVALID 0xFF
|
||||
|
||||
#define _ASSETS\
|
||||
X(ASSET_EMPTY)\
|
||||
X(ASSET_BLANK)\
|
||||
X(ASSET_BLOCK_FRAME)\
|
||||
X(ASSET_BUILDMODE_HIGHLIGHT)\
|
||||
X(ASSET_PLAYER)\
|
||||
X(ASSET_THING)\
|
||||
X(ASSET_CREATURE)\
|
||||
X(ASSET_CREATURE_FOOD)\
|
||||
X(ASSET_CHEST)\
|
||||
X(ASSET_SPLITTER)\
|
||||
X(ASSET_ASSEMBLER)\
|
||||
X(ASSET_FURNACE)\
|
||||
X(ASSET_CRAFTBENCH)\
|
||||
X(ASSET_BLUEPRINT_BEGIN)\
|
||||
X(ASSET_BLUEPRINT)\
|
||||
X(ASSET_BLUEPRINT_DEMO_HOUSE)\
|
||||
X(ASSET_BLUEPRINT_END)\
|
||||
X(ASSET_FENCE)\
|
||||
X(ASSET_DEV)\
|
||||
X(ASSET_GROUND)\
|
||||
X(ASSET_DIRT)\
|
||||
X(ASSET_WATER)\
|
||||
X(ASSET_LAVA)\
|
||||
X(ASSET_WALL)\
|
||||
X(ASSET_HILL)\
|
||||
X(ASSET_HILL_SNOW)\
|
||||
X(ASSET_HOLE)\
|
||||
X(ASSET_WOOD)\
|
||||
X(ASSET_TREE)\
|
||||
X(ASSET_COAL)\
|
||||
X(ASSET_IRON_ORE)\
|
||||
X(ASSET_IRON_INGOT)\
|
||||
X(ASSET_IRON_PLATES)\
|
||||
X(ASSET_SCREWS)\
|
||||
X(ASSET_LOG)\
|
||||
X(ASSET_PLANK)\
|
||||
X(ASSET_TEST_TALL)\
|
||||
X(ASSET_BELT)\
|
||||
X(ASSET_BELT_LEFT)\
|
||||
X(ASSET_BELT_RIGHT)\
|
||||
X(ASSET_BELT_UP)\
|
||||
X(ASSET_BELT_DOWN)
|
||||
|
||||
typedef enum {
|
||||
#define X(idx) idx,
|
||||
_ASSETS
|
||||
#undef X
|
||||
MAX_INTERNAL_ASSETS,
|
||||
NEXT_FREE_ASSET = MAX_INTERNAL_ASSETS,
|
||||
MAX_ASSETS = 255
|
||||
} asset_id;
|
||||
|
||||
extern const char *asset_names[];
|
|
@ -3,6 +3,7 @@
|
|||
#include "platform/platform.h"
|
||||
#include "world/world.h"
|
||||
#include "pkt/packet.h"
|
||||
#include "models/database.h"
|
||||
#include "platform/signal_handling.h"
|
||||
#include "net/network.h"
|
||||
#include "models/entity.h"
|
||||
|
@ -10,6 +11,7 @@
|
|||
#include "world/entity_view.h"
|
||||
#include "core/camera.h"
|
||||
#include "platform/profiler.h"
|
||||
#include "platform/renderer.h"
|
||||
|
||||
#include "flecs/flecs_os_api_stdcpp.h"
|
||||
#include "flecs.h"
|
||||
|
@ -21,12 +23,19 @@
|
|||
#include "packets/pkt_01_welcome.h"
|
||||
#include "packets/pkt_switch_viewer.h"
|
||||
|
||||
#define RAYLIB_NUKLEAR_IMPLEMENTATION
|
||||
ZPL_DIAGNOSTIC_PUSH_WARNLEVEL(0)
|
||||
#include "raylib-nuklear.h"
|
||||
ZPL_DIAGNOSTIC_POP
|
||||
|
||||
static uint8_t game_mode;
|
||||
static uint8_t game_should_close;
|
||||
|
||||
static world_view *world_viewers;
|
||||
static world_view *active_viewer;
|
||||
|
||||
struct nk_context *game_ui = 0;
|
||||
|
||||
static WORLD_PKT_READER(pkt_reader) {
|
||||
pkt_header header = {0};
|
||||
uint32_t ok = pkt_header_decode(&header, data, datalen);
|
||||
|
@ -92,7 +101,7 @@ void game_world_view_cycle_active(int8_t dir) {
|
|||
game_world_view_set_active_by_idx(zpl_max(0, (idx+dir)%zpl_buffer_count(world_viewers)));
|
||||
}
|
||||
void game_world_view_set_active_by_idx(uint16_t idx) {
|
||||
ZPL_ASSERT(idx >= 0 && idx < zpl_buffer_count(world_viewers));
|
||||
ZPL_ASSERT(idx < zpl_buffer_count(world_viewers));
|
||||
game_world_view_set_active(&world_viewers[idx]);
|
||||
}
|
||||
|
||||
|
@ -125,10 +134,13 @@ float game_time() {
|
|||
return (float)get_cached_time();
|
||||
}
|
||||
|
||||
void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled) {
|
||||
void game_setup(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled) {
|
||||
game_mode = play_mode;
|
||||
game_should_close = false;
|
||||
|
||||
entity_default_spawnlist();
|
||||
game_init(db_init());
|
||||
|
||||
#ifndef _DEBUG
|
||||
const char *host_ip = "lab.zakto.pw";
|
||||
#else
|
||||
|
@ -147,6 +159,9 @@ void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_
|
|||
world_viewers_init(num_viewers);
|
||||
active_viewer = &world_viewers[0];
|
||||
camera_reset();
|
||||
|
||||
Font font = LoadFontEx("art/anonymous_pro_bold.ttf", 14, 0, 0);
|
||||
game_ui = InitNuklearEx(font, 14);
|
||||
}
|
||||
|
||||
if (game_mode != GAMEKIND_SINGLE) {
|
||||
|
@ -168,6 +183,8 @@ void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_
|
|||
}
|
||||
}
|
||||
|
||||
game_init_ecs();
|
||||
|
||||
if (game_mode == GAMEKIND_SINGLE) {
|
||||
for (uint32_t i = 0; i < num_viewers; i++) {
|
||||
pkt_00_init_send(i);
|
||||
|
@ -180,6 +197,7 @@ int8_t game_is_networked() {
|
|||
}
|
||||
|
||||
void game_shutdown() {
|
||||
db_shutdown();
|
||||
|
||||
if (game_mode == GAMEKIND_CLIENT) {
|
||||
network_client_disconnect();
|
||||
|
@ -200,7 +218,8 @@ void game_shutdown() {
|
|||
|
||||
// TODO(zaklaus): crashes on exit
|
||||
//platform_shutdown();
|
||||
}
|
||||
UnloadNuklear(game_ui);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t game_is_running() {
|
||||
|
@ -215,13 +234,14 @@ game_kind game_get_kind(void) {
|
|||
return game_mode;
|
||||
}
|
||||
|
||||
void game_input() {
|
||||
void game_core_input() {
|
||||
if (game_mode != GAMEKIND_HEADLESS) {
|
||||
platform_input();
|
||||
UpdateNuklear(game_ui);
|
||||
}
|
||||
}
|
||||
|
||||
void game_update() {
|
||||
void game_core_update() {
|
||||
static double last_update = 0.0f;
|
||||
if (game_mode == GAMEKIND_CLIENT) {
|
||||
network_client_tick();
|
||||
|
@ -243,12 +263,16 @@ void game_update() {
|
|||
last_update = get_cached_time();
|
||||
}
|
||||
|
||||
void game_render() {
|
||||
void game_core_render() {
|
||||
if (game_mode != GAMEKIND_HEADLESS) {
|
||||
platform_render();
|
||||
}
|
||||
}
|
||||
|
||||
void game_draw_ui() {
|
||||
DrawNuklear(game_ui);
|
||||
}
|
||||
|
||||
void game_action_send_keystate(game_keystate_data *data) {
|
||||
pkt_send_keystate_send(active_viewer->view_id, data);
|
||||
}
|
||||
|
@ -267,3 +291,71 @@ void game_request_close() {
|
|||
platform_request_close();
|
||||
}
|
||||
}
|
||||
|
||||
static game_world_render_entry* render_queue = NULL;
|
||||
|
||||
static void game__world_view_render_push_entry(uint64_t key, entity_view * data) {
|
||||
if (!data) return;
|
||||
|
||||
if (data->kind == EKIND_CHUNK) {
|
||||
world_view *view = game_world_view_get_active();
|
||||
float size = (float)(view->chunk_size * WORLD_BLOCK_SIZE);
|
||||
float offset = 0.0;
|
||||
for (size_t ty = 0; ty < view->chunk_size; ty++) {
|
||||
for (size_t tx = 0; tx < view->chunk_size; tx++) {
|
||||
block_id blk_id = data->outer_blocks[(ty*view->chunk_size)+tx];
|
||||
if (blk_id != 0) {
|
||||
game_world_render_entry entry = {
|
||||
.key = key,
|
||||
.data = data,
|
||||
.blk_id = blk_id,
|
||||
.x = (data->x*size + offset) + (float)tx*WORLD_BLOCK_SIZE + WORLD_BLOCK_SIZE/2,
|
||||
.y = (data->y*size + offset) + (float)ty*WORLD_BLOCK_SIZE + WORLD_BLOCK_SIZE/2,
|
||||
.cy = (data->y*size + offset) + (float)ty*WORLD_BLOCK_SIZE + WORLD_BLOCK_SIZE/2,
|
||||
};
|
||||
|
||||
if (!(blocks_get_flags(blk_id) & BLOCK_FLAG_COLLISION)) {
|
||||
entry.cy = ZPL_F32_MIN;
|
||||
}
|
||||
|
||||
zpl_array_append(render_queue, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
game_world_render_entry entry = {
|
||||
.key = key,
|
||||
.data = data,
|
||||
.x = data->x,
|
||||
.y = data->y,
|
||||
.cy = data->y,
|
||||
.blk_id = 0,
|
||||
};
|
||||
zpl_array_append(render_queue, entry);
|
||||
}
|
||||
|
||||
static void game__world_view_render_ground(uint64_t key, entity_view * data) {
|
||||
if (data->kind != EKIND_CHUNK) return;
|
||||
renderer_draw_entry(key, data, 0);
|
||||
}
|
||||
|
||||
void game_world_view_render_world(void) {
|
||||
if (!render_queue) {
|
||||
zpl_array_init(render_queue, zpl_heap());
|
||||
}
|
||||
|
||||
zpl_array_clear(render_queue);
|
||||
|
||||
profile(PROF_RENDER_PUSH_AND_SORT_ENTRIES) {
|
||||
game_world_view_active_entity_map(game__world_view_render_push_entry);
|
||||
zpl_sort_array(render_queue, zpl_array_count(render_queue), zpl_f32_cmp(zpl_offset_of(game_world_render_entry, cy)));
|
||||
}
|
||||
|
||||
game_world_view_active_entity_map(game__world_view_render_ground);
|
||||
|
||||
for (zpl_isize i = 0; i < zpl_array_count(render_queue); i++) {
|
||||
renderer_draw_entry(render_queue[i].key, render_queue[i].data, &render_queue[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "platform/system.h"
|
||||
#include "world/world_view.h"
|
||||
#include "packets/pkt_send_keystate.h"
|
||||
#include "packets/pkt_send_code.h"
|
||||
|
||||
typedef enum {
|
||||
GAMEKIND_SINGLE,
|
||||
|
@ -10,7 +11,7 @@ typedef enum {
|
|||
FORCE_GAMEKIND_UINT8 = UINT8_MAX
|
||||
} game_kind;
|
||||
|
||||
void game_init(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled);
|
||||
void game_setup(const char *ip, uint16_t port, game_kind play_mode, uint32_t num_viewers, int32_t seed, uint16_t chunk_size, uint16_t chunk_amount, int8_t is_dash_enabled);
|
||||
void game_shutdown();
|
||||
void game_request_close();
|
||||
uint8_t game_is_running();
|
||||
|
@ -19,9 +20,24 @@ float game_time();
|
|||
game_kind game_get_kind(void);
|
||||
|
||||
//~ NOTE(zaklaus): game events
|
||||
// Implemented by games
|
||||
void game_init(bool new_db);
|
||||
void game_init_ecs(); // called once the world is initialised
|
||||
void game_input();
|
||||
void game_update();
|
||||
void game_render();
|
||||
void game_player_joined(uint64_t ent);
|
||||
void game_player_departed(uint64_t ent);
|
||||
void game_player_died(uint64_t ent);
|
||||
void game_client_receive_code(pkt_send_code data);
|
||||
|
||||
// base methods called from games
|
||||
void game_core_input();
|
||||
void game_core_update();
|
||||
void game_core_render();
|
||||
|
||||
//~ Called from platform.c
|
||||
void game_draw_ui();
|
||||
|
||||
//~ NOTE(zaklaus): world view management
|
||||
world_view *game_world_view_get_active(void);
|
||||
|
@ -32,6 +48,7 @@ void game_world_view_set_active(world_view *view);
|
|||
void game_world_view_cycle_active(int8_t dir);
|
||||
void game_world_view_active_entity_map(void (*map_proc)(uint64_t key, entity_view * value));
|
||||
entity_view *game_world_view_active_get_entity(uint64_t ent_id);
|
||||
void game_world_view_render_world(void);
|
||||
|
||||
//~ NOTE(zaklaus): viewer -> host actions
|
||||
void game_action_send_keystate(game_keystate_data *data);
|
||||
|
|
|
@ -5,7 +5,6 @@ typedef struct {
|
|||
float phy_walk_drag;
|
||||
uint64_t demo_npc_move_speed;
|
||||
uint64_t demo_npc_steer_speed;
|
||||
float furnace_cook_time;
|
||||
float item_pick_radius;
|
||||
float item_merger_radius;
|
||||
float item_attract_radius;
|
||||
|
@ -25,6 +24,8 @@ typedef struct {
|
|||
float vehicle_brake_force;
|
||||
float veh_enter_radius;
|
||||
float blueprint_build_time;
|
||||
|
||||
// survival rules
|
||||
} game_rulesdef;
|
||||
|
||||
extern game_rulesdef game_rules;
|
||||
|
|
|
@ -4,11 +4,10 @@ game_rulesdef game_rules = {
|
|||
.phy_walk_drag = 4.23f,
|
||||
.demo_npc_move_speed = 500,
|
||||
.demo_npc_steer_speed = 300,
|
||||
.furnace_cook_time = 1.f,
|
||||
.item_pick_radius = 25.0f,
|
||||
.item_merger_radius = 75.0f,
|
||||
.item_attract_radius = 75.0f,
|
||||
.item_attract_force = .98f,
|
||||
.item_attract_force = 1.98f,
|
||||
.item_container_reach_radius = 105.0f,
|
||||
.item_drop_pickup_time = 2.5f,
|
||||
.item_drop_merger_time = 6.5f,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "debug/debug_draw.h"
|
||||
#include "dev/debug_draw.h"
|
||||
#include "core/game.h"
|
||||
|
||||
static debug_draw_queue draw_queue = {0};
|
||||
|
||||
#ifndef _DEBUG
|
||||
#if !defined(_DEBUG) || 0
|
||||
static bool draw_is_enabled = false;
|
||||
#else
|
||||
static bool draw_is_enabled = true;
|
|
@ -1,4 +1,4 @@
|
|||
#include "debug/debug_replay.h"
|
||||
#include "dev/debug_replay.h"
|
||||
#include "core/camera.h"
|
||||
#include "models/entity.h"
|
||||
|
||||
|
@ -12,9 +12,6 @@ typedef enum {
|
|||
RPKIND_PLACE_ICE_RINK,
|
||||
RPKIND_PLACE_ERASE_CHANGES,
|
||||
RPKIND_SPAWN_CIRCLING_DRIVER,
|
||||
RPKIND_SPAWN_ICEMAKER_ITEM,
|
||||
RPKIND_SPAWN_CHEST,
|
||||
RPKIND_SPAWN_BELT,
|
||||
} replay_kind;
|
||||
|
||||
typedef struct {
|
||||
|
@ -225,15 +222,6 @@ void debug_replay_update(void) {
|
|||
case RPKIND_PLACE_ERASE_CHANGES:{
|
||||
ActEraseWorldChanges();
|
||||
}break;
|
||||
case RPKIND_SPAWN_ICEMAKER_ITEM:{
|
||||
ActSpawnCoal();
|
||||
}break;
|
||||
case RPKIND_SPAWN_CHEST:{
|
||||
ActSpawnChest();
|
||||
}break;
|
||||
case RPKIND_SPAWN_BELT:{
|
||||
ActSpawnBelt();
|
||||
}break;
|
||||
default: {
|
||||
ZPL_PANIC("unreachable");
|
||||
}break;
|
|
@ -1,5 +1,5 @@
|
|||
#include "debug/debug_ui.h"
|
||||
#include "debug/debug_draw.h"
|
||||
#include "dev/debug_ui.h"
|
||||
#include "dev/debug_draw.h"
|
||||
#include "raylib.h"
|
||||
#include "models/prefabs/vehicle.h"
|
||||
#include "core/camera.h"
|
||||
|
@ -9,6 +9,10 @@
|
|||
|
||||
#include "models/components.h"
|
||||
|
||||
ZPL_DIAGNOSTIC_PUSH_WARNLEVEL(0)
|
||||
#include "raylib-nuklear.h"
|
||||
ZPL_DIAGNOSTIC_POP
|
||||
|
||||
typedef enum {
|
||||
DITEM_RAW,
|
||||
DITEM_GAP,
|
||||
|
@ -16,7 +20,9 @@ typedef enum {
|
|||
DITEM_BUTTON,
|
||||
DITEM_SLIDER,
|
||||
DITEM_LIST,
|
||||
DITEM_TOOL,
|
||||
DITEM_COND,
|
||||
|
||||
DITEM_END,
|
||||
|
||||
DITEM_FORCE_UINT8 = UINT8_MAX
|
||||
|
@ -41,6 +47,8 @@ static uint8_t is_debug_open = 1;
|
|||
static uint8_t is_handle_ctrl_held;
|
||||
static float debug_xpos = DBG_START_XPOS;
|
||||
static float debug_ypos = DBG_START_YPOS;
|
||||
static zpl_u16 sel_item_id = 0;
|
||||
static struct nk_context *dev_ui = 0;
|
||||
|
||||
typedef enum {
|
||||
L_NONE = 0,
|
||||
|
@ -71,6 +79,11 @@ typedef struct debug_item {
|
|||
void (*on_change)(float);
|
||||
} slider;
|
||||
|
||||
struct {
|
||||
uint8_t is_open;
|
||||
void (*on_draw)(void);
|
||||
} tool;
|
||||
|
||||
void (*on_click)(void);
|
||||
|
||||
uint8_t (*on_success)(void);
|
||||
|
@ -82,10 +95,13 @@ typedef struct debug_item {
|
|||
static void UIDrawText(const char *text, float posX, float posY, int fontSize, Color color);
|
||||
static int UIMeasureText(const char *text, int fontSize);
|
||||
|
||||
#include "debug/debug_replay.c"
|
||||
#include "dev/debug_replay.c"
|
||||
|
||||
#include "debug/debug_ui_actions.c"
|
||||
#include "debug/debug_ui_widgets.c"
|
||||
#include "gui/ui_skin.c"
|
||||
|
||||
#include "dev/debug_ui_actions.c"
|
||||
#include "dev/debug_ui_widgets.c"
|
||||
#include "dev/debug_ui_tools.c"
|
||||
|
||||
static debug_item items[] = {
|
||||
{
|
||||
|
@ -133,17 +149,24 @@ static debug_item items[] = {
|
|||
.list = {
|
||||
.is_collapsed = true,
|
||||
.items = (debug_item[]) {
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn car", .on_click = ActSpawnCar },
|
||||
{
|
||||
.kind = DITEM_LIST,
|
||||
.name = "spawn item",
|
||||
.list = {
|
||||
.items = (debug_item[]) {
|
||||
{ .kind = DITEM_TEXT, .name = "selected", .proc = DrawSelectedSpawnItem },
|
||||
{ .kind = DITEM_BUTTON, .name = "Previous", .on_click = ActSpawnItemPrev },
|
||||
{ .kind = DITEM_BUTTON, .name = "Next", .on_click = ActSpawnItemNext },
|
||||
{ .kind = DITEM_BUTTON, .name = "Spawn <", .on_click = ActSpawnSelItem },
|
||||
{ .kind = DITEM_END },
|
||||
},
|
||||
.is_collapsed = false
|
||||
}
|
||||
},
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn car", .on_click = ActSpawnCar },
|
||||
{ .kind = DITEM_BUTTON, .name = "place ice rink", .on_click = ActPlaceIceRink },
|
||||
{ .kind = DITEM_BUTTON, .name = "erase world changes", .on_click = ActEraseWorldChanges },
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn circling driver", .on_click = ActSpawnCirclingDriver },
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn coal lump", .on_click = ActSpawnCoal },
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn chest", .on_click = ActSpawnChest },
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn belt", .on_click = ActSpawnBelt },
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn furnace", .on_click = ActSpawnFurnace },
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn big tree", .on_click = ActSpawnBigTree },
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn demo blueprint", .on_click = ActSpawnDemoHouseItem },
|
||||
{ .kind = DITEM_BUTTON, .name = "spawn random durability icemaker", .on_click = ActSpawnDurabilityTest },
|
||||
{
|
||||
.kind = DITEM_LIST,
|
||||
.name = "demo npcs",
|
||||
|
@ -232,12 +255,27 @@ static debug_item items[] = {
|
|||
{ .kind = DITEM_RAW, .val = PROF_RENDER, .proc = DrawProfilerDelta },
|
||||
{ .kind = DITEM_RAW, .val = PROF_UPDATE_SYSTEMS, .proc = DrawProfilerDelta },
|
||||
{ .kind = DITEM_RAW, .val = PROF_ENTITY_LERP, .proc = DrawProfilerDelta },
|
||||
{ .kind = DITEM_RAW, .val = PROF_INTEGRATE_POS, .proc = DrawProfilerDelta },
|
||||
{ .kind = DITEM_RAW, .val = PROF_INTEGRATE_POS, .proc = DrawProfilerDelta },
|
||||
{ .kind = DITEM_RAW, .val = PROF_PHYS_BLOCK_COLS, .proc = DrawProfilerDelta },
|
||||
{ .kind = DITEM_RAW, .val = PROF_PHYS_BODY_COLS, .proc = DrawProfilerDelta },
|
||||
{ .kind = DITEM_RAW, .val = PROF_RENDER_PUSH_AND_SORT_ENTRIES, .proc = DrawProfilerDelta },
|
||||
{ .kind = DITEM_END },
|
||||
},
|
||||
.is_collapsed = 1
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
.kind = DITEM_LIST,
|
||||
.name = "tools",
|
||||
.list = {
|
||||
.items = (debug_item[]) {
|
||||
{ .kind = DITEM_TOOL, .name = "asset inspector", .tool = { .is_open = 0, .on_draw = ToolAssetInspector } },
|
||||
{ .kind = DITEM_TOOL, .name = "entity inspector", .tool = { .is_open = 0, .on_draw = ToolEntityInspector } },
|
||||
{ .kind = DITEM_END },
|
||||
},
|
||||
.is_collapsed = 0
|
||||
}
|
||||
},
|
||||
#if !defined(PLATFORM_WEB)
|
||||
{
|
||||
.kind = DITEM_BUTTON,
|
||||
|
@ -340,6 +378,25 @@ debug_draw_result debug_draw_list(debug_item *list, float xpos, float ypos, bool
|
|||
ypos += DBG_FONT_SPACING;
|
||||
}break;
|
||||
|
||||
case DITEM_TOOL: {
|
||||
char const *text = TextFormat("> %s", it->name);
|
||||
if (it->name_width == 0) {
|
||||
it->name_width = (float)UIMeasureText(text, DBG_FONT_SIZE);
|
||||
}
|
||||
Color color = RAYWHITE;
|
||||
if (is_btn_pressed(xpos, ypos, it->name_width, DBG_FONT_SIZE, &color)) {
|
||||
it->tool.is_open ^= 1;
|
||||
}
|
||||
|
||||
debug_draw_result res = DrawColoredText(xpos, ypos, text, color);
|
||||
ypos = res.y;
|
||||
|
||||
if (it->tool.is_open) {
|
||||
if (is_shadow_rendered) break;
|
||||
it->tool.on_draw();
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
|
||||
}break;
|
||||
|
@ -353,6 +410,19 @@ void debug_draw(void) {
|
|||
// NOTE(zaklaus): Flush old debug samples
|
||||
debug_draw_flush();
|
||||
|
||||
set_style(dev_ui, THEME_RED);
|
||||
|
||||
static zpl_u8 first_run=0;
|
||||
if (!first_run) {
|
||||
first_run = 1;
|
||||
ActSpawnItemNext();
|
||||
|
||||
// Initialize Nuklear ctx
|
||||
dev_ui = InitNuklear(10);
|
||||
}
|
||||
|
||||
UpdateNuklear(dev_ui);
|
||||
|
||||
float xpos = debug_xpos;
|
||||
float ypos = debug_ypos;
|
||||
|
||||
|
@ -397,6 +467,8 @@ void debug_draw(void) {
|
|||
debug_draw_list(items, xpos+DBG_SHADOW_OFFSET_XPOS, ypos+DBG_SHADOW_OFFSET_YPOS, 1); // NOTE(zaklaus): draw shadow
|
||||
debug_draw_list(items, xpos, ypos, 0);
|
||||
}
|
||||
|
||||
DrawNuklear(dev_ui);
|
||||
}
|
||||
|
||||
debug_area_status check_mouse_area(float xpos, float ypos, float w, float h) {
|
|
@ -1,8 +1,10 @@
|
|||
#include "debug/debug_ui.h"
|
||||
#include "dev/debug_ui.h"
|
||||
#include "world/blocks.h"
|
||||
#include "models/items.h"
|
||||
#include "net/network.h"
|
||||
|
||||
#include "models/entity.h"
|
||||
|
||||
void
|
||||
ActExitGame(void) {
|
||||
game_request_close();
|
||||
|
@ -22,89 +24,34 @@ ActSpawnCar(void) {
|
|||
}
|
||||
|
||||
void
|
||||
ActSpawnCoal(void) {
|
||||
ecs_entity_t e = item_spawn(ASSET_COAL, 32);
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
entity_set_position(e, dest->x, dest->y);
|
||||
|
||||
debug_replay_special_action(RPKIND_SPAWN_ICEMAKER_ITEM);
|
||||
ActSpawnItemPrev(void) {
|
||||
while (true) {
|
||||
--sel_item_id;
|
||||
item_id id = item_find_no_proxy(sel_item_id);
|
||||
if (sel_item_id > 0 && id != ASSET_INVALID && (item_get_usage(id) != UKIND_PROXY)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ActSpawnChest(void) {
|
||||
ecs_entity_t e = item_spawn(ASSET_CHEST, 32);
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
entity_set_position(e, dest->x, dest->y);
|
||||
|
||||
debug_replay_special_action(RPKIND_SPAWN_CHEST);
|
||||
ActSpawnItemNext(void) {
|
||||
while (true) {
|
||||
++sel_item_id;
|
||||
item_id id = item_find_no_proxy(sel_item_id);
|
||||
if (sel_item_id > 0 && id != ASSET_INVALID && (item_get_usage(id) != UKIND_PROXY)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ActSpawnBelt(void) {
|
||||
ecs_entity_t e = item_spawn(ASSET_BELT, 32);
|
||||
ActSpawnSelItem(void) {
|
||||
ecs_entity_t e = item_spawn(sel_item_id, 32);
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
entity_set_position(e, dest->x, dest->y);
|
||||
|
||||
debug_replay_special_action(RPKIND_SPAWN_BELT);
|
||||
}
|
||||
|
||||
void
|
||||
ActSpawnDurabilityTest(void) {
|
||||
ecs_entity_t e = item_spawn(ASSET_COAL, 1);
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
entity_set_position(e, dest->x, dest->y);
|
||||
|
||||
Item *it = ecs_get_mut(world_ecs(), e, Item);
|
||||
it->durability = (float)(rand() % 100) / 100.0f;
|
||||
}
|
||||
|
||||
void
|
||||
ActSpawnFurnace(void) {
|
||||
ecs_entity_t e = item_spawn(ASSET_FURNACE, 32);
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
entity_set_position(e, dest->x, dest->y);
|
||||
}
|
||||
|
||||
void
|
||||
ActSpawnBigTree(void) {
|
||||
ecs_entity_t e = item_spawn(ASSET_BIG_TREE, 32);
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
entity_set_position(e, dest->x, dest->y);
|
||||
}
|
||||
|
||||
void
|
||||
ActSpawnDemoHouseItem(void) {
|
||||
ecs_entity_t e = item_spawn(ASSET_BLUEPRINT, 1);
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
Position * dest = ecs_get_mut(world_ecs(), e, Position);
|
||||
*dest = *origin;
|
||||
entity_set_position(e, dest->x, dest->y);
|
||||
entity_set_position(e, origin->x, origin->y);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -285,8 +232,7 @@ ActSpawnDemoNPCs(void) {
|
|||
if (zpl_array_count(demo_npcs) >= 100000) return;
|
||||
|
||||
for (uint32_t i = 0; i < 1000; i++) {
|
||||
uint64_t e = entity_spawn(EKIND_DEMO_NPC);
|
||||
ecs_add(world_ecs(), e, DemoNPC);
|
||||
uint64_t e = entity_spawn_id(ASSET_CREATURE);
|
||||
Position *pos = ecs_get_mut(world_ecs(), e, Position);
|
||||
pos->x=(float)(rand() % world_dim());
|
||||
pos->y=(float)(rand() % world_dim());
|
|
@ -0,0 +1,143 @@
|
|||
// debug tools written with Nuklear UI
|
||||
#include "models/assets.h"
|
||||
#include "world/blocks.h"
|
||||
#include "models/items.h"
|
||||
|
||||
extern void tooltip_show_cursor(const char* name);
|
||||
extern const char *tooltip_find_desc_contents(const char *name);
|
||||
|
||||
void ToolAssetInspector(void) {
|
||||
if (nk_begin(dev_ui, "Asset Inspector", nk_rect(400, 100, 240, 800),
|
||||
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| NK_WINDOW_TITLE))
|
||||
{
|
||||
for (int i = 0; i < MAX_ASSETS; i++) {
|
||||
uint16_t idx = assets_find(i);
|
||||
if (idx != ASSET_INVALID && nk_tree_push_id(dev_ui, NK_TREE_TAB, asset_names[i], NK_MINIMIZED, i)) {
|
||||
{
|
||||
// draw kind
|
||||
const char *asset_kind_name = assets_get_kind_name(idx);
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "kind: %s", asset_kind_name);
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "spawnable entity: %s", entity_spawn_provided(i) ? "true" : "false");
|
||||
|
||||
if (nk_button_label(dev_ui, "show tooltip")) {
|
||||
tooltip_show_cursor(asset_names[i]);
|
||||
}
|
||||
|
||||
if (nk_button_label(dev_ui, "spawn at me")) {
|
||||
uint64_t e = entity_spawn_id(i);
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
entity_set_position(e, origin->x, origin->y);
|
||||
}
|
||||
|
||||
// draw help text
|
||||
if (nk_tree_push_id(dev_ui, NK_TREE_NODE, "description", NK_MINIMIZED, i)) {
|
||||
{
|
||||
const char *desc = tooltip_find_desc_contents(asset_names[i]);
|
||||
if (desc) {
|
||||
nk_layout_row_dynamic(dev_ui, 0, 1);
|
||||
nk_label_wrap(dev_ui, desc);
|
||||
}
|
||||
}
|
||||
nk_tree_pop(dev_ui);
|
||||
}
|
||||
// draw block
|
||||
block_id blk_id = blocks_find(i);
|
||||
if (blk_id != 0xF) {
|
||||
if (nk_tree_push_id(dev_ui, NK_TREE_NODE, "block", NK_MINIMIZED, i)) {
|
||||
{
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "symbol: %s", zpl_bprintf("%c", blocks_get_symbol(blk_id)));
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "flags: %u", blocks_get_flags(blk_id));
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "drag: %f", blocks_get_drag(blk_id));
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "friction: %f", blocks_get_friction(blk_id));
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "bounce: %f", blocks_get_bounce(blk_id));
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "velx: %f", blocks_get_velx(blk_id));
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "vely: %f", blocks_get_vely(blk_id));
|
||||
}
|
||||
nk_tree_pop(dev_ui);
|
||||
}
|
||||
}
|
||||
|
||||
// draw item
|
||||
item_id it_id = item_find_no_proxy(i);
|
||||
if (it_id != ASSET_INVALID) {
|
||||
if (nk_tree_push_id(dev_ui, NK_TREE_NODE, "item", NK_MINIMIZED, i)) {
|
||||
{
|
||||
item_desc it = item_get_desc(it_id);
|
||||
|
||||
if (nk_button_label(dev_ui, "spawn")) {
|
||||
ecs_entity_t e = item_spawn(i, it.max_quantity);
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
entity_set_position(e, origin->x, origin->y);
|
||||
}
|
||||
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "usage: %d", it.usage);
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "attachment: %d", it.attachment);
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "max quantity: %d", it.max_quantity);
|
||||
nk_labelf(dev_ui, NK_TEXT_LEFT, "has storage: %s", it.has_storage ? "true" : "false");
|
||||
|
||||
// todo: draw item-specific data
|
||||
}
|
||||
nk_tree_pop(dev_ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
nk_tree_pop(dev_ui);
|
||||
}
|
||||
}
|
||||
nk_end(dev_ui);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ToolEntityInspector(void) {
|
||||
if (nk_begin(dev_ui, "Entity Inspector", nk_rect(660, 100, 240, 800),
|
||||
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE| NK_WINDOW_TITLE))
|
||||
{
|
||||
static ecs_query_t *q = 0;
|
||||
if (!q) {
|
||||
q = ecs_query(world_ecs(), {
|
||||
.filter.terms = {
|
||||
{ .id = ecs_id(Position) },
|
||||
{ .id = ecs_id(Classify), .inout = EcsIn }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ecs_iter_t it = ecs_query_iter(world_ecs(), q);
|
||||
while (ecs_query_next(&it)) {
|
||||
Position *p = ecs_field(&it, Position, 1);
|
||||
const Classify *c = ecs_field(&it, Classify, 2);
|
||||
|
||||
for (int i = 0; i < it.count; i++) {
|
||||
if (nk_tree_push_id(dev_ui, NK_TREE_NODE, zpl_bprintf("%lld [%s]", it.entities[i], class_names[c[i].id]), NK_MINIMIZED, (int)it.entities[i])) {
|
||||
{
|
||||
nk_label(dev_ui, "position:", NK_TEXT_LEFT);
|
||||
nk_property_float(dev_ui, "#x:", ZPL_F32_MIN, &p[i].x, ZPL_F32_MAX, 0.1f, 0.2f);
|
||||
nk_property_float(dev_ui, "#y:", ZPL_F32_MIN, &p[i].y, ZPL_F32_MAX, 0.1f, 0.2f);
|
||||
|
||||
if (nk_button_label(dev_ui, "teleport to")) {
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), it.entities[i], Position);
|
||||
entity_set_position(plr, origin->x, origin->y);
|
||||
}
|
||||
|
||||
if (nk_button_label(dev_ui, "teleport here")) {
|
||||
ecs_entity_t plr = camera_get().ent_id;
|
||||
|
||||
Position const* origin = ecs_get(world_ecs(), plr, Position);
|
||||
entity_set_position(it.entities[i], origin->x, origin->y);
|
||||
}
|
||||
}
|
||||
nk_tree_pop(dev_ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nk_end(dev_ui);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#include "debug/debug_ui.h"
|
||||
#include "dev/debug_ui.h"
|
||||
#include "raylib.h"
|
||||
#include "platform/platform.h"
|
||||
#include "net/network.h"
|
||||
|
@ -119,6 +119,11 @@ DrawDemoNPCCount(debug_item *it, float xpos, float ypos) {
|
|||
return DrawFormattedText(xpos, ypos, TextFormat("%d", demo_npcs ? zpl_array_count(demo_npcs) : 0));
|
||||
}
|
||||
|
||||
static inline debug_draw_result
|
||||
DrawSelectedSpawnItem(debug_item *it, float xpos, float ypos) {
|
||||
(void)it;
|
||||
return DrawFormattedText(xpos, ypos, TextFormat("%s", asset_names[sel_item_id]));
|
||||
}
|
||||
|
||||
// NOTE(zaklaus): world simulation
|
||||
static inline debug_draw_result
|
|
@ -7,9 +7,7 @@ Texture2D texgen_build_anim_fallback(asset_id id, int64_t counter) {
|
|||
(void)counter;
|
||||
switch (id) {
|
||||
case ASSET_WATER: {
|
||||
Image img = LoadImageEco("water");
|
||||
ImageColorBrightness(&img, zpl_abs((counter % 64 - 32)*2));
|
||||
return Image2TexEco(img);
|
||||
return LoadTexEco(zpl_bprintf("%s%d", "water", counter%3));
|
||||
}break;
|
||||
|
||||
default: return GenColorEco(PINK); break;
|
||||
|
@ -21,11 +19,17 @@ Texture2D texgen_build_sprite_fallback(asset_id id) {
|
|||
case ASSET_BLANK: return GenColorEco(WHITE); break;
|
||||
case ASSET_BUILDMODE_HIGHLIGHT: return GenColorEco(WHITE); break;
|
||||
case ASSET_BLOCK_FRAME: return GenFrameRect(); break;
|
||||
case ASSET_BIG_TREE: return LoadTexEco("bigtree"); break;
|
||||
|
||||
// NOTE(zaklaus): items
|
||||
case ASSET_COAL: return LoadTexEco("coal");
|
||||
case ASSET_BLUEPRINT: return LoadTexEco("blueprint");
|
||||
case ASSET_IRON_ORE: return LoadTexEco("iron_ore");
|
||||
case ASSET_IRON_INGOT: return LoadTexEco("iron_ingot");
|
||||
case ASSET_IRON_PLATES: return LoadTexEco("iron_plate");
|
||||
case ASSET_SCREWS: return LoadTexEco("screws");
|
||||
case ASSET_LOG: return LoadTexEco("log");
|
||||
case ASSET_PLANK: return LoadTexEco("plank");
|
||||
case ASSET_CREATURE: return GenColorEco(YELLOW);
|
||||
case ASSET_CREATURE_FOOD: return GenColorEco(GREEN);
|
||||
|
||||
// NOTE(zaklaus): blocks
|
||||
case ASSET_FENCE: return LoadTexEco("fence");
|
||||
|
@ -36,7 +40,8 @@ Texture2D texgen_build_sprite_fallback(asset_id id) {
|
|||
case ASSET_HILL: return LoadTexEco("rock");
|
||||
case ASSET_LAVA: return LoadTexEco("lava");
|
||||
case ASSET_WOOD: return LoadTexEco("wood");
|
||||
case ASSET_TREE: return LoadTexEco("tree");
|
||||
case ASSET_TREE: return LoadTexEco("bigtree");
|
||||
case ASSET_TEST_TALL: return LoadTexEco("test-tall");
|
||||
// case ASSET_WATER: return LoadTexEco("water");
|
||||
|
||||
case ASSET_BELT:
|
||||
|
@ -47,8 +52,17 @@ Texture2D texgen_build_sprite_fallback(asset_id id) {
|
|||
|
||||
// NOTE(zaklaus): devices
|
||||
case ASSET_CHEST: return LoadTexEco("chest");
|
||||
case ASSET_FURNACE: return LoadTexEco("furnace-export");
|
||||
case ASSET_FURNACE: return LoadTexEco("furnace");
|
||||
case ASSET_CRAFTBENCH: return LoadTexEco("craftbench");
|
||||
case ASSET_SPLITTER: return LoadTexEco("item_splitter");
|
||||
case ASSET_ASSEMBLER: return LoadTexEco("assembler");
|
||||
|
||||
default: return GenColorEco(PINK); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (id > ASSET_BLUEPRINT_BEGIN && id < ASSET_BLUEPRINT_END) {
|
||||
return LoadTexEco("blueprint");
|
||||
}
|
||||
|
||||
return GenColorEco(PINK);
|
||||
}
|
||||
|
|
|
@ -41,13 +41,13 @@ void buildmode_draw(void) {
|
|||
buildmode_clear_buffers();
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_B)){
|
||||
if (input_is_pressed(IN_TOGGLE_DEMOLITION)){
|
||||
build_is_deletion_mode = !build_is_deletion_mode;
|
||||
}
|
||||
|
||||
Item *item = &e->items[e->selected_item];
|
||||
|
||||
if (e->has_items && !e->inside_vehicle && item->quantity > 0 && (!is_outside_range || build_is_deletion_mode)) {
|
||||
if (e->has_items && !e->inside_vehicle && (build_is_deletion_mode || (item->quantity > 0 && !is_outside_range))) {
|
||||
item_usage usage = 0;
|
||||
uint16_t item_id = 0;
|
||||
if (!build_is_deletion_mode){
|
||||
|
@ -69,8 +69,9 @@ void buildmode_draw(void) {
|
|||
qty = item->quantity;
|
||||
}
|
||||
|
||||
world_block_lookup l = world_block_from_realpos((float)cam.x, (float)cam.y);
|
||||
world_view_block_lookup l = world_view_block_from_realpos(game_world_view_get_active(), (float)cam.x, (float)cam.y);
|
||||
if (build_is_deletion_mode && !l.is_outer){
|
||||
renderer_draw_single((float)cam.x, (float)cam.y, ASSET_BUILDMODE_HIGHLIGHT, ColorAlpha(RED, 0.4f));
|
||||
goto build_skip_placements;
|
||||
}
|
||||
|
||||
|
@ -104,8 +105,12 @@ void buildmode_draw(void) {
|
|||
}
|
||||
|
||||
|
||||
if (!is_outside_range)
|
||||
renderer_draw_single((float)cam.x, (float)cam.y, ASSET_BUILDMODE_HIGHLIGHT, ColorAlpha(build_is_deletion_mode ? RED : WHITE, 0.2f));
|
||||
if (!is_outside_range) {
|
||||
if (build_is_deletion_mode)
|
||||
renderer_draw_single((float)cam.x, (float)cam.y, ASSET_BUILDMODE_HIGHLIGHT, ColorAlpha(RED, 0.2f));
|
||||
else
|
||||
renderer_draw_single((float)cam.x, (float)cam.y, item->kind, ColorAlpha(WHITE, 0.2f));
|
||||
}
|
||||
|
||||
build_skip_placements:
|
||||
build_num_placements = zpl_min(build_num_placements, qty);
|
||||
|
@ -114,7 +119,7 @@ void buildmode_draw(void) {
|
|||
|
||||
for (size_t i = 0; i < build_num_placements; i++) {
|
||||
item_placement *it = &build_placements[i];
|
||||
renderer_draw_single(it->x, it->y, ASSET_BUILDMODE_HIGHLIGHT, ColorAlpha(build_is_deletion_mode ? RED : WHITE, 0.4f));
|
||||
renderer_draw_single(it->x, it->y, !build_is_deletion_mode ? item->kind : ASSET_BUILDMODE_HIGHLIGHT, ColorAlpha(build_is_deletion_mode ? RED : RAYWHITE, 0.6f));
|
||||
}
|
||||
|
||||
if (build_is_in_draw_mode) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include "models/crafting.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t selected_item;
|
||||
bool drop_item;
|
||||
|
@ -11,6 +13,7 @@ typedef struct {
|
|||
bool swap;
|
||||
uint8_t swap_from;
|
||||
uint8_t swap_to;
|
||||
uint16_t craft_item;
|
||||
} inv_keystate;
|
||||
|
||||
static inv_keystate player_inv = {0};
|
||||
|
@ -21,6 +24,120 @@ bool inv_is_inside = false;
|
|||
bool inv_is_storage_action = false;
|
||||
bool inv_swap_storage = false;
|
||||
|
||||
// TODO(zaklaus):
|
||||
// TODO(zaklaus): MOVE TO COMMON UI MODULE
|
||||
// TODO(zaklaus):
|
||||
|
||||
typedef struct {
|
||||
float x, y;
|
||||
} inv_draw_result;
|
||||
|
||||
static inline
|
||||
int UIMeasureText(const char *text, int fontSize) {
|
||||
Vector2 vec = { 0.0f, 0.0f };
|
||||
|
||||
// Check if default font has been loaded
|
||||
if (GetFontDefault().texture.id != 0) {
|
||||
int defaultFontSize = 10; // Default Font chars height in pixel
|
||||
int new_spacing = fontSize/defaultFontSize;
|
||||
|
||||
vec = MeasureTextEx(GetFontDefault(), text, (float)fontSize, (float)new_spacing);
|
||||
}
|
||||
|
||||
return (int)vec.x;
|
||||
}
|
||||
|
||||
static inline
|
||||
void UIDrawText(const char *text, float posX, float posY, int fontSize, Color color) {
|
||||
// Check if default font has been loaded
|
||||
if (GetFontDefault().texture.id != 0) {
|
||||
Vector2 position = { (float)posX , (float)posY };
|
||||
|
||||
int defaultFontSize = 22; // Default Font chars height in pixel
|
||||
int new_spacing = fontSize/defaultFontSize;
|
||||
|
||||
DrawTextEx(GetFontDefault(), text, position, (float)fontSize , (float)new_spacing , color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline inv_draw_result
|
||||
DrawColoredText(float xpos, float ypos, char const *text, Color color) {
|
||||
ZPL_ASSERT(text);
|
||||
UIDrawText(text, xpos, ypos, 22, color);
|
||||
|
||||
char const *p = text;
|
||||
uint8_t newlines = 1;
|
||||
|
||||
do {
|
||||
if (*p == '\n')
|
||||
++newlines;
|
||||
} while (*p++ != 0);
|
||||
|
||||
return (inv_draw_result){.x = xpos + UIMeasureText(text, 22), .y = ypos + 22*newlines};
|
||||
}
|
||||
|
||||
|
||||
static inline
|
||||
inv_draw_result inventory_draw_crafting_btn(float xpos, float ypos, const char *name, uint16_t id, Color color) {
|
||||
float name_width=0.0f;
|
||||
char const *text = TextFormat("> %s", name);
|
||||
name_width = (float)UIMeasureText(text, 22);
|
||||
|
||||
Color new_color = color;
|
||||
if (is_btn_pressed(xpos, ypos, name_width, 22, &new_color)) {
|
||||
inv_is_inside = true;
|
||||
player_inv.craft_item = id;
|
||||
}
|
||||
|
||||
if (check_mouse_area(xpos, ypos, name_width, 22) != DAREA_OUTSIDE) {
|
||||
Vector2 mpos = GetMousePosition();
|
||||
recipe rp = craft_get_recipe_data(craft_get_recipe_id_from_product(id));
|
||||
if (nk_begin(game_ui , name, nk_rect(mpos.x+15, mpos.y+15, name_width+5, 1200),
|
||||
NK_WINDOW_BORDER | NK_WINDOW_NO_INPUT | NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_DYNAMIC)) {
|
||||
if (nk_tree_push_id(game_ui, NK_TREE_NODE, "Overview", NK_MAXIMIZED, id)) {
|
||||
{
|
||||
tooltip_draw_contents(tooltip_find_desc(name));
|
||||
}
|
||||
nk_tree_pop(game_ui);
|
||||
}
|
||||
if (nk_tree_push_id(game_ui, NK_TREE_NODE, "Reagents", NK_MAXIMIZED, id)) {
|
||||
for (asset_id i = 0; rp.reagents[i].id; i++) {
|
||||
nk_label(game_ui, asset_names[rp.reagents[i].id], NK_TEXT_LEFT);
|
||||
}
|
||||
nk_tree_pop(game_ui);
|
||||
}
|
||||
nk_end(game_ui);
|
||||
}
|
||||
}
|
||||
|
||||
Color _c_compare_lol = BLACK;
|
||||
if (!zpl_memcompare(&color, &_c_compare_lol, sizeof(Color))) {
|
||||
new_color = BLACK;
|
||||
}
|
||||
|
||||
inv_draw_result res = DrawColoredText(xpos, ypos, text, new_color);
|
||||
ypos = res.y;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline
|
||||
bool inventory_draw_crafting_list(entity_view *e, float xpos, float ypos) {
|
||||
float start_xpos = xpos;
|
||||
float start_ypos = ypos;
|
||||
|
||||
for (uint16_t i = 0; e->craftables[i]; ++i) {
|
||||
asset_id id = e->craftables[i];
|
||||
inventory_draw_crafting_btn(start_xpos+1, ypos+1, asset_names[id], id, BLACK);
|
||||
inv_draw_result entry = inventory_draw_crafting_btn(start_xpos, ypos, asset_names[id], id, RAYWHITE);
|
||||
ypos = entry.y;
|
||||
xpos = zpl_max(xpos, entry.x);
|
||||
}
|
||||
|
||||
return check_mouse_area(start_xpos, start_ypos, xpos-start_xpos, ypos-start_ypos) != DAREA_OUTSIDE;
|
||||
}
|
||||
|
||||
void inventory_draw_panel(entity_view *e, bool is_player, float sx, float sy){
|
||||
if (!e->has_items && is_player)
|
||||
return;
|
||||
|
@ -37,8 +154,10 @@ void inventory_draw_panel(entity_view *e, bool is_player, float sx, float sy){
|
|||
inv_keystate *inv = (!is_player) ? &storage_inv : &player_inv;
|
||||
inv_keystate *inv2 = (is_player) ? &storage_inv : &player_inv;
|
||||
|
||||
bool inside_craft = !is_player && inventory_draw_crafting_list(e, screenWidth/2.0f - 684, screenHeight/2.0f - 128);
|
||||
|
||||
inv->is_inside = check_mouse_area(sx, sy, (float)grid_size, (float)grid_size) != DAREA_OUTSIDE;
|
||||
inv_is_inside |= inv->is_inside;
|
||||
inv_is_inside |= inv->is_inside || inside_craft;
|
||||
|
||||
for (int32_t i = 0; i < inv_size; i += 1) {
|
||||
{
|
||||
|
@ -83,7 +202,11 @@ void inventory_draw_panel(entity_view *e, bool is_player, float sx, float sy){
|
|||
DrawRectangleLinesEco(x, y, 64, 64, color);
|
||||
|
||||
if (item->quantity > 0) {
|
||||
DrawTexturePro(GetSpriteTexture2D(assets_find(item->kind)), ASSET_SRC_RECT(), ASSET_DST_RECT(x,y), (Vector2){0.5f,0.5f}, 0.0f, WHITE);
|
||||
Texture2D tex = GetSpriteTexture2D(assets_find(item->kind));
|
||||
float aspect = tex.width/(float)tex.height;
|
||||
float size = WORLD_BLOCK_SIZE * aspect;
|
||||
float ofs_x = (WORLD_BLOCK_SIZE-size)/2.0f;
|
||||
DrawTexturePro(tex, ASSET_SRC_RECT_TEX(tex.width, tex.height), ASSET_DST_RECT_TEX(x+ofs_x, y, size, WORLD_BLOCK_SIZE), (Vector2){0.5f,0.5f}, 0.0f, WHITE);
|
||||
}
|
||||
|
||||
if (item->quantity > 1) {
|
||||
|
@ -116,7 +239,11 @@ void inventory_render_held_item(bool is_player){
|
|||
Vector2 mpos = GetMousePosition();
|
||||
mpos.x -= 32;
|
||||
mpos.y -= 32;
|
||||
DrawTexturePro(GetSpriteTexture2D(assets_find(inv->held_item.kind)), ASSET_SRC_RECT(), ASSET_DST_RECT(mpos.x, mpos.y), (Vector2){0.5f,0.5f}, 0.0f, ColorAlpha(WHITE, 0.8f));
|
||||
Texture2D tex = GetSpriteTexture2D(assets_find(inv->held_item.kind));
|
||||
float aspect = tex.width/(float)tex.height;
|
||||
float size = WORLD_BLOCK_SIZE * aspect;
|
||||
float ofs_x = (WORLD_BLOCK_SIZE-size)/2.0f;
|
||||
DrawTexturePro(tex, ASSET_SRC_RECT_TEX(tex.width, tex.height), ASSET_DST_RECT_TEX(mpos.x+ofs_x, mpos.y, size, WORLD_BLOCK_SIZE), (Vector2){0.5f,0.5f}, 0.0f, ColorAlpha(WHITE, 0.8f));
|
||||
DrawTextEco(zpl_bprintf("%d", inv->held_item.quantity), mpos.x, mpos.y, 16, RAYWHITE, 0.0f);
|
||||
|
||||
if (!inv->is_inside && IsMouseButtonReleased(MOUSE_LEFT_BUTTON) && !inv2->is_inside) {
|
||||
|
@ -130,6 +257,7 @@ void inventory_render_held_item(bool is_player){
|
|||
void inventory_reset_states(inv_keystate *ik) {
|
||||
ik->drop_item = false;
|
||||
ik->swap = false;
|
||||
ik->craft_item = 0;
|
||||
}
|
||||
|
||||
void inventory_draw() {
|
||||
|
@ -143,7 +271,7 @@ void inventory_draw() {
|
|||
entity_view *e = game_world_view_active_get_entity(cam.ent_id);
|
||||
if (!e || !e->has_items) return;
|
||||
|
||||
if (IsKeyPressed(KEY_TAB)) {
|
||||
if (input_is_pressed(IN_TOGGLE_INV)) {
|
||||
inv_is_open = !inv_is_open;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
#define MAX_NOTIFICATIONS_ON_SCREEN 5
|
||||
|
||||
typedef struct {
|
||||
zpl_string title;
|
||||
zpl_string text;
|
||||
} notification;
|
||||
|
||||
static notification *notifications = 0;
|
||||
|
||||
static bool show_notification_list = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void notification_draw(void) {
|
||||
float width = (float)GetScreenWidth();
|
||||
float height = (float)GetScreenHeight();
|
||||
// draw ctrl panel
|
||||
if (nk_begin(game_ui, "Notifications", nk_rect(width - 220, 20, 200, 80),
|
||||
NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_TITLE | NK_WINDOW_DYNAMIC)) {
|
||||
{
|
||||
nk_layout_row_dynamic(game_ui, 0, 2);
|
||||
|
||||
if (nk_button_label(game_ui, "Clear All")) {
|
||||
notification_clear();
|
||||
}
|
||||
|
||||
if (nk_button_label(game_ui, show_notification_list ? "Hide Manager" : "Show All")) {
|
||||
show_notification_list ^= 1;
|
||||
}
|
||||
}
|
||||
nk_end(game_ui);
|
||||
}
|
||||
|
||||
float ypos = 100;
|
||||
zpl_isize cnt = zpl_min(zpl_array_count(notifications), MAX_NOTIFICATIONS_ON_SCREEN)-1;
|
||||
|
||||
for (zpl_isize i = cnt; i >= 0; --i) {
|
||||
notification *notif = (notifications + i);
|
||||
if (nk_begin_titled(game_ui, zpl_bprintf("%d%fnotif%s", i, ypos, notif->title), notif->title, nk_rect(width - 320, ypos, 300, 1200),
|
||||
NK_WINDOW_DYNAMIC|NK_WINDOW_NO_SCROLLBAR)) {
|
||||
{
|
||||
if (nk_tree_push_id(game_ui, NK_TREE_TAB, notif->title, NK_MAXIMIZED, (int)i)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
ypos += nk_window_get_panel(game_ui)->row.height + 80;
|
||||
|
||||
nk_end(game_ui);
|
||||
}
|
||||
}
|
||||
|
||||
if (show_notification_list) {
|
||||
if (nk_begin(game_ui, "Notifications Manager", nk_rect(width/2.0f - 320, height/2.0f - 240, 640, 480),
|
||||
NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_TITLE | NK_WINDOW_MOVABLE | NK_WINDOW_DYNAMIC )) {
|
||||
{
|
||||
nk_layout_row_dynamic(game_ui, 5 , 1);
|
||||
{
|
||||
for (zpl_isize i = 0; i < zpl_array_count(notifications); ++i) {
|
||||
notification *notif = (notifications + i);
|
||||
if (nk_tree_push_id(game_ui, NK_TREE_TAB, notif->title, NK_MINIMIZED, (int)i)) {
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
nk_tree_pop(game_ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nk_layout_row_dynamic(game_ui, 0, 2);
|
||||
|
||||
if (nk_button_label(game_ui, "Clear All")) {
|
||||
notification_clear();
|
||||
}
|
||||
|
||||
if (nk_button_label(game_ui, "Hide Manager")) {
|
||||
show_notification_list = 0 ;
|
||||
}
|
||||
}
|
||||
nk_end(game_ui);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void notification_push(const char* title, const char* text);
|
|
@ -0,0 +1,14 @@
|
|||
void spritesheet_viewer(struct nk_context *ctx, struct nk_image spritesheet, Vector2 frameSize, int framesPerRow) {
|
||||
const int maxFrames = (int)((spritesheet.w*spritesheet.h) / (frameSize.x*frameSize.y));
|
||||
nk_layout_row_static(ctx, 32, 32, (int)(nk_window_get_size(ctx).x / frameSize.x) -1);
|
||||
for(int frame = 0; frame < maxFrames; frame++) {
|
||||
float ox = (frame % framesPerRow) * frameSize.x;
|
||||
float oy = (int)(frame / framesPerRow) * frameSize.y;
|
||||
spritesheet.region[0] = (nk_ushort)ox;
|
||||
spritesheet.region[1] = (nk_ushort)oy;
|
||||
spritesheet.region[2] = (nk_ushort)frameSize.x;
|
||||
spritesheet.region[3] = (nk_ushort)frameSize.y;
|
||||
nk_image(ctx, spritesheet);
|
||||
nk_labelf(ctx, NK_TEXT_ALIGN_LEFT, "%d", frame);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,254 @@
|
|||
// Tooltip system with multilevel modal support
|
||||
|
||||
typedef struct _tooltip {
|
||||
const char *name;
|
||||
const char *content;
|
||||
const char **links;
|
||||
} tooltip;
|
||||
|
||||
static tooltip *tooltips = 0;
|
||||
|
||||
//~ registration
|
||||
|
||||
void tooltip_register(tooltip desc) {
|
||||
if (!tooltips) {
|
||||
zpl_array_init(tooltips, zpl_heap());
|
||||
}
|
||||
|
||||
desc.links = 0;
|
||||
zpl_array_append(tooltips, desc);
|
||||
}
|
||||
|
||||
void tooltip_destroy_all(void) {
|
||||
if (!tooltips) return;
|
||||
|
||||
for (zpl_isize i = 0; i < zpl_array_count(tooltips); ++i) {
|
||||
tooltip *tp = (tooltips + i);
|
||||
|
||||
if (tp->links) {
|
||||
zpl_array_free(tp->links);
|
||||
}
|
||||
}
|
||||
|
||||
zpl_array_free(tooltips);
|
||||
}
|
||||
|
||||
void tooltip_build_links(void) {
|
||||
for (zpl_isize i = 0; i < zpl_array_count(tooltips); ++i) {
|
||||
tooltip *tp = (tooltips + i);
|
||||
|
||||
for (zpl_isize j = 0; j < zpl_array_count(tooltips); ++j) {
|
||||
tooltip *linked_tp = (tooltips + j);
|
||||
if (tp == linked_tp)
|
||||
continue;
|
||||
|
||||
if (strstr(tp->content, linked_tp->name)) {
|
||||
if (!tp->links) {
|
||||
zpl_array_init(tp->links, zpl_heap());
|
||||
}
|
||||
|
||||
zpl_array_append(tp->links, linked_tp->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tooltip_register_defaults(void) {
|
||||
// test
|
||||
tooltip_register( (tooltip) { .name = "ASSET_WOOD", .content = "Used as a building material or fuel for the ASSET_FURNACE." } );
|
||||
tooltip_register( (tooltip) { .name = "ASSET_FURNACE", .content = "Producer used to smelt ASSET_IRON_ORE into ASSET_IRON_INGOT." } );
|
||||
tooltip_register( (tooltip) { .name = "ASSET_IRON_ORE", .content = "Natural resource that can be smelted in ASSET_FURNACE." } );
|
||||
tooltip_register( (tooltip) { .name = "ASSET_IRON_INGOT", .content = "Used as a building material. It is smelted from ASSET_IRON_ORE." } );
|
||||
tooltip_register( (tooltip) { .name = "ASSET_SCREWS", .content = "Used as a building material. It is crafted from ASSET_IRON_PLATES." } );
|
||||
tooltip_register( (tooltip) { .name = "craft", .content = "Crafting is the process of constructing tools, items, and blocks." } );
|
||||
tooltip_register( (tooltip) { .name = "smelt", .content = "Smelting is a process of applying heat to ore, to extract a base metal. It is a form of extractive metallurgy. It is used to extract many metals from their ores, including silver, iron, copper, and other base metals." } );
|
||||
}
|
||||
|
||||
//~ rendering
|
||||
|
||||
#define TOOLTIP_MOUSE_DIST 400.0f
|
||||
|
||||
typedef struct _tooltip_node {
|
||||
float xpos, ypos;
|
||||
tooltip *desc;
|
||||
struct _tooltip_node *next;
|
||||
} tooltip_node;
|
||||
|
||||
static tooltip_node main_tooltip = { 0 };
|
||||
static bool tooltip__should_stay_open = false;
|
||||
|
||||
tooltip *tooltip_find_desc(const char *name) {
|
||||
for (zpl_isize i = 0; i < zpl_array_count(tooltips); ++i) {
|
||||
tooltip *tp = (tooltips + i);
|
||||
|
||||
if (!strcmp(tp->name, name))
|
||||
return tp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *tooltip_find_desc_contents(const char *name) {
|
||||
if (!tooltips) return 0;
|
||||
|
||||
for (zpl_isize i = 0; i < zpl_array_count(tooltips); ++i) {
|
||||
tooltip *tp = (tooltips + i);
|
||||
|
||||
if (!strcmp(tp->name, name))
|
||||
return tp->content;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tooltip_clear(void);
|
||||
|
||||
void tooltip_show(const char* name, float xpos, float ypos) {
|
||||
if (!tooltips) return;
|
||||
|
||||
tooltip *desc = tooltip_find_desc(name);
|
||||
if (!name) return;
|
||||
|
||||
tooltip_clear();
|
||||
|
||||
main_tooltip = (tooltip_node) {
|
||||
.xpos = xpos,
|
||||
.ypos = ypos,
|
||||
.desc = desc,
|
||||
.next = 0
|
||||
};
|
||||
}
|
||||
|
||||
void tooltip_show_cursor(const char* name) {
|
||||
Vector2 mpos = GetMousePosition();
|
||||
tooltip_show(name, mpos.x + 15, mpos.y + 15);
|
||||
}
|
||||
|
||||
void tooltip__clear_node(tooltip_node *node) {
|
||||
if (node->next) {
|
||||
tooltip__clear_node(node->next);
|
||||
zpl_mfree(node->next);
|
||||
}
|
||||
}
|
||||
|
||||
void tooltip_clear(void) {
|
||||
tooltip__clear_node(&main_tooltip);
|
||||
main_tooltip = (tooltip_node) {0};
|
||||
}
|
||||
|
||||
void tooltip_draw_contents(tooltip *desc) {
|
||||
if (!desc) return;
|
||||
nk_layout_row_dynamic(game_ui, 0, 1);
|
||||
nk_label_wrap(game_ui, desc->content);
|
||||
}
|
||||
|
||||
void tooltip__draw_node(tooltip_node *node) {
|
||||
if (!node) return;
|
||||
if (!node->desc) return;
|
||||
|
||||
tooltip *desc = node->desc;
|
||||
Vector2 mpos = GetMousePosition();
|
||||
|
||||
if (nk_begin_titled(game_ui, zpl_bprintf("%d%s", (int)node->xpos, desc->name), desc->name, nk_rect(node->xpos, node->ypos, 500, 3200),
|
||||
NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_DYNAMIC | NK_WINDOW_TITLE | NK_WINDOW_MOVABLE)) {
|
||||
tooltip_draw_contents(desc);
|
||||
|
||||
if (desc->links) {
|
||||
nk_label(game_ui, "See Also:", NK_TEXT_LEFT);
|
||||
nk_layout_row_dynamic(game_ui, 20, 2);
|
||||
|
||||
for (zpl_isize i = 0; i < zpl_array_count(desc->links); ++i) {
|
||||
if (nk_button_label(game_ui, desc->links[i])) {
|
||||
if (node->next) tooltip__clear_node(node->next);
|
||||
if (!node->next) node->next = zpl_malloc(sizeof(tooltip_node));
|
||||
*node->next = (tooltip_node) {
|
||||
.xpos = mpos.x+15,
|
||||
.ypos = mpos.y+15,
|
||||
.desc = tooltip_find_desc(desc->links[i]),
|
||||
.next = 0
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// suggest closing tooltip
|
||||
struct nk_vec2 wpos = nk_window_get_position(game_ui);
|
||||
struct nk_vec2 wsize = nk_window_get_content_region_size(game_ui);
|
||||
struct nk_panel *wpanel = nk_window_get_panel(game_ui);
|
||||
Vector2 tp_pos = (Vector2) { .x = wpos.x + wsize.x/2.0f, .y = wpos.y + wpanel->row.height / 2.0f };
|
||||
if (Vector2Distance(mpos, tp_pos) <= TOOLTIP_MOUSE_DIST) {
|
||||
tooltip__should_stay_open = true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
DrawCircleV(tp_pos, TOOLTIP_MOUSE_DIST, BLUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
nk_end(game_ui);
|
||||
|
||||
// draw nested tooltip
|
||||
if (node->next) {
|
||||
tooltip__draw_node(node->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tooltip_draw(void) {
|
||||
// draw tooltip
|
||||
tooltip__draw_node(&main_tooltip);
|
||||
|
||||
if (!tooltip__should_stay_open) {
|
||||
tooltip_clear();
|
||||
}
|
||||
|
||||
tooltip__should_stay_open = false;
|
||||
|
||||
// draw search bar
|
||||
float width = (float)GetScreenWidth();
|
||||
float height = (float)GetScreenHeight();
|
||||
|
||||
if (nk_begin(game_ui, "#searchbar", nk_rect(width / 2.0f - 200, 15.f, 400, 600), NK_WINDOW_DYNAMIC | NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR)) {
|
||||
{
|
||||
static int len=0; static char buffer[256] = { 0 };
|
||||
|
||||
|
||||
static bool show_all = false;
|
||||
|
||||
if (len > 0) {
|
||||
nk_layout_row_dynamic(game_ui, 15, 1);
|
||||
if (nk_button_label(game_ui, "clear all")) {
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nk_layout_row_dynamic(game_ui, 35, 1);
|
||||
|
||||
if (!(nk_edit_string(game_ui, NK_EDIT_SIMPLE, buffer, &len, 255, nk_filter_ascii) & NK_WIDGET_STATE_ACTIVE) && len == 0 ) {
|
||||
show_all = true;
|
||||
}
|
||||
buffer[len] = 0;
|
||||
|
||||
if (len > 0 || show_all) {
|
||||
if (nk_tree_push(game_ui, NK_TREE_TAB, "results", NK_MAXIMIZED)) {
|
||||
for (zpl_isize i = 0; i < zpl_array_count(tooltips); ++i) {
|
||||
tooltip *tp = (tooltips + i);
|
||||
|
||||
if (strstr(tp->name, buffer) || show_all) {
|
||||
if (nk_button_label(game_ui, tp->name)) {
|
||||
tooltip_show_cursor(tp->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
nk_tree_pop(game_ui);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT) || len > 0) {
|
||||
show_all = false;
|
||||
}
|
||||
}
|
||||
nk_end(game_ui);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,483 @@
|
|||
enum theme {THEME_BLACK, THEME_WHITE, THEME_RED, THEME_BLUE, THEME_DARK, THEME_ECO};
|
||||
|
||||
static void set_style(struct nk_context *ctx, enum theme theme)
|
||||
{
|
||||
struct nk_color table[NK_COLOR_COUNT];
|
||||
if (theme == THEME_WHITE) {
|
||||
table[NK_COLOR_TEXT] = nk_rgba(70, 70, 70, 255);
|
||||
table[NK_COLOR_WINDOW] = nk_rgba(175, 175, 175, 255);
|
||||
table[NK_COLOR_HEADER] = nk_rgba(175, 175, 175, 255);
|
||||
table[NK_COLOR_BORDER] = nk_rgba(0, 0, 0, 255);
|
||||
table[NK_COLOR_BUTTON] = nk_rgba(185, 185, 185, 255);
|
||||
table[NK_COLOR_BUTTON_HOVER] = nk_rgba(170, 170, 170, 255);
|
||||
table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(160, 160, 160, 255);
|
||||
table[NK_COLOR_TOGGLE] = nk_rgba(150, 150, 150, 255);
|
||||
table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(120, 120, 120, 255);
|
||||
table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(175, 175, 175, 255);
|
||||
table[NK_COLOR_SELECT] = nk_rgba(190, 190, 190, 255);
|
||||
table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(175, 175, 175, 255);
|
||||
table[NK_COLOR_SLIDER] = nk_rgba(190, 190, 190, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(80, 80, 80, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(70, 70, 70, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(60, 60, 60, 255);
|
||||
table[NK_COLOR_PROPERTY] = nk_rgba(175, 175, 175, 255);
|
||||
table[NK_COLOR_EDIT] = nk_rgba(150, 150, 150, 255);
|
||||
table[NK_COLOR_EDIT_CURSOR] = nk_rgba(0, 0, 0, 255);
|
||||
table[NK_COLOR_COMBO] = nk_rgba(175, 175, 175, 255);
|
||||
table[NK_COLOR_CHART] = nk_rgba(160, 160, 160, 255);
|
||||
table[NK_COLOR_CHART_COLOR] = nk_rgba(45, 45, 45, 255);
|
||||
table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba( 255, 0, 0, 255);
|
||||
table[NK_COLOR_SCROLLBAR] = nk_rgba(180, 180, 180, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(140, 140, 140, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(150, 150, 150, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(160, 160, 160, 255);
|
||||
table[NK_COLOR_TAB_HEADER] = nk_rgba(180, 180, 180, 255);
|
||||
nk_style_from_table(ctx, table);
|
||||
} else if (theme == THEME_RED) {
|
||||
table[NK_COLOR_TEXT] = nk_rgba(190, 190, 190, 255);
|
||||
table[NK_COLOR_WINDOW] = nk_rgba(30, 33, 40, 215);
|
||||
table[NK_COLOR_HEADER] = nk_rgba(181, 45, 69, 220);
|
||||
table[NK_COLOR_BORDER] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_BUTTON] = nk_rgba(181, 45, 69, 255);
|
||||
table[NK_COLOR_BUTTON_HOVER] = nk_rgba(190, 50, 70, 255);
|
||||
table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(195, 55, 75, 255);
|
||||
table[NK_COLOR_TOGGLE] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(45, 60, 60, 255);
|
||||
table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(181, 45, 69, 255);
|
||||
table[NK_COLOR_SELECT] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(181, 45, 69, 255);
|
||||
table[NK_COLOR_SLIDER] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(181, 45, 69, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(186, 50, 74, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(191, 55, 79, 255);
|
||||
table[NK_COLOR_PROPERTY] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_EDIT] = nk_rgba(51, 55, 67, 225);
|
||||
table[NK_COLOR_EDIT_CURSOR] = nk_rgba(190, 190, 190, 255);
|
||||
table[NK_COLOR_COMBO] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_CHART] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_CHART_COLOR] = nk_rgba(170, 40, 60, 255);
|
||||
table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba( 255, 0, 0, 255);
|
||||
table[NK_COLOR_SCROLLBAR] = nk_rgba(30, 33, 40, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(64, 84, 95, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(70, 90, 100, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(75, 95, 105, 255);
|
||||
table[NK_COLOR_TAB_HEADER] = nk_rgba(181, 45, 69, 220);
|
||||
nk_style_from_table(ctx, table);
|
||||
} else if (theme == THEME_ECO) {
|
||||
table[NK_COLOR_TEXT] = nk_rgba(190, 190, 190, 255);
|
||||
table[NK_COLOR_WINDOW] = nk_rgba(40, 43, 10, 235);
|
||||
table[NK_COLOR_HEADER] = nk_rgba(32, 96, 64 , 220);
|
||||
table[NK_COLOR_BORDER] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_BUTTON] = nk_rgba(20, 23, 30, 215);
|
||||
table[NK_COLOR_BUTTON_HOVER] = nk_rgba(32, 96, 64 , 235);
|
||||
table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(52, 116, 84 , 255);
|
||||
table[NK_COLOR_TOGGLE] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(45, 60, 60, 255);
|
||||
table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(181, 45, 69, 255);
|
||||
table[NK_COLOR_SELECT] = nk_rgba(20, 23, 30, 215);
|
||||
table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(181, 45, 69, 255);
|
||||
table[NK_COLOR_SLIDER] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(181, 45, 69, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(186, 50, 74, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(191, 55, 79, 255);
|
||||
table[NK_COLOR_PROPERTY] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_EDIT] = nk_rgba(51, 55, 67, 225);
|
||||
table[NK_COLOR_EDIT_CURSOR] = nk_rgba(190, 190, 190, 255);
|
||||
table[NK_COLOR_COMBO] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_CHART] = nk_rgba(51, 55, 67, 255);
|
||||
table[NK_COLOR_CHART_COLOR] = nk_rgba(170, 40, 60, 255);
|
||||
table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba( 255, 0, 0, 255);
|
||||
table[NK_COLOR_SCROLLBAR] = nk_rgba(30, 33, 40, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(64, 84, 95, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(70, 90, 100, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(75, 95, 105, 255);
|
||||
table[NK_COLOR_TAB_HEADER] = nk_rgba(32, 96, 64 , 220);
|
||||
nk_style_from_table(ctx, table);
|
||||
} else if (theme == THEME_BLUE) {
|
||||
table[NK_COLOR_TEXT] = nk_rgba(20, 20, 20, 255);
|
||||
table[NK_COLOR_WINDOW] = nk_rgba(202, 212, 214, 215);
|
||||
table[NK_COLOR_HEADER] = nk_rgba(137, 182, 224, 220);
|
||||
table[NK_COLOR_BORDER] = nk_rgba(140, 159, 173, 255);
|
||||
table[NK_COLOR_BUTTON] = nk_rgba(137, 182, 224, 255);
|
||||
table[NK_COLOR_BUTTON_HOVER] = nk_rgba(142, 187, 229, 255);
|
||||
table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(147, 192, 234, 255);
|
||||
table[NK_COLOR_TOGGLE] = nk_rgba(177, 210, 210, 255);
|
||||
table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(182, 215, 215, 255);
|
||||
table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(137, 182, 224, 255);
|
||||
table[NK_COLOR_SELECT] = nk_rgba(177, 210, 210, 255);
|
||||
table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(137, 182, 224, 255);
|
||||
table[NK_COLOR_SLIDER] = nk_rgba(177, 210, 210, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(137, 182, 224, 245);
|
||||
table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(142, 188, 229, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(147, 193, 234, 255);
|
||||
table[NK_COLOR_PROPERTY] = nk_rgba(210, 210, 210, 255);
|
||||
table[NK_COLOR_EDIT] = nk_rgba(210, 210, 210, 225);
|
||||
table[NK_COLOR_EDIT_CURSOR] = nk_rgba(20, 20, 20, 255);
|
||||
table[NK_COLOR_COMBO] = nk_rgba(210, 210, 210, 255);
|
||||
table[NK_COLOR_CHART] = nk_rgba(210, 210, 210, 255);
|
||||
table[NK_COLOR_CHART_COLOR] = nk_rgba(137, 182, 224, 255);
|
||||
table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba( 255, 0, 0, 255);
|
||||
table[NK_COLOR_SCROLLBAR] = nk_rgba(190, 200, 200, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(64, 84, 95, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(70, 90, 100, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(75, 95, 105, 255);
|
||||
table[NK_COLOR_TAB_HEADER] = nk_rgba(156, 193, 220, 255);
|
||||
nk_style_from_table(ctx, table);
|
||||
} else if (theme == THEME_DARK) {
|
||||
table[NK_COLOR_TEXT] = nk_rgba(210, 210, 210, 255);
|
||||
table[NK_COLOR_WINDOW] = nk_rgba(57, 67, 71, 215);
|
||||
table[NK_COLOR_HEADER] = nk_rgba(51, 51, 56, 220);
|
||||
table[NK_COLOR_BORDER] = nk_rgba(46, 46, 46, 255);
|
||||
table[NK_COLOR_BUTTON] = nk_rgba(48, 83, 111, 255);
|
||||
table[NK_COLOR_BUTTON_HOVER] = nk_rgba(58, 93, 121, 255);
|
||||
table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(63, 98, 126, 255);
|
||||
table[NK_COLOR_TOGGLE] = nk_rgba(50, 58, 61, 255);
|
||||
table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(45, 53, 56, 255);
|
||||
table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(48, 83, 111, 255);
|
||||
table[NK_COLOR_SELECT] = nk_rgba(57, 67, 61, 255);
|
||||
table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(48, 83, 111, 255);
|
||||
table[NK_COLOR_SLIDER] = nk_rgba(50, 58, 61, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(48, 83, 111, 245);
|
||||
table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(53, 88, 116, 255);
|
||||
table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(58, 93, 121, 255);
|
||||
table[NK_COLOR_PROPERTY] = nk_rgba(50, 58, 61, 255);
|
||||
table[NK_COLOR_EDIT] = nk_rgba(50, 58, 61, 225);
|
||||
table[NK_COLOR_EDIT_CURSOR] = nk_rgba(210, 210, 210, 255);
|
||||
table[NK_COLOR_COMBO] = nk_rgba(50, 58, 61, 255);
|
||||
table[NK_COLOR_CHART] = nk_rgba(50, 58, 61, 255);
|
||||
table[NK_COLOR_CHART_COLOR] = nk_rgba(48, 83, 111, 255);
|
||||
table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba(255, 0, 0, 255);
|
||||
table[NK_COLOR_SCROLLBAR] = nk_rgba(50, 58, 61, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(48, 83, 111, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(53, 88, 116, 255);
|
||||
table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(58, 93, 121, 255);
|
||||
table[NK_COLOR_TAB_HEADER] = nk_rgba(48, 83, 111, 255);
|
||||
nk_style_from_table(ctx, table);
|
||||
} else {
|
||||
nk_style_default(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
typedef struct media {
|
||||
GLint skin;
|
||||
struct nk_image menu;
|
||||
struct nk_image check;
|
||||
struct nk_image check_cursor;
|
||||
struct nk_image option;
|
||||
struct nk_image option_cursor;
|
||||
struct nk_image header;
|
||||
struct nk_image window;
|
||||
struct nk_image scrollbar_inc_button;
|
||||
struct nk_image scrollbar_inc_button_hover;
|
||||
struct nk_image scrollbar_dec_button;
|
||||
struct nk_image scrollbar_dec_button_hover;
|
||||
struct nk_image button;
|
||||
struct nk_image button_hover;
|
||||
struct nk_image button_active;
|
||||
struct nk_image tab_minimize;
|
||||
struct nk_image tab_maximize;
|
||||
struct nk_image slider;
|
||||
struct nk_image slider_hover;
|
||||
struct nk_image slider_active;
|
||||
} media;
|
||||
|
||||
void nk_skin_gwen(void) {
|
||||
media.skin = image_load("../skins/gwen.png");
|
||||
media.check = nk_subimage_id(media.skin, 512,512, nk_rect(464,32,15,15));
|
||||
media.check_cursor = nk_subimage_id(media.skin, 512,512, nk_rect(450,34,11,11));
|
||||
media.option = nk_subimage_id(media.skin, 512,512, nk_rect(464,64,15,15));
|
||||
media.option_cursor = nk_subimage_id(media.skin, 512,512, nk_rect(451,67,9,9));
|
||||
media.header = nk_subimage_id(media.skin, 512,512, nk_rect(128,0,127,24));
|
||||
media.window = nk_subimage_id(media.skin, 512,512, nk_rect(128,23,127,104));
|
||||
media.scrollbar_inc_button = nk_subimage_id(media.skin, 512,512, nk_rect(464,256,15,15));
|
||||
media.scrollbar_inc_button_hover = nk_subimage_id(media.skin, 512,512, nk_rect(464,320,15,15));
|
||||
media.scrollbar_dec_button = nk_subimage_id(media.skin, 512,512, nk_rect(464,224,15,15));
|
||||
media.scrollbar_dec_button_hover = nk_subimage_id(media.skin, 512,512, nk_rect(464,288,15,15));
|
||||
media.button = nk_subimage_id(media.skin, 512,512, nk_rect(384,336,127,31));
|
||||
media.button_hover = nk_subimage_id(media.skin, 512,512, nk_rect(384,368,127,31));
|
||||
media.button_active = nk_subimage_id(media.skin, 512,512, nk_rect(384,400,127,31));
|
||||
media.tab_minimize = nk_subimage_id(media.skin, 512,512, nk_rect(451, 99, 9, 9));
|
||||
media.tab_maximize = nk_subimage_id(media.skin, 512,512, nk_rect(467,99,9,9));
|
||||
media.slider = nk_subimage_id(media.skin, 512,512, nk_rect(418,33,11,14));
|
||||
media.slider_hover = nk_subimage_id(media.skin, 512,512, nk_rect(418,49,11,14));
|
||||
media.slider_active = nk_subimage_id(media.skin, 512,512, nk_rect(418,64,11,14));
|
||||
|
||||
/* window */
|
||||
ctx.style.window.background = nk_rgb(204,204,204);
|
||||
ctx.style.window.fixed_background = nk_style_item_image(media.window);
|
||||
ctx.style.window.border_color = nk_rgb(67,67,67);
|
||||
ctx.style.window.combo_border_color = nk_rgb(67,67,67);
|
||||
ctx.style.window.contextual_border_color = nk_rgb(67,67,67);
|
||||
ctx.style.window.menu_border_color = nk_rgb(67,67,67);
|
||||
ctx.style.window.group_border_color = nk_rgb(67,67,67);
|
||||
ctx.style.window.tooltip_border_color = nk_rgb(67,67,67);
|
||||
ctx.style.window.scrollbar_size = nk_vec2(16,16);
|
||||
ctx.style.window.border_color = nk_rgba(0,0,0,0);
|
||||
ctx.style.window.padding = nk_vec2(8,4);
|
||||
ctx.style.window.border = 3;
|
||||
|
||||
/* window header */
|
||||
ctx.style.window.header.normal = nk_style_item_image(media.header);
|
||||
ctx.style.window.header.hover = nk_style_item_image(media.header);
|
||||
ctx.style.window.header.active = nk_style_item_image(media.header);
|
||||
ctx.style.window.header.label_normal = nk_rgb(95,95,95);
|
||||
ctx.style.window.header.label_hover = nk_rgb(95,95,95);
|
||||
ctx.style.window.header.label_active = nk_rgb(95,95,95);
|
||||
|
||||
/* scrollbar */
|
||||
ctx.style.scrollv.normal = nk_style_item_color(nk_rgb(184,184,184));
|
||||
ctx.style.scrollv.hover = nk_style_item_color(nk_rgb(184,184,184));
|
||||
ctx.style.scrollv.active = nk_style_item_color(nk_rgb(184,184,184));
|
||||
ctx.style.scrollv.cursor_normal = nk_style_item_color(nk_rgb(220,220,220));
|
||||
ctx.style.scrollv.cursor_hover = nk_style_item_color(nk_rgb(235,235,235));
|
||||
ctx.style.scrollv.cursor_active = nk_style_item_color(nk_rgb(99,202,255));
|
||||
ctx.style.scrollv.dec_symbol = NK_SYMBOL_NONE;
|
||||
ctx.style.scrollv.inc_symbol = NK_SYMBOL_NONE;
|
||||
ctx.style.scrollv.show_buttons = nk_true;
|
||||
ctx.style.scrollv.border_color = nk_rgb(81,81,81);
|
||||
ctx.style.scrollv.cursor_border_color = nk_rgb(81,81,81);
|
||||
ctx.style.scrollv.border = 1;
|
||||
ctx.style.scrollv.rounding = 0;
|
||||
ctx.style.scrollv.border_cursor = 1;
|
||||
ctx.style.scrollv.rounding_cursor = 2;
|
||||
|
||||
/* scrollbar buttons */
|
||||
ctx.style.scrollv.inc_button.normal = nk_style_item_image(media.scrollbar_inc_button);
|
||||
ctx.style.scrollv.inc_button.hover = nk_style_item_image(media.scrollbar_inc_button_hover);
|
||||
ctx.style.scrollv.inc_button.active = nk_style_item_image(media.scrollbar_inc_button_hover);
|
||||
ctx.style.scrollv.inc_button.border_color = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.inc_button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.inc_button.text_normal = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.inc_button.text_hover = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.inc_button.text_active = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.inc_button.border = 0.0f;
|
||||
|
||||
ctx.style.scrollv.dec_button.normal = nk_style_item_image(media.scrollbar_dec_button);
|
||||
ctx.style.scrollv.dec_button.hover = nk_style_item_image(media.scrollbar_dec_button_hover);
|
||||
ctx.style.scrollv.dec_button.active = nk_style_item_image(media.scrollbar_dec_button_hover);
|
||||
ctx.style.scrollv.dec_button.border_color = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.dec_button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.dec_button.text_normal = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.dec_button.text_hover = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.dec_button.text_active = nk_rgba(0,0,0,0);
|
||||
ctx.style.scrollv.dec_button.border = 0.0f;
|
||||
|
||||
/* checkbox toggle */
|
||||
{struct nk_style_toggle *toggle;
|
||||
toggle = &ctx.style.checkbox;
|
||||
toggle->normal = nk_style_item_image(media.check);
|
||||
toggle->hover = nk_style_item_image(media.check);
|
||||
toggle->active = nk_style_item_image(media.check);
|
||||
toggle->cursor_normal = nk_style_item_image(media.check_cursor);
|
||||
toggle->cursor_hover = nk_style_item_image(media.check_cursor);
|
||||
toggle->text_normal = nk_rgb(95,95,95);
|
||||
toggle->text_hover = nk_rgb(95,95,95);
|
||||
toggle->text_active = nk_rgb(95,95,95);}
|
||||
|
||||
/* option toggle */
|
||||
{struct nk_style_toggle *toggle;
|
||||
toggle = &ctx.style.option;
|
||||
toggle->normal = nk_style_item_image(media.option);
|
||||
toggle->hover = nk_style_item_image(media.option);
|
||||
toggle->active = nk_style_item_image(media.option);
|
||||
toggle->cursor_normal = nk_style_item_image(media.option_cursor);
|
||||
toggle->cursor_hover = nk_style_item_image(media.option_cursor);
|
||||
toggle->text_normal = nk_rgb(95,95,95);
|
||||
toggle->text_hover = nk_rgb(95,95,95);
|
||||
toggle->text_active = nk_rgb(95,95,95);}
|
||||
|
||||
/* default button */
|
||||
ctx.style.button.normal = nk_style_item_image(media.button);
|
||||
ctx.style.button.hover = nk_style_item_image(media.button_hover);
|
||||
ctx.style.button.active = nk_style_item_image(media.button_active);
|
||||
ctx.style.button.border_color = nk_rgba(0,0,0,0);
|
||||
ctx.style.button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.button.text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.button.text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.button.text_active = nk_rgb(95,95,95);
|
||||
|
||||
/* default text */
|
||||
ctx.style.text.color = nk_rgb(95,95,95);
|
||||
|
||||
/* contextual button */
|
||||
ctx.style.contextual_button.normal = nk_style_item_color(nk_rgb(206,206,206));
|
||||
ctx.style.contextual_button.hover = nk_style_item_color(nk_rgb(229,229,229));
|
||||
ctx.style.contextual_button.active = nk_style_item_color(nk_rgb(99,202,255));
|
||||
ctx.style.contextual_button.border_color = nk_rgba(0,0,0,0);
|
||||
ctx.style.contextual_button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.contextual_button.text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.contextual_button.text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.contextual_button.text_active = nk_rgb(95,95,95);
|
||||
|
||||
/* menu button */
|
||||
ctx.style.menu_button.normal = nk_style_item_color(nk_rgb(206,206,206));
|
||||
ctx.style.menu_button.hover = nk_style_item_color(nk_rgb(229,229,229));
|
||||
ctx.style.menu_button.active = nk_style_item_color(nk_rgb(99,202,255));
|
||||
ctx.style.menu_button.border_color = nk_rgba(0,0,0,0);
|
||||
ctx.style.menu_button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.menu_button.text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.menu_button.text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.menu_button.text_active = nk_rgb(95,95,95);
|
||||
|
||||
/* tree */
|
||||
ctx.style.tab.text = nk_rgb(95,95,95);
|
||||
ctx.style.tab.tab_minimize_button.normal = nk_style_item_image(media.tab_minimize);
|
||||
ctx.style.tab.tab_minimize_button.hover = nk_style_item_image(media.tab_minimize);
|
||||
ctx.style.tab.tab_minimize_button.active = nk_style_item_image(media.tab_minimize);
|
||||
ctx.style.tab.tab_minimize_button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.tab_minimize_button.text_normal = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.tab_minimize_button.text_hover = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.tab_minimize_button.text_active = nk_rgba(0,0,0,0);
|
||||
|
||||
ctx.style.tab.tab_maximize_button.normal = nk_style_item_image(media.tab_maximize);
|
||||
ctx.style.tab.tab_maximize_button.hover = nk_style_item_image(media.tab_maximize);
|
||||
ctx.style.tab.tab_maximize_button.active = nk_style_item_image(media.tab_maximize);
|
||||
ctx.style.tab.tab_maximize_button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.tab_maximize_button.text_normal = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.tab_maximize_button.text_hover = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.tab_maximize_button.text_active = nk_rgba(0,0,0,0);
|
||||
|
||||
ctx.style.tab.node_minimize_button.normal = nk_style_item_image(media.tab_minimize);
|
||||
ctx.style.tab.node_minimize_button.hover = nk_style_item_image(media.tab_minimize);
|
||||
ctx.style.tab.node_minimize_button.active = nk_style_item_image(media.tab_minimize);
|
||||
ctx.style.tab.node_minimize_button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.node_minimize_button.text_normal = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.node_minimize_button.text_hover = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.node_minimize_button.text_active = nk_rgba(0,0,0,0);
|
||||
|
||||
ctx.style.tab.node_maximize_button.normal = nk_style_item_image(media.tab_maximize);
|
||||
ctx.style.tab.node_maximize_button.hover = nk_style_item_image(media.tab_maximize);
|
||||
ctx.style.tab.node_maximize_button.active = nk_style_item_image(media.tab_maximize);
|
||||
ctx.style.tab.node_maximize_button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.node_maximize_button.text_normal = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.node_maximize_button.text_hover = nk_rgba(0,0,0,0);
|
||||
ctx.style.tab.node_maximize_button.text_active = nk_rgba(0,0,0,0);
|
||||
|
||||
/* selectable */
|
||||
ctx.style.selectable.normal = nk_style_item_color(nk_rgb(206,206,206));
|
||||
ctx.style.selectable.hover = nk_style_item_color(nk_rgb(206,206,206));
|
||||
ctx.style.selectable.pressed = nk_style_item_color(nk_rgb(206,206,206));
|
||||
ctx.style.selectable.normal_active = nk_style_item_color(nk_rgb(185,205,248));
|
||||
ctx.style.selectable.hover_active = nk_style_item_color(nk_rgb(185,205,248));
|
||||
ctx.style.selectable.pressed_active = nk_style_item_color(nk_rgb(185,205,248));
|
||||
ctx.style.selectable.text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.selectable.text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.selectable.text_pressed = nk_rgb(95,95,95);
|
||||
ctx.style.selectable.text_normal_active = nk_rgb(95,95,95);
|
||||
ctx.style.selectable.text_hover_active = nk_rgb(95,95,95);
|
||||
ctx.style.selectable.text_pressed_active = nk_rgb(95,95,95);
|
||||
|
||||
/* slider */
|
||||
ctx.style.slider.normal = nk_style_item_hide();
|
||||
ctx.style.slider.hover = nk_style_item_hide();
|
||||
ctx.style.slider.active = nk_style_item_hide();
|
||||
ctx.style.slider.bar_normal = nk_rgb(156,156,156);
|
||||
ctx.style.slider.bar_hover = nk_rgb(156,156,156);
|
||||
ctx.style.slider.bar_active = nk_rgb(156,156,156);
|
||||
ctx.style.slider.bar_filled = nk_rgb(156,156,156);
|
||||
ctx.style.slider.cursor_normal = nk_style_item_image(media.slider);
|
||||
ctx.style.slider.cursor_hover = nk_style_item_image(media.slider_hover);
|
||||
ctx.style.slider.cursor_active = nk_style_item_image(media.slider_active);
|
||||
ctx.style.slider.cursor_size = nk_vec2(16.5f,21);
|
||||
ctx.style.slider.bar_height = 1;
|
||||
|
||||
/* progressbar */
|
||||
ctx.style.progress.normal = nk_style_item_color(nk_rgb(231,231,231));
|
||||
ctx.style.progress.hover = nk_style_item_color(nk_rgb(231,231,231));
|
||||
ctx.style.progress.active = nk_style_item_color(nk_rgb(231,231,231));
|
||||
ctx.style.progress.cursor_normal = nk_style_item_color(nk_rgb(63,242,93));
|
||||
ctx.style.progress.cursor_hover = nk_style_item_color(nk_rgb(63,242,93));
|
||||
ctx.style.progress.cursor_active = nk_style_item_color(nk_rgb(63,242,93));
|
||||
ctx.style.progress.border_color = nk_rgb(114,116,115);
|
||||
ctx.style.progress.padding = nk_vec2(0,0);
|
||||
ctx.style.progress.border = 2;
|
||||
ctx.style.progress.rounding = 1;
|
||||
|
||||
/* combo */
|
||||
ctx.style.combo.normal = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.combo.hover = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.combo.active = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.combo.border_color = nk_rgb(95,95,95);
|
||||
ctx.style.combo.label_normal = nk_rgb(95,95,95);
|
||||
ctx.style.combo.label_hover = nk_rgb(95,95,95);
|
||||
ctx.style.combo.label_active = nk_rgb(95,95,95);
|
||||
ctx.style.combo.border = 1;
|
||||
ctx.style.combo.rounding = 1;
|
||||
|
||||
/* combo button */
|
||||
ctx.style.combo.button.normal = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.combo.button.hover = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.combo.button.active = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.combo.button.text_background = nk_rgb(216,216,216);
|
||||
ctx.style.combo.button.text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.combo.button.text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.combo.button.text_active = nk_rgb(95,95,95);
|
||||
|
||||
/* property */
|
||||
ctx.style.property.normal = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.property.hover = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.property.active = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.property.border_color = nk_rgb(81,81,81);
|
||||
ctx.style.property.label_normal = nk_rgb(95,95,95);
|
||||
ctx.style.property.label_hover = nk_rgb(95,95,95);
|
||||
ctx.style.property.label_active = nk_rgb(95,95,95);
|
||||
ctx.style.property.sym_left = NK_SYMBOL_TRIANGLE_LEFT;
|
||||
ctx.style.property.sym_right = NK_SYMBOL_TRIANGLE_RIGHT;
|
||||
ctx.style.property.rounding = 10;
|
||||
ctx.style.property.border = 1;
|
||||
|
||||
/* edit */
|
||||
ctx.style.edit.normal = nk_style_item_color(nk_rgb(240,240,240));
|
||||
ctx.style.edit.hover = nk_style_item_color(nk_rgb(240,240,240));
|
||||
ctx.style.edit.active = nk_style_item_color(nk_rgb(240,240,240));
|
||||
ctx.style.edit.border_color = nk_rgb(62,62,62);
|
||||
ctx.style.edit.cursor_normal = nk_rgb(99,202,255);
|
||||
ctx.style.edit.cursor_hover = nk_rgb(99,202,255);
|
||||
ctx.style.edit.cursor_text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.edit.cursor_text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.edit.text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.edit.text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.edit.text_active = nk_rgb(95,95,95);
|
||||
ctx.style.edit.selected_normal = nk_rgb(99,202,255);
|
||||
ctx.style.edit.selected_hover = nk_rgb(99,202,255);
|
||||
ctx.style.edit.selected_text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.edit.selected_text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.edit.border = 1;
|
||||
ctx.style.edit.rounding = 2;
|
||||
|
||||
/* property buttons */
|
||||
ctx.style.property.dec_button.normal = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.property.dec_button.hover = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.property.dec_button.active = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.property.dec_button.text_background = nk_rgba(0,0,0,0);
|
||||
ctx.style.property.dec_button.text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.property.dec_button.text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.property.dec_button.text_active = nk_rgb(95,95,95);
|
||||
ctx.style.property.inc_button = ctx.style.property.dec_button;
|
||||
|
||||
/* property edit */
|
||||
ctx.style.property.edit.normal = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.property.edit.hover = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.property.edit.active = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.property.edit.border_color = nk_rgba(0,0,0,0);
|
||||
ctx.style.property.edit.cursor_normal = nk_rgb(95,95,95);
|
||||
ctx.style.property.edit.cursor_hover = nk_rgb(95,95,95);
|
||||
ctx.style.property.edit.cursor_text_normal = nk_rgb(216,216,216);
|
||||
ctx.style.property.edit.cursor_text_hover = nk_rgb(216,216,216);
|
||||
ctx.style.property.edit.text_normal = nk_rgb(95,95,95);
|
||||
ctx.style.property.edit.text_hover = nk_rgb(95,95,95);
|
||||
ctx.style.property.edit.text_active = nk_rgb(95,95,95);
|
||||
ctx.style.property.edit.selected_normal = nk_rgb(95,95,95);
|
||||
ctx.style.property.edit.selected_hover = nk_rgb(95,95,95);
|
||||
ctx.style.property.edit.selected_text_normal = nk_rgb(216,216,216);
|
||||
ctx.style.property.edit.selected_text_hover = nk_rgb(216,216,216);
|
||||
|
||||
/* chart */
|
||||
ctx.style.chart.background = nk_style_item_color(nk_rgb(216,216,216));
|
||||
ctx.style.chart.border_color = nk_rgb(81,81,81);
|
||||
ctx.style.chart.color = nk_rgb(95,95,95);
|
||||
ctx.style.chart.selected_color = nk_rgb(255,0,0);
|
||||
ctx.style.chart.border = 1;
|
||||
}
|
||||
#endif
|
|
@ -1,46 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#define ASSET_INVALID 0xFF
|
||||
|
||||
typedef enum {
|
||||
// NOTE(zaklaus): Debug
|
||||
ASSET_EMPTY,
|
||||
ASSET_BLANK,
|
||||
ASSET_BLOCK_FRAME,
|
||||
ASSET_BUILDMODE_HIGHLIGHT,
|
||||
ASSET_BIG_TREE,
|
||||
|
||||
// NOTE(zaklaus): entities
|
||||
ASSET_PLAYER,
|
||||
ASSET_THING,
|
||||
ASSET_CHEST,
|
||||
ASSET_FURNACE,
|
||||
ASSET_BLUEPRINT,
|
||||
|
||||
// NOTE(zaklaus): items
|
||||
|
||||
// NOTE(zaklaus): blocks
|
||||
ASSET_FENCE,
|
||||
ASSET_DEV,
|
||||
ASSET_GROUND,
|
||||
ASSET_DIRT,
|
||||
ASSET_WATER,
|
||||
ASSET_LAVA,
|
||||
ASSET_WALL,
|
||||
ASSET_HILL,
|
||||
ASSET_HILL_SNOW,
|
||||
ASSET_HOLE,
|
||||
ASSET_WOOD,
|
||||
ASSET_TREE,
|
||||
ASSET_COAL,
|
||||
ASSET_IRON_ORE,
|
||||
ASSET_IRON_INGOT,
|
||||
|
||||
ASSET_BELT,
|
||||
ASSET_BELT_LEFT,
|
||||
ASSET_BELT_RIGHT,
|
||||
ASSET_BELT_UP,
|
||||
ASSET_BELT_DOWN,
|
||||
|
||||
MAX_ASSETS = 1024,
|
||||
} asset_id;
|
|
@ -1,44 +0,0 @@
|
|||
#include "models/assets.h"
|
||||
|
||||
#define ASSET_ENTRY(asset, asset_kind)\
|
||||
{\
|
||||
.id = asset,\
|
||||
.kind = asset_kind,\
|
||||
}
|
||||
|
||||
#define ASSET_SND(asset) ASSET_ENTRY(asset, AKIND_SOUND)
|
||||
#define ASSET_TEX(asset) ASSET_ENTRY(asset, AKIND_TEXTURE)
|
||||
#define ASSET_ANI(asset) ASSET_ENTRY(asset, AKIND_ANIM)
|
||||
|
||||
static asset assets[] = {
|
||||
ASSET_TEX(ASSET_EMPTY),
|
||||
ASSET_TEX(ASSET_BLANK),
|
||||
ASSET_TEX(ASSET_BLOCK_FRAME),
|
||||
ASSET_TEX(ASSET_BUILDMODE_HIGHLIGHT),
|
||||
ASSET_TEX(ASSET_BIG_TREE),
|
||||
|
||||
ASSET_TEX(ASSET_COAL),
|
||||
ASSET_TEX(ASSET_CHEST),
|
||||
ASSET_TEX(ASSET_FURNACE),
|
||||
ASSET_TEX(ASSET_BLUEPRINT),
|
||||
|
||||
// NOTE(zaklaus): blocks
|
||||
ASSET_TEX(ASSET_FENCE),
|
||||
ASSET_TEX(ASSET_DEV),
|
||||
ASSET_TEX(ASSET_GROUND),
|
||||
ASSET_TEX(ASSET_DIRT),
|
||||
ASSET_ANI(ASSET_WATER),
|
||||
ASSET_TEX(ASSET_LAVA),
|
||||
ASSET_TEX(ASSET_WALL),
|
||||
ASSET_TEX(ASSET_HILL),
|
||||
ASSET_TEX(ASSET_HILL_SNOW),
|
||||
ASSET_TEX(ASSET_HOLE),
|
||||
ASSET_TEX(ASSET_WOOD),
|
||||
ASSET_TEX(ASSET_TREE),
|
||||
|
||||
ASSET_TEX(ASSET_BELT),
|
||||
ASSET_TEX(ASSET_BELT_LEFT),
|
||||
ASSET_TEX(ASSET_BELT_RIGHT),
|
||||
ASSET_TEX(ASSET_BELT_UP),
|
||||
ASSET_TEX(ASSET_BELT_DOWN),
|
||||
};
|
|
@ -1,29 +0,0 @@
|
|||
#include "world/blocks.h"
|
||||
|
||||
#define BLOCK(a, f, s, ...)\
|
||||
{\
|
||||
.kind = a, .flags = f, .symbol = s, __VA_ARGS__\
|
||||
}
|
||||
|
||||
static block blocks[] = {
|
||||
BLOCK(ASSET_EMPTY, 0, 'E'),
|
||||
BLOCK(ASSET_GROUND, 0, '.', .drag = 1.0f, .friction = 1.0f),
|
||||
BLOCK(ASSET_DIRT, 0, ',', .drag = 2.1f , .friction = 1.0f),
|
||||
BLOCK(ASSET_WALL, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f),
|
||||
BLOCK(ASSET_HILL, BLOCK_FLAG_COLLISION, '^', .drag = 1.0f , .friction = 1.0f),
|
||||
BLOCK(ASSET_HILL_SNOW, BLOCK_FLAG_COLLISION, '*', .drag = 1.0f , .friction = 1.0f),
|
||||
BLOCK(ASSET_WATER, 0, '~', .drag = 0.11f , .friction = 1.0f),
|
||||
BLOCK(ASSET_LAVA, BLOCK_FLAG_HAZARD, '!', .drag = 6.2f , .friction = 4.0f),
|
||||
BLOCK(ASSET_FENCE, BLOCK_FLAG_COLLISION, '[', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f),
|
||||
BLOCK(ASSET_WOOD, BLOCK_FLAG_COLLISION, ']', .drag = 1.0f , .friction = 1.0f, .bounce = 0.0f),
|
||||
BLOCK(ASSET_TREE, BLOCK_FLAG_COLLISION|BLOCK_FLAG_DESTROY_ON_COLLISION, '@', .drag = 1.0f , .friction = 1.0f, .bounce = 0.0f),
|
||||
BLOCK(ASSET_CHEST, BLOCK_FLAG_ENTITY, 'C'),
|
||||
BLOCK(ASSET_FURNACE, BLOCK_FLAG_ENTITY, 'F'),
|
||||
|
||||
BLOCK(ASSET_BELT_LEFT, 0, '@', .drag = 1.0f , .friction = 1.0f, .velx = -150.0f),
|
||||
BLOCK(ASSET_BELT_RIGHT, 0, '@', .drag = 1.0f , .friction = 1.0f, .velx = 150.0f),
|
||||
BLOCK(ASSET_BELT_UP, 0, '@', .drag = 1.0f , .friction = 1.0f, .vely = -150.0f),
|
||||
BLOCK(ASSET_BELT_DOWN, 0, '@', .drag = 1.0f , .friction = 1.0f, .vely = 150.0f),
|
||||
};
|
||||
|
||||
ZPL_STATIC_ASSERT(sizeof(blocks)/sizeof(block) < ZPL_U16_MAX, "too many registered blocks! (max. 65536)");
|
|
@ -1,16 +0,0 @@
|
|||
// NOTE(zaklaus): access to spawners
|
||||
#include "models/prefabs/storage.h"
|
||||
#include "models/prefabs/furnace.h"
|
||||
#include "models/prefabs/blueprint.h"
|
||||
|
||||
static struct {
|
||||
asset_id id;
|
||||
uint64_t (*proc)();
|
||||
uint64_t (*proc_udata)(void*);
|
||||
} entity_spawnlist[] = {
|
||||
{ .id = ASSET_CHEST, .proc = storage_spawn },
|
||||
{ .id = ASSET_FURNACE, .proc = furnace_spawn },
|
||||
{ .id = ASSET_BLUEPRINT, .proc_udata = blueprint_spawn_udata },
|
||||
};
|
||||
|
||||
#define MAX_ENTITY_SPAWNDEFS ((sizeof(entity_spawnlist))/(sizeof(entity_spawnlist[0])))
|
|
@ -1,27 +0,0 @@
|
|||
#include "models/items.h"
|
||||
#include "world/entity_view.h"
|
||||
#include "items_list_helpers.h"
|
||||
|
||||
static item_desc items[] = {
|
||||
{ .kind = 0, .max_quantity = 0, },
|
||||
ITEM_INGREDIENT(ASSET_COAL, 64, ASSET_FURNACE, ASSET_BELT, 0),
|
||||
ITEM_SELF(ASSET_FENCE, 64),
|
||||
ITEM_ENERGY(ASSET_WOOD, ASSET_FURNACE, 64, 15.0f),
|
||||
ITEM_HOLD(ASSET_TREE, 64),
|
||||
|
||||
// ITEM_BLUEPRINT(ASSET_BLUEPRINT, 1, 4, 4, "]]]]]CF] ]]]]]"),
|
||||
ITEM_BLUEPRINT(ASSET_BLUEPRINT, 1, 4, 4, PROT({ ASSET_WOOD,ASSET_WOOD,ASSET_WOOD,ASSET_WOOD,
|
||||
ASSET_WOOD,ASSET_FURNACE,ASSET_CHEST,ASSET_WOOD,
|
||||
ASSET_FENCE,ASSET_EMPTY,ASSET_EMPTY,ASSET_WOOD,
|
||||
ASSET_WALL,ASSET_EMPTY,ASSET_EMPTY,ASSET_WOOD})),
|
||||
|
||||
ITEM_SELF_DIR(ASSET_BELT, 999),
|
||||
ITEM_PROXY(ASSET_BELT_LEFT, ASSET_BELT),
|
||||
ITEM_PROXY(ASSET_BELT_RIGHT, ASSET_BELT),
|
||||
ITEM_PROXY(ASSET_BELT_UP, ASSET_BELT),
|
||||
ITEM_PROXY(ASSET_BELT_DOWN, ASSET_BELT),
|
||||
|
||||
ITEM_ENT(ASSET_CHEST, 32, ASSET_CHEST),
|
||||
ITEM_ENT(ASSET_FURNACE, 32, ASSET_FURNACE),
|
||||
ITEM_ENT(ASSET_BIG_TREE, 32, ASSET_FURNACE),
|
||||
};
|
|
@ -1,105 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#define ITEM_HOLD(asset, qty, ...)\
|
||||
{\
|
||||
.kind = asset,\
|
||||
.usage = UKIND_HOLD,\
|
||||
.attachment = UDATA_NONE,\
|
||||
.max_quantity = qty,\
|
||||
__VA_ARGS__\
|
||||
}
|
||||
|
||||
#define ITEM_ENERGY(asset, producer_asset, qty, energy_value, ...)\
|
||||
{\
|
||||
.kind = asset,\
|
||||
.usage = UKIND_HOLD,\
|
||||
.attachment = UDATA_ENERGY_SOURCE,\
|
||||
.max_quantity = qty,\
|
||||
.energy_source = {\
|
||||
.producer = producer_asset,\
|
||||
.energy_level = energy_value\
|
||||
},\
|
||||
__VA_ARGS__\
|
||||
}
|
||||
|
||||
#define ITEM_BLUEPRINT(asset, qty, w_, h_, plan_, ...)\
|
||||
{\
|
||||
.kind = asset,\
|
||||
.usage = UKIND_PLACE_ITEM_DATA,\
|
||||
.attachment = UDATA_NONE,\
|
||||
.max_quantity = qty,\
|
||||
.blueprint = {\
|
||||
.w = w_,\
|
||||
.h = h_,\
|
||||
.plan = (const asset_id[])plan_\
|
||||
},\
|
||||
.place_item = {\
|
||||
.id = asset\
|
||||
},\
|
||||
__VA_ARGS__\
|
||||
}
|
||||
|
||||
#define ITEM_INGREDIENT(asset, qty, _producer, _product, _additional, ...)\
|
||||
{\
|
||||
.kind = asset,\
|
||||
.usage = UKIND_HOLD,\
|
||||
.attachment = UDATA_INGREDIENT,\
|
||||
.max_quantity = qty,\
|
||||
.ingredient = {\
|
||||
.producer = _producer,\
|
||||
.product = _product,\
|
||||
.additional_ingredient = _additional,\
|
||||
},\
|
||||
__VA_ARGS__\
|
||||
}
|
||||
|
||||
#define ITEM_BLOCK(asset, qty, build_asset, ...)\
|
||||
{\
|
||||
.kind = asset,\
|
||||
.usage = UKIND_PLACE,\
|
||||
.attachment = UDATA_NONE,\
|
||||
.max_quantity = qty,\
|
||||
.place = {\
|
||||
.kind = build_asset,\
|
||||
},\
|
||||
__VA_ARGS__\
|
||||
}
|
||||
|
||||
#define ITEM_BLOCK_DIR(asset, qty, build_asset, ...)\
|
||||
{\
|
||||
.kind = asset,\
|
||||
.usage = UKIND_PLACE,\
|
||||
.attachment = UDATA_NONE,\
|
||||
.max_quantity = qty,\
|
||||
.place = {\
|
||||
.kind = build_asset,\
|
||||
.directional = true,\
|
||||
},\
|
||||
__VA_ARGS__\
|
||||
}
|
||||
|
||||
#define ITEM_PROXY(asset, proxy_id, ...)\
|
||||
{\
|
||||
.kind = asset,\
|
||||
.usage = UKIND_PROXY,\
|
||||
.attachment = UDATA_NONE,\
|
||||
.proxy = {\
|
||||
.id = proxy_id,\
|
||||
},\
|
||||
__VA_ARGS__\
|
||||
}
|
||||
|
||||
#define ITEM_ENT(asset, qty, eid, ...)\
|
||||
{\
|
||||
.kind = asset,\
|
||||
.usage = UKIND_PLACE_ITEM,\
|
||||
.attachment = UDATA_NONE,\
|
||||
.max_quantity = qty,\
|
||||
.place_item = {\
|
||||
.id = eid\
|
||||
},\
|
||||
__VA_ARGS__\
|
||||
}
|
||||
|
||||
#define ITEM_SELF(asset, qty, ...) ITEM_BLOCK(asset, qty, asset, __VA_ARGS__)
|
||||
#define ITEM_SELF_DIR(asset, qty, ...) ITEM_BLOCK_DIR(asset, qty, asset, __VA_ARGS__)
|
|
@ -1,8 +1,10 @@
|
|||
#include "models/assets.h"
|
||||
#include "raylib.h"
|
||||
#include "gen/texgen.h"
|
||||
#include "models/database.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define ASSETS_COUNT (sizeof(assets)/sizeof(asset))
|
||||
//#define ASSETS_COUNT (sizeof(assets)/sizeof(asset))
|
||||
|
||||
typedef struct {
|
||||
asset_id id;
|
||||
|
@ -16,15 +18,45 @@ typedef struct {
|
|||
// NOTE(zaklaus): metadata
|
||||
} asset;
|
||||
|
||||
#include "lists/assets_list.c"
|
||||
//#include "lists/assets_list.c"
|
||||
static asset *assets;
|
||||
|
||||
#define ASSET_FRAME_RENDER_MS (1.0/5.0)
|
||||
#define ASSETS_COUNT (zpl_array_count(assets))
|
||||
|
||||
#define ASSET_FRAME_RENDER_MS (1.0/1.0)
|
||||
#define ASSET_FRAME_SKIP 4
|
||||
static int64_t assets_frame_counter = 1;
|
||||
static double assets_frame_next_draw = 0.0;
|
||||
|
||||
#include <time.h>
|
||||
|
||||
static uint16_t asset_counter;
|
||||
|
||||
void assets_new(const char *name) {
|
||||
assert(asset_counter < MAX_ASSETS);
|
||||
db_exec(zpl_bprintf("INSERT INTO assets (id, name) VALUES (%d, '%s');", asset_counter++, name));
|
||||
}
|
||||
|
||||
void assets_db_init(void) {
|
||||
for (uint16_t i=0; i<MAX_INTERNAL_ASSETS; i++) {
|
||||
assets_new(asset_names[i]+6);
|
||||
}
|
||||
|
||||
asset_counter = NEXT_FREE_ASSET;
|
||||
}
|
||||
|
||||
void assets_db(void) {
|
||||
zpl_array_init(assets, zpl_heap());
|
||||
db_push("SELECT * FROM resources;");
|
||||
for (size_t i=0, end=db_rows(); i<end; i++) {
|
||||
asset a={0};
|
||||
a.id = db_int("asset", i);
|
||||
a.kind = db_int("kind", i);
|
||||
zpl_array_append(assets, a);
|
||||
}
|
||||
db_pop();
|
||||
}
|
||||
|
||||
int32_t assets_setup(void) {
|
||||
for (uint32_t i=0; i<ASSETS_COUNT; i++) {
|
||||
asset *b = &assets[i];
|
||||
|
@ -94,7 +126,7 @@ uint16_t assets_find(asset_id id) {
|
|||
return i;
|
||||
}
|
||||
|
||||
ZPL_PANIC("Unknown asset id: %d\n", id);
|
||||
//ZPL_PANIC("Unknown asset id: %d\n", id);
|
||||
return ASSET_INVALID;
|
||||
}
|
||||
|
||||
|
@ -102,6 +134,11 @@ asset_kind assets_get_kind(uint16_t id) {
|
|||
return assets[id].kind;
|
||||
}
|
||||
|
||||
const char* assets_get_kind_name(uint16_t id) {
|
||||
static const char* names[] = { "Texture", "Animated Texture", "Sound" };
|
||||
return names[assets[id].kind];
|
||||
}
|
||||
|
||||
void *assets_get_snd(uint16_t id) {
|
||||
return (void*)&assets[id].snd;;
|
||||
}
|
||||
|
@ -109,3 +146,9 @@ void *assets_get_snd(uint16_t id) {
|
|||
void *assets_get_tex(uint16_t id) {
|
||||
return (void*)&assets[id].tex;
|
||||
}
|
||||
|
||||
const char *asset_names[] = {
|
||||
#define X(id) #id,
|
||||
_ASSETS
|
||||
#undef X
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "platform/system.h"
|
||||
|
||||
#include "lists/assets_ids.h"
|
||||
#include "assets_ids.h"
|
||||
|
||||
typedef enum {
|
||||
AKIND_TEXTURE,
|
||||
|
@ -11,6 +11,9 @@ typedef enum {
|
|||
FORCE_AKIND_UINT8 = UINT8_MAX
|
||||
} asset_kind;
|
||||
|
||||
void assets_db_init(void);
|
||||
void assets_db(void);
|
||||
void assets_new(const char *name);
|
||||
int32_t assets_setup(void);
|
||||
int32_t assets_frame(void);
|
||||
void assets_destroy(void);
|
||||
|
@ -18,9 +21,13 @@ void assets_destroy(void);
|
|||
uint16_t assets_find(asset_id id);
|
||||
|
||||
asset_kind assets_get_kind(uint16_t id);
|
||||
const char *assets_get_kind_name(uint16_t id);
|
||||
void *assets_get_snd(uint16_t id);
|
||||
void *assets_get_tex(uint16_t id);
|
||||
uint16_t assets_resolve_proxy(uint16_t id);
|
||||
|
||||
// NOTE(zaklaus): client only
|
||||
#define ASSET_SRC_RECT() ((Rectangle){0, 0, 64, 64})
|
||||
#define ASSET_DST_RECT(x,y) ((Rectangle){x, y, 64, 64})
|
||||
#define ASSET_SRC_RECT_TEX(w,h) ((Rectangle){0, 0, (float)w, (float)h})
|
||||
#define ASSET_DST_RECT_TEX(x,y,w,h) ((Rectangle){x, y, (float)w, (float)h})
|
||||
|
|
|
@ -1,51 +1,15 @@
|
|||
#include "models/components.h"
|
||||
|
||||
ECS_COMPONENT_DECLARE(Vector2D);
|
||||
ECS_COMPONENT_DECLARE(Position);
|
||||
ECS_COMPONENT_DECLARE(Velocity);
|
||||
ECS_COMPONENT_DECLARE(Chunk);
|
||||
ECS_COMPONENT_DECLARE(Drawable);
|
||||
ECS_COMPONENT_DECLARE(Input);
|
||||
ECS_COMPONENT_DECLARE(ClientInfo);
|
||||
ECS_COMPONENT_DECLARE(Health);
|
||||
ECS_COMPONENT_DECLARE(Classify);
|
||||
ECS_COMPONENT_DECLARE(Vehicle);
|
||||
ECS_COMPONENT_DECLARE(IsInVehicle);
|
||||
ECS_COMPONENT_DECLARE(Item);
|
||||
ECS_COMPONENT_DECLARE(BlockHarvest);
|
||||
ECS_COMPONENT_DECLARE(Inventory);
|
||||
ECS_COMPONENT_DECLARE(ItemContainer);
|
||||
ECS_COMPONENT_DECLARE(Producer);
|
||||
ECS_COMPONENT_DECLARE(EnergySource);
|
||||
ECS_COMPONENT_DECLARE(Ingredient);
|
||||
ECS_COMPONENT_DECLARE(Device);
|
||||
ECS_COMPONENT_DECLARE(Blueprint);
|
||||
ECS_COMPONENT_DECLARE(DemoNPC);
|
||||
ECS_COMPONENT_DECLARE(StreamInfo);
|
||||
|
||||
|
||||
#define X(comp) ECS_COMPONENT_DECLARE(comp);
|
||||
_COMPS
|
||||
#undef X
|
||||
|
||||
void ComponentsImport(ecs_world_t *ecs) {
|
||||
ECS_MODULE(ecs, Components);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, Vector2D);
|
||||
ECS_COMPONENT_DEFINE(ecs, Position);
|
||||
ECS_COMPONENT_DEFINE(ecs, Velocity);
|
||||
ECS_COMPONENT_DEFINE(ecs, Chunk);
|
||||
ECS_COMPONENT_DEFINE(ecs, Drawable);
|
||||
ECS_COMPONENT_DEFINE(ecs, Input);
|
||||
ECS_COMPONENT_DEFINE(ecs, ClientInfo);
|
||||
ECS_COMPONENT_DEFINE(ecs, Health);
|
||||
ECS_COMPONENT_DEFINE(ecs, Classify);
|
||||
ECS_COMPONENT_DEFINE(ecs, Vehicle);
|
||||
ECS_COMPONENT_DEFINE(ecs, IsInVehicle);
|
||||
ECS_COMPONENT_DEFINE(ecs, Item);
|
||||
ECS_COMPONENT_DEFINE(ecs, BlockHarvest);
|
||||
ECS_COMPONENT_DEFINE(ecs, Inventory);
|
||||
ECS_COMPONENT_DEFINE(ecs, ItemContainer);
|
||||
ECS_COMPONENT_DEFINE(ecs, Producer);
|
||||
ECS_COMPONENT_DEFINE(ecs, EnergySource);
|
||||
ECS_COMPONENT_DEFINE(ecs, Ingredient);
|
||||
ECS_COMPONENT_DEFINE(ecs, Device);
|
||||
ECS_COMPONENT_DEFINE(ecs, Blueprint);
|
||||
ECS_COMPONENT_DEFINE(ecs, DemoNPC);
|
||||
ECS_COMPONENT_DEFINE(ecs, StreamInfo);
|
||||
#define X(comp) ECS_COMPONENT_DEFINE(ecs, comp);
|
||||
_COMPS
|
||||
#undef X
|
||||
}
|
||||
|
|
|
@ -2,19 +2,11 @@
|
|||
#include "flecs.h"
|
||||
#include "models/assets.h"
|
||||
|
||||
#define ecs_get_mut_ex(world, entity, T) \
|
||||
(ECS_CAST(T*, world_component_cached(world, entity, ecs_id(T))))
|
||||
|
||||
#define ecs_get_if(world, entity, T) \
|
||||
(world_entity_valid(entity) ? ecs_get(world, entity, T) : NULL)
|
||||
(world_entity_valid(entity) ? ecs_get(world, entity, T) : NULL)
|
||||
|
||||
#define ecs_get_mut_if_ex(world, entity, component) \
|
||||
(ecs_get_if(world, entity, component) ? ecs_get_mut_ex(world, entity, component) : NULL)
|
||||
|
||||
#ifndef ecs_get_mut_if
|
||||
#define ecs_get_mut_if(world, entity, component)\
|
||||
(ecs_get(world, entity, component) ? ecs_get_mut(world, entity, component) : NULL)
|
||||
#endif
|
||||
#define ecs_get_mut_if(world, entity, component) \
|
||||
(ecs_get_if(world, entity, component) ? ecs_get_mut(world, entity, component) : NULL)
|
||||
|
||||
#define ITEMS_INVENTORY_SIZE 9
|
||||
#define ITEMS_CONTAINER_SIZE 16
|
||||
|
@ -38,6 +30,30 @@ typedef struct {
|
|||
typedef Vector2D Position;
|
||||
typedef Vector2D Velocity;
|
||||
|
||||
typedef struct { char _unused; } InAir;
|
||||
typedef struct { char _unused; } TriggerOnly;
|
||||
|
||||
typedef struct {
|
||||
float angle;
|
||||
} Rotation;
|
||||
|
||||
enum {
|
||||
PHYS_CIRCLE,
|
||||
PHYS_AABB,
|
||||
};
|
||||
|
||||
#define INFINITE_MASS -1.0f
|
||||
|
||||
typedef struct {
|
||||
uint8_t kind;
|
||||
union {
|
||||
struct {
|
||||
float r;
|
||||
} circle;
|
||||
};
|
||||
float mass;
|
||||
} PhysicsBody;
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
|
@ -45,6 +61,8 @@ typedef struct {
|
|||
float my;
|
||||
float bx;
|
||||
float by;
|
||||
float hx;
|
||||
float hy;
|
||||
uint8_t use;
|
||||
uint8_t sprint;
|
||||
uint8_t ctrl;
|
||||
|
@ -63,6 +81,7 @@ typedef struct {
|
|||
uint8_t swap_storage;
|
||||
uint8_t swap_from;
|
||||
uint8_t swap_to;
|
||||
asset_id craft_item;
|
||||
|
||||
// NOTE(zaklaus): build mode
|
||||
uint8_t num_placements;
|
||||
|
@ -81,15 +100,32 @@ typedef struct {
|
|||
float hp;
|
||||
float max_hp;
|
||||
|
||||
//NOTE(zaklaus): Intentionally global, to allow for creative use of damage combos
|
||||
float pain_time;
|
||||
float heal_time;
|
||||
// acumulated damage
|
||||
float dmg;
|
||||
} Health;
|
||||
|
||||
typedef struct { char _unused; } Dead;
|
||||
|
||||
typedef struct {
|
||||
uint16_t timer;
|
||||
} Respawn;
|
||||
|
||||
typedef struct {
|
||||
float amt;
|
||||
} HealthRegen;
|
||||
|
||||
typedef struct {
|
||||
uint8_t delay;
|
||||
} HealDelay;
|
||||
|
||||
typedef struct {
|
||||
uint16_t id;
|
||||
} Classify;
|
||||
|
||||
typedef struct {
|
||||
uint8_t layer;
|
||||
} StreamLayerOverride;
|
||||
|
||||
typedef struct {
|
||||
uint64_t seats[4];
|
||||
|
||||
|
@ -114,6 +150,19 @@ typedef struct {
|
|||
float durability; // 1.0 - 0.0 (0.0 = broken), we can only ever merge items of the same durability
|
||||
} Item;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t spritesheet;
|
||||
uint32_t frame;
|
||||
};
|
||||
struct {
|
||||
uint32_t sprite_id;
|
||||
uint32_t sprite_data;
|
||||
};
|
||||
};
|
||||
} Sprite;
|
||||
|
||||
typedef struct {
|
||||
char _unused;
|
||||
} BlockHarvest;
|
||||
|
@ -129,23 +178,40 @@ typedef struct {
|
|||
ecs_entity_t items[ITEMS_CONTAINER_SIZE];
|
||||
} ItemContainer;
|
||||
|
||||
enum {
|
||||
PRODUCER_PUSH_PRODUCT,
|
||||
PRODUCER_PUSH_ANY,
|
||||
PRODUCER_PUSH_NONE,
|
||||
};
|
||||
|
||||
enum {
|
||||
PRODUCER_CRAFT_WAITING,
|
||||
PRODUCER_CRAFT_BUSY,
|
||||
PRODUCER_CRAFT_ENQUEUED,
|
||||
PRODUCER_CRAFT_AUTO,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
asset_id target_item;
|
||||
asset_id processed_item;
|
||||
float process_time;
|
||||
uint32_t processed_item_qty;
|
||||
int32_t process_ticks;
|
||||
int32_t process_ticks_left;
|
||||
float energy_level;
|
||||
uint8_t pending_task;
|
||||
uint8_t push_filter;
|
||||
} Producer;
|
||||
|
||||
typedef struct {
|
||||
uint32_t push_qty;
|
||||
uint8_t counter;
|
||||
} ItemRouter;
|
||||
|
||||
typedef struct {
|
||||
asset_id kind;
|
||||
float energy_level;
|
||||
} EnergySource;
|
||||
|
||||
typedef struct {
|
||||
asset_id producer;
|
||||
asset_id additional_ingredient; // optional - can specify additional item we need in the container to craft this item
|
||||
asset_id product;
|
||||
} Ingredient;
|
||||
|
||||
typedef struct {
|
||||
uint16_t asset;
|
||||
|
||||
|
@ -167,27 +233,84 @@ typedef struct {
|
|||
|
||||
typedef struct {char _unused;} DemoNPC;
|
||||
|
||||
extern ECS_COMPONENT_DECLARE(Vector2D);
|
||||
extern ECS_COMPONENT_DECLARE(Position);
|
||||
extern ECS_COMPONENT_DECLARE(Velocity);
|
||||
extern ECS_COMPONENT_DECLARE(Chunk);
|
||||
extern ECS_COMPONENT_DECLARE(Drawable);
|
||||
extern ECS_COMPONENT_DECLARE(Input);
|
||||
extern ECS_COMPONENT_DECLARE(ClientInfo);
|
||||
extern ECS_COMPONENT_DECLARE(Health);
|
||||
extern ECS_COMPONENT_DECLARE(Classify);
|
||||
extern ECS_COMPONENT_DECLARE(Vehicle);
|
||||
extern ECS_COMPONENT_DECLARE(IsInVehicle);
|
||||
extern ECS_COMPONENT_DECLARE(Item);
|
||||
extern ECS_COMPONENT_DECLARE(BlockHarvest);
|
||||
extern ECS_COMPONENT_DECLARE(Inventory);
|
||||
extern ECS_COMPONENT_DECLARE(ItemContainer);
|
||||
extern ECS_COMPONENT_DECLARE(Producer);
|
||||
extern ECS_COMPONENT_DECLARE(EnergySource);
|
||||
extern ECS_COMPONENT_DECLARE(Ingredient);
|
||||
extern ECS_COMPONENT_DECLARE(Device);
|
||||
extern ECS_COMPONENT_DECLARE(Blueprint);
|
||||
extern ECS_COMPONENT_DECLARE(DemoNPC);
|
||||
extern ECS_COMPONENT_DECLARE(StreamInfo);
|
||||
typedef struct {
|
||||
int16_t hunger_satisfied;
|
||||
int16_t mating_satisfied;
|
||||
int16_t life_remaining;
|
||||
} Creature;
|
||||
|
||||
typedef struct { char _unused; } SeeksFood;
|
||||
typedef struct { char _unused; } SeeksCompanion;
|
||||
|
||||
// survival comps
|
||||
typedef struct {
|
||||
uint8_t atk_delay;
|
||||
uint16_t despawn_timer;
|
||||
} Mob;
|
||||
typedef struct {
|
||||
uint64_t plr;
|
||||
} MobHuntPlayer;
|
||||
|
||||
typedef struct {
|
||||
char _unused;
|
||||
} MobMelee;
|
||||
|
||||
typedef struct {
|
||||
uint16_t projectile_count;
|
||||
uint8_t damage;
|
||||
uint8_t spawn_delay;
|
||||
} WeaponKnife;
|
||||
|
||||
typedef struct {
|
||||
uint8_t damage;
|
||||
float origin_x, origin_y;
|
||||
ecs_entity_t owner;
|
||||
} WeaponProjectile;
|
||||
|
||||
#define _COMPS\
|
||||
X(Vector2D)\
|
||||
X(Position)\
|
||||
X(Velocity)\
|
||||
X(InAir)\
|
||||
X(Rotation)\
|
||||
X(TriggerOnly)\
|
||||
X(PhysicsBody)\
|
||||
X(Chunk)\
|
||||
X(Drawable)\
|
||||
X(Input)\
|
||||
X(ClientInfo)\
|
||||
X(Health)\
|
||||
X(Dead)\
|
||||
X(Respawn)\
|
||||
X(HealthRegen)\
|
||||
X(HealDelay)\
|
||||
X(Mob)\
|
||||
X(MobHuntPlayer)\
|
||||
X(MobMelee)\
|
||||
X(WeaponKnife)\
|
||||
X(WeaponProjectile)\
|
||||
X(Classify)\
|
||||
X(Vehicle)\
|
||||
X(StreamLayerOverride)\
|
||||
X(IsInVehicle)\
|
||||
X(Item)\
|
||||
X(BlockHarvest)\
|
||||
X(Inventory)\
|
||||
X(ItemContainer)\
|
||||
X(Producer)\
|
||||
X(EnergySource)\
|
||||
X(ItemRouter)\
|
||||
X(Device)\
|
||||
X(Blueprint)\
|
||||
X(DemoNPC)\
|
||||
X(Creature)\
|
||||
X(SeeksFood)\
|
||||
X(SeeksCompanion)\
|
||||
X(Sprite)\
|
||||
X(StreamInfo)
|
||||
|
||||
#define X(comp) extern ECS_COMPONENT_DECLARE(comp);
|
||||
_COMPS
|
||||
#undef X
|
||||
|
||||
void ComponentsImport(ecs_world_t *ecs);
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
#include "crafting.h"
|
||||
#include "models/items.h"
|
||||
#include "models/database.h"
|
||||
|
||||
//#include "lists/crafting_list.c"
|
||||
static recipe *recipes;
|
||||
#define MAX_RECIPES (zpl_array_count(recipes))
|
||||
|
||||
void craft_db(void) {
|
||||
zpl_array_init(recipes, zpl_heap());
|
||||
db_push("SELECT * FROM recipes;");
|
||||
for (size_t i=0, end=db_rows(); i<end; i++) {
|
||||
recipe r={0};
|
||||
r.product = db_int("product", i);
|
||||
r.product_qty = db_int("product_qty", i);
|
||||
r.process_ticks = db_int("process_ticks", i);
|
||||
r.producer = db_int("producer", i);
|
||||
zpl_array_init(r.reagents, zpl_heap());
|
||||
db_push(zpl_bprintf("SELECT * FROM recipe_reagents WHERE recipe_id=%d;", i+1));
|
||||
for (size_t j=0, j_end=db_rows(); j<j_end; j++) {
|
||||
reagent rea={0};
|
||||
size_t reagent_id = db_int("reagent_id", j);
|
||||
db_push(zpl_bprintf("SELECT * FROM reagents WHERE id=%d;", reagent_id));
|
||||
rea.id = db_int("asset_id", 0);
|
||||
rea.qty = db_int("qty", 0);
|
||||
db_pop();
|
||||
zpl_array_append(r.reagents, rea);
|
||||
}
|
||||
db_pop();
|
||||
zpl_array_append(recipes, r);
|
||||
}
|
||||
db_pop();
|
||||
}
|
||||
|
||||
uint32_t craft__find_num_recipes_by_reagent(asset_id producer, asset_id id) {
|
||||
uint32_t num_recipes=0;
|
||||
for (int i = 0; i < (int)MAX_RECIPES; ++i) {
|
||||
if (recipes[i].producer == producer) {
|
||||
for (int j = 0; recipes[i].reagents[j].id; ++j) {
|
||||
if (recipes[i].reagents[j].id == id) {
|
||||
++num_recipes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return num_recipes;
|
||||
}
|
||||
|
||||
recipe *craft__find_recipe_by_reagent(asset_id producer, asset_id id, uint32_t slot_id) {
|
||||
for (int i = 0; i < (int)MAX_RECIPES; ++i) {
|
||||
if (recipes[i].producer == producer) {
|
||||
for (int j = 0; recipes[i].reagents[j].id; ++j) {
|
||||
if (recipes[i].reagents[j].id == id) {
|
||||
if (slot_id > 0) {
|
||||
--slot_id;
|
||||
continue;
|
||||
}
|
||||
return &recipes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t craft_get_recipe_id_from_product(asset_id id) {
|
||||
for (int i = 0; i < (int)MAX_RECIPES; ++i) {
|
||||
if (id == recipes[i].product) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return ASSET_INVALID;
|
||||
}
|
||||
|
||||
recipe craft_get_recipe_data(uint16_t i) {
|
||||
ZPL_ASSERT(i < MAX_RECIPES);
|
||||
return recipes[i];
|
||||
}
|
||||
|
||||
bool craft_is_reagent_used_in_producer(asset_id reagent, asset_id producer) {
|
||||
return craft__find_num_recipes_by_reagent(producer, reagent) > 0;
|
||||
}
|
||||
|
||||
bool craft_is_item_produced_by_producer(asset_id item, asset_id producer) {
|
||||
for (int i = 0; i < (int)MAX_RECIPES; ++i) {
|
||||
if (recipes[i].producer == producer && item == recipes[i].product) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool craft_is_item_produced_by_reagent(asset_id item, asset_id reagent) {
|
||||
for (int i = 0; i < (int)MAX_RECIPES; ++i) {
|
||||
if (item == recipes[i].product) {
|
||||
for (int j = 0; recipes[i].reagents[j].id; ++j) {
|
||||
if (recipes[i].reagents[j].id == reagent)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t craft_get_num_recipes(void) {
|
||||
return MAX_RECIPES;
|
||||
}
|
||||
|
||||
asset_id craft_get_recipe_asset(uint16_t id) {
|
||||
ZPL_ASSERT(id < MAX_RECIPES);
|
||||
return recipes[id].product;
|
||||
}
|
||||
|
||||
asset_id craft_perform_recipe(ecs_entity_t *items, asset_id producer, asset_id target, uint32_t *quantity, int32_t *process_ticks) {
|
||||
ZPL_ASSERT_NOT_NULL(items);
|
||||
|
||||
for (int i = 0; i < ITEMS_CONTAINER_SIZE; i++) {
|
||||
ecs_entity_t item_slot_ent = items[i];
|
||||
if (item_slot_ent == 0) continue;
|
||||
Item *item = item_get_data(item_slot_ent);
|
||||
if (!item) continue;
|
||||
|
||||
uint32_t num_recipes = craft__find_num_recipes_by_reagent(producer, item->kind);
|
||||
for (uint32_t rec_i = 0; rec_i < num_recipes; ++rec_i) {
|
||||
// TODO(zaklaus): slow, find a better way to retrieve known recipes
|
||||
recipe *rec = craft__find_recipe_by_reagent(producer, item->kind, rec_i);
|
||||
if (!rec) {
|
||||
// NOTE(zaklaus): this item is not used as a reagent, skip it.
|
||||
// TODO(zaklaus): is this a bug? should we assert?
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target != 0 && rec->product != target) {
|
||||
// NOTE(zaklaus): we were asked to produce a specific product,
|
||||
// however this recipe is not compatible, bail.
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t skip_slot=0;
|
||||
|
||||
// NOTE(zaklaus): analyse if all the reagents are present
|
||||
for (int j = 0; rec->reagents[j].id; ++j) {
|
||||
reagent *rea = &rec->reagents[j];
|
||||
uint32_t pending_qty = rea->qty;
|
||||
|
||||
for (int k = 0; k < ITEMS_CONTAINER_SIZE; k++) {
|
||||
ecs_entity_t rea_item_slot_ent = items[k];
|
||||
if (rea_item_slot_ent == 0) continue;
|
||||
Item *rea_item = item_get_data(rea_item_slot_ent);
|
||||
if (!rea_item) continue;
|
||||
|
||||
if (rea->id == rea_item->kind && rea_item->quantity > 0) {
|
||||
pending_qty -= zpl_min(pending_qty, rea_item->quantity);
|
||||
|
||||
if (pending_qty == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pending_qty > 0) {
|
||||
// NOTE(zaklaus): reagent not found, bail
|
||||
skip_slot=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(zaklaus): demand not met, bye!
|
||||
if (skip_slot)
|
||||
continue;
|
||||
|
||||
// NOTE(zaklaus): deplete used reagents
|
||||
for (int j = 0; rec->reagents[j].id; ++j) {
|
||||
reagent *rea = &rec->reagents[j];
|
||||
uint32_t pending_qty = rea->qty;
|
||||
|
||||
for (int k = 0; k < ITEMS_CONTAINER_SIZE; k++) {
|
||||
ecs_entity_t rea_item_slot_ent = items[k];
|
||||
if (rea_item_slot_ent == 0) continue;
|
||||
Item *rea_item = item_get_data(rea_item_slot_ent);
|
||||
if (!rea_item) continue;
|
||||
|
||||
if (rea->id == rea_item->kind && rea_item->quantity > 0) {
|
||||
rea_item->quantity -= zpl_min(pending_qty, rea_item->quantity);
|
||||
pending_qty -= zpl_min(pending_qty, rea_item->quantity);
|
||||
if (rea_item->quantity == 0) {
|
||||
item_despawn(rea_item_slot_ent);
|
||||
items[k] = 0;
|
||||
}
|
||||
|
||||
if (pending_qty == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(zaklaus): all done, return the product and its qty
|
||||
*quantity = rec->product_qty;
|
||||
*process_ticks = rec->process_ticks;
|
||||
return rec->product;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(zaklaus): might be removed
|
||||
asset_id craft_has_byproducts(asset_id product) {
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
// TODO(zaklaus): might be removed
|
||||
uint32_t craft_resolve_graph(asset_id product, uint16_t *hops, uint8_t direct_cost) {
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
#include "platform/system.h"
|
||||
#include "models/assets.h"
|
||||
|
||||
#include "models/components.h"
|
||||
|
||||
typedef struct {
|
||||
asset_id id;
|
||||
uint32_t qty;
|
||||
} reagent;
|
||||
|
||||
typedef struct {
|
||||
asset_id product;
|
||||
uint32_t product_qty;
|
||||
int32_t process_ticks;
|
||||
asset_id producer;
|
||||
reagent *reagents;
|
||||
} recipe;
|
||||
|
||||
void craft_db(void);
|
||||
|
||||
// NOTE(zaklaus): resolves recipe dependencies and consumes reagents
|
||||
// to enqueue a production of a new item.
|
||||
// TODO(zaklaus): "items" is assumed to come from ItemContainer component.
|
||||
asset_id craft_perform_recipe(ecs_entity_t *items, asset_id producer, asset_id target, uint32_t *quantity, int32_t *process_ticks);
|
||||
|
||||
// NOTE(zaklaus): mostly used by item router so we don't push reagents out
|
||||
bool craft_is_reagent_used_in_producer(asset_id reagent, asset_id producer);
|
||||
|
||||
// used to filter out craftables
|
||||
bool craft_is_item_produced_by_producer(asset_id item, asset_id producer);
|
||||
|
||||
// used to filter out reagents
|
||||
bool craft_is_item_produced_by_reagent(asset_id item, asset_id reagent);
|
||||
|
||||
// NOTE(zaklaus): utilities
|
||||
uint16_t craft_get_num_recipes(void);
|
||||
asset_id craft_get_recipe_asset(uint16_t id);
|
||||
uint16_t craft_get_recipe_id_from_product(asset_id id);
|
||||
recipe craft_get_recipe_data(uint16_t i);
|
||||
|
||||
//~TODO(zaklaus): not implemented and might get removed
|
||||
|
||||
// NOTE(zaklaus): informs us on whether this product has any byproducts desired.
|
||||
asset_id craft_has_byproducts(asset_id product);
|
||||
|
||||
// NOTE(zaklaus): resolves the production chain and analyses the amount of items required
|
||||
// and a number of hops (production layers) needed to produce the item.
|
||||
// optionally, it allows to calculate "direct_cost" of the product.
|
||||
uint32_t craft_resolve_graph(asset_id product, uint16_t *hops, uint8_t direct_cost);
|
|
@ -0,0 +1,191 @@
|
|||
#include "models/database.h"
|
||||
#include "models/assets.h"
|
||||
|
||||
#include "3rd_sqlite3.h"
|
||||
#include "zpl.h"
|
||||
|
||||
#include "world/blocks.h"
|
||||
#include "models/crafting.h"
|
||||
#include "models/items.h"
|
||||
|
||||
#ifndef ECO2D_DB
|
||||
#define ECO2D_DB "eco2d.db"
|
||||
#endif
|
||||
|
||||
static sqlite3 *db;
|
||||
static zpl_array(zpl_csv_object) csv_stack;
|
||||
|
||||
static
|
||||
void sql_asset(sqlite3_context *ctx, int argc, sqlite3_value **argv) {
|
||||
if (argc == 1) {
|
||||
const char *name = (const char *)sqlite3_value_text(argv[0]);
|
||||
if (name) {
|
||||
sqlite3_result_int(ctx, atoi(db_get(zpl_bprintf("SELECT id FROM assets WHERE name = '%s'", name), false)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_result_null(ctx);
|
||||
}
|
||||
|
||||
bool db_init() {
|
||||
bool new_db = !zpl_fs_exists(ECO2D_DB);
|
||||
sqlite3_open(ECO2D_DB, &db);
|
||||
assert(db && "Failed to open database.");
|
||||
|
||||
zpl_array_init(csv_stack, zpl_heap());
|
||||
sqlite3_create_function(db, "asset", 1, SQLITE_UTF8, NULL, sql_asset, NULL, NULL);
|
||||
|
||||
if (new_db) {
|
||||
zpl_printf("[INFO] Creating new database...\n");
|
||||
db_exec_file("art/queries/eco2d/tables.sql");
|
||||
assets_db_init();
|
||||
|
||||
db_exec_file("art/queries/eco2d/resources.sql");
|
||||
db_exec_file("art/queries/eco2d/blocks.sql");
|
||||
db_exec_file("art/queries/eco2d/recipes.sql");
|
||||
db_exec_file("art/queries/eco2d/items.sql");
|
||||
}
|
||||
|
||||
// initialise models db
|
||||
zpl_printf("[INFO] Loading models from database...\n");
|
||||
assets_db(); zpl_printf("[INFO] Assets loaded.\n");
|
||||
blocks_db(); zpl_printf("[INFO] Blocks loaded.\n");
|
||||
craft_db(); zpl_printf("[INFO] Recipes loaded.\n");
|
||||
item_db(); zpl_printf("[INFO] Items loaded.\n");
|
||||
return new_db;
|
||||
}
|
||||
|
||||
void db_shutdown() {
|
||||
sqlite3_close(db);
|
||||
}
|
||||
|
||||
char *db_get(char *query, bool header) {
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db, query, -1, &stmt, 0);
|
||||
if (rc) {
|
||||
zpl_printf("[ERROR] Failed to prepare query: %s\n", sqlite3_errmsg(db));
|
||||
return 0;
|
||||
}
|
||||
|
||||
zpl_string buf = zpl_string_make(zpl_heap(), "");
|
||||
bool is_first=header;
|
||||
int cols = sqlite3_column_count(stmt);
|
||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
if (is_first) {
|
||||
is_first = 0;
|
||||
for (int i = 0; i < cols; i++) {
|
||||
buf = zpl_string_appendc(buf, (const char *)sqlite3_column_name(stmt, i));
|
||||
|
||||
if (i < cols - 1) {
|
||||
buf = zpl_string_appendc(buf, ",");
|
||||
}
|
||||
}
|
||||
|
||||
buf = zpl_string_appendc(buf, "\n");
|
||||
}
|
||||
for (int i = 0; i < cols; i++) {
|
||||
const char *val = (const char *)sqlite3_column_text(stmt, i);
|
||||
if (val == NULL)
|
||||
val = "\"(null)\"";
|
||||
buf = zpl_string_appendc(buf, val);
|
||||
|
||||
if (i < cols - 1) {
|
||||
buf = zpl_string_appendc(buf, ",");
|
||||
}
|
||||
}
|
||||
|
||||
buf = zpl_string_appendc(buf, "\n");
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
#if 0
|
||||
char *data = zpl_bprintf("%s", buf);
|
||||
zpl_string_free(buf);
|
||||
#else //@leak
|
||||
char *data = (char *)buf;
|
||||
#endif
|
||||
return data;
|
||||
}
|
||||
|
||||
char *db_row(char *table, char *name) {
|
||||
int kind = atoi(db_get(zpl_bprintf("SELECT id FROM assets WHERE name='%s';", name), 0));
|
||||
return db_get(zpl_bprintf("SELECT * FROM %s WHERE kind='%d';", table, kind), 1);
|
||||
}
|
||||
|
||||
bool db_csv(zpl_csv_object *csv, char *query) {
|
||||
zpl_zero_item(csv);
|
||||
char *res = db_get(query, 1);
|
||||
assert(res);
|
||||
return zpl_csv_parse(csv, res, zpl_heap(), 1);
|
||||
}
|
||||
|
||||
bool db_row_csv(zpl_csv_object *csv, char *table, char *name) {
|
||||
zpl_zero_item(csv);
|
||||
char *res = db_row(table, name);
|
||||
assert(res);
|
||||
return zpl_csv_parse(csv, res, zpl_heap(), 1);
|
||||
}
|
||||
|
||||
bool db_push(char *query) {
|
||||
zpl_csv_object csv;
|
||||
if (db_csv(&csv, query)) {
|
||||
return false;
|
||||
}
|
||||
zpl_array_append(csv_stack, csv);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool db_row_push(char *table, char *name) {
|
||||
zpl_csv_object csv;
|
||||
if (db_row_csv(&csv, table, name)) {
|
||||
return false;
|
||||
}
|
||||
zpl_array_append(csv_stack, csv);
|
||||
return true;
|
||||
}
|
||||
|
||||
zpl_adt_node *db_field(char *field, int row) {
|
||||
zpl_csv_object *csv = db_last();
|
||||
for (int i = 0; i < zpl_array_count(csv->nodes); i++) {
|
||||
if (!zpl_strcmp(csv->nodes[i].name, field)) {
|
||||
return &csv->nodes[i].nodes[row];
|
||||
}
|
||||
}
|
||||
assert(0 && "Field not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t db_rows() {
|
||||
zpl_csv_object *csv = db_last();
|
||||
return zpl_array_count(csv->nodes[0].nodes);
|
||||
}
|
||||
|
||||
zpl_csv_object *db_last() {
|
||||
assert(zpl_array_count(csv_stack) > 0);
|
||||
return zpl_array_end(csv_stack);
|
||||
}
|
||||
|
||||
void db_pop() {
|
||||
assert(zpl_array_count(csv_stack) > 0);
|
||||
zpl_csv_free(zpl_array_end(csv_stack));
|
||||
zpl_array_pop(csv_stack);
|
||||
}
|
||||
|
||||
bool db_exec_file(const char *sql) {
|
||||
zpl_file_contents contents = zpl_file_read_contents(zpl_heap(), true, sql);
|
||||
if (!db_exec(contents.data)) {
|
||||
assert(0 && "Failed to create tables");
|
||||
return false;
|
||||
}
|
||||
zpl_file_free_contents(&contents);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool db_exec(const char *query) {
|
||||
bool ok = !sqlite3_exec(db, query, 0, 0, 0);
|
||||
if (!ok) {
|
||||
zpl_printf("[ERROR] Failed to execute query: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
#include "platform/system.h"
|
||||
#include "zpl.h"
|
||||
|
||||
bool db_init();
|
||||
void db_shutdown();
|
||||
|
||||
// raw query data getters
|
||||
char *db_get(char *query, bool header);
|
||||
char *db_row(char *table, char *name);
|
||||
bool db_csv(zpl_csv_object *csv, char *query);
|
||||
bool db_row_csv(zpl_csv_object *csv, char *table, char *name);
|
||||
|
||||
// csv backed data queries
|
||||
bool db_push(char *query);
|
||||
bool db_row_push(char *table, char *name);
|
||||
zpl_adt_node *db_field(char *field, int row);
|
||||
size_t db_rows();
|
||||
#define db_str(fld, row) (db_field(fld, row)->string)
|
||||
#define db_flt(fld, row) (db_field(fld, row)->type == ZPL_ADT_TYPE_STRING ? 0.0f : db_field(fld, row)->real)
|
||||
#define db_int(fld, row) (db_field(fld, row)->type == ZPL_ADT_TYPE_STRING ? 0 : db_field(fld, row)->integer)
|
||||
zpl_csv_object *db_last();
|
||||
void db_pop();
|
||||
|
||||
// sql execution
|
||||
bool db_exec_file(const char *sql);
|
||||
bool db_exec(const char *query);
|
||||
|
|
@ -8,8 +8,44 @@
|
|||
#include "systems/systems.h"
|
||||
#include "zpl.h"
|
||||
|
||||
typedef struct {
|
||||
asset_id id;
|
||||
uint64_t (*proc)();
|
||||
uint64_t (*proc_udata)(void*);
|
||||
} spawndef;
|
||||
|
||||
static spawndef *entity_spawnlist;
|
||||
|
||||
void entity_add_spawndef(uint16_t id, uint64_t (*proc)()) {
|
||||
spawndef def={0};
|
||||
def.id = id;
|
||||
def.proc = proc;
|
||||
zpl_array_append(entity_spawnlist, def);
|
||||
}
|
||||
|
||||
void entity_add_spawndef_data(uint16_t id, uint64_t (*proc)(void*)) {
|
||||
spawndef def={0};
|
||||
def.id = id;
|
||||
def.proc_udata = proc;
|
||||
zpl_array_append(entity_spawnlist, def);
|
||||
}
|
||||
|
||||
// NOTE(zaklaus): bring in entity spawnlist
|
||||
#include "lists/entity_spawnlist.c"
|
||||
// #include "lists/entity_spawnlist.c"
|
||||
#include "models/prefabs/prefabs_list.c"
|
||||
#define MAX_ENTITY_SPAWNDEFS ((size_t)zpl_array_count(entity_spawnlist))
|
||||
|
||||
void entity_default_spawnlist(void) {
|
||||
zpl_array_init(entity_spawnlist, zpl_heap());
|
||||
|
||||
entity_add_spawndef(ASSET_CHEST, storage_spawn);
|
||||
entity_add_spawndef(ASSET_FURNACE, furnace_spawn);
|
||||
entity_add_spawndef(ASSET_CRAFTBENCH, craftbench_spawn);
|
||||
entity_add_spawndef(ASSET_SPLITTER, splitter_spawn);
|
||||
entity_add_spawndef(ASSET_ASSEMBLER, assembler_spawn);
|
||||
entity_add_spawndef(ASSET_CREATURE, creature_spawn);
|
||||
entity_add_spawndef_data(ASSET_BLUEPRINT, blueprint_spawn_udata);
|
||||
}
|
||||
|
||||
uint64_t entity_spawn(uint16_t class_id) {
|
||||
ecs_entity_t e = ecs_new(world_ecs(), 0);
|
||||
|
@ -18,20 +54,13 @@ uint64_t entity_spawn(uint16_t class_id) {
|
|||
entity_wake(e);
|
||||
|
||||
if (class_id != EKIND_SERVER) {
|
||||
ecs_set(world_ecs(), e, Velocity, {0});
|
||||
Position *pos = ecs_get_mut(world_ecs(), e, Position);
|
||||
#if 1
|
||||
pos->x=(float)(rand() % world_dim());
|
||||
pos->y=(float)(rand() % world_dim());
|
||||
entity_set_position(e, pos->x, pos->y);
|
||||
#else
|
||||
pos->x=350.0f;
|
||||
pos->y=88.0f;
|
||||
#endif
|
||||
|
||||
librg_entity_track(world_tracker(), e);
|
||||
librg_entity_chunk_set(world_tracker(), e, librg_chunk_from_realpos(world_tracker(), pos->x, pos->y, 0));
|
||||
librg_entity_track(world_collision_grid(), e);
|
||||
ecs_set(world_ecs(), e, Velocity, { 0 });
|
||||
entity_set_position(e, (float)(rand() % world_dim()), (float)(rand() % world_dim()));
|
||||
|
||||
librg_entity_owner_set(world_tracker(), e, (int64_t)e);
|
||||
librg_entity_owner_set(world_collision_grid(), e, (int64_t)e);
|
||||
}
|
||||
|
||||
return (uint64_t)e;
|
||||
|
@ -56,8 +85,19 @@ uint64_t entity_spawn_id_with_data(uint16_t id, void *udata){
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool entity_spawn_provided(uint16_t id) {
|
||||
for (size_t i = 0; i < MAX_ENTITY_SPAWNDEFS; ++i){
|
||||
if (entity_spawnlist[i].id == id){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void entity_batch_despawn(uint64_t *ids, size_t num_ids) {
|
||||
for (size_t i = 0; i < num_ids; i++ ) {
|
||||
librg_entity_untrack(world_collision_grid(), ids[i]);
|
||||
librg_entity_untrack(world_tracker(), ids[i]);
|
||||
ecs_delete(world_ecs(), ids[i]);
|
||||
}
|
||||
|
@ -65,14 +105,17 @@ void entity_batch_despawn(uint64_t *ids, size_t num_ids) {
|
|||
|
||||
void entity_despawn(uint64_t ent_id) {
|
||||
librg_entity_untrack(world_tracker(), ent_id);
|
||||
librg_entity_untrack(world_collision_grid(), ent_id);
|
||||
ecs_delete(world_ecs(), ent_id);
|
||||
}
|
||||
|
||||
void entity_set_position(uint64_t ent_id, float x, float y) {
|
||||
ecs_set(world_ecs(), ent_id, Position, {x, y});
|
||||
Position *p = ecs_get_mut(world_ecs(), ent_id, Position);
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
librg_entity_chunk_set(world_tracker(), ent_id, librg_chunk_from_realpos(world_tracker(), x, y, 0));
|
||||
librg_entity_chunk_set(world_collision_grid(), ent_id, librg_chunk_from_realpos(world_collision_grid(), x, y, 0));
|
||||
entity_wake(ent_id);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,16 @@
|
|||
uint64_t entity_spawn(uint16_t class_id /* 0 = no streaming */);
|
||||
uint64_t entity_spawn_id(uint16_t id);
|
||||
uint64_t entity_spawn_id_with_data(uint16_t id, void* udata);
|
||||
bool entity_spawn_provided(uint16_t id);
|
||||
void entity_batch_despawn(uint64_t *ids, size_t num_ids);
|
||||
void entity_despawn(uint64_t ent_id);
|
||||
void entity_set_position(uint64_t ent_id, float x, float y);
|
||||
|
||||
// NOTE(zaklaus): spawndef manager
|
||||
|
||||
void entity_add_spawndef(uint16_t id, uint64_t (*proc)());
|
||||
void entity_add_spawndef_data(uint16_t id, uint64_t (*proc)(void*));
|
||||
void entity_default_spawnlist(void);
|
||||
|
||||
// NOTE(zaklaus): action-based entity stream throttling
|
||||
void entity_wake(uint64_t ent_id);
|
||||
|
|
|
@ -3,16 +3,72 @@
|
|||
#include "world/entity_view.h"
|
||||
#include "world/world.h"
|
||||
#include "world/blocks.h"
|
||||
#include "models/database.h"
|
||||
|
||||
#include "models/components.h"
|
||||
|
||||
#include "zpl.h"
|
||||
|
||||
#include "lists/items_list.c"
|
||||
#define ITEMS_COUNT (sizeof(items)/sizeof(item_desc))
|
||||
//#include "lists/items_list.c"
|
||||
static item_desc *items;
|
||||
#define ITEMS_COUNT (zpl_array_count(items))
|
||||
|
||||
void item_db(void) {
|
||||
zpl_array_init(items, zpl_heap());
|
||||
db_push("SELECT * FROM items;");
|
||||
for (size_t i = 0, end = db_rows(); i < end; i++) {
|
||||
item_desc item = {0};
|
||||
item.kind = db_int("kind", i);
|
||||
item.usage = db_int("usage", i);
|
||||
item.attachment = db_int("attachment", i);
|
||||
item.max_quantity = db_int("max_quantity", i);
|
||||
item.has_storage = db_int("has_storage", i);
|
||||
|
||||
switch (item.usage) {
|
||||
case UKIND_PLACE:
|
||||
case UKIND_PLACE_ITEM:
|
||||
case UKIND_PLACE_ITEM_DATA:
|
||||
item.place.kind = db_int("place_kind", i);
|
||||
item.place.directional = db_int("directional", i);
|
||||
item.place_item.id = db_int("place_item_id", i);
|
||||
break;
|
||||
case UKIND_PROXY:
|
||||
item.proxy.id = db_int("proxy_id", i);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (item.attachment) {
|
||||
case UDATA_ENERGY_SOURCE:
|
||||
item.energy_source.producer = db_int("producer", i);
|
||||
item.energy_source.energy_level = db_flt("energy_level", i);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle blueprint data if present
|
||||
// if (item.usage == UKIND_PLACE_ITEM_DATA) {
|
||||
// item.blueprint.w = db_int("blueprint_w", i);
|
||||
// item.blueprint.h = db_int("blueprint_h", i);
|
||||
// const char *plan_str = db_str("blueprint_plan", i);
|
||||
//
|
||||
// // Convert the plan string to an array of asset_id
|
||||
// size_t plan_len = strlen(plan_str);
|
||||
// item.blueprint.plan = malloc(plan_len * sizeof(asset_id));
|
||||
// for (size_t j = 0; j < plan_len; j++) {
|
||||
// item.blueprint.plan[j] = plan_str[j]; // Assuming plan_str is a string of asset_id
|
||||
// }
|
||||
// }
|
||||
|
||||
zpl_array_append(items, item);
|
||||
}
|
||||
db_pop();
|
||||
}
|
||||
|
||||
static inline item_id item_resolve_proxy(item_id id) {
|
||||
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT);
|
||||
ZPL_ASSERT(id < ITEMS_COUNT);
|
||||
item_usage usage = items[id].usage;
|
||||
if (usage == UKIND_PROXY) {
|
||||
return item_find(items[id].proxy.id);
|
||||
|
@ -50,20 +106,14 @@ uint64_t item_spawn(asset_id kind, uint32_t qty) {
|
|||
}
|
||||
|
||||
switch (it->attachment) {
|
||||
case UDATA_ENERGY_SOURCE: {
|
||||
EnergySource *f = ecs_get_mut(world_ecs(), e, EnergySource);
|
||||
*f = (EnergySource){
|
||||
.kind = it->energy_source.producer,
|
||||
.energy_level = it->energy_source.energy_level,
|
||||
};
|
||||
} break;
|
||||
case UDATA_INGREDIENT: {
|
||||
Ingredient *i = ecs_get_mut(world_ecs(), e, Ingredient);
|
||||
i->producer = it->ingredient.producer;
|
||||
i->product = it->ingredient.product;
|
||||
i->additional_ingredient = it->ingredient.additional_ingredient;
|
||||
} break;
|
||||
default: break;
|
||||
case UDATA_ENERGY_SOURCE: {
|
||||
EnergySource *f = ecs_get_mut(world_ecs(), e, EnergySource);
|
||||
*f = (EnergySource){
|
||||
.kind = it->energy_source.producer,
|
||||
.energy_level = it->energy_source.energy_level,
|
||||
};
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return (uint64_t)e;
|
||||
|
@ -77,11 +127,17 @@ item_id item_find(asset_id kind) {
|
|||
return ASSET_INVALID;
|
||||
}
|
||||
|
||||
item_id item_find_no_proxy(asset_id kind) {
|
||||
for (item_id i=0; i<ITEMS_COUNT; i++) {
|
||||
if (items[i].kind == kind)
|
||||
return i;
|
||||
}
|
||||
return ASSET_INVALID;
|
||||
}
|
||||
|
||||
Item *item_get_data(uint64_t ent) {
|
||||
if (!world_entity_valid(ent)) return NULL;
|
||||
// if (ecs_get(world_ecs(), ent, ItemAlreadyEdited)) return NULL;
|
||||
// ecs_add(world_ecs(), ent, ItemAlreadyEdited);
|
||||
return ecs_get_mut_if_ex(world_ecs(), ent, Item);
|
||||
return ecs_get_mut_if(world_ecs(), ent, Item);
|
||||
}
|
||||
|
||||
const Item *item_get_data_const(uint64_t ent) {
|
||||
|
@ -164,16 +220,21 @@ void item_despawn(uint64_t id) {
|
|||
}
|
||||
|
||||
uint32_t item_max_quantity(item_id id) {
|
||||
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT);
|
||||
ZPL_ASSERT(id < ITEMS_COUNT);
|
||||
return items[id].max_quantity;
|
||||
}
|
||||
|
||||
item_usage item_get_usage(item_id id) {
|
||||
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT);
|
||||
ZPL_ASSERT(id < ITEMS_COUNT);
|
||||
return items[id].usage;
|
||||
}
|
||||
|
||||
bool item_get_place_directional(item_id id) {
|
||||
ZPL_ASSERT(id >= 0 && id < ITEMS_COUNT);
|
||||
ZPL_ASSERT(id < ITEMS_COUNT);
|
||||
return items[id].place.directional;
|
||||
}
|
||||
|
||||
item_desc item_get_desc(item_id id) {
|
||||
ZPL_ASSERT(id < ITEMS_COUNT);
|
||||
return items[id];
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ typedef enum {
|
|||
typedef enum {
|
||||
UDATA_NONE,
|
||||
UDATA_ENERGY_SOURCE,
|
||||
UDATA_INGREDIENT,
|
||||
} item_attachment;
|
||||
|
||||
typedef struct {
|
||||
|
@ -52,12 +51,6 @@ typedef struct {
|
|||
asset_id producer;
|
||||
float energy_level;
|
||||
} energy_source;
|
||||
|
||||
struct {
|
||||
asset_id producer;
|
||||
asset_id product;
|
||||
asset_id additional_ingredient;
|
||||
} ingredient;
|
||||
};
|
||||
|
||||
// NOTE: item data
|
||||
|
@ -72,6 +65,8 @@ typedef struct {
|
|||
|
||||
typedef uint16_t item_id;
|
||||
|
||||
void item_db(void);
|
||||
|
||||
// NOTE(zaklaus): item drops
|
||||
void item_show(uint64_t ent, bool show);
|
||||
|
||||
|
@ -80,6 +75,7 @@ void item_despawn(uint64_t id);
|
|||
|
||||
// NOTE(zaklaus): items
|
||||
item_id item_find(asset_id kind);
|
||||
item_id item_find_no_proxy(asset_id kind);
|
||||
void item_use(ecs_world_t *ecs, ecs_entity_t e, Item *it, Position p, uint64_t udata);
|
||||
Item *item_get_data(uint64_t ent);
|
||||
const Item *item_get_data_const(uint64_t ent);
|
||||
|
@ -87,3 +83,4 @@ const Item *item_get_data_const(uint64_t ent);
|
|||
uint32_t item_max_quantity(item_id id);
|
||||
item_usage item_get_usage(item_id id);
|
||||
bool item_get_place_directional(item_id id);
|
||||
item_desc item_get_desc(item_id id);
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
#include "vehicle.h"
|
||||
|
||||
#include "world/entity_view.h"
|
||||
#include "world/world.h"
|
||||
|
||||
#include "models/device.h"
|
||||
#include "models/entity.h"
|
||||
#include "models/items.h"
|
||||
#include "models/components.h"
|
||||
|
||||
uint64_t blueprint_spawn(uint8_t w, uint8_t h, const asset_id *plan) {
|
||||
ZPL_ASSERT((w*h) < 256);
|
||||
ecs_entity_t e = device_spawn(ASSET_BLUEPRINT);
|
||||
|
||||
Blueprint *blueprint = ecs_get_mut(world_ecs(), e, Blueprint);
|
||||
blueprint->w = w;
|
||||
blueprint->h = h;
|
||||
zpl_memcopy(blueprint->plan, plan, w*h*sizeof(asset_id));
|
||||
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
uint64_t blueprint_spawn_udata(void* udata) {
|
||||
item_desc *it = (item_desc*)udata;
|
||||
return blueprint_spawn(it->blueprint.w, it->blueprint.h, it->blueprint.plan);
|
||||
}
|
||||
|
||||
void blueprint_despawn(uint64_t id) {
|
||||
entity_despawn(id);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
#include "platform/system.h"
|
||||
|
||||
uint64_t blueprint_spawn(uint8_t w, uint8_t h, const uint16_t *plan);
|
||||
uint64_t blueprint_spawn_udata(void* udata);
|
||||
void blueprint_despawn(uint64_t id);
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
#include "furnace.h"
|
||||
#include "models/device.h"
|
||||
#include "world/world.h"
|
||||
|
||||
#include "models/entity.h"
|
||||
#include "models/components.h"
|
||||
|
||||
uint64_t furnace_spawn(void) {
|
||||
ecs_entity_t e = device_spawn(ASSET_FURNACE);
|
||||
|
||||
ItemContainer *storage = ecs_get_mut(world_ecs(), e, ItemContainer);
|
||||
*storage = (ItemContainer){0};
|
||||
|
||||
Producer *producer = ecs_get_mut(world_ecs(), e, Producer);
|
||||
*producer = (Producer){0};
|
||||
producer->energy_level = 69.0f;
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
void furnace_despawn(uint64_t ent_id) {
|
||||
entity_despawn(ent_id);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "platform/system.h"
|
||||
|
||||
uint64_t furnace_spawn(void);
|
||||
void furnace_despawn(uint64_t id);
|
||||
|
|
@ -6,6 +6,8 @@
|
|||
#include "models/entity.h"
|
||||
#include "models/components.h"
|
||||
|
||||
#include "core/game.h"
|
||||
|
||||
#define PLAYER_MAX_HP 100.0f
|
||||
|
||||
uint64_t player_spawn(char *name) {
|
||||
|
@ -17,9 +19,12 @@ uint64_t player_spawn(char *name) {
|
|||
|
||||
ecs_set_name(world_ecs(), e, name);
|
||||
ecs_set(world_ecs(), e, ClientInfo, {0});
|
||||
ecs_set(world_ecs(), e, Input, {0});
|
||||
ecs_set(world_ecs(), e, Inventory, {0});
|
||||
ecs_set(world_ecs(), e, Health, {.hp = PLAYER_MAX_HP, .max_hp = PLAYER_MAX_HP});
|
||||
ecs_set(world_ecs(), e, Health, {.hp = PLAYER_MAX_HP, .max_hp = PLAYER_MAX_HP});
|
||||
ecs_set(world_ecs(), e, Velocity, { 0 });
|
||||
ecs_set(world_ecs(), e, PhysicsBody, { .kind = PHYS_AABB, .mass = INFINITE_MASS });
|
||||
Input *i = ecs_get_mut(world_ecs(), e, Input);
|
||||
*i = (Input){ 0 };
|
||||
i->hx = 1.0f;
|
||||
|
||||
librg_entity_owner_set(world_tracker(), e, (int64_t)e);
|
||||
|
||||
|
@ -27,5 +32,6 @@ uint64_t player_spawn(char *name) {
|
|||
}
|
||||
|
||||
void player_despawn(uint64_t ent_id) {
|
||||
game_player_departed(ent_id);
|
||||
entity_despawn(ent_id);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
#include "models/device.h"
|
||||
#include "models/assets.h"
|
||||
#include "world/world.h"
|
||||
#include "models/components.h"
|
||||
#include "world/entity_view.h"
|
||||
#include "world/world.h"
|
||||
#include "models/device.h"
|
||||
#include "models/entity.h"
|
||||
#include "models/items.h"
|
||||
#include "models/components.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
uint64_t assembler_spawn(void) {
|
||||
ecs_entity_t e = device_spawn(ASSET_ASSEMBLER);
|
||||
|
||||
ItemContainer *storage = ecs_get_mut(world_ecs(), e, ItemContainer);
|
||||
*storage = (ItemContainer){0};
|
||||
|
||||
Producer *producer = ecs_get_mut(world_ecs(), e, Producer);
|
||||
*producer = (Producer){0};
|
||||
producer->energy_level = 69.0f;
|
||||
producer->pending_task = PRODUCER_CRAFT_AUTO;
|
||||
producer->push_filter = PRODUCER_PUSH_PRODUCT;
|
||||
producer->target_item = ASSET_INVALID;
|
||||
|
||||
ecs_set(world_ecs(), e, ItemRouter, {.push_qty = 1, .counter = 0});
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
uint64_t blueprint_spawn(uint8_t w, uint8_t h, const asset_id *plan) {
|
||||
ZPL_ASSERT((w*h) < 256);
|
||||
ecs_entity_t e = device_spawn(ASSET_BLUEPRINT);
|
||||
|
||||
Blueprint *blueprint = ecs_get_mut(world_ecs(), e, Blueprint);
|
||||
blueprint->w = w;
|
||||
blueprint->h = h;
|
||||
zpl_memcopy(blueprint->plan, plan, w*h*sizeof(asset_id));
|
||||
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
uint64_t blueprint_spawn_udata(void* udata) {
|
||||
item_desc *it = (item_desc*)udata;
|
||||
return blueprint_spawn(it->blueprint.w, it->blueprint.h, it->blueprint.plan);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
uint64_t craftbench_spawn(void) {
|
||||
ecs_entity_t e = device_spawn(ASSET_CRAFTBENCH);
|
||||
|
||||
ItemContainer *storage = ecs_get_mut(world_ecs(), e, ItemContainer);
|
||||
*storage = (ItemContainer){0};
|
||||
|
||||
Producer *producer = ecs_get_mut(world_ecs(), e, Producer);
|
||||
*producer = (Producer){0};
|
||||
producer->energy_level = 69.0f;
|
||||
producer->pending_task = PRODUCER_CRAFT_WAITING;
|
||||
producer->push_filter = PRODUCER_PUSH_NONE;
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
uint64_t furnace_spawn(void) {
|
||||
ecs_entity_t e = device_spawn(ASSET_FURNACE);
|
||||
|
||||
ItemContainer *storage = ecs_get_mut(world_ecs(), e, ItemContainer);
|
||||
*storage = (ItemContainer){0};
|
||||
|
||||
Producer *producer = ecs_get_mut(world_ecs(), e, Producer);
|
||||
*producer = (Producer){0};
|
||||
producer->energy_level = 69.0f;
|
||||
producer->pending_task = PRODUCER_CRAFT_AUTO;
|
||||
producer->push_filter = PRODUCER_PUSH_ANY;
|
||||
|
||||
ecs_set(world_ecs(), e, ItemRouter, {.push_qty = 1, .counter = 0});
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
uint64_t splitter_spawn(void) {
|
||||
ecs_entity_t e = device_spawn(ASSET_SPLITTER);
|
||||
|
||||
ItemContainer *storage = ecs_get_mut(world_ecs(), e, ItemContainer);
|
||||
*storage = (ItemContainer){0};
|
||||
|
||||
ecs_set(world_ecs(), e, ItemRouter, {.push_qty = 1, .counter = 0});
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
uint64_t storage_spawn(void) {
|
||||
ecs_entity_t e = device_spawn(ASSET_CHEST);
|
||||
|
||||
ItemContainer *storage = ecs_get_mut(world_ecs(), e, ItemContainer);
|
||||
*storage = (ItemContainer){0};
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#include "storage.h"
|
||||
#include "models/device.h"
|
||||
#include "world/world.h"
|
||||
|
||||
#include "models/entity.h"
|
||||
#include "models/components.h"
|
||||
|
||||
uint64_t storage_spawn(void) {
|
||||
ecs_entity_t e = device_spawn(ASSET_CHEST);
|
||||
|
||||
ItemContainer *storage = ecs_get_mut(world_ecs(), e, ItemContainer);
|
||||
*storage = (ItemContainer){0};
|
||||
return (uint64_t)e;
|
||||
}
|
||||
|
||||
void storage_despawn(uint64_t ent_id) {
|
||||
entity_despawn(ent_id);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "platform/system.h"
|
||||
|
||||
uint64_t storage_spawn(void);
|
||||
void storage_despawn(uint64_t id);
|
||||
|
|
@ -29,14 +29,9 @@ int32_t pkt_00_init_handler(pkt_header *header) {
|
|||
uint64_t peer_id = (uint64_t)header->udata;
|
||||
uint64_t ent_id = player_spawn(NULL);
|
||||
|
||||
Position *pos = ecs_get_mut(world_ecs(), ent_id, Position);
|
||||
|
||||
#if 1
|
||||
entity_set_position(ent_id, world_dim()/2.0f + rand()%15*15.0f, world_dim()/2.0f + rand()%15*15.0f);
|
||||
#else
|
||||
pos->x = rand()%world_dim();
|
||||
pos->y = rand()%world_dim();
|
||||
#endif
|
||||
|
||||
game_player_joined(ent_id);
|
||||
|
||||
zpl_printf("[INFO] initializing player entity id: %d with view id: %d for peer id: %d...\n", ent_id, table.view_id, peer_id);
|
||||
ecs_set(world_ecs(), ent_id, ClientInfo, {.peer = peer_id, .view_id = header->view_id, .active = false });
|
||||
|
|