Example #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);
    }
}
Example #2
0
struct region *test_create_region(int x, int y, const terrain_type *terrain)
{
  region *r = new_region(x, y, NULL, 0);
  terraform_region(r, terrain);
  rsettrees(r, 0, 0);
  rsettrees(r, 1, 0);
  rsettrees(r, 2, 0);
  rsethorses(r, 0);
  rsetpeasants(r, terrain->size);
  return r;
}
Example #3
0
static void
volcano_destruction(region * volcano, region * r, region * rn,
  const char *damage)
{
  attrib *a;
  unit **up;
  int percent = 25, time = 6 + rng_int() % 12;

  rsettrees(r, 2, 0);
  rsettrees(r, 1, 0);
  rsettrees(r, 0, 0);

  a = a_find(r->attribs, &at_reduceproduction);
  if (!a) {
    a = make_reduceproduction(percent, time);
  } else {
    /* Produktion vierteln ... */
    a->data.sa[0] = (short)percent;
    /* Für 6-17 Runden */
    a->data.sa[1] = (short)(a->data.sa[1] + time);
  }

  /* Personen bekommen 4W10 Punkte Schaden. */

  for (up = &r->units; *up;) {
    unit *u = *up;
    if (u->number) {
      int dead = damage_unit(u, damage, true, false);
      if (dead) {
        ADDMSG(&u->faction->msgs, msg_message("volcano_dead",
            "unit region dead", u, volcano, dead));
      }
      if (r == volcano && !fval(u->faction, FFL_SELECT)) {
        fset(u->faction, FFL_SELECT);
        if (rn) {
          ADDMSG(&u->faction->msgs, msg_message("volcanooutbreak",
              "regionv regionn", r, rn));
        } else {
          ADDMSG(&u->faction->msgs, msg_message("volcanooutbreaknn",
              "region", r));
        }
      }
    }
    if (u == *up)
      up = &u->next;
  }

  remove_empty_units_in_region(r);
}
Example #4
0
static int tolua_region_set_resource(lua_State * L)
{
    region *r = (region *)tolua_tousertype(L, 1, 0);
    const char *type = tolua_tostring(L, 2, 0);
    int result, value = (int)tolua_tonumber(L, 3, 0);
    critbit_tree * cb = special_resources();
    void * match;

    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:
            rsettrees(r, result, value);
            break;
        case 3:
            deathcounts(r, value - deathcount(r));
            break;
        case 4:
            add_chaoscount(r, value - get_chaoscount(r));
            break;
        }
    }
    else {
        const resource_type *rtype = rt_find(type);
        if (rtype != NULL) {
            region_setresource(r, rtype, value);
        }
    }
    return 0;
}
Example #5
0
static void test_cr_mallorn(CuTest *tc) {
    stream strm;
    char line[1024];
    faction *f;
    region *r;
    
    setup_resources();

    f = test_create_faction(NULL);
    r = test_create_region(0, 0, NULL);
    r->land->horses = 1;
    r->land->peasants = 200;
    r->land->money = 300;
    r->flags |= RF_MALLORN;
    rsettrees(r, 0, 1);
    rsettrees(r, 1, 2);
    rsettrees(r, 2, 3);

    mstream_init(&strm);
    cr_output_resources(&strm, f, r, false);
    strm.api->rewind(strm.handle);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "3;Baeume", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "2;Schoesslinge", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "1;Mallorn", line);

    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9));
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "\"Mallornschoesslinge\";type", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "2;number", line);

    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9));
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "\"Mallorn\";type", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "3;number", line);

    mstream_done(&strm);
    test_teardown();
}
Example #6
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;
}
Example #7
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();
}
Example #8
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));
        }
    }
}
Example #9
0
static void test_cr_resources(CuTest *tc) {
    stream strm;
    char line[1024];
    faction *f;
    region *r;
    unit *u;

    setup_resources();

    f = test_create_faction(NULL);
    r = test_create_region(0, 0, NULL);
    u = test_create_unit(f, r);
    set_level(u, SK_QUARRYING, 1);
    r->land->horses = 1;
    r->land->peasants = 200;
    r->land->money = 300;
    rsettrees(r, 0, 1);
    rsettrees(r, 1, 2);
    rsettrees(r, 2, 3);
    region_setresource(r, get_resourcetype(R_STONE), 1);

    mstream_init(&strm);
    cr_output_resources(&strm, f, r, true);
    strm.api->rewind(strm.handle);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "3;Baeume", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "2;Schoesslinge", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "1;Steine", line);

    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9));
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "\"Schoesslinge\";type", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "2;number", line);

    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9));
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "\"Blumen\";type", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "3;number", line);

    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9));
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "\"Silber\";type", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "300;number", line);

    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9));
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "\"Bauern\";type", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "200;number", line);

    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9));
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "\"Pferde\";type", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "1;number", line);

    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertIntEquals(tc, 0, memcmp(line, "RESOURCE ", 9));
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "\"Steine\";type", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "1;skill", line);
    CuAssertIntEquals(tc, 0, strm.api->readln(strm.handle, line, sizeof(line)));
    CuAssertStrEquals(tc, "1;number", line);

    mstream_done(&strm);
    test_teardown();
}