Esempio n. 1
0
static void prepare_starting_region(region * r)
{
    int n, t;
    double p;

    assert(r->land);

    /* population between 30% and 60% of max */
    p = rng_double();
    n = (int)(r->terrain->size * (0.3 + p * 0.3));
    rsetpeasants(r, n);

    /* trees: don't squash the peasants, and at least 5% should be forrest */
    t = (rtrees(r, 2) + rtrees(r, 1) / 2) * TREESIZE;
    if (t < r->terrain->size / 20 || t + n > r->terrain->size) {
        double p2 = 0.05 + rng_double() * (1.0 - p - 0.05);
        int maxtrees = (int)(r->terrain->size / 1.25 / TREESIZE);   /* 1.25 = each young tree will take 1/2 the space of old trees */
        int trees = (int)(p2 * maxtrees);

        rsettrees(r, 2, trees);
        rsettrees(r, 1, trees / 2);
        rsettrees(r, 0, trees / 4);
    }

    /* horses: between 1% and 2% */
    p = rng_double();
    rsethorses(r, (int)(r->terrain->size * (0.01 + p * 0.01)));

    if (!markets_module()) {
        fix_demand(r);
    }
}
Esempio n. 2
0
bool r_isforest(const region * r)
{
    if (fval(r->terrain, FOREST_REGION)) {
        /* needs to be covered with at leas 48% trees */
        int mincover = (int)(r->terrain->size * 0.48);
        int trees = rtrees(r, 2) + rtrees(r, 1);
        return (trees * TREESIZE >= mincover);
    }
    return false;
}
Esempio n. 3
0
static int do_potion(unit * u, region *r, const potion_type * ptype, int amount)
{
  if (ptype == oldpotiontype[P_LIFE]) {
    int holz = 0;
    static int tree_type = -1;
    static int tree_count = -1;
    if (tree_type < 0) {
      tree_type = get_param_int(global.parameters, "rules.magic.wol_type", 1);
      tree_count =
        get_param_int(global.parameters, "rules.magic.wol_effect", 10);
    }
    /* mallorn is required to make mallorn forests, wood for regular ones */
    if (fval(r, RF_MALLORN)) {
      holz = use_pooled(u, rt_find("mallorn"),
        GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, tree_count * amount);
    } else {
      holz = use_pooled(u, rt_find("log"),
        GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, tree_count * amount);
    }
    if (r->land == 0)
      holz = 0;
    if (holz < tree_count * amount) {
      int x = holz / tree_count;
      if (holz % tree_count)
        ++x;
      if (x < amount)
        amount = x;
    }
    rsettrees(r, tree_type, rtrees(r, tree_type) + holz);
    ADDMSG(&u->faction->msgs, msg_message("growtree_effect",
        "mage amount", u, holz));
  } else if (ptype == oldpotiontype[P_HEILWASSER]) {
    u->hp = _min(unit_max_hp(u) * u->number, u->hp + 400 * amount);
  } else if (ptype == oldpotiontype[P_PEOPLE]) {
    attrib *a = (attrib *) a_find(r->attribs, &at_peasantluck);
    if (!a)
      a = a_add(&r->attribs, a_new(&at_peasantluck));
    a->data.i += amount;
  } else if (ptype == oldpotiontype[P_HORSE]) {
    attrib *a = (attrib *) a_find(r->attribs, &at_horseluck);
    if (!a)
      a = a_add(&r->attribs, a_new(&at_horseluck));
    a->data.i += amount;
  } else if (ptype == oldpotiontype[P_WAHRHEIT]) {
    fset(u, UFL_DISBELIEVES);
    amount = 1;
  } else if (ptype == oldpotiontype[P_MACHT]) {
    /* Verfünffacht die HP von max. 10 Personen in der Einheit */
    u->hp += _min(u->number, 10 * amount) * unit_max_hp(u) * 4;
  } else {
    change_effect(u, ptype, 10 * amount);
  }
  return amount;
}
Esempio n. 4
0
static int tolua_region_get_resource(lua_State * L)
{
    region *r;
    const char *type;
    const resource_type *rtype;
    int result = 0;
    void * match;
    critbit_tree * cb = special_resources();

    r = (region *)tolua_tousertype(L, 1, 0);
    LUA_ASSERT(r != NULL, "invalid parameter");
    type = tolua_tostring(L, 2, 0);
    LUA_ASSERT(type != NULL, "invalid parameter");

    if (cb_find_prefix(cb, type, strlen(type) + 1, &match, 1, 0)) {
        cb_get_kv(match, &result, sizeof(result));
        switch (result) {
        case 0:
        case 1:
        case 2:
            result = rtrees(r, result);
            break;
        case 3:
            result = deathcount(r);
            break;
        case 4:
            result = get_chaoscount(r);
            break;
        }
    }
    else {
        rtype = rt_find(type);
        if (rtype) {
            result = region_getresource(r, rtype);
        }
        else {
            result = -1;
        }
    }

    lua_pushinteger(L, result);
    return 1;
}
Esempio n. 5
0
/* In a->data.ca[1] steht der Prozentsatz mit dem sich die Einheit
 * auflöst, in a->data.ca[0] kann angegeben werden, wohin die Personen
 * verschwinden. Passiert bereits in der ersten Runde! */
