can buy/sell crap from station
This commit is contained in:
@@ -12,6 +12,17 @@ fn u64 writeU64ToBufferLE(u8* buffer, u64 value) {
|
|||||||
return 8;// number of bytes written
|
return 8;// number of bytes written
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn u64 writeF32ToBufferLE(u8* buffer, f32 value) {
|
||||||
|
u32 bits;
|
||||||
|
memcpy(&bits, &value, sizeof(u32)); // reinterpret float bits as integer
|
||||||
|
|
||||||
|
buffer[0] = (u8)(bits & 0xFF);
|
||||||
|
buffer[1] = (u8)((bits >> 8) & 0xFF);
|
||||||
|
buffer[2] = (u8)((bits >> 16) & 0xFF);
|
||||||
|
buffer[3] = (u8)((bits >> 24) & 0xFF);
|
||||||
|
return 4;// number of bytes written
|
||||||
|
}
|
||||||
|
|
||||||
fn u64 writeU32ToBufferLE(u8* buffer, u32 value) {
|
fn u64 writeU32ToBufferLE(u8* buffer, u32 value) {
|
||||||
buffer[0] = (u8)(value & 0xFF);
|
buffer[0] = (u8)(value & 0xFF);
|
||||||
buffer[1] = (u8)((value >> 8) & 0xFF);
|
buffer[1] = (u8)((value >> 8) & 0xFF);
|
||||||
@@ -45,6 +56,18 @@ fn u64 readU64FromBufferLE(u8 *buffer) {
|
|||||||
((u64)buffer[7] << 56);
|
((u64)buffer[7] << 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn f32 readF32FromBufferLE(u8 *buf) {
|
||||||
|
u32 bits = 0;
|
||||||
|
bits |= (u32)(u8)buf[0] << 0;
|
||||||
|
bits |= (u32)(u8)buf[1] << 8;
|
||||||
|
bits |= (u32)(u8)buf[2] << 16;
|
||||||
|
bits |= (u32)(u8)buf[3] << 24;
|
||||||
|
|
||||||
|
f32 value;
|
||||||
|
memcpy(&value, &bits, sizeof(f32));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
fn u32 readU32FromBufferLE(u8 *buffer) {
|
fn u32 readU32FromBufferLE(u8 *buffer) {
|
||||||
return (u32)buffer[0] |
|
return (u32)buffer[0] |
|
||||||
((u32)buffer[1] << 8) |
|
((u32)buffer[1] << 8) |
|
||||||
|
|||||||
+197
-21
@@ -34,6 +34,14 @@ typedef enum Tab {
|
|||||||
Tab_Count,
|
Tab_Count,
|
||||||
} Tab;
|
} Tab;
|
||||||
|
|
||||||
|
typedef enum StationTabStates {
|
||||||
|
StationTabStateTable,
|
||||||
|
StationTabStateTransact,
|
||||||
|
StationTabStateResult,
|
||||||
|
StationTabStateLoading,
|
||||||
|
StationTabStates_Count,
|
||||||
|
} StationTabStates;
|
||||||
|
|
||||||
typedef enum Screen {
|
typedef enum Screen {
|
||||||
ScreenLogin,
|
ScreenLogin,
|
||||||
ScreenCreateCharacter,
|
ScreenCreateCharacter,
|
||||||
@@ -74,6 +82,12 @@ typedef struct EntityList {
|
|||||||
Entity* items;
|
Entity* items;
|
||||||
} EntityList;
|
} EntityList;
|
||||||
|
|
||||||
|
typedef struct TransactionResult {
|
||||||
|
bool buying;
|
||||||
|
u32 qty;
|
||||||
|
u32 cr;
|
||||||
|
} TransactionResult;
|
||||||
|
|
||||||
typedef struct ParsedServerMessage {
|
typedef struct ParsedServerMessage {
|
||||||
Message type;
|
Message type;
|
||||||
u16 port;
|
u16 port;
|
||||||
@@ -86,6 +100,8 @@ typedef struct ParsedServerMessage {
|
|||||||
Pos2u8 positions[STAR_SYSTEM_COUNT];
|
Pos2u8 positions[STAR_SYSTEM_COUNT];
|
||||||
PlanetType planet_types[MAX_PLANETS*STAR_SYSTEM_COUNT];
|
PlanetType planet_types[MAX_PLANETS*STAR_SYSTEM_COUNT];
|
||||||
StarSystem sys;
|
StarSystem sys;
|
||||||
|
PlayerShip ship;
|
||||||
|
TransactionResult tx_result;
|
||||||
//Entity entities[PARSED_CLIENT_ENTITY_LEN];
|
//Entity entities[PARSED_CLIENT_ENTITY_LEN];
|
||||||
//u64 ids[PARSED_IDS_LEN];
|
//u64 ids[PARSED_IDS_LEN];
|
||||||
} ParsedServerMessage;
|
} ParsedServerMessage;
|
||||||
@@ -133,7 +149,8 @@ typedef struct GameState {
|
|||||||
StarSystem map[STAR_SYSTEM_COUNT];
|
StarSystem map[STAR_SYSTEM_COUNT];
|
||||||
Pos2 pos;
|
Pos2 pos;
|
||||||
StarSystem current;
|
StarSystem current;
|
||||||
bool modal;
|
StationTabStates station_tab_state;
|
||||||
|
TransactionResult tx_result;
|
||||||
} GameState;
|
} GameState;
|
||||||
|
|
||||||
///// GLOBALS
|
///// GLOBALS
|
||||||
@@ -365,15 +382,22 @@ fn void clearServerSentState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn void handleIncomingMessage(u8* message, u32 len, SocketAddress sender, i32 socket) {
|
fn void handleIncomingMessage(u8* message, u32 len, SocketAddress sender, i32 socket) {
|
||||||
Message msg_type = message[0];
|
u64 msg_pos = 0;
|
||||||
|
Message msg_type = message[msg_pos++];
|
||||||
dbg("handleIncomingMessage() of len=%d, message=%s\n", len, MESSAGE_STRINGS[msg_type]);
|
dbg("handleIncomingMessage() of len=%d, message=%s\n", len, MESSAGE_STRINGS[msg_type]);
|
||||||
u8List bytes = {len, len, message};
|
u8List bytes = {len, len, message};
|
||||||
u64 msg_pos = 1;
|
|
||||||
ParsedServerMessage parsed = {0};
|
ParsedServerMessage parsed = {0};
|
||||||
parsed.type = msg_type;
|
parsed.type = msg_type;
|
||||||
switch (msg_type) {
|
switch (msg_type) {
|
||||||
case MessageNewAccountCreated:
|
case MessageNewAccountCreated:
|
||||||
case MessageBadPw: {/*nothing to parse but the type*/} break;
|
case MessageBadPw: {/*nothing to parse but the type*/} break;
|
||||||
|
case MessageTransactionResult: {
|
||||||
|
parsed.tx_result.buying = message[msg_pos++];
|
||||||
|
parsed.tx_result.qty = readU32FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 4;
|
||||||
|
parsed.tx_result.cr = readU32FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 4;
|
||||||
|
} break;
|
||||||
case MessageStarPositions: {
|
case MessageStarPositions: {
|
||||||
u32 star_msg_size = 2+MAX_PLANETS;
|
u32 star_msg_size = 2+MAX_PLANETS;
|
||||||
for (u32 i = 0; i < STAR_SYSTEM_COUNT; i++) {
|
for (u32 i = 0; i < STAR_SYSTEM_COUNT; i++) {
|
||||||
@@ -393,6 +417,36 @@ fn void handleIncomingMessage(u8* message, u32 len, SocketAddress sender, i32 so
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case MessagePlayerDetails: {
|
||||||
|
parsed.ship.type = message[msg_pos++];
|
||||||
|
parsed.ship.drive_efficiency = message[msg_pos++];
|
||||||
|
parsed.ship.life_support_efficiency = message[msg_pos++];
|
||||||
|
parsed.ship.vacuum_cargo_slots = readU16FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 2;
|
||||||
|
parsed.ship.climate_cargo_slots = readU16FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 2;
|
||||||
|
parsed.ship.passenger_berths = readU16FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 2;
|
||||||
|
parsed.ship.passenger_amenities_flags = readU16FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 2;
|
||||||
|
parsed.ship.smugglers_hold_cu_m = readU16FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 2;
|
||||||
|
parsed.ship.remaining_mortgage = readU32FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 4;
|
||||||
|
parsed.ship.interest_rate = readF32FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 4;
|
||||||
|
parsed.ship.cu_m_fuel = readU32FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 4;
|
||||||
|
parsed.ship.cu_m_o2 = readU32FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 4;
|
||||||
|
parsed.ship.credits = readF32FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 4;
|
||||||
|
parsed.ship.id = readU64FromBufferLE(message + msg_pos);
|
||||||
|
msg_pos += 8;
|
||||||
|
for (u32 i = 0; i < Commodity_Count; i++, msg_pos += 4) {
|
||||||
|
parsed.ship.commodities[i] = readU32FromBufferLE(message + msg_pos);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case MessageCharacterId: {
|
case MessageCharacterId: {
|
||||||
parsed.id = readU64FromBufferLE(message + 1);
|
parsed.id = readU64FromBufferLE(message + 1);
|
||||||
} break;
|
} break;
|
||||||
@@ -446,6 +500,7 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return should_quit;
|
return should_quit;
|
||||||
}
|
}
|
||||||
|
char sbuf[512] = {0};
|
||||||
|
|
||||||
// process server messages
|
// process server messages
|
||||||
u32 msg_iters = 0;
|
u32 msg_iters = 0;
|
||||||
@@ -454,6 +509,30 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
while (next_net_msg != NULL) {
|
while (next_net_msg != NULL) {
|
||||||
msg_iters += 0;
|
msg_iters += 0;
|
||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
|
case MessageTransactionResult: {
|
||||||
|
state->station_tab_state = StationTabStateResult;
|
||||||
|
MemoryCopyStruct(&state->tx_result, &msg.tx_result);
|
||||||
|
} break;
|
||||||
|
case MessagePlayerDetails: {
|
||||||
|
if (msg.ship.id == state->me.id) {
|
||||||
|
state->me.type = msg.ship.type;
|
||||||
|
state->me.drive_efficiency = msg.ship.drive_efficiency;
|
||||||
|
state->me.life_support_efficiency = msg.ship.life_support_efficiency;
|
||||||
|
state->me.vacuum_cargo_slots = msg.ship.vacuum_cargo_slots;
|
||||||
|
state->me.climate_cargo_slots = msg.ship.climate_cargo_slots;
|
||||||
|
state->me.passenger_berths = msg.ship.passenger_berths;
|
||||||
|
state->me.passenger_amenities_flags = msg.ship.passenger_amenities_flags;
|
||||||
|
state->me.smugglers_hold_cu_m = msg.ship.smugglers_hold_cu_m;
|
||||||
|
state->me.remaining_mortgage = msg.ship.remaining_mortgage;
|
||||||
|
state->me.interest_rate = msg.ship.interest_rate;
|
||||||
|
state->me.cu_m_fuel = msg.ship.cu_m_fuel;
|
||||||
|
state->me.cu_m_o2 = msg.ship.cu_m_o2;
|
||||||
|
state->me.credits = msg.ship.credits;
|
||||||
|
for (u32 i = 0; i < Commodity_Count; i++) {
|
||||||
|
state->me.commodities[i] = msg.ship.commodities[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case MessageStarPositions: {
|
case MessageStarPositions: {
|
||||||
for (u32 i = 0; i < STAR_SYSTEM_COUNT; i++) {
|
for (u32 i = 0; i < STAR_SYSTEM_COUNT; i++) {
|
||||||
state->map[i].x = msg.positions[i].x;
|
state->map[i].x = msg.positions[i].x;
|
||||||
@@ -557,7 +636,6 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
}
|
}
|
||||||
|
|
||||||
//// RENDERING
|
//// RENDERING
|
||||||
char tmp_buffer[64] = {0};
|
|
||||||
u16 line = 2;
|
u16 line = 2;
|
||||||
// 1. draw the outline
|
// 1. draw the outline
|
||||||
Box b = { .x = 2, .y = line, .width = screen_dimensions.width - 5, .height = screen_dimensions.height - 5 };
|
Box b = { .x = 2, .y = line, .width = screen_dimensions.width - 5, .height = screen_dimensions.height - 5 };
|
||||||
@@ -581,8 +659,8 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
f32 rm = r / 12.0;
|
f32 rm = r / 12.0;
|
||||||
u32 n = 12 * 4;
|
u32 n = 12 * 4;
|
||||||
u32 payment = principal_borrowed * (rm*pow((1.0+rm),n))/(pow((1+rm),n) - 1);
|
u32 payment = principal_borrowed * (rm*pow((1.0+rm),n))/(pow((1+rm),n) - 1);
|
||||||
sprintf(tmp_buffer, "Mortgage: $%d @ %f%% = $%d minimum payment per turn", selected_ship_cost - STARTING_DOWN_PAYMENT, mortgage_rate, payment);
|
sprintf(sbuf, "Mortgage: $%d @ %f%% = $%d minimum payment per turn", selected_ship_cost - STARTING_DOWN_PAYMENT, mortgage_rate, payment);
|
||||||
renderStrToBuffer(tui->frame_buffer, 5, ++line, tmp_buffer, screen_dimensions);
|
renderStrToBuffer(tui->frame_buffer, 5, ++line, sbuf, screen_dimensions);
|
||||||
line++;
|
line++;
|
||||||
// the table
|
// the table
|
||||||
TableDrawInfo info = {
|
TableDrawInfo info = {
|
||||||
@@ -701,13 +779,33 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
if (input_buffer[0] == 'q' || user_pressed_esc) {
|
if (input_buffer[0] == 'q' || user_pressed_esc) {
|
||||||
should_quit = true;
|
should_quit = true;
|
||||||
}
|
}
|
||||||
|
renderStrToBuffer(tui->frame_buffer, box.x+2, box.y+1, SHIP_TYPE_STRINGS[state->me.type], screen_dimensions);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, box.x+2, box.y+2, "Credits: ", screen_dimensions);
|
||||||
|
MemoryZero(sbuf, 512);
|
||||||
|
sprintf(sbuf, "%.2f", state->me.credits);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, box.x+15, box.y+2, sbuf, screen_dimensions);
|
||||||
|
for (u32 i = 0; i < Commodity_Count; i++) {
|
||||||
|
MemoryZero(sbuf, 512);
|
||||||
|
sprintf(sbuf, "%-42s %d", COMMODITY_STRINGS[i], state->me.commodities[i]);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, box.x+4, box.y+4+i, sbuf, screen_dimensions);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case TabStation: {
|
case TabStation: {
|
||||||
if (input_buffer[0] == 'q' || user_pressed_esc) {
|
if (input_buffer[0] == 'q' || user_pressed_esc) {
|
||||||
if (state->modal) {
|
switch (state->station_tab_state) {
|
||||||
state->modal = !state->modal;
|
case StationTabStateTable:
|
||||||
} else {
|
|
||||||
should_quit = true;
|
should_quit = true;
|
||||||
|
break;
|
||||||
|
case StationTabStateTransact:
|
||||||
|
state->station_tab_state = StationTabStateTable;
|
||||||
|
break;
|
||||||
|
case StationTabStateResult:
|
||||||
|
state->station_tab_state = StationTabStateTransact;
|
||||||
|
break;
|
||||||
|
case StationTabStateLoading:
|
||||||
|
state->station_tab_state = StationTabStateTable;
|
||||||
|
break;
|
||||||
|
case StationTabStates_Count: assert(false && "something has gone horribly wrong");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (user_pressed_up) {
|
if (user_pressed_up) {
|
||||||
@@ -744,35 +842,67 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
}
|
}
|
||||||
renderTable(tui, info, state->row.selected_index, MARKET_COMMODITY_FIELDS, 1, rows, sizeof(MarketCommodity));
|
renderTable(tui, info, state->row.selected_index, MARKET_COMMODITY_FIELDS, 1, rows, sizeof(MarketCommodity));
|
||||||
|
|
||||||
if (user_pressed_enter) {
|
if (state->station_tab_state != StationTabStateTable) {
|
||||||
state->modal = !state->modal;
|
|
||||||
if (state->modal) {
|
|
||||||
state->modal_choice.len = 2;
|
|
||||||
state->modal_choice.selected_index = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (state->modal) {
|
|
||||||
if (user_pressed_right) {
|
if (user_pressed_right) {
|
||||||
state->modal_choice.selected_index = 1;
|
state->modal_choice.selected_index = 1;
|
||||||
} else if (user_pressed_left) {
|
} else if (user_pressed_left) {
|
||||||
state->modal_choice.selected_index = 0;
|
state->modal_choice.selected_index = 0;
|
||||||
|
} else if (user_pressed_a_number) {
|
||||||
|
String next_char = { 1, 2, (char*)input_buffer };
|
||||||
|
stringChunkListAppend(&state->string_arena, &state->message_input, next_char);
|
||||||
|
} else if (user_pressed_backspace) {
|
||||||
|
stringChunkListDeleteLast(&state->string_arena, &state->message_input);
|
||||||
}
|
}
|
||||||
// draw the "purchase order" modal
|
|
||||||
|
// draw the modal
|
||||||
|
bool buy_selected = state->modal_choice.selected_index == 0;
|
||||||
Box modal_outline = {
|
Box modal_outline = {
|
||||||
.x = (tui->screen_dimensions.width - 50) / 2,
|
.x = (tui->screen_dimensions.width - 50) / 2,
|
||||||
.y = (tui->screen_dimensions.height - 15) / 2,
|
.y = (tui->screen_dimensions.height - 15) / 2,
|
||||||
.height = 15,
|
.height = 15,
|
||||||
.width = 50,
|
.width = 50,
|
||||||
};
|
};
|
||||||
|
clearBox(tui, modal_outline);
|
||||||
drawAnsiBox(tui->frame_buffer, modal_outline, tui->screen_dimensions, false);
|
drawAnsiBox(tui->frame_buffer, modal_outline, tui->screen_dimensions, false);
|
||||||
str cname = COMMODITIES[state->row.selected_index].name;
|
|
||||||
renderStrToBuffer(tui->frame_buffer, modal_outline.x+(modal_outline.width/2)-strlen(cname), modal_outline.y+1, cname, screen_dimensions);
|
|
||||||
u32 y_off = modal_outline.y+2;
|
u32 y_off = modal_outline.y+2;
|
||||||
|
str cname = COMMODITIES[state->row.selected_index].name;
|
||||||
|
if (state->station_tab_state == StationTabStateResult) {
|
||||||
|
if (state->tx_result.buying) {
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+((modal_outline.width-10)/2), y_off++, "Purchased!", screen_dimensions);
|
||||||
|
} else {
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+((modal_outline.width-5)/2), y_off++, "Sold!", screen_dimensions);
|
||||||
|
}
|
||||||
|
MemoryZero(sbuf, 512);
|
||||||
|
sprintf(sbuf, "%d %s", state->tx_result.qty, cname);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+((modal_outline.width-strlen(sbuf))/2), y_off++, sbuf, screen_dimensions);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+((modal_outline.width-3)/2), y_off++, "for", screen_dimensions);
|
||||||
|
MemoryZero(sbuf, 512);
|
||||||
|
sprintf(sbuf, "%d credits", state->tx_result.cr);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+((modal_outline.width-strlen(sbuf))/2), y_off++, sbuf, screen_dimensions);
|
||||||
|
y_off++;
|
||||||
|
u32 exit_x = modal_outline.x+((modal_outline.width-4)/2);
|
||||||
|
u32 pos = XYToPos(exit_x, y_off, tui->screen_dimensions.width);
|
||||||
|
for (u32 i = 0; i < 4; i++) {
|
||||||
|
tui->frame_buffer[pos+i].background = ANSI_WHITE;
|
||||||
|
tui->frame_buffer[pos+i].foreground = ANSI_BLACK;
|
||||||
|
}
|
||||||
|
tui->cursor.x = exit_x;
|
||||||
|
tui->cursor.y = y_off;
|
||||||
|
renderStrToBuffer(tui->frame_buffer, exit_x, y_off++, "EXIT", screen_dimensions);
|
||||||
|
|
||||||
|
if (user_pressed_enter) {
|
||||||
|
state->station_tab_state = StationTabStateTable;
|
||||||
|
}
|
||||||
|
} else if (state->station_tab_state == StationTabStateLoading) {
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+2, y_off, "Loading...", screen_dimensions);
|
||||||
|
} else { // StationTabStateTransact
|
||||||
|
// draw the "purchase order" modal
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+(modal_outline.width/2)-strlen(cname), modal_outline.y+1, cname, screen_dimensions);
|
||||||
u32 buy_x = modal_outline.x+2;
|
u32 buy_x = modal_outline.x+2;
|
||||||
u32 sell_x = modal_outline.x+modal_outline.width-6;
|
u32 sell_x = modal_outline.x+modal_outline.width-6;
|
||||||
renderStrToBuffer(tui->frame_buffer, buy_x, y_off, "Buy", screen_dimensions);
|
renderStrToBuffer(tui->frame_buffer, buy_x, y_off, "Buy", screen_dimensions);
|
||||||
renderStrToBuffer(tui->frame_buffer, sell_x, y_off, "Sell", screen_dimensions);
|
renderStrToBuffer(tui->frame_buffer, sell_x, y_off, "Sell", screen_dimensions);
|
||||||
if (state->modal_choice.selected_index == 0) {
|
if (buy_selected) {
|
||||||
u32 pos = XYToPos(buy_x, y_off, tui->screen_dimensions.width);
|
u32 pos = XYToPos(buy_x, y_off, tui->screen_dimensions.width);
|
||||||
tui->frame_buffer[pos].background = ANSI_WHITE;
|
tui->frame_buffer[pos].background = ANSI_WHITE;
|
||||||
tui->frame_buffer[pos].foreground = ANSI_BLACK;
|
tui->frame_buffer[pos].foreground = ANSI_BLACK;
|
||||||
@@ -791,6 +921,52 @@ fn bool updateAndRender(TuiState* tui, void* s, u8* input_buffer, u64 loop_count
|
|||||||
tui->frame_buffer[pos+3].background = ANSI_WHITE;
|
tui->frame_buffer[pos+3].background = ANSI_WHITE;
|
||||||
tui->frame_buffer[pos+3].foreground = ANSI_BLACK;
|
tui->frame_buffer[pos+3].foreground = ANSI_BLACK;
|
||||||
}
|
}
|
||||||
|
y_off++;
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+((modal_outline.width-8)/2), y_off++, "Quantity", screen_dimensions);
|
||||||
|
renderStringChunkList(tui, &state->message_input, modal_outline.x+8, y_off);
|
||||||
|
tui->cursor.x = modal_outline.x + 8 + state->message_input.total_size;
|
||||||
|
tui->cursor.y = y_off++;
|
||||||
|
if (buy_selected) {
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+((modal_outline.width-4)/2), y_off++, "Cost", screen_dimensions);
|
||||||
|
} else {
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+((modal_outline.width-6)/2), y_off++, "Profit", screen_dimensions);
|
||||||
|
}
|
||||||
|
String input_q_str = stringChunkToString(&permanent_arena, state->message_input);
|
||||||
|
u32 input_quantity = atoi(input_q_str.bytes);
|
||||||
|
u32 credits = input_quantity * (buy_selected ? rows[state->row.selected_index].ask : rows[state->row.selected_index].bid);
|
||||||
|
arenaDealloc(&permanent_arena, input_q_str.capacity);
|
||||||
|
MemoryZero(sbuf, 512);
|
||||||
|
sprintf(sbuf, "%d", credits);
|
||||||
|
renderStrToBuffer(tui->frame_buffer, modal_outline.x+8, y_off++, sbuf, screen_dimensions);
|
||||||
|
|
||||||
|
if (user_pressed_enter) {
|
||||||
|
// send the "purchase" or "sell" message to server
|
||||||
|
// get back new "status" of things
|
||||||
|
u32 msg_idx = 0;
|
||||||
|
UDPMessage msg = {0};
|
||||||
|
msg.address = udp->server_address;
|
||||||
|
// 1. msg type/CommandType
|
||||||
|
msg.bytes[msg_idx++] = CommandTransact;
|
||||||
|
// 2. buy?
|
||||||
|
msg.bytes[msg_idx++] = buy_selected;
|
||||||
|
// 3. quantity
|
||||||
|
msg_idx += writeU32ToBufferLE(msg.bytes + msg_idx, input_quantity);
|
||||||
|
// 4. commodity
|
||||||
|
msg.bytes[msg_idx++] = rows[state->row.selected_index].type;
|
||||||
|
msg.bytes_len = msg_idx;
|
||||||
|
|
||||||
|
outgoingMessageQueuePush(network_send_queue, &msg);
|
||||||
|
|
||||||
|
state->station_tab_state = StationTabStateLoading;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we are on the table
|
||||||
|
if (user_pressed_enter) {
|
||||||
|
state->station_tab_state = StationTabStateTransact;
|
||||||
|
state->modal_choice.len = 2;
|
||||||
|
state->modal_choice.selected_index = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Tab_Count: {} break;
|
case Tab_Count: {} break;
|
||||||
|
|||||||
+14
-9
@@ -95,15 +95,6 @@ fn RGB rgbDarken(RGB color, f32 factor) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
fn RGB ansiToRGB(u8 ansi) {
|
|
||||||
ansi -= 16;
|
|
||||||
u8 b = ansi % 51;
|
|
||||||
ansi -= ()
|
|
||||||
u8 g =
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
fn bool rgbEq(RGB a, RGB b) {
|
fn bool rgbEq(RGB a, RGB b) {
|
||||||
return a.r == b.r && a.g == b.g && a.b == b.b;
|
return a.r == b.r && a.g == b.g && a.b == b.b;
|
||||||
}
|
}
|
||||||
@@ -137,6 +128,20 @@ fn void copyStr(u8* bytes, str cstring) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn void clearBox(TuiState* tui, Box box) {
|
||||||
|
for (u32 i = 0; i < box.height; i++) {
|
||||||
|
for (u32 ii = 0; ii < box.width; ii++) {
|
||||||
|
u32 pos = XYToPos(box.x+ii, box.y+i, tui->screen_dimensions.width);
|
||||||
|
tui->frame_buffer[pos].background = 0;
|
||||||
|
tui->frame_buffer[pos].foreground = 0;
|
||||||
|
tui->frame_buffer[pos].bytes[0] = 0;
|
||||||
|
tui->frame_buffer[pos].bytes[1] = 0;
|
||||||
|
tui->frame_buffer[pos].bytes[2] = 0;
|
||||||
|
tui->frame_buffer[pos].bytes[3] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn void drawAnsiBox(Pixel* buf, Box box, Dim2 sd, bool bold) {
|
fn void drawAnsiBox(Pixel* buf, Box box, Dim2 sd, bool bold) {
|
||||||
str items[] = {"┌","─","┐","│","└","┘"};
|
str items[] = {"┌","─","┐","│","└","┘"};
|
||||||
str b_items[] = {"┏","━","┓","┃","┗","┛"};
|
str b_items[] = {"┏","━","┓","┃","┗","┛"};
|
||||||
|
|||||||
+164
-26
@@ -42,6 +42,8 @@ typedef struct ParsedClientCommand {
|
|||||||
u16 alt_port;
|
u16 alt_port;
|
||||||
u32 sender_ip;
|
u32 sender_ip;
|
||||||
u32 alt_ip;
|
u32 alt_ip;
|
||||||
|
u32 qty;
|
||||||
|
CommodityType commodity;
|
||||||
StringChunkList name;
|
StringChunkList name;
|
||||||
StringChunkList pass;
|
StringChunkList pass;
|
||||||
u64 id;
|
u64 id;
|
||||||
@@ -369,6 +371,80 @@ fn u32 findClientHandleBySocketAddress(ClientList* clients, SocketAddress addres
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn StarSystem* findAccountsSystem(Account* a) {
|
||||||
|
for (u32 i = 0; i < STAR_SYSTEM_COUNT; i++) {
|
||||||
|
if (state.map[i].x == a->pos.x && state.map[i].y == a->pos.y) {
|
||||||
|
return &state.map[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &state.map[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn u32 starSystemPlanetCount(StarSystem* sys) {
|
||||||
|
u32 planet_count = 0;
|
||||||
|
for (u32 i = 0; i < MAX_PLANETS; i++) {
|
||||||
|
if (sys->planets[i].type != PlanetTypeNull) {
|
||||||
|
planet_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return planet_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn UDPMessage makeMessageSystemCommodities(StarSystem* sys) {
|
||||||
|
UDPMessage outgoing_message = {0};
|
||||||
|
u32 planet_count = starSystemPlanetCount(sys);
|
||||||
|
u32 msg_i = 0;
|
||||||
|
outgoing_message.bytes[msg_i++] = (u8)MessageSystemCommodities;
|
||||||
|
outgoing_message.bytes[msg_i++] = (u8)sys->idx;
|
||||||
|
outgoing_message.bytes[msg_i++] = (u8)planet_count;
|
||||||
|
for (u32 i = 0; i < planet_count; i++) {
|
||||||
|
for (u32 ii = 0; ii < Commodity_Count; ii++) {
|
||||||
|
outgoing_message.bytes[msg_i++] = sys->planets[i].commodities[ii];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outgoing_message.bytes_len = msg_i;
|
||||||
|
return outgoing_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void sendMessageTransactionResult(SocketAddress addr, u32 qty, bool buying, u32 credits) {
|
||||||
|
UDPMessage outgoing_message = {.address = addr};
|
||||||
|
u32 msg_i = 0;
|
||||||
|
outgoing_message.bytes[msg_i++] = (u8)MessageTransactionResult;
|
||||||
|
outgoing_message.bytes[msg_i++] = buying;
|
||||||
|
msg_i += writeU32ToBufferLE(outgoing_message.bytes + msg_i, qty);
|
||||||
|
msg_i += writeU32ToBufferLE(outgoing_message.bytes + msg_i, credits);
|
||||||
|
outgoing_message.bytes_len = msg_i;
|
||||||
|
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
||||||
|
printf("%s sent\n", MESSAGE_STRINGS[outgoing_message.bytes[0]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void sendMessagePlayerDetails(PlayerShip ship, SocketAddress addr) {
|
||||||
|
UDPMessage outgoing_message = {.address = addr};
|
||||||
|
u32 msg_i = 0;
|
||||||
|
outgoing_message.bytes[msg_i++] = (u8)MessagePlayerDetails;
|
||||||
|
outgoing_message.bytes[msg_i++] = ship.type;
|
||||||
|
outgoing_message.bytes[msg_i++] = ship.drive_efficiency;
|
||||||
|
outgoing_message.bytes[msg_i++] = ship.life_support_efficiency;
|
||||||
|
msg_i += writeU16ToBufferLE(outgoing_message.bytes + msg_i, ship.vacuum_cargo_slots);
|
||||||
|
msg_i += writeU16ToBufferLE(outgoing_message.bytes + msg_i, ship.climate_cargo_slots);
|
||||||
|
msg_i += writeU16ToBufferLE(outgoing_message.bytes + msg_i, ship.passenger_berths);
|
||||||
|
msg_i += writeU16ToBufferLE(outgoing_message.bytes + msg_i, ship.passenger_amenities_flags);
|
||||||
|
msg_i += writeU16ToBufferLE(outgoing_message.bytes + msg_i, ship.smugglers_hold_cu_m);
|
||||||
|
msg_i += writeU32ToBufferLE(outgoing_message.bytes + msg_i, ship.remaining_mortgage);
|
||||||
|
msg_i += writeF32ToBufferLE(outgoing_message.bytes + msg_i, ship.interest_rate);
|
||||||
|
msg_i += writeU32ToBufferLE(outgoing_message.bytes + msg_i, ship.cu_m_fuel);
|
||||||
|
msg_i += writeU32ToBufferLE(outgoing_message.bytes + msg_i, ship.cu_m_o2);
|
||||||
|
msg_i += writeF32ToBufferLE(outgoing_message.bytes + msg_i, ship.credits);
|
||||||
|
msg_i += writeU64ToBufferLE(outgoing_message.bytes + msg_i, ship.id);
|
||||||
|
for (u32 i = 0; i < Commodity_Count; i++) {
|
||||||
|
msg_i += writeU32ToBufferLE(outgoing_message.bytes + msg_i, ship.commodities[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
outgoing_message.bytes_len = msg_i;
|
||||||
|
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
||||||
|
printf("%s sent\n", MESSAGE_STRINGS[outgoing_message.bytes[0]]);
|
||||||
|
}
|
||||||
|
|
||||||
fn void handleIncomingMessage(u8* message, u32 len, SocketAddress sender, i32 socket) {
|
fn void handleIncomingMessage(u8* message, u32 len, SocketAddress sender, i32 socket) {
|
||||||
dbg("%d: %s from %s:%d\n", len, command_type_strings[message[0]], inet_ntoa(sender.sin_addr), sender.sin_port);
|
dbg("%d: %s from %s:%d\n", len, command_type_strings[message[0]], inet_ntoa(sender.sin_addr), sender.sin_port);
|
||||||
u32 msg_idx = 0;
|
u32 msg_idx = 0;
|
||||||
@@ -420,6 +496,12 @@ fn void handleIncomingMessage(u8* message, u32 len, SocketAddress sender, i32 so
|
|||||||
} break;
|
} break;
|
||||||
case CommandKeepAlive:
|
case CommandKeepAlive:
|
||||||
break;
|
break;
|
||||||
|
case CommandTransact: {
|
||||||
|
printf("command transact received\n");
|
||||||
|
parsed.byte = message[1]; // buy?
|
||||||
|
parsed.qty = readU32FromBufferLE(message + 2);
|
||||||
|
parsed.commodity = message[6];
|
||||||
|
} break;
|
||||||
case CommandCreateCharacter: {
|
case CommandCreateCharacter: {
|
||||||
printf("command create character received\n");
|
printf("command create character received\n");
|
||||||
parsed.byte = message[1];
|
parsed.byte = message[1];
|
||||||
@@ -475,9 +557,25 @@ fn void* sendNetworkUpdates(void* sock) {
|
|||||||
// continue; // they are still creating their character
|
// continue; // they are still creating their character
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
// update allthe changed systems
|
||||||
|
for (u32 i = 0; i < STAR_SYSTEM_COUNT; i++) {
|
||||||
|
if (state.map[i].changed == true) {
|
||||||
|
UDPMessage msg_data = makeMessageSystemCommodities(&state.map[i]);
|
||||||
|
u8List msg = {
|
||||||
|
.capacity = UDP_MAX_MESSAGE_LEN,
|
||||||
|
.items = msg_data.bytes,
|
||||||
|
.length = msg_data.bytes_len,
|
||||||
|
};
|
||||||
|
sendUDPu8List(socket, &client.address, &msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} unlockMutex(&state.client_mutex);
|
} unlockMutex(&state.client_mutex);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < STAR_SYSTEM_COUNT; i++) {
|
||||||
|
state.map[i].changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
u32 loop_duration = osTimeMicrosecondsNow() - loop_start;
|
u32 loop_duration = osTimeMicrosecondsNow() - loop_start;
|
||||||
i32 remaining_time = GOAL_NETWORK_SEND_LOOP_US - loop_duration;
|
i32 remaining_time = GOAL_NETWORK_SEND_LOOP_US - loop_duration;
|
||||||
if (remaining_time > 0) {
|
if (remaining_time > 0) {
|
||||||
@@ -522,6 +620,56 @@ fn void* gameLoop(void* params) {
|
|||||||
u32 client_handle = findClientHandleBySocketAddress(&state.clients, sender);
|
u32 client_handle = findClientHandleBySocketAddress(&state.clients, sender);
|
||||||
Client* client = &state.clients.items[client_handle];
|
Client* client = &state.clients.items[client_handle];
|
||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
|
case CommandTransact: {
|
||||||
|
printf("Transact for client_handle=%d, on #%lld", client_handle, state.frame);
|
||||||
|
bool is_buying_from_system = msg.byte;
|
||||||
|
Account* account = &state.accounts[client->account_id];
|
||||||
|
StarSystem* sys = findAccountsSystem(account);
|
||||||
|
printf("%d %lld %s\n", account->id, account->ship.id, sys->name);
|
||||||
|
u32 total_available = sys->planets[0].commodities[msg.commodity] + sys->planets[1].commodities[msg.commodity] + sys->planets[2].commodities[msg.commodity];
|
||||||
|
u32 qty_traded = 0;
|
||||||
|
u32 credit_value = 0;
|
||||||
|
if (is_buying_from_system) {
|
||||||
|
printf("is buying from system\n");
|
||||||
|
for (u32 amount_to_buy = Min(msg.qty, total_available); amount_to_buy > 0; amount_to_buy--, total_available--) {
|
||||||
|
u32 price = priceForCommodity(msg.commodity, total_available, false);
|
||||||
|
if (price > account->ship.credits) {
|
||||||
|
amount_to_buy = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
credit_value += price;
|
||||||
|
account->ship.credits -= price;
|
||||||
|
account->ship.commodities[msg.commodity] += 1;
|
||||||
|
qty_traded += 1;
|
||||||
|
if (sys->planets[0].commodities[msg.commodity]) {
|
||||||
|
sys->planets[0].commodities[msg.commodity] -= 1;
|
||||||
|
} else if (sys->planets[1].commodities[msg.commodity]) {
|
||||||
|
sys->planets[1].commodities[msg.commodity] -= 1;
|
||||||
|
} else if (sys->planets[2].commodities[msg.commodity]) {
|
||||||
|
sys->planets[2].commodities[msg.commodity] -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// selling to system logic
|
||||||
|
qty_traded = Min(msg.qty, account->ship.commodities[msg.commodity]);
|
||||||
|
u32 planet_count = starSystemPlanetCount(sys);
|
||||||
|
for (
|
||||||
|
u32 amount_to_sell = qty_traded;
|
||||||
|
amount_to_sell > 0;
|
||||||
|
amount_to_sell--, total_available++
|
||||||
|
) {
|
||||||
|
u32 price = priceForCommodity(msg.commodity, total_available, true);
|
||||||
|
credit_value += price;
|
||||||
|
account->ship.credits += price;
|
||||||
|
account->ship.commodities[msg.commodity] -= 1;
|
||||||
|
u8 planet_idx = rand() % planet_count;
|
||||||
|
sys->planets[planet_idx].commodities[msg.commodity] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sys->changed = true;
|
||||||
|
sendMessagePlayerDetails(account->ship, sender);
|
||||||
|
sendMessageTransactionResult(sender, qty_traded, is_buying_from_system, credit_value);
|
||||||
|
} break;
|
||||||
case CommandKeepAlive: {
|
case CommandKeepAlive: {
|
||||||
dbg("KeepAlive for client_handle=%d, %ld", client_handle, state.frame);
|
dbg("KeepAlive for client_handle=%d, %ld", client_handle, state.frame);
|
||||||
state.clients.items[client_handle].last_ping = state.frame;
|
state.clients.items[client_handle].last_ping = state.frame;
|
||||||
@@ -573,6 +721,7 @@ fn void* gameLoop(void* params) {
|
|||||||
if (state.accounts[i].id == 0 && state.accounts[i].name.length == 0) {
|
if (state.accounts[i].id == 0 && state.accounts[i].name.length == 0) {
|
||||||
existing_account = &state.accounts[i];
|
existing_account = &state.accounts[i];
|
||||||
existing_account->id = i;
|
existing_account->id = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
existing_account->name = name;
|
existing_account->name = name;
|
||||||
@@ -582,7 +731,7 @@ fn void* gameLoop(void* params) {
|
|||||||
if (existing_account->ship.id != 0) {
|
if (existing_account->ship.id != 0) {
|
||||||
// tell the client their account id
|
// tell the client their account id
|
||||||
outgoing_message.bytes[0] = (u8)MessageCharacterId;
|
outgoing_message.bytes[0] = (u8)MessageCharacterId;
|
||||||
writeU64ToBufferLE(outgoing_message.bytes + 1, existing_account->id);
|
writeU64ToBufferLE(outgoing_message.bytes + 1, existing_account->ship.id);
|
||||||
outgoing_message.bytes_len = 9;
|
outgoing_message.bytes_len = 9;
|
||||||
outgoing_message.address = sender;
|
outgoing_message.address = sender;
|
||||||
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
||||||
@@ -598,8 +747,8 @@ fn void* gameLoop(void* params) {
|
|||||||
printf("client_handle=%d, acct_id=%d\n", client_handle, existing_account->id);
|
printf("client_handle=%d, acct_id=%d\n", client_handle, existing_account->id);
|
||||||
} break;
|
} break;
|
||||||
case CommandCreateCharacter: {
|
case CommandCreateCharacter: {
|
||||||
Account account = state.accounts[client->account_id];
|
Account* account = &state.accounts[client->account_id];
|
||||||
if (account.ship.id == 0) {
|
if (account->ship.id == 0) {
|
||||||
ShipTemplate template = SHIPS[msg.byte];
|
ShipTemplate template = SHIPS[msg.byte];
|
||||||
PlayerShip player_ship = {
|
PlayerShip player_ship = {
|
||||||
.type = msg.byte,
|
.type = msg.byte,
|
||||||
@@ -613,26 +762,29 @@ fn void* gameLoop(void* params) {
|
|||||||
.base_cost = template.base_cost,
|
.base_cost = template.base_cost,
|
||||||
.remaining_mortgage = template.base_cost - STARTING_DOWN_PAYMENT,
|
.remaining_mortgage = template.base_cost - STARTING_DOWN_PAYMENT,
|
||||||
.interest_rate = calcInterestRate(template.base_cost, STARTING_DOWN_PAYMENT),
|
.interest_rate = calcInterestRate(template.base_cost, STARTING_DOWN_PAYMENT),
|
||||||
|
.credits = 10000.0,
|
||||||
//.cu_m_fuel; // we are just saying you can buy as much fuel as you want
|
//.cu_m_fuel; // we are just saying you can buy as much fuel as you want
|
||||||
//.cu_m_o2; // we are just saying you can buy as much o2 as you want
|
//.cu_m_o2; // we are just saying you can buy as much o2 as you want
|
||||||
.id = ++state.next_eid, // start from 1
|
.id = ++state.next_eid, // start from 1
|
||||||
};
|
};
|
||||||
account.ship = player_ship;
|
account->ship = player_ship;
|
||||||
printf("ship_type=%s, client_handle=%d, acct_id=%d\n", SHIP_TYPE_STRINGS[msg.byte], client_handle, account.id);
|
printf("ship_type=%s, client_handle=%d, acct_id=%d\n", SHIP_TYPE_STRINGS[msg.byte], client_handle, account->id);
|
||||||
u32 starting_system_idx = rand() % STAR_SYSTEM_COUNT;
|
u32 starting_system_idx = rand() % STAR_SYSTEM_COUNT;
|
||||||
StarSystem starting_system = state.map[starting_system_idx];
|
StarSystem starting_system = state.map[starting_system_idx];
|
||||||
account.pos.x = starting_system.x;
|
account->pos.x = starting_system.x;
|
||||||
account.pos.y = starting_system.y;
|
account->pos.y = starting_system.y;
|
||||||
|
|
||||||
// tell the client their account id
|
// tell the client their account id
|
||||||
outgoing_message.address = sender;
|
outgoing_message.address = sender;
|
||||||
outgoing_message.bytes_len = 9;
|
outgoing_message.bytes_len = 9;
|
||||||
outgoing_message.bytes[0] = (u8)MessageCharacterId;
|
outgoing_message.bytes[0] = (u8)MessageCharacterId;
|
||||||
writeU64ToBufferLE(outgoing_message.bytes + 1, account.id);
|
writeU64ToBufferLE(outgoing_message.bytes + 1, account->ship.id);
|
||||||
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
||||||
printf("MessageCharacterId sent\n");
|
printf("MessageCharacterId sent\n");
|
||||||
|
|
||||||
// TODO tell the client about the map
|
sendMessagePlayerDetails(account->ship, sender);
|
||||||
|
|
||||||
|
// tell the client about the map
|
||||||
u32 star_msg_size = 2+MAX_PLANETS;
|
u32 star_msg_size = 2+MAX_PLANETS;
|
||||||
outgoing_message.address = sender;
|
outgoing_message.address = sender;
|
||||||
outgoing_message.bytes_len = 1+(star_msg_size*STAR_SYSTEM_COUNT);
|
outgoing_message.bytes_len = 1+(star_msg_size*STAR_SYSTEM_COUNT);
|
||||||
@@ -647,25 +799,10 @@ fn void* gameLoop(void* params) {
|
|||||||
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
||||||
printf("%s sent\n", MESSAGE_STRINGS[outgoing_message.bytes[0]]);
|
printf("%s sent\n", MESSAGE_STRINGS[outgoing_message.bytes[0]]);
|
||||||
|
|
||||||
u32 planet_count = 0;
|
outgoing_message = makeMessageSystemCommodities(&starting_system);
|
||||||
for (u32 i = 0; i < MAX_PLANETS; i++) {
|
outgoing_message.address = sender;
|
||||||
if (starting_system.planets[i].type != PlanetTypeNull) {
|
|
||||||
planet_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outgoing_message.bytes_len = 1 + 1 + 1 + (planet_count * Commodity_Count);
|
|
||||||
u32 msg_i = 0;
|
|
||||||
outgoing_message.bytes[msg_i++] = (u8)MessageSystemCommodities;
|
|
||||||
outgoing_message.bytes[msg_i++] = (u8)starting_system_idx;
|
|
||||||
outgoing_message.bytes[msg_i++] = (u8)planet_count;
|
|
||||||
for (u32 i = 0; i < planet_count; i++) {
|
|
||||||
for (u32 ii = 0; ii < Commodity_Count; ii++) {
|
|
||||||
outgoing_message.bytes[msg_i++] = starting_system.planets[i].commodities[ii];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
outgoingMessageQueuePush(state.network_send_queue, &outgoing_message);
|
||||||
printf("%s sent\n", MESSAGE_STRINGS[outgoing_message.bytes[0]]);
|
printf("%s sent\n", MESSAGE_STRINGS[outgoing_message.bytes[0]]);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
printf("client tried to create a character when he already has one.");
|
printf("client tried to create a character when he already has one.");
|
||||||
}
|
}
|
||||||
@@ -738,6 +875,7 @@ i32 main(i32 argc, ptr argv[]) {
|
|||||||
state.clients.items = (Client*)arenaAllocArray(&permanent_arena, Client, SERVER_MAX_CLIENTS);
|
state.clients.items = (Client*)arenaAllocArray(&permanent_arena, Client, SERVER_MAX_CLIENTS);
|
||||||
// set position of all star systems
|
// set position of all star systems
|
||||||
for (u32 i = 0; i < STAR_SYSTEM_COUNT; i++) {
|
for (u32 i = 0; i < STAR_SYSTEM_COUNT; i++) {
|
||||||
|
state.map[i].idx = i;
|
||||||
state.map[i].name = STAR_NAMES[i];
|
state.map[i].name = STAR_NAMES[i];
|
||||||
state.map[i].crime = rand() % 100;
|
state.map[i].crime = rand() % 100;
|
||||||
state.map[i].x = rand() % MAP_WIDTH;
|
state.map[i].x = rand() % MAP_WIDTH;
|
||||||
|
|||||||
@@ -341,9 +341,11 @@ typedef struct Planet {
|
|||||||
} Planet;
|
} Planet;
|
||||||
|
|
||||||
typedef struct StarSystem {
|
typedef struct StarSystem {
|
||||||
|
bool changed;
|
||||||
u32 x;
|
u32 x;
|
||||||
u32 y;
|
u32 y;
|
||||||
u32 crime;
|
u32 crime;
|
||||||
|
u32 idx;
|
||||||
str name;
|
str name;
|
||||||
Planet planets[MAX_PLANETS];
|
Planet planets[MAX_PLANETS];
|
||||||
} StarSystem;
|
} StarSystem;
|
||||||
@@ -413,6 +415,7 @@ typedef enum CommandType {
|
|||||||
CommandKeepAlive,
|
CommandKeepAlive,
|
||||||
CommandLogin,
|
CommandLogin,
|
||||||
CommandCreateCharacter,
|
CommandCreateCharacter,
|
||||||
|
CommandTransact,
|
||||||
CommandType_Count,
|
CommandType_Count,
|
||||||
} CommandType;
|
} CommandType;
|
||||||
static const char* command_type_strings[] = {
|
static const char* command_type_strings[] = {
|
||||||
@@ -431,6 +434,8 @@ typedef enum Message {
|
|||||||
MessageNewAccountCreated,
|
MessageNewAccountCreated,
|
||||||
MessageStarPositions,
|
MessageStarPositions,
|
||||||
MessageSystemCommodities,
|
MessageSystemCommodities,
|
||||||
|
MessagePlayerDetails,
|
||||||
|
MessageTransactionResult,
|
||||||
Message_Count,
|
Message_Count,
|
||||||
} Message;
|
} Message;
|
||||||
static const char* MESSAGE_STRINGS[] = {
|
static const char* MESSAGE_STRINGS[] = {
|
||||||
@@ -440,6 +445,8 @@ static const char* MESSAGE_STRINGS[] = {
|
|||||||
"NewAccountCreated",
|
"NewAccountCreated",
|
||||||
"StarPositions",
|
"StarPositions",
|
||||||
"SystemCommodities",
|
"SystemCommodities",
|
||||||
|
"PlayerDetails",
|
||||||
|
"TransactionResult",
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //GAMESHARED_H
|
#endif //GAMESHARED_H
|
||||||
|
|||||||
Reference in New Issue
Block a user