From 3f736214164d49bca8c10af6f711c3c476520bb6 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Sun, 19 Jan 2014 11:30:52 -0600 Subject: [PATCH] commodities --- Makefile | 6 +- commodities.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++ commodities.h | 37 ++++++++++ snis.h | 9 +++ snis_server.c | 41 ++++++++++- 5 files changed, 288 insertions(+), 5 deletions(-) create mode 100644 commodities.c create mode 100644 commodities.h diff --git a/Makefile b/Makefile index 8d6f933a..91c9c566 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,8 @@ COMMONOBJS=mathutils.o snis_alloc.o snis_socket_io.o snis_marshal.o \ bline.o shield_strength.o stacktrace.o snis_ship_type.o \ snis_faction.o mtwist.o infinite-taunt.o SERVEROBJS=${COMMONOBJS} snis_server.o names.o starbase-comms.o \ - power-model.o quat.o vec4.o matrix.o snis_event_callback.o space-part.o fleet.o + power-model.o quat.o vec4.o matrix.o snis_event_callback.o space-part.o fleet.o \ + commodities.c CLIENTOBJS=${COMMONOBJS} ${OGGOBJ} ${SNDOBJS} shader.o graph_dev_opengl.o snis_ui_element.o snis_graph.o \ snis_client.o snis_font.o snis_text_input.o \ @@ -356,6 +357,9 @@ mtwist.o: mtwist.c mtwist.h fleet.o: fleet.c fleet.h $(Q)$(COMPILE) +commodities.o: commodities.c commodities.h + $(Q)$(COMPILE) + test_matrix: matrix.c matrix.h $(CC) ${MYCFLAGS} ${GTKCFLAGS} -DTEST_MATRIX -o test_matrix matrix.c -lm diff --git a/commodities.c b/commodities.c new file mode 100644 index 00000000..4489403a --- /dev/null +++ b/commodities.c @@ -0,0 +1,200 @@ +/* + Copyright (C) 2014 Stephen M. Cameron + Author: Stephen M. Cameron + + This file is part of Spacenerds In Space. + + Spacenerds in Space is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Spacenerds in Space is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Spacenerds in Space; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include + +#include "commodities.h" + +#if 0 +struct commodity { + char name[40]; + char unit[40]; + float base_price; + float volatility; + float legality; + float government_adjust; + float economy_adjust; + float tech_adjust; +}; +#endif + +static void clean_spaces(char *line) +{ + char *s, *d; + int skip_spaces = 1; + + s = line; + d = line; + + while (*s) { + if ((*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r') && skip_spaces) { + s++; + continue; + } + skip_spaces = 0; + if (*s == '\t' || *s == '\n' || *s == '\r') + *s = ' '; + if (*s == ' ') + skip_spaces = 1; + *d = *s; + s++; + d++; + } +} + +static int parse_error(char *filename, char *line, int ln, char *bad_word) +{ + if (bad_word) + printf("Error at line %s:%d at %s\n", filename, ln, bad_word); + else + printf("Error at line %s:%d\n", filename, ln); + return -1; +} + +static int parse_float_field(char *filename, char *line, int ln, float *value) +{ + char *c; + char word[100]; + int rc; + + c = strtok(NULL, ","); + if (!c) + return parse_error(filename, line, ln, NULL); + strcpy(word, c); + clean_spaces(word); + rc = sscanf(word, "%f", value); + if (rc != 1) + return parse_error(filename, line, ln, word); + return 0; +} + +static void uppercase(char *w) +{ + char *i; + + for (i = w; *i; i++) + *i = toupper(*i); +} + +static int parse_line(char *filename, char *line, int ln, struct commodity *c) +{ + char *x; + char word[100]; + int rc; + + if (line[0] == '#') + return 1; + clean_spaces(line); + if (strcmp(line, "") == 0) + return 1; + + /* Name */ + x = strtok(line, ","); + if (!x) + return parse_error(filename, line, ln, NULL); + strcpy(word, x); + clean_spaces(word); + uppercase(word); + strcpy(c->name, word); + + /* unit */ + x = strtok(NULL, ","); + if (!x) + return parse_error(filename, line, ln, NULL); + strcpy(word, x); + clean_spaces(word); + uppercase(word); + strcpy(c->unit, word); + + rc = parse_float_field(filename, line, ln, &c->base_price); + if (rc) + return rc; + rc = parse_float_field(filename, line, ln, &c->volatility); + if (rc) + return rc; + rc = parse_float_field(filename, line, ln, &c->legality); + if (rc) + return rc; + rc = parse_float_field(filename, line, ln, &c->government_adjust); + if (rc) + return rc; + rc = parse_float_field(filename, line, ln, &c->economy_adjust); + if (rc) + return rc; + rc = parse_float_field(filename, line, ln, &c->tech_adjust); + if (rc) + return rc; + return 0; +} + +#define MAX_COMMODITIES 100 + +struct commodity **read_commodities(char *filename, int *ncommodities) +{ + FILE *f; + char line[1000]; + char *l; + struct commodity c, *clist; + int rc, ln = 0; + int n = 0; + + n = 0; + clist = malloc(sizeof(*clist) * MAX_COMMODITIES); + memset(clist, 0, sizeof(*clist) * MAX_COMMODITIES); + + f = fopen(filename, "r"); + if (!f) + return NULL; + + while (!feof(f)) { + l = fgets(line, 1000, f); + if (!l) + break; + line[strlen(line) - 1] = '\0'; + ln++; + rc = parse_line(filename, line, ln, &c); + switch (rc) { + case 0: + clist[n] = c; + n++; +#if 0 + printf("%s:%s:%f:%f:%f:%f:%f:%f\n", + c.name, c.unit, + c.base_price, + c.volatility, + c.legality, + c.government_adjust, + c.economy_adjust, + c.tech_adjust); +#endif + continue; + case 1: /* comment */ + continue; + case -1: + return NULL; + } + } + *ncommodities = n; + return (struct commodity **) clist; +} diff --git a/commodities.h b/commodities.h new file mode 100644 index 00000000..4bbcc92d --- /dev/null +++ b/commodities.h @@ -0,0 +1,37 @@ +#ifndef COMMODITIES_H__ +#define COMMODITIES_H__ +/* + Copyright (C) 2014 Stephen M. Cameron + Author: Stephen M. Cameron + + This file is part of Spacenerds In Space. + + Spacenerds in Space is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + Spacenerds in Space is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Spacenerds in Space; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +struct commodity { + char name[40]; + char unit[40]; + float base_price; + float volatility; + float legality; + float government_adjust; + float economy_adjust; + float tech_adjust; +}; + +struct commodity **read_commodities(char *filename, int *ncommodities); + +#endif diff --git a/snis.h b/snis.h index 78ffacd6..3b359724 100644 --- a/snis.h +++ b/snis.h @@ -58,6 +58,7 @@ #define NPLANET_MATERIALS 4 #define NPLANETS 10 #define NBASES (NPLANETS + 3) +#define COMMODITIES_PER_BASE 10 #define MAXPLAYERS 10 @@ -347,11 +348,19 @@ struct ship_data { float braking_factor; }; +struct marketplace_data { + int item; + float qty; + float refill_rate; +}; + struct starbase_data { uint8_t under_attack; uint32_t last_time_called_for_help; uint8_t lifeform_count; char name[16]; + struct marketplace_data *mkt; + int associated_planet_id; }; struct nebula_data { diff --git a/snis_server.c b/snis_server.c index 0333ae3a..d37038d8 100644 --- a/snis_server.c +++ b/snis_server.c @@ -74,6 +74,7 @@ #include "power-model.h" #include "snis_event_callback.h" #include "fleet.h" +#include "commodities.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define CLIENT_UPDATE_PERIOD_NSECS 500000000 @@ -141,6 +142,9 @@ static char *asset_dir; static int nebulalist[NNEBULA] = { 0 }; +static int ncommodities; +static struct commodity **commodity; + static inline void client_lock() { (void) pthread_mutex_lock(&client_mutex); @@ -3723,8 +3727,27 @@ static int add_asteroid(double x, double y, double z, double vx, double vz, doub return i; } +static void init_starbase_market(struct snis_entity *o) +{ + int i; + struct marketplace_data *mkt = NULL; + + o->tsd.starbase.mkt = NULL; + if (ncommodities == 0) + return; + mkt = malloc(sizeof(*mkt) * COMMODITIES_PER_BASE); + o->tsd.starbase.mkt = mkt; + if (!mkt) + return; + for (i = 0; i < COMMODITIES_PER_BASE; i++) { + mkt[i].item = snis_randn(ncommodities); + mkt[i].qty = snis_randn(100); /* TODO: something better */ + mkt[i].refill_rate = (float) snis_randn(1000) / 1000.0; /* TODO: something better */ + } +} + static int add_starbase(double x, double y, double z, - double vx, double vz, double heading, int n) + double vx, double vz, double heading, int n, uint32_t assoc_planet_id) { int i; @@ -3739,6 +3762,8 @@ static int add_starbase(double x, double y, double z, go[i].tsd.starbase.last_time_called_for_help = 0; go[i].tsd.starbase.under_attack = 0; go[i].tsd.starbase.lifeform_count = snis_randn(100) + 100; + go[i].tsd.starbase.associated_planet_id = assoc_planet_id; + init_starbase_market(&go[i]); go[i].sdata.shield_strength = 255; /* FIXME, why name stored twice? probably just use sdata.name is best * but might be because we should know starbase name even if science @@ -3760,7 +3785,7 @@ static int l_add_starbase(lua_State *l) n = lua_tonumber(lua_state, 4); pthread_mutex_lock(&universe_mutex); - i = add_starbase(x, y, z, 0, 0, 0, n); + i = add_starbase(x, y, z, 0, 0, 0, n, -1); lua_pushnumber(lua_state, i < 0 ? -1.0 : (double) go[i].id); pthread_mutex_unlock(&universe_mutex); return 1; @@ -4042,6 +4067,7 @@ static void add_starbases(void) { int i, j, p, found; double x, y, z; + uint32_t assoc_planet_id; for (i = 0; i < NBASES; i++) { if (i < NPLANETS) { @@ -4057,6 +4083,7 @@ static void add_starbases(void) y = go[j].y + dy; z = go[j].z + dz; found = 1; + assoc_planet_id = go[j].id; break; } } @@ -4066,13 +4093,15 @@ static void add_starbases(void) x = ((double) snis_randn(1000)) * XKNOWN_DIM / 1000.0; y = ((double) snis_randn(1000) - 500.0) * YKNOWN_DIM / 1000.0; z = ((double) snis_randn(1000)) * ZKNOWN_DIM / 1000.0; + assoc_planet_id = (uint32_t) -1; } } else { x = ((double) snis_randn(1000)) * XKNOWN_DIM / 1000.0; y = ((double) snis_randn(1000) - 500.0) * YKNOWN_DIM / 1000.0; z = ((double) snis_randn(1000)) * ZKNOWN_DIM / 1000.0; + assoc_planet_id = (uint32_t) -1; } - add_starbase(x, y, z, 0.0, 0.0, 0.0, i); + add_starbase(x, y, z, 0.0, 0.0, 0.0, i, assoc_planet_id); } } @@ -6072,7 +6101,7 @@ static int process_create_item(struct game_client *c) i = add_ship(); break; case OBJTYPE_STARBASE: - i = add_starbase(x, 0, z, 0, 0, 0, snis_randn(100)); + i = add_starbase(x, 0, z, 0, 0, 0, snis_randn(100), -1); break; case OBJTYPE_PLANET: i = add_planet(x, 0.0, z); @@ -8428,6 +8457,10 @@ int main(int argc, char *argv[]) override_asset_dir(); + char commodity_path[PATH_MAX]; + sprintf(commodity_path, "%s/%s", asset_dir, "commodities.txt"); + commodity = read_commodities(commodity_path, &ncommodities); + if (read_ship_types()) { fprintf(stderr, "%s: unable to read ship types\n", argv[0]); return -1;