static void dissolve_units(void)
{
  region *r;
  unit *u;
  int n;
  int i;

  for (r = regions; r; r = r->next) {
    for (u = r->units; u; u = u->next) {
      attrib *a = a_find(u->attribs, &at_unitdissolve);
      if (a) {
        message *msg;

        if (u->age == 0 && a->data.ca[1] < 100)
          continue;

        /* TODO: Durch einzelne Berechnung ersetzen */
        if (a->data.ca[1] == 100) {
          n = u->number;
        } else {
          n = 0;
          for (i = 0; i < u->number; i++) {
            if (rng_int() % 100 < a->data.ca[1])
              n++;
          }
        }

        /* wenn keiner verschwindet, auch keine Meldung */
        if (n == 0) {
          continue;
        }

        scale_number(u, u->number - n);

        switch (a->data.ca[0]) {
          case 1:
            rsetpeasants(r, rpeasants(r) + n);
            msg =
              msg_message("dissolve_units_1", "unit region number race", u, r,
              n, u_race(u));
            break;
          case 2:
            if (r->land && !fval(r, RF_MALLORN)) {
              rsettrees(r, 2, rtrees(r, 2) + n);
              msg =
                msg_message("dissolve_units_2", "unit region number race", u, r,
                n, u_race(u));
            } else {
              msg =
                msg_message("dissolve_units_3", "unit region number race", u, r,
                n, u_race(u));
            }
            break;
          default:
              if (u_race(u) == get_race(RC_STONEGOLEM)
                  || u_race(u) == get_race(RC_IRONGOLEM)) {
              msg =
                msg_message("dissolve_units_4", "unit region number race", u, r,
                n, u_race(u));
            } else {
              msg =
                msg_message("dissolve_units_5", "unit region number race", u, r,
                n, u_race(u));
            }
            break;
        }

        add_message(&u->faction->msgs, msg);
        msg_release(msg);
      }
    }
  }

  remove_empty_units();
}
Esempio n. 6
0
void terraform_region(region * r, const terrain_type * terrain)
{
    /* Resourcen, die nicht mehr vorkommen können, löschen */
    const terrain_type *oldterrain = r->terrain;
    rawmaterial **lrm = &r->resources;

    assert(terrain);

    while (*lrm) {
        rawmaterial *rm = *lrm;
        const resource_type *rtype = NULL;

        if (terrain->production != NULL) {
            int i;
            for (i = 0; terrain->production[i].type; ++i) {
                if (rm->type->rtype == terrain->production[i].type) {
                    rtype = rm->type->rtype;
                    break;
                }
            }
        }
        if (rtype == NULL) {
            *lrm = rm->next;
            free(rm);
        }
        else {
            lrm = &rm->next;
        }
    }

    r->terrain = terrain;
    terraform_resources(r);

    if (!fval(terrain, LAND_REGION)) {
        region_setinfo(r, NULL);
        if (r->land != NULL) {
            i_freeall(&r->land->items);
            freeland(r->land);
            r->land = NULL;
        }
        rsettrees(r, 0, 0);
        rsettrees(r, 1, 0);
        rsettrees(r, 2, 0);
        rsethorses(r, 0);
        rsetpeasants(r, 0);
        rsetmoney(r, 0);
        freset(r, RF_ENCOUNTER);
        freset(r, RF_MALLORN);
        /* Beschreibung und Namen löschen */
        return;
    }

    if (r->land) {
        int d;
        for (d = 0; d != MAXDIRECTIONS; ++d) {
            rsetroad(r, d, 0);
        }
        i_freeall(&r->land->items);
    }
    else {
        static struct surround {
            struct surround *next;
            const luxury_type *type;
            int value;
        } *trash = NULL, *nb = NULL;
        const luxury_type *ltype = NULL;
        direction_t d;
        int mnr = 0;

        r->land = calloc(1, sizeof(land_region));
        r->land->ownership = NULL;
        region_set_morale(r, MORALE_DEFAULT, -1);
        region_setname(r, makename());
        for (d = 0; d != MAXDIRECTIONS; ++d) {
            region *nr = rconnect(r, d);
            if (nr && nr->land) {
                struct demand *sale = r->land->demands;
                while (sale && sale->value != 0)
                    sale = sale->next;
                if (sale) {
                    struct surround *sr = nb;
                    while (sr && sr->type != sale->type)
                        sr = sr->next;
                    if (!sr) {
                        if (trash) {
                            sr = trash;
                            trash = trash->next;
                        }
                        else {
                            sr = calloc(1, sizeof(struct surround));
                        }
                        sr->next = nb;
                        sr->type = sale->type;
                        sr->value = 1;
                        nb = sr;
                    }
                    else
                        sr->value++;
                    ++mnr;
                }
            }
        }
        if (!nb) {
            // TODO: this is really lame
            int i = get_maxluxuries();
            if (i > 0) {
                i = rng_int() % i;
                ltype = luxurytypes;
                while (i--)
                    ltype = ltype->next;
            }
        }
        else {
            int i = rng_int() % mnr;
            struct surround *srd = nb;
            while (i > srd->value) {
                i -= srd->value;
                srd = srd->next;
            }
            if (srd->type)
                setluxuries(r, srd->type);
            while (srd->next != NULL)
                srd = srd->next;
            srd->next = trash;
            trash = nb;
            nb = NULL;
        }
    }

    if (fval(terrain, LAND_REGION)) {
        const item_type *itype = NULL;
        char equip_hash[64];

        /* TODO: put the equipment in struct terrain, faster */
        sprintf(equip_hash, "terrain_%s", terrain->_name);
        equip_items(&r->land->items, get_equipment(equip_hash));

        if (r->terrain->herbs) {
            int len = 0;
            while (r->terrain->herbs[len])
                ++len;
            if (len)
                itype = r->terrain->herbs[rng_int() % len];
        }
        if (itype != NULL) {
            rsetherbtype(r, itype);
            rsetherbs(r, (short)(50 + rng_int() % 31));
        }
        else {
            rsetherbtype(r, NULL);
        }
        if (oldterrain == NULL || !fval(oldterrain, LAND_REGION)) {
            if (rng_int() % 100 < 3)
                fset(r, RF_MALLORN);
            else
                freset(r, RF_MALLORN);
            if (rng_int() % 100 < ENCCHANCE) {
                fset(r, RF_ENCOUNTER);
            }
        }
    }

    if (oldterrain == NULL || terrain->size != oldterrain->size) {
        if (terrain == newterrain(T_PLAIN)) {
            rsethorses(r, rng_int() % (terrain->size / 50));
            if (rng_int() % 100 < 40) {
                rsettrees(r, 2, terrain->size * (30 + rng_int() % 40) / 1000);
            }
        }
        else if (chance(0.2)) {
            rsettrees(r, 2, terrain->size * (30 + rng_int() % 40) / 1000);
        }
        else {
            rsettrees(r, 2, 0);
        }
        rsettrees(r, 1, rtrees(r, 2) / 4);
        rsettrees(r, 0, rtrees(r, 2) / 8);

        if (!fval(r, RF_CHAOTIC)) {
            int peasants;
            peasants = (maxworkingpeasants(r) * (20 + dice_rand("6d10"))) / 100;
            rsetpeasants(r, _max(100, peasants));
            rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL,
                INT_MAX) + 1) + rng_int() % 5));
        }
    }
}