actually rendering a table
This commit is contained in:
@@ -0,0 +1,122 @@
|
|||||||
|
space-trader-multiplayer-boardgame-esque:
|
||||||
|
- projector shows the star-map with everyone's positions
|
||||||
|
- players all have a laptop to control their character
|
||||||
|
- choose a starting ship
|
||||||
|
- you have 10_000 credits, and the down-payment % of the ship total value affects the interest rate you get
|
||||||
|
- Ships:
|
||||||
|
- attributes:
|
||||||
|
- cargo space
|
||||||
|
- Alcubierre Drive efficiency
|
||||||
|
- Passenger space
|
||||||
|
- Passenger amenities
|
||||||
|
- smugglers holds
|
||||||
|
- life-support system
|
||||||
|
- Sparrow [2, 1, 0, shared-bunk, 1, 0, 1, 100k]
|
||||||
|
- Dart [5, 8, 2, shared-bunk, 0, 1, 2, 150k]
|
||||||
|
- Hauler-Prime Z-1 [120, 2, 0, X, 2, 1, 4, 180k]
|
||||||
|
- NX-400 [15, 4, 8, shared-bunk, 0, 2, 3, 280k]
|
||||||
|
- CabinRun 40-X [40, 3, 45, shared-bunk, 1, 4, 6, 380k]
|
||||||
|
- IronBulk X7 [350, 3, 0, X, 3, 2, 8, 420k]
|
||||||
|
- Solaris-200 [25, 6, 24, shared-bunk, 0, 3, 4, 520k]
|
||||||
|
- Merchant's Run [180, 5, 12, shared-bunk, 1, 2, 5, 620k]
|
||||||
|
- Genesis-Long-Haul V2 [100, 4, 80, shared-bunk, 2, 6, 10, 720k]
|
||||||
|
- Titan-Class HC-3000 [800, 4, 0, X, 3, 3, 15, 890k]
|
||||||
|
- Steady Hand [420, 6, 25, shared-bunk, 1, 4, 7, 1.1m]
|
||||||
|
- Pathfinder [60, 6, 65, shared-bunk, 0, 5, 8, 1.4m]
|
||||||
|
- Ark-Class Transport A1 [250, 5, 95, shared-bunk, 3, 8, 18, 1.6m]
|
||||||
|
- Starlight [8, 9, 5, private-apartment, 0, 3, 2, 2.1m]
|
||||||
|
- Leviathan's Route [900, 7, 40, shared-bunk, 2, 6, 12, 2.3m]
|
||||||
|
- Voyager's Dream [140, 7, 100, shared-bunk, 1, 8, 12, 2.8m]
|
||||||
|
- Apex-5000 Deluxe [150, 8, 18, private-apartment, 0, 4, 6, 3.2m]
|
||||||
|
- Aurora Crown [18, 10, 35, private-apartment, 0, 4, 5, 3.8m]
|
||||||
|
- TerraFreight Luxe-900 [380, 9, 30, private-apartment, 0, 5, 8, 4.5m]
|
||||||
|
- Odyssey [320, 8, 100, shared-bunk, 2, 10, 20, 5.4m]
|
||||||
|
- Celestial Palace [55, 9, 85, private-apartment, 0, 7, 10, 6.2m]
|
||||||
|
- Sovereign Expanse [950, 10, 60, private-apartment, 1, 8, 20, 8.7m]
|
||||||
|
- Nexus-Elite-7 [120, 10, 100, private-apartment, 0, 9, 14, 9.1m]
|
||||||
|
- Infinity's Embrace [280, 10, 100, private-apartment, 1, 10, 22, 10m]
|
||||||
|
- turn-based. Everyone does their trading at the same time, and then flies to the next station
|
||||||
|
- instead of making journeys take longer, for game-sake, longer journeys just cost more fuel.
|
||||||
|
- "faster" drives are actually just more fuel efficient
|
||||||
|
- the prices of goods are supply/demand based on quantity produced/consumed at planets/stations
|
||||||
|
- the prices/goods available at a place are only visible to those who are in the station
|
||||||
|
- stations may build "reputation" prices for repeat suppliers/buyers.
|
||||||
|
- players can trade with each other while at the same station
|
||||||
|
- certain stations have shipyards, with mortgages available for trade-in/upgrading ships drives/storage capacity, etc.
|
||||||
|
- all systems have a safety rating, indicating likelyhood of piracy. High risk systems often have higher profitablilty
|
||||||
|
- AI station trading agent for haggling deal-making?
|
||||||
|
- transport contracts available at stations randomly.
|
||||||
|
- in a system, you can fly out to the asteroid belt and try to buy from miners directly, but it's a gamble on even finding any of them.
|
||||||
|
- game ends when someone pays off their ship's mortgage.
|
||||||
|
- passengers/VIP transport
|
||||||
|
- playstyles:
|
||||||
|
- Mass-Cargo hauler
|
||||||
|
- Fast-expensive-goods transport (precious metals)
|
||||||
|
- passenger transport
|
||||||
|
- commodities:
|
||||||
|
- Hydrogen (Fuel)
|
||||||
|
- Oxygen
|
||||||
|
- Water
|
||||||
|
- Food: (plants provide seed versions as well)
|
||||||
|
- Wheat
|
||||||
|
- rice
|
||||||
|
- corn
|
||||||
|
- potatoes
|
||||||
|
- beef
|
||||||
|
- chicken
|
||||||
|
- butter
|
||||||
|
- olive oil
|
||||||
|
- alcohol
|
||||||
|
- fertilizer
|
||||||
|
- cleaning supplies
|
||||||
|
- air filters
|
||||||
|
- Chemicals
|
||||||
|
- clothes
|
||||||
|
- textiles
|
||||||
|
- Electronics
|
||||||
|
- Construction parts
|
||||||
|
- 3D printer parts
|
||||||
|
- clothing fabricator
|
||||||
|
- hand tools
|
||||||
|
- machine tools
|
||||||
|
- cutlery
|
||||||
|
- robots
|
||||||
|
- plastics
|
||||||
|
- hand weapons
|
||||||
|
- batteries
|
||||||
|
- solar panels
|
||||||
|
- medicines
|
||||||
|
- optical components
|
||||||
|
- glass
|
||||||
|
- Metals (Ore-form and Purified-form):
|
||||||
|
- Lithium
|
||||||
|
- Berylium
|
||||||
|
- Magnesium
|
||||||
|
- Aluminium
|
||||||
|
- Silicon
|
||||||
|
- Scandium
|
||||||
|
- Titanium
|
||||||
|
- Vanadium
|
||||||
|
- Chromium
|
||||||
|
- Manganese
|
||||||
|
- Iron
|
||||||
|
- Cobalt
|
||||||
|
- Nickel
|
||||||
|
- Copper
|
||||||
|
- Zinc
|
||||||
|
- Selenium
|
||||||
|
- Zirconium
|
||||||
|
- Molybdenum
|
||||||
|
- Ruthenium
|
||||||
|
- Rhodium
|
||||||
|
- Palladium
|
||||||
|
- Silver
|
||||||
|
- Cadmium
|
||||||
|
- Tin
|
||||||
|
- Tungsten
|
||||||
|
- Rhenium
|
||||||
|
- Iridium
|
||||||
|
- Platinum
|
||||||
|
- Gold
|
||||||
|
- Mercury
|
||||||
|
- Lead
|
||||||
+47
-1
@@ -492,7 +492,6 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
state->screen = ScreenMainGame;
|
state->screen = ScreenMainGame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->menu.selected_index >= state->menu.len) {
|
if (state->menu.selected_index >= state->menu.len) {
|
||||||
state->menu.selected_index = 0;
|
state->menu.selected_index = 0;
|
||||||
}
|
}
|
||||||
@@ -511,6 +510,52 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
// TODO: game-specific character creation stuff
|
// TODO: game-specific character creation stuff
|
||||||
// 3. draw the ship choices
|
// 3. draw the ship choices
|
||||||
str ship_label = "Choose your starting ship:";
|
str ship_label = "Choose your starting ship:";
|
||||||
|
line++;
|
||||||
|
// the table
|
||||||
|
str cols[SHIP_DETAIL_COUNT] = {"Type", "Cost", "DriveEff", "LifeSupp", "V.Cargo", "C.Cargo", "Passengers", "SmugglersHold"};
|
||||||
|
u32 table_x = 5;
|
||||||
|
u32 table_col_pad = 1;
|
||||||
|
// render the headers
|
||||||
|
u32 col_x_pos = 0;
|
||||||
|
for (u32 i = 0; i < SHIP_DETAIL_COUNT; col_x_pos += SHIP_FIELDS[i].width+table_col_pad, i++) {
|
||||||
|
renderStrToBuffer(tui->frame_buffer, table_x+col_x_pos, line, cols[i], screen_dimensions);
|
||||||
|
for (u32 ii = 0; ii < SHIP_FIELDS[i].width; ii++) {
|
||||||
|
renderUtf8CharToBuffer(tui->frame_buffer, table_x+col_x_pos+ii, line+1, "━", screen_dimensions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line++;
|
||||||
|
line++;
|
||||||
|
// render the columns
|
||||||
|
char tmp_buffer[32] = {0};
|
||||||
|
for (u32 i = 0; i < ShipType_Count; line++, i++) {
|
||||||
|
col_x_pos = 0;
|
||||||
|
ShipTemplate ship = SHIPS[i];
|
||||||
|
for (u32 ii = 0; ii < SHIP_DETAIL_COUNT; col_x_pos += SHIP_FIELDS[ii].width+table_col_pad, ii++) {
|
||||||
|
FieldDescriptor details = SHIP_FIELDS[ii];
|
||||||
|
void *field_ptr = (char *)&ship + details.offset;
|
||||||
|
switch (details.type) {
|
||||||
|
case FieldTypeEnum: {
|
||||||
|
renderStrToBuffer(tui->frame_buffer, table_x+col_x_pos, line, details.enum_vals[ship.type], screen_dimensions);
|
||||||
|
} break;
|
||||||
|
case FieldTypeU8: {
|
||||||
|
MemoryZero(tmp_buffer, 32);
|
||||||
|
sprintf(tmp_buffer, "%d", *(u8 *)field_ptr);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, table_x+col_x_pos, line, tmp_buffer, screen_dimensions);
|
||||||
|
} break;
|
||||||
|
case FieldTypeU16: {
|
||||||
|
MemoryZero(tmp_buffer, 32);
|
||||||
|
sprintf(tmp_buffer, "%d", *(u16 *)field_ptr);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, table_x+col_x_pos, line, tmp_buffer, screen_dimensions);
|
||||||
|
} break;
|
||||||
|
case FieldTypeU32: {
|
||||||
|
MemoryZero(tmp_buffer, 32);
|
||||||
|
sprintf(tmp_buffer, "%d", *(u32 *)field_ptr);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, table_x+col_x_pos, line, tmp_buffer, screen_dimensions);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
renderStrToBuffer(tui->frame_buffer, 5, ++line, ship_label, screen_dimensions);
|
renderStrToBuffer(tui->frame_buffer, 5, ++line, ship_label, screen_dimensions);
|
||||||
line++;
|
line++;
|
||||||
renderChoiceMenu(
|
renderChoiceMenu(
|
||||||
@@ -523,6 +568,7 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
state->menu.selected_index,
|
state->menu.selected_index,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
} break;
|
} break;
|
||||||
case ScreenMainGame: {
|
case ScreenMainGame: {
|
||||||
// SIMULATION
|
// SIMULATION
|
||||||
|
|||||||
+36
-1
@@ -33,12 +33,14 @@ typedef enum ShipType {
|
|||||||
ShipNX400,
|
ShipNX400,
|
||||||
ShipType_Count,
|
ShipType_Count,
|
||||||
} ShipType;
|
} ShipType;
|
||||||
static const char* SHIP_TYPE_STRINGS[] = {
|
global str SHIP_TYPE_STRINGS[] = {
|
||||||
"Sparrow",
|
"Sparrow",
|
||||||
"Dart",
|
"Dart",
|
||||||
"Hauler-Prime Z-1",
|
"Hauler-Prime Z-1",
|
||||||
"NX-400",
|
"NX-400",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SHIP_DETAIL_COUNT (8)
|
||||||
typedef struct ShipTemplate {
|
typedef struct ShipTemplate {
|
||||||
ShipType type;
|
ShipType type;
|
||||||
u8 drive_efficiency;
|
u8 drive_efficiency;
|
||||||
@@ -77,6 +79,39 @@ global ShipTemplate SHIPS[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FieldTypeU8,
|
||||||
|
FieldTypeU16,
|
||||||
|
FieldTypeU32,
|
||||||
|
FieldTypeFloat,
|
||||||
|
FieldTypeString,
|
||||||
|
FieldTypeEnum,
|
||||||
|
FieldType_Count,
|
||||||
|
} FieldType;
|
||||||
|
|
||||||
|
typedef struct FieldDescriptor {
|
||||||
|
str name;
|
||||||
|
FieldType type;
|
||||||
|
size_t offset;
|
||||||
|
int width; // column width for display
|
||||||
|
str* enum_vals;
|
||||||
|
} FieldDescriptor;
|
||||||
|
|
||||||
|
// Define field metadata using offsetof
|
||||||
|
#define offsetof(st, m) ((size_t)&(((st*)0)->m))
|
||||||
|
|
||||||
|
// Field descriptors for Employee
|
||||||
|
global FieldDescriptor SHIP_FIELDS[SHIP_DETAIL_COUNT] = {
|
||||||
|
{ "Type", FieldTypeEnum, offsetof(ShipTemplate, type), 16, (str*)&SHIP_TYPE_STRINGS },
|
||||||
|
{ "Cost", FieldTypeU32, offsetof(ShipTemplate, base_cost), 8 },
|
||||||
|
{ "DriveEff", FieldTypeU8, offsetof(ShipTemplate, drive_efficiency), 8 },
|
||||||
|
{ "LifeSupp", FieldTypeU8, offsetof(ShipTemplate, life_support_efficiency), 8 },
|
||||||
|
{ "V.Cargo", FieldTypeU16, offsetof(ShipTemplate, vacuum_cargo_slots), 7 },
|
||||||
|
{ "C.Cargo", FieldTypeU16, offsetof(ShipTemplate, climate_cargo_slots), 7 },
|
||||||
|
{ "Passengers", FieldTypeU16, offsetof(ShipTemplate, passenger_berths), 10 },
|
||||||
|
{ "SmugglersHold", FieldTypeU16, offsetof(ShipTemplate, smugglers_hold_cu_m), 13 },
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct PlayerShip {
|
typedef struct PlayerShip {
|
||||||
ShipType type;
|
ShipType type;
|
||||||
u8 drive_efficiency;
|
u8 drive_efficiency;
|
||||||
|
|||||||
Reference in New Issue
Block a user