NPCs 1: tools to integrate properties

This commit is contained in:
Pyrex 2024-02-28 19:05:52 -08:00
parent df1d1450e7
commit 567db0bd71
12 changed files with 369 additions and 17 deletions

View File

@ -17,6 +17,7 @@ cc_library(
add_sprites(name="game_collectibles", n=24)
add_sprites(name="game_player", n=96)
add_sprites(name="game_npcs", n=64)
add_sprites(name="game_tiles", n=120)
run_binary(

BIN
game/art/game_npcs.aseprite Normal file

Binary file not shown.

8
game/art/game_npcs.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef GAME_NPCS_H
#define GAME_NPCS_H
#include "sys/sys.h"
extern sys_spritesheet spr_game_npcs;
#endif // GAME_NPCS_H

BIN
game/art/game_npcs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

View File

@ -15,11 +15,8 @@ const char* game_title() {
void game_init() {
sys_init();
game_collectibles_preinit();
map_game_map_create_entities();
game_collectibles_init();
game_palette_init();
game_player_init();
}

View File

@ -20,8 +20,6 @@ struct {
sys_i32 game_collectible_wobb_frame = 0;
void game_collectibles_preinit() {
}
void game_collectible_create(sys_i32 x, sys_i32 y, game_collectible_type type) {
assert(game_collectible_next < GAME_COLLECTIBLES_N && "too many collectibles");
@ -31,10 +29,6 @@ void game_collectible_create(sys_i32 x, sys_i32 y, game_collectible_type type) {
game_collectibles[id].type = type;
}
void game_collectibles_init() {
}
sys_i32 game_collectible_wobb() {
return game_wobb3(game_collectible_wobb_frame & 0xff);
}

View File

@ -17,10 +17,8 @@ typedef struct {
bool collected;
} game_collectible;
void game_collectibles_preinit();
void game_collectible_create(sys_i32 x, sys_i32 y, game_collectible_type type);
void game_collectibles_init();
void game_collectibles_update();
void game_collectibles_draw();

1
game/game_npc.c Normal file
View File

@ -0,0 +1 @@
#include "game_npc.h"

4
game/game_npc.h Normal file
View File

@ -0,0 +1,4 @@
#ifndef GAME_NPC_H
#define GAME_NPC_H
#endif // GAME_NPC_H

View File

@ -11,7 +11,7 @@
"iid": "7db5fd20-b0a0-11ee-9688-af2c6adbc1d6",
"jsonVersion": "1.5.3",
"appBuildId": 473703,
"nextUid": 122,
"nextUid": 130,
"identifierStyle": "Lowercase",
"toc": [],
"worldLayout": "Free",
@ -3477,6 +3477,227 @@
"pivotX": 0,
"pivotY": 0,
"fieldDefs": []
},
{
"identifier": "npc",
"uid": 122,
"tags": [],
"exportToToc": false,
"allowOutOfBounds": false,
"doc": null,
"width": 16,
"height": 16,
"resizableX": false,
"resizableY": false,
"minWidth": null,
"maxWidth": null,
"minHeight": null,
"maxHeight": null,
"keepAspectRatio": false,
"tileOpacity": 1,
"fillOpacity": 0.08,
"lineOpacity": 0,
"hollow": false,
"color": "#E4A672",
"renderMode": "Tile",
"showName": true,
"tilesetId": 123,
"tileRenderMode": "FitInside",
"tileRect": { "tilesetUid": 123, "x": 0, "y": 0, "w": 16, "h": 16 },
"uiTileRect": null,
"nineSliceBorders": [],
"maxCount": 0,
"limitScope": "PerLevel",
"limitBehavior": "MoveLastOne",
"pivotX": 0,
"pivotY": 0,
"fieldDefs": [
{
"identifier": "sprite_id",
"doc": null,
"__type": "Int",
"uid": 125,
"type": "F_Int",
"isArray": false,
"canBeNull": false,
"arrayMinLength": null,
"arrayMaxLength": null,
"editorDisplayMode": "Hidden",
"editorDisplayScale": 1,
"editorDisplayPos": "Above",
"editorLinkStyle": "StraightArrow",
"editorDisplayColor": null,
"editorAlwaysShow": false,
"editorShowInWorld": true,
"editorCutLongValues": true,
"editorTextSuffix": null,
"editorTextPrefix": null,
"useForSmartColor": false,
"exportToToc": false,
"searchable": false,
"min": null,
"max": null,
"regex": null,
"acceptFileTypes": null,
"defaultOverride": null,
"textLanguageMode": null,
"symmetricalRef": false,
"autoChainRef": true,
"allowOutOfLevelRef": true,
"allowedRefs": "OnlySame",
"allowedRefsEntityUid": null,
"allowedRefTags": [],
"tilesetUid": null
},
{
"identifier": "palette_id",
"doc": null,
"__type": "Int",
"uid": 126,
"type": "F_Int",
"isArray": false,
"canBeNull": false,
"arrayMinLength": null,
"arrayMaxLength": null,
"editorDisplayMode": "Hidden",
"editorDisplayScale": 1,
"editorDisplayPos": "Above",
"editorLinkStyle": "StraightArrow",
"editorDisplayColor": null,
"editorAlwaysShow": false,
"editorShowInWorld": true,
"editorCutLongValues": true,
"editorTextSuffix": null,
"editorTextPrefix": null,
"useForSmartColor": false,
"exportToToc": false,
"searchable": false,
"min": null,
"max": null,
"regex": null,
"acceptFileTypes": null,
"defaultOverride": null,
"textLanguageMode": null,
"symmetricalRef": false,
"autoChainRef": true,
"allowOutOfLevelRef": true,
"allowedRefs": "OnlySame",
"allowedRefsEntityUid": null,
"allowedRefTags": [],
"tilesetUid": null
},
{
"identifier": "inflict_id",
"doc": null,
"__type": "Int",
"uid": 127,
"type": "F_Int",
"isArray": false,
"canBeNull": false,
"arrayMinLength": null,
"arrayMaxLength": null,
"editorDisplayMode": "Hidden",
"editorDisplayScale": 1,
"editorDisplayPos": "Above",
"editorLinkStyle": "StraightArrow",
"editorDisplayColor": null,
"editorAlwaysShow": false,
"editorShowInWorld": true,
"editorCutLongValues": true,
"editorTextSuffix": null,
"editorTextPrefix": null,
"useForSmartColor": false,
"exportToToc": false,
"searchable": false,
"min": null,
"max": null,
"regex": null,
"acceptFileTypes": null,
"defaultOverride": null,
"textLanguageMode": null,
"symmetricalRef": false,
"autoChainRef": true,
"allowOutOfLevelRef": true,
"allowedRefs": "OnlySame",
"allowedRefsEntityUid": null,
"allowedRefTags": [],
"tilesetUid": null
},
{
"identifier": "dialogue",
"doc": null,
"__type": "Array<String>",
"uid": 124,
"type": "F_String",
"isArray": true,
"canBeNull": false,
"arrayMinLength": null,
"arrayMaxLength": null,
"editorDisplayMode": "Hidden",
"editorDisplayScale": 1,
"editorDisplayPos": "Above",
"editorLinkStyle": "StraightArrow",
"editorDisplayColor": null,
"editorAlwaysShow": false,
"editorShowInWorld": true,
"editorCutLongValues": true,
"editorTextSuffix": null,
"editorTextPrefix": null,
"useForSmartColor": false,
"exportToToc": false,
"searchable": false,
"min": null,
"max": null,
"regex": null,
"acceptFileTypes": null,
"defaultOverride": null,
"textLanguageMode": null,
"symmetricalRef": false,
"autoChainRef": true,
"allowOutOfLevelRef": true,
"allowedRefs": "OnlySame",
"allowedRefsEntityUid": null,
"allowedRefTags": [],
"tilesetUid": null
},
{
"identifier": "no_cake_dialogue",
"doc": null,
"__type": "String",
"uid": 129,
"type": "F_String",
"isArray": false,
"canBeNull": true,
"arrayMinLength": null,
"arrayMaxLength": null,
"editorDisplayMode": "Hidden",
"editorDisplayScale": 1,
"editorDisplayPos": "Above",
"editorLinkStyle": "StraightArrow",
"editorDisplayColor": null,
"editorAlwaysShow": false,
"editorShowInWorld": true,
"editorCutLongValues": true,
"editorTextSuffix": null,
"editorTextPrefix": null,
"useForSmartColor": false,
"exportToToc": false,
"searchable": false,
"min": null,
"max": null,
"regex": null,
"acceptFileTypes": null,
"defaultOverride": null,
"textLanguageMode": null,
"symmetricalRef": false,
"autoChainRef": true,
"allowOutOfLevelRef": true,
"allowedRefs": "OnlySame",
"allowedRefsEntityUid": null,
"allowedRefTags": [],
"tilesetUid": null
}
]
}
], "tilesets": [
{
@ -3544,6 +3765,28 @@
"opaqueTiles": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"averageColors": "9a86a6969a86a6969a86a6969a86a69600000000000000000000000000000000dc859d94dc858d94bc759d94ac857d95000000000000000000000000000000000f051f050f051f050f051f050f051f0500000000000000000000000000000000ab777ca6ab777ca69a777ca68a776ca600000000000000000000000000000000a9869797a9869797a9869797a9869797000000000000000000000000000000007d555c757d555c857d555c756d564c7600000000000000000000000000000000"
}
},
{
"__cWid": 8,
"__cHei": 8,
"identifier": "game_npcs",
"uid": 123,
"relPath": "../art/game_npcs.png",
"embedAtlas": null,
"pxWid": 64,
"pxHei": 64,
"tileGridSize": 8,
"spacing": 0,
"padding": 0,
"tags": [],
"tagsSourceEnumUid": null,
"enumTags": [],
"customData": [],
"savedSelections": [],
"cachedPixelData": {
"opaqueTiles": "0000000000000000000000000000000000000000000000000000000000000000",
"averageColors": "bd8aae896b897d7a86ba8c899c9aae89daac9bbc7c8b489b7d8a69aadaac9bbc49aa5c9b0000000000000000000000007c8b489b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
}
], "enums": [], "externalEnums": [], "levelFields": [] },
"levels": [
@ -3949,6 +4192,34 @@
"fieldInstances": [],
"__worldX": 376,
"__worldY": 488
},
{
"__identifier": "npc",
"__grid": [26,12],
"__pivot": [0,0],
"__tags": [],
"__tile": { "tilesetUid": 123, "x": 0, "y": 0, "w": 16, "h": 16 },
"__smartColor": "#E4A672",
"iid": "013b9de0-b0a0-11ee-9688-2f8ccd9fe15d",
"width": 16,
"height": 16,
"defUid": 122,
"px": [208,96],
"fieldInstances": [
{ "__identifier": "sprite_id", "__type": "Int", "__value": 0, "__tile": null, "defUid": 125, "realEditorValues": [] },
{ "__identifier": "palette_id", "__type": "Int", "__value": 0, "__tile": null, "defUid": 126, "realEditorValues": [] },
{ "__identifier": "inflict_id", "__type": "Int", "__value": 0, "__tile": null, "defUid": 127, "realEditorValues": [] },
{ "__identifier": "dialogue", "__type": "Array<String>", "__value": [ "Croc! I love you.", "But you should go to the next screen." ], "__tile": null, "defUid": 124, "realEditorValues": [ {
"id": "V_String",
"params": ["Croc! I love you."]
}, {
"id": "V_String",
"params": ["But you should go to the next screen."]
} ] },
{ "__identifier": "no_cake_dialogue", "__type": "String", "__value": null, "__tile": null, "defUid": 129, "realEditorValues": [] }
],
"__worldX": 464,
"__worldY": 528
}
]
}

