Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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);
    }
}
Example #4
0
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;
}
Example #5
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;
}
Example #6
0
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);
                    }
                }
            }
        }
    }
}
Example #7
0
/** 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;
}
Example #8
0
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);
    }
}