/* vi: set ts=2: +-------------------+ Christian Schlittchen | | Enno Rehling | Eressea PBEM host | Katja Zedel | (c) 1998 - 2003 | Henning Peters | | Ingo Wilken +-------------------+ Stefan Reich This program may not be used, modified or distributed without prior permission by the authors of Eressea. */ #include #include #include "market.h" #include #include #include #include #include #include #include #include #include #include #include static unsigned int get_markets(region * r, unit ** results, size_t size) { unsigned int n = 0; building * b; static building_type * btype; if (!btype) btype = bt_find("market"); if (!btype) return 0; for (b=r->buildings;nnext) { if (b->type==btype && (b->flags&BLD_WORKING) && b->size>=b->type->maxsize) { unit * u = building_owner(b); unsigned int i; for (i=0;u && i!=n;++i) { /* only one market per faction */ if (results[i]->faction==u->faction) u = NULL; } if (u) { results[n++] = u; } } } return n; } static void free_market(attrib * a) { item * items = (item *)a->data.v; i_freeall(&items); a->data.v = 0; } attrib_type at_market = { "script", NULL, free_market, NULL, NULL, NULL, ATF_UNIQUE }; static int rc_luxury_trade(const struct race * rc) { if (rc) { return get_param_int(rc->parameters, "luxury_trade", 1000); } return 1000; } static int rc_herb_trade(const struct race * rc) { if (rc) { return get_param_int(rc->parameters, "herb_trade", 500); } return 500; } #define MAX_MARKETS 128 #define MIN_PEASANTS 50 /* if there are at least this many peasants, you will get 1 good */ void do_markets(void) { unit_list * traders = 0; unit * markets[MAX_MARKETS]; region * r; for (r=regions;r;r=r->next) { if (r->land) { faction * f = region_get_owner(r); const struct race * rc = f?f->race:NULL; int p = rpeasants(r); int numlux = rc_luxury_trade(rc), numherbs = rc_herb_trade(rc); numlux = (p+numlux-MIN_PEASANTS)/numlux; numherbs = (p+numherbs-MIN_PEASANTS)/numherbs; if (numlux>0 || numherbs>0) { int d, nmarkets = 0; const item_type * lux = r_luxury(r); const item_type * herb = r->land->herbtype; nmarkets += get_markets(r, markets+nmarkets, MAX_MARKETS-nmarkets); for (d=0;d!=MAXDIRECTIONS;++d) { region * r2 = rconnect(r, d); if (r2 && r2->buildings) { nmarkets += get_markets(r2, markets+nmarkets, MAX_MARKETS-nmarkets); } } if (nmarkets) { while (lux && numlux--) { int n = rng_int() % nmarkets; unit * u = markets[n]; item * items; attrib * a = a_find(u->attribs, &at_market); if (a==NULL) { unit_list * ulist = malloc(sizeof(unit_list)); a = a_add(&u->attribs, a_new(&at_market)); ulist->next = traders; ulist->data = u; traders = ulist; } items = (item *)a->data.v; i_change(&items, lux, 1); a->data.v = items; /* give 1 luxury */ } while (herb && numherbs--) { int n = rng_int() % nmarkets; unit * u = markets[n]; item * items; attrib * a = a_find(u->attribs, &at_market); if (a==NULL) { unit_list * ulist = malloc(sizeof(unit_list)); a = a_add(&u->attribs, a_new(&at_market)); ulist->next = traders; ulist->data = u; traders = ulist; } items = (item *)a->data.v; i_change(&items, herb, 1); a->data.v = items; /* give 1 herb */ } } } } } while (traders) { unit_list * trade = traders; unit * u = trade->data; attrib * a = a_find(u->attribs, &at_market); item * items = a->data.v; a->data.v = NULL; while (items) { item * itm = items; items = itm->next; if (itm->number) { ADDMSG(&u->faction->msgs, msg_message("buyamount", "unit amount resource", u, itm->number, itm->type->rtype)); itm->next = NULL; i_add(&u->items, itm); } else { i_free(itm); } } traders = trade->next; a_remove(&u->attribs, a); free(trade); } } #ifndef DISABLE_TESTS #include "market_test.c" #endif