diff --git a/src/donations.c b/src/donations.c index b272f6f80..c9b4a6c6a 100644 --- a/src/donations.c +++ b/src/donations.c @@ -4,57 +4,76 @@ #include #include #include +#include #include +typedef struct transfer { + struct region *r; + struct faction *f1, *f2; + int amount; +} transfer; + +static quicklist *transfers = 0; + +int cmp_transfer(const void *v1, const void *v2) { + const transfer *t1 = (const transfer *)v1; + const transfer *t2 = (const transfer *)v2; + if (t1->r == t2->r) { + if (t1->f1 == t2->f1) { + if (t1->f2 == t2->f2) { + return 0; + } + return t1->f2->no - t2->f2->no; + } + return t1->f1->no - t2->f1->no; + } + return t1->r->uid - t2->r->uid; +} + void add_donation(faction * f1, faction * f2, int amount, region * r) { - donation *sp; + transfer tr, *tf; + quicklist *ql = transfers; + int qi = 0; - sp = r->donations_; - - while (sp) { - if (sp->f1 == f1 && sp->f2 == f2) { - sp->amount += amount; - return; - } - sp = sp->next; + tr.r = r; + tr.f1 = f1; + tr.f2 = f2; + tr.amount = amount; + if (ql_set_find_ex(&ql, &qi, &tr, cmp_transfer)) { + tf = (transfer *)ql_get(ql, qi); + tf->amount += amount; } - - sp = calloc(1, sizeof(donation)); - sp->f1 = f1; - sp->f2 = f2; - sp->amount = amount; - sp->next = r->donations_; - r->donations_ = sp; + else { + tf = malloc(sizeof(transfer)); + memcpy(tf, &tr, sizeof(transfer)); + } + ql_set_insert_ex(&transfers, tf, cmp_transfer); } void free_donations(void) { - region *r; - for (r = regions; r; r = r->next) { - while (r->donations_) { - donation *don = r->donations_; - r->donations_ = don->next; - free(don); - } - } + ql_foreach(transfers, free); + ql_free(transfers); + transfers = 0; +} + +static void report_transfer(faction *f1, faction *f2, region *r, int amount) { + struct message *msg = msg_message("donation", + "from to amount", f1, f2, amount); + r_addmessage(r, f1, msg); + r_addmessage(r, f2, msg); + msg_release(msg); } void report_donations(void) { - region *r; - for (r = regions; r; r = r->next) { - while (r->donations_) { - donation *sp = r->donations_; - if (sp->amount > 0) { - struct message *msg = msg_message("donation", - "from to amount", sp->f1, sp->f2, sp->amount); - r_addmessage(r, sp->f1, msg); - r_addmessage(r, sp->f2, msg); - msg_release(msg); - } - r->donations_ = sp->next; - free(sp); + ql_iter qli = qli_init(&transfers);; + + while (qli_more(qli)) { + transfer *tf = (transfer *)qli_next(&qli); + if (tf->amount > 0) { + report_transfer(tf->f1, tf->f2, tf->r, tf->amount); } } } diff --git a/src/kernel/region.h b/src/kernel/region.h index 3bf4b4748..93453364a 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -62,7 +62,6 @@ extern "C" { struct message; struct message_list; struct rawmaterial; - struct donation; struct item; #define MORALE_TAX_FACTOR 0.005 /* 0.5% tax per point of morale */ @@ -104,12 +103,6 @@ extern "C" { struct region_owner *ownership; } land_region; - typedef struct donation { - struct donation *next; - struct faction *f1, *f2; - int amount; - } donation; - typedef struct region { struct region *next; struct land_region *land; @@ -133,7 +126,6 @@ extern "C" { struct message_list *msgs; } *individual_messages; struct attrib *attribs; - struct donation *donations_; const struct terrain_type *terrain; struct rawmaterial *resources; #ifdef FAST_CONNECT