diff --git a/assets/item/items.csv b/assets/item/items.csv index 8b25944..5376a99 100644 --- a/assets/item/items.csv +++ b/assets/item/items.csv @@ -1,4 +1,4 @@ -id,type, -POTION,MEDICINE, -POTATO,FOOD, -APPLE,FOOD, \ No newline at end of file +id,type,weight +POTION,MEDICINE,1.0 +POTATO,FOOD,0.5 +APPLE,FOOD,0.3 \ No newline at end of file diff --git a/src/item/item.h b/src/item/item.h index 568c202..08f671b 100644 --- a/src/item/item.h +++ b/src/item/item.h @@ -15,8 +15,10 @@ #include "item/itemid.h" #include "item/itemname.h" +// test. typedef struct { - itemtype_t type; + const char_t *name; + const itemtype_t type; } item_t; extern const item_t ITEMS[]; \ No newline at end of file diff --git a/tools/csv_to_array/__main__.py b/tools/csv_to_array/__main__.py index 8fe455f..f13e6ea 100644 --- a/tools/csv_to_array/__main__.py +++ b/tools/csv_to_array/__main__.py @@ -1,6 +1,7 @@ import argparse import os import csv +from tools.util.type import detectType, stringToCType, typeToCType parser = argparse.ArgumentParser(description="Convert CSV to .h defines") parser.add_argument("--csv", required=True, help="Path to CSV file") @@ -34,6 +35,7 @@ with open(args.csv, newline='') as csvfile: index_col_idx = headers.index(args.index_column) data_col_idx = headers.index(args.data_column) keyValuePairs = {} + valType = None for row in reader: key = row[index_col_idx] value = row[data_col_idx] @@ -42,73 +44,19 @@ with open(args.csv, newline='') as csvfile: if key in keyValuePairs: raise ValueError(f"Duplicate key '{key}' found in CSV") keyValuePairs[key] = value - - # Determine type. Can be float, int, bool, or string. - isFloat = False - isInt = False - isBool = False - isString = False - - # If there's no entries, assume string type. - if len(keyValuePairs) == 0: - isString = True - else: - allInts = True - allFloats = True - - # Check if ALL values can be parsed as int or float. - for value in keyValuePairs.values(): - if allInts: - try: - int(value) - except: - allInts = False - if allFloats: - try: - float(value) - except: - allFloats = False - - if not allInts and not allFloats: - break - - if allInts: - isInt = True - elif allFloats: - isFloat = True - else: - # Not all floats/ints, probably string or bool, check first entry - firstValue = next(iter(keyValuePairs.values())) - if firstValue.lower() in ['true', 'false']: - isBool = True - else: - isString = True - - typeString = "" - if isFloat: - typeString = "float" - elif isInt: - typeString = "int" - elif isBool: - typeString = "bool" - elif isString: - typeString = "char*" + if valType is None: + valType = detectType(value) + + if valType is None: + valType = 'String' # Now begin generating header. - outHeader += f"static const {typeString} {args.variable}[] = {{\n" + cType = typeToCType(valType) + outHeader += f"static const {cType} {args.variable}[] = {{\n" for key in keyValuePairs: outHeader += f" [{args.index_prefix}{key}] = " value = keyValuePairs[key] - if isFloat: - outHeader += str(float(value)) - elif isInt: - outHeader += str(int(value)) - elif isBool: - asBool = 'true' if value.lower() == 'true' else 'false' - outHeader += asBool - elif isString: - escaped = value.replace('\\', '\\\\').replace('"', '\\"') - outHeader += f'"{escaped}"' + outHeader += stringToCType(value) outHeader += ",\n" outHeader += "};\n\n" diff --git a/tools/item/CMakeLists.txt b/tools/item/CMakeLists.txt index 3854d35..5f01c04 100644 --- a/tools/item/CMakeLists.txt +++ b/tools/item/CMakeLists.txt @@ -1,37 +1 @@ -# Copyright (c) 2026 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -function(dusk_item_csv CSV_FILE) - dusk_csv_to_enum( - ${CSV_FILE} - item/itemtype.h - itemtype_t - ITEM_TYPE_ - type - ) - - dusk_csv_to_enum( - ${CSV_FILE} - item/itemid.h - itemid_t - ITEM_ID_ - id - ) - - dusk_csv_to_array( - ${CSV_FILE} - item/itemname.h - ITEM_NAMES - item/itemid.h - ITEM_ID_ - id - id - ) - - target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} - PUBLIC - ITEM_CSV_GENERATED=1 - ) -endfunction() \ No newline at end of file +add_subdirectory(csv) \ No newline at end of file diff --git a/tools/item/csv/CMakeLists.txt b/tools/item/csv/CMakeLists.txt new file mode 100644 index 0000000..9e3898d --- /dev/null +++ b/tools/item/csv/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright (c) 2026 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +function(dusk_item_csv CSV_FILE) + # dusk_csv_to_enum( + # ${CSV_FILE} + # item/itemtype.h + # itemtype_t + # ITEM_TYPE_ + # type + # ) + + # dusk_csv_to_enum( + # ${CSV_FILE} + # item/itemid.h + # itemid_t + # ITEM_ID_ + # id + # ) + + # dusk_csv_to_array( + # ${CSV_FILE} + # item/itemname.h + # ITEM_NAMES + # item/itemid.h + # ITEM_ID_ + # id + # id + # ) + + target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} + PUBLIC + ITEM_CSV_GENERATED=1 + ) + + dusk_run_python( + dusk_item_csv_defs + tools.item.csv + --csv ${CSV_FILE} + --output ${DUSK_GENERATED_HEADERS_DIR}/item/itemdefs.h + ) + add_dependencies(${DUSK_LIBRARY_TARGET_NAME} dusk_item_csv_defs) +endfunction() \ No newline at end of file diff --git a/tools/item/csv/__main__.py b/tools/item/csv/__main__.py new file mode 100644 index 0000000..f337507 --- /dev/null +++ b/tools/item/csv/__main__.py @@ -0,0 +1,19 @@ +import argparse +import os +import csv +from tools.util.type import detectType, stringToCType, typeToCType + +parser = argparse.ArgumentParser(description="Item CSV to .h defines") +parser.add_argument("--csv", required=True, help="Path to item CSV file") +parser.add_argument("--output", required=True, help="Path to output .h file") +args = parser.parse_args() + +# Load up CSV file. +outHeader = "#pragma once\n" +outHeader += "#include \"item/item.h\"\n\n" +with open(args.csv, newline="", encoding="utf-8") as csvfile: + reader = csv.DictReader(csvfile) + + # CSV must have id and type columns. + if "id" not in reader.fieldnames or "type" not in reader.fieldnames: + raise Exception("CSV file must have 'id' and 'type' columns") \ No newline at end of file diff --git a/tools/util/type.py b/tools/util/type.py new file mode 100644 index 0000000..32dd36a --- /dev/null +++ b/tools/util/type.py @@ -0,0 +1,44 @@ +def detectType(value: str) -> str: + val = value.strip() + # Boolean check + if val.lower() in {'true', 'false'}: + return 'Boolean' + + # Int check + try: + int(val) + return 'Int' + except ValueError: + pass + + # Float check + try: + float(val) + return 'Float' + except ValueError: + pass + + # Default to String + return 'String' + +def typeToCType(valType: str) -> str: + if valType == 'Int': + return 'int' + elif valType == 'Float': + return 'float' + elif valType == 'Boolean': + return 'bool' + else: + return 'char_t*' + +def stringToCType(value: str) -> str: + valType = detectType(value) + if valType == 'Int': + return str(int(value)) + elif valType == 'Float': + return str(float(value)) + elif valType == 'Boolean': + return 'true' if value.lower() == 'true' else 'false' + else: + escaped = value.replace('\\', '\\\\').replace('"', '\\"') + return f'"{escaped}"' \ No newline at end of file