static order *get_money_for_dragon(region * r, unit * udragon, int wanted) { int n; bool attacks = attack_chance > 0.0; /* falls genug geld in der region ist, treiben wir steuern ein. */ if (rmoney(r) >= wanted) { /* 5% chance, dass der drache aus einer laune raus attackiert */ if (!attacks || chance(1.0 - u_race(udragon)->aggression)) { /* Drachen haben in E3 und E4 keine Einnahmen. Neuer Befehl Pluendern erstmal nur fuer Monster?*/ return create_order(K_LOOT, default_locale, NULL); } } /* falls der drache launisch ist, oder das regionssilber knapp, greift er alle an * und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */ n = 0; if (attacks && is_guard(udragon, GUARD_TAX)) { unit *u; for (u = r->units; u; u = u->next) { if (u->faction != udragon->faction && cansee(udragon->faction, r, u, 0) && !in_safe_building(u, udragon)) { int m = get_money(u); if (m != 0) { order *ord = monster_attack(udragon, u); if (ord) { addlist(&udragon->orders, ord); n += m; } } } } } /* falls die einnahmen erreicht werden, bleibt das monster noch eine */ /* runde hier. */ if (n + rmoney(r) >= wanted) { return create_order(K_LOOT, default_locale, NULL); } /* wenn wir NULL zurueckliefern, macht der drache was anderes, z.b. weggehen */ return NULL; }
static int all_money(region * r, faction * f) { unit *u; int m; m = rmoney(r); for (u = r->units; u; u = u->next) { if (f != u->faction) { m += get_money(u); } } return m; }
void plagues(region * r) { int peasants; int i; int dead = 0; peasants = rpeasants(r); dead = (int)(0.5 + PLAGUE_VICTIMS * peasants); for (i = dead; i != 0; i--) { if (rng_double() < PLAGUE_HEALCHANCE && rmoney(r) >= PLAGUE_HEALCOST) { rsetmoney(r, rmoney(r) - PLAGUE_HEALCOST); --dead; } } if (dead > 0) { message *msg = add_message(&r->msgs, msg_message("pest", "dead", dead)); msg_release(msg); deathcounts(r, dead); rsetpeasants(r, peasants - dead); } }
int region_getresource(const region * r, const resource_type * rtype) { const rawmaterial *rm; for (rm = r->resources; rm; rm = rm->next) { if (rm->type->rtype == rtype) { return rm->amount; } } if (rtype == get_resourcetype(R_SILVER)) return rmoney(r); if (rtype == get_resourcetype(R_HORSE)) return rhorses(r); if (rtype == get_resourcetype(R_PEASANT)) return rpeasants(r); return 0; }
summary *make_summary(void) { faction *f; region *r; unit *u; summary *s = calloc(1, sizeof(summary)); const struct resource_type *rhorse = get_resourcetype(R_HORSE); for (f = factions; f; f = f->next) { const struct locale *lang = f->locale; struct language *plang = s->languages; while (plang && plang->locale != lang) plang = plang->next; if (!plang) { plang = calloc(sizeof(struct language), 1); plang->next = s->languages; s->languages = plang; plang->locale = lang; } ++plang->number; f->nregions = 0; f->num_total = 0; f->money = 0; if (f->alive && f->units) { s->factions++; /* Problem mit Monsterpartei ... */ if (!is_monsters(f)) { s->factionrace[old_race(f->race)]++; } } } /* count everything */ for (r = regions; r; r = r->next) { s->pferde += rhorses(r); s->schiffe += listlen(r->ships); s->gebaeude += listlen(r->buildings); if (!fval(r->terrain, SEA_REGION)) { s->landregionen++; if (r->units) { s->landregionen_mit_spielern++; } if (fval(r, RF_ORCIFIED)) { s->orkifizierte_regionen++; } if (r->terrain == newterrain(T_VOLCANO)) { s->inactive_volcanos++; } else if (r->terrain == newterrain(T_VOLCANO_SMOKING)) { s->active_volcanos++; } } if (r->units) { s->regionen_mit_spielern++; } if (rpeasants(r) || r->units) { s->inhabitedregions++; s->peasants += rpeasants(r); s->peasantmoney += rmoney(r); /* Einheiten Info. nregions darf nur einmal pro Partei * incrementiert werden. */ for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); for (u = r->units; u; u = u->next) { f = u->faction; if (!is_monsters(u->faction)) { skill *sv; item *itm; s->nunits++; s->playerpop += u->number; if (u->flags & UFL_HERO) { s->heroes += u->number; } s->spielerpferde += i_get(u->items, rhorse->itype); s->playermoney += get_money(u); s->armed_men += armedmen(u, true); for (itm = u->items; itm; itm = itm->next) { if (itm->type->rtype->wtype) { s->waffen += itm->number; } if (itm->type->rtype->atype) { s->ruestungen += itm->number; } } s->spielerpferde += i_get(u->items, rhorse->itype); for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { skill_t sk = sv->id; int aktskill = eff_skill(u, sk, r); if (aktskill > s->maxskill) s->maxskill = aktskill; } if (!fval(f, FFL_SELECT)) { f->nregions++; fset(f, FFL_SELECT); } } f->num_total += u->number; f->money += get_money(u); s->poprace[old_race(u_race(u))] += u->number; } } } return s; }
void destroyfaction(faction ** fp) { faction * f = *fp; unit *u = f->units; *fp = f->next; f->next = dead_factions; dead_factions = f; fset(f, FFL_QUIT); f->_alive = false; if (f->spellbook) { spellbook_clear(f->spellbook); free(f->spellbook); f->spellbook = 0; } if (f->seen_factions) { selist_free(f->seen_factions); f->seen_factions = 0; } while (u) { /* give away your stuff, to ghosts if you cannot (quest items) */ if (u->items) { region *r = u->region; int result = gift_items(u, GIFT_FRIENDS | GIFT_PEASANTS); if (result != 0) { save_special_items(u); } if (r->land && !!playerrace(u_race(u))) { const race *rc = u_race(u); int m = rmoney(r); /* Personen gehen nur an die Bauern, wenn sie auch von dort * stammen */ if ((rc->ec_flags & ECF_REC_ETHEREAL) == 0) { int p = rpeasants(u->region); int h = rhorses(u->region); item *itm; p += (int)(u->number * rc->recruit_multi); for (itm = u->items; itm; itm = itm->next) { if (itm->type->flags & ITF_ANIMAL) { h += itm->number; } } rsetpeasants(r, p); rsethorses(r, h); } m += get_money(u); rsetmoney(r, m); } } set_number(u, 0); u = u->nextF; } handle_event(f->attribs, "destroy", f); if (f->alliance) { setalliance(f, NULL); } funhash(f); /* units of other factions that were disguised as this faction * have their disguise replaced by ordinary faction hiding. */ if (rule_stealth_other()) { region *rc; for (rc = regions; rc; rc = rc->next) { for (u = rc->units; u; u = u->next) { if (u->attribs && get_otherfaction(u) == f) { a_removeall(&u->attribs, &at_otherfaction); if (rule_stealth_anon()) { fset(u, UFL_ANON_FACTION); } } } } } }
/** give all items to friends or peasants. * this function returns 0 on success, or 1 if there are items that * could not be destroyed. */ int gift_items(unit * u, int flags) { region *r = u->region; item **itm_p = &u->items; int retval = 0; int rule = rule_give(); assert(u->region); assert(u->faction); if ((u->faction->flags & FFL_QUIT) == 0 || (rule & GIVE_ONDEATH) == 0) { if ((rule & GIVE_ALLITEMS) == 0 && (flags & GIFT_FRIENDS)) flags -= GIFT_FRIENDS; if ((rule & GIVE_PEASANTS) == 0 && (flags & GIFT_PEASANTS)) flags -= GIFT_PEASANTS; if ((rule & GIVE_SELF) == 0 && (flags & GIFT_SELF)) flags -= GIFT_SELF; } if (u->items == NULL || fval(u_race(u), RCF_ILLUSIONARY)) return 0; if ((u_race(u)->ec_flags & GIVEITEM) == 0) return 0; /* at first, I should try giving my crap to my own units in this region */ if (u->faction && (u->faction->flags & FFL_QUIT) == 0 && (flags & GIFT_SELF)) { unit *u2, *u3 = NULL; for (u2 = r->units; u2; u2 = u2->next) { if (u2 != u && u2->faction == u->faction && u2->number > 0) { /* some units won't take stuff: */ if (u_race(u2)->ec_flags & GETITEM) { /* we don't like to gift it to units that won't give it back */ if (u_race(u2)->ec_flags & GIVEITEM) { i_merge(&u2->items, &u->items); u->items = NULL; break; } else { u3 = u2; } } } } if (u->items && u3) { /* if nobody else takes it, we give it to a unit that has issues */ i_merge(&u3->items, &u->items); u->items = NULL; } if (u->items == NULL) return 0; } /* if I have friends, I'll try to give my stuff to them */ if (u->faction && (flags & GIFT_FRIENDS)) { int number = 0; buddy *friends = get_friends(u, &number); while (friends) { struct buddy *nf = friends; unit *u2 = nf->unit; item *itm = u->items; while (itm != NULL) { const item_type *itype = itm->type; item *itn = itm->next; int n = itm->number; n = n * nf->number / number; if (n > 0) { i_change(&u->items, itype, -n); i_change(&u2->items, itype, n); } itm = itn; } number -= nf->number; friends = nf->next; free(nf); } if (u->items == NULL) return 0; } /* last, but not least, give money and horses to peasants */ while (*itm_p) { item *itm = *itm_p; if (flags & GIFT_PEASANTS) { if (!fval(u->region->terrain, SEA_REGION)) { if (itm->type == olditemtype[I_HORSE]) { rsethorses(r, rhorses(r) + itm->number); itm->number = 0; } else if (itm->type == i_silver) { rsetmoney(r, rmoney(r) + itm->number); itm->number = 0; } } } if (itm->number > 0 && (itm->type->flags & ITF_NOTLOST)) { itm_p = &itm->next; retval = -1; } else { i_remove(itm_p, itm); i_free(itm); } } return retval; }
void get_food(region * r) { plane *pl = rplane(r); unit *u; int peasantfood = rpeasants(r) * 10; static int food_rules = -1; static int gamecookie = -1; if (food_rules < 0 || gamecookie != global.cookie) { gamecookie = global.cookie; food_rules = get_param_int(global.parameters, "rules.economy.food", 0); } if (food_rules & FOOD_IS_FREE) { return; } /* 1. Versorgung von eigenen Einheiten. Das vorhandene Silber * wird zunächst so auf die Einheiten aufgeteilt, dass idealerweise * jede Einheit genug Silber für ihren Unterhalt hat. */ for (u = r->units; u; u = u->next) { int need = lifestyle(u); /* Erstmal zurücksetzen */ freset(u, UFL_HUNGER); if (u->ship && (u->ship->flags & SF_FISHING)) { unit *v; int c = 2; for (v = u; c > 0 && v; v = v->next) { if (v->ship == u->ship) { int get = 0; if (v->number <= c) { get = lifestyle(v); } else { get = lifestyle(v) * c / v->number; } if (get) { change_money(v, get); } } c -= v->number; } u->ship->flags -= SF_FISHING; } if (food_rules & FOOD_FROM_PEASANTS) { struct faction *owner = region_get_owner(r); /* if the region is owned, and the owner is nice, then we'll get * food from the peasants - should not be used with WORK */ if (owner != NULL && (get_alliance(owner, u->faction) & HELP_MONEY)) { int rm = rmoney(r); int use = _min(rm, need); rsetmoney(r, rm - use); need -= use; } } need -= get_money(u); if (need > 0) { unit *v; for (v = r->units; need && v; v = v->next) { if (v->faction == u->faction && help_money(v)) { int give = get_money(v) - lifestyle(v); give = _min(need, give); if (give > 0) { change_money(v, -give); change_money(u, give); need -= give; } } } } } /* 2. Versorgung durch Fremde. Das Silber alliierter Einheiten wird * entsprechend verteilt. */ for (u = r->units; u; u = u->next) { int need = lifestyle(u); faction *f = u->faction; need -= _max(0, get_money(u)); if (need > 0) { unit *v; if (food_rules & FOOD_FROM_OWNER) { /* the owner of the region is the first faction to help out when you're hungry */ faction *owner = region_get_owner(r); if (owner && owner != u->faction) { for (v = r->units; v; v = v->next) { if (v->faction == owner && alliedunit(v, f, HELP_MONEY) && help_money(v)) { help_feed(v, u, &need); break; } } } } for (v = r->units; need && v; v = v->next) { if (v->faction != f && alliedunit(v, f, HELP_MONEY) && help_money(v)) { help_feed(v, u, &need); } } /* Die Einheit hat nicht genug Geld zusammengekratzt und * nimmt Schaden: */ if (need > 0) { int lspp = lifestyle(u) / u->number; if (lspp > 0) { int number = (need + lspp - 1) / lspp; if (hunger(number, u)) fset(u, UFL_HUNGER); } } } } /* 3. bestimmen, wie viele Bauern gefressen werden. * bei fehlenden Bauern den Dämon hungern lassen */ for (u = r->units; u; u = u->next) { if (u_race(u) == get_race(RC_DAEMON)) { int hungry = u->number; /* use peasantblood before eating the peasants themselves */ const struct potion_type *pt_blood = 0; const resource_type *rt_blood = rt_find("peasantblood"); if (rt_blood) { pt_blood = rt_blood->ptype; } if (pt_blood) { /* always start with the unit itself, then the first known unit that may have some blood */ unit *donor = u; while (donor != NULL && hungry > 0) { int blut = get_effect(donor, pt_blood); blut = _min(blut, hungry); if (blut) { change_effect(donor, pt_blood, -blut); hungry -= blut; } if (donor == u) donor = r->units; while (donor != NULL) { if (u_race(donor) == get_race(RC_DAEMON) && donor != u) { if (get_effect(donor, pt_blood)) { /* if he's in our faction, drain him: */ if (donor->faction == u->faction) break; } } donor = donor->next; } } } /* remaining demons feed on peasants */ if (pl == NULL || !fval(pl, PFL_NOFEED)) { if (peasantfood >= hungry) { peasantfood -= hungry; hungry = 0; } else { hungry -= peasantfood; peasantfood = 0; } if (hungry > 0) { static int demon_hunger = -1; if (demon_hunger < 0) { demon_hunger = get_param_int(global.parameters, "hunger.demons", 0); } if (demon_hunger == 0) { /* demons who don't feed are hungry */ if (hunger(hungry, u)) fset(u, UFL_HUNGER); } else { /* no damage, but set the hungry-flag */ fset(u, UFL_HUNGER); } } } } } rsetpeasants(r, peasantfood / 10); /* 3. Von den überlebenden das Geld abziehen: */ for (u = r->units; u; u = u->next) { int need = _min(get_money(u), lifestyle(u)); change_money(u, -need); } }