View File

@ -34,4 +34,28 @@ void map_game_map_collectible_money_small_create(sys_i32 x, sys_i32 y) {
(y + 1) * TILE_SZ_MICROPIXEL,
GAME_COLLECTIBLE_TYPE_MONEY_SMALL
);
}
void map_game_map_npc_create(sys_i32 x, sys_i32 y) {
// TODO
}
void map_game_map_npc_set_sprite_id(sys_i32 id) {
// TODO
}
void map_game_map_npc_set_inflict_id(sys_i32 id) {
// TODO
}
void map_game_map_npc_set_no_cake_dialogue(const char* dialogue) {
// TODO
}
void map_game_map_npc_set_palette_id(sys_i32 id) {
// TODO
}
void map_game_map_npc_add_dialogue(const char* dialogue) {
// TODO
}

View File

@ -17,15 +17,37 @@ sys_map map_{{map_name}} = {
void map_{{map_name}}_{{entity_type}}_create(sys_i32 x, sys_i32 y);
{% endfor %}
{% for entity_name, field_name, c_type, render_mode in entity_fields %}
{% if render_mode == "scalar" %}
void map_{{map_name}}_{{entity_name}}_set_{{field_name}}({{c_type}} value);
{% elif render_mode == "array" %}
void map_{{map_name}}_{{entity_name}}_add_{{field_name}}({{c_type}} value);
{% else %}
wtf; // {{ render_mode }}
{% endif %}
{% endfor %}
void map_{{map_name}}_create_entities() {
{% for entity in entities %}
map_{{map_name}}_{{entity.type}}_create({{entity.x}}, {{entity.y}});
{% for field in entity.fields %}
{% if field.renderMode == "scalar" %}
map_{{map_name}}_{{entity.type}}_set_{{field.name}}({{field.value|safe}});
{% elif field.renderMode == "array" %}
{% for s in field.value %}
map_{{map_name}}_{{entity.type}}_add_{{field.name}}({{s|safe}});
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
}
""".lstrip()
def main(map_name, fname_ldtk, fname_c):
width, height, tiles, entities = load_mapdata(fname_ldtk)
width, height, tiles, entities, entity_types, entity_fields = load_mapdata(fname_ldtk)
print(entity_fields)
with open(fname_c, "wt") as output:
output.write(
@ -34,8 +56,9 @@ def main(map_name, fname_ldtk, fname_c):
tiles=tiles,
width=width,
height=height,
entity_types=sorted(set(i["type"] for i in entities)),
entities=entities,
entity_types=entity_types,
entity_fields=entity_fields,
)
)
@ -43,6 +66,8 @@ def main(map_name, fname_ldtk, fname_c):
def load_mapdata(fname_ldtk):
sparse_tiles = {}
entities = []
entity_types = set()
entity_fields = set()
with open(fname_ldtk, "rt") as f:
data = json.load(f)
@ -62,11 +87,27 @@ def load_mapdata(fname_ldtk):
if layer["__identifier"] == "entities":
for e in layer["entityInstances"]:
# TODO: Other fields?
entities.append({
entity = {
"type": e["__identifier"],
"x": e["__worldX"] // 8,
"y": e["__worldY"] // 8,
})
"fields": []
}
for f in e["fieldInstances"]:
field = {
"name": f["__identifier"],
}
field["value"], field["renderMode"], rendered_type = format_field_value(f["__type"], f["__value"])
entity["fields"].append(field)
entity_fields.add((
entity["type"],
field["name"],
rendered_type,
field["renderMode"]
))
entities.append(entity)
entity_types.add(entity["type"])
x_min = 0
y_min = 0
@ -83,7 +124,20 @@ def load_mapdata(fname_ldtk):
else:
dense_tiles.append(255)
return width, height, dense_tiles, entities
return width, height, dense_tiles, entities, entity_types, entity_fields
def format_field_value(ty, val):
if ty == "Int":
return str(val), "scalar", "sys_i32"
elif ty == "String":
if val is None:
return "NULL", "scalar", "const char*"
return json.dumps(val), "scalar" # this is close enough to being right in C
elif ty == "Array<Int>":
return [format_field_value("Int", i)[0] for i in val], "array", "sys_i32"
elif ty == "Array<String>":
return [format_field_value("String", i)[0] for i in val], "array", "const char*"
def annot_xy(lst, w, h):