Beispiel #1
0
static int tolua_region_create(lua_State * L)
{
    int x = (int)tolua_tonumber(L, 1, 0);
    int y = (int)tolua_tonumber(L, 2, 0);
    const char *tname = tolua_tostring(L, 3, 0);
    if (tname) {
        plane *pl = findplane(x, y);
        const terrain_type *terrain = get_terrain(tname);
        region *r, *result;
        if (!terrain) {
            return 0;
        }

        assert(!pnormalize(&x, &y, pl));
        r = result = findregion(x, y);

        if (r != NULL && r->units != NULL) {
            /* TODO: error message */
            result = NULL;
        }
        else if (r == NULL) {
            result = new_region(x, y, pl, 0);
        }
        if (result) {
            terraform_region(result, terrain);
            if (result->land) {
                fix_demand(result);
            }
        }

        tolua_pushusertype(L, result, TOLUA_CAST "region");
        return 1;
    }
    return 0;
}
Beispiel #2
0
region *new_region(int x, int y, struct plane *pl, int uid)
{
    region *r;

    pnormalize(&x, &y, pl);
    r = rfindhash(x, y);

    if (r) {
        log_error("duplicate region discovered: %s(%d,%d)\n", regionname(r, NULL), x, y);
        if (r->units)
            log_error("duplicate region contains units\n");
        return r;
    }
    r = calloc(1, sizeof(region));
    r->x = x;
    r->y = y;
    r->uid = uid;
    r->age = 1;
    r->_plane = pl;
    rhash(r);
    hash_uid(r);
    if (last)
        addlist(&last, r);
    else
        addlist(&regions, r);
    last = r;
    assert(r->next == NULL);
    r->index = ++max_index;
    return r;
}
Beispiel #3
0
static void frame_regions(int age, const terrain_type * terrain)
{
    plane *hplane = get_homeplane();
    region *r = regions;
    for (r = regions; r; r = r->next) {
        plane *pl = rplane(r);
        direction_t d;
        if (r->age < age)
            continue;
        if (pl != hplane)
            continue;                 /* only do this on the main world */
        if (r->terrain == terrain)
            continue;

        for (d = 0; d != MAXDIRECTIONS; ++d) {
            region *rn = rconnect(r, d);
            if (rn == NULL) {
                int x = r->x + delta_x[d];
                int y = r->y + delta_y[d];
                pnormalize(&x, &y, pl);
                rn = new_region(x, y, pl, 0);
                terraform_region(rn, terrain);
                rn->age = r->age;
            }
        }
    }
}
Beispiel #4
0
/**
 ** GM: TERRAFORM <x> <y> <terrain>
 ** requires: permission-key "gmterf"
 **/
static void gm_terraform(const void *tnext, struct unit *u, struct order *ord)
{
  const struct plane *p = rplane(u->region);
  int x = rel_to_abs(p, u->faction, getint(), 0);
  int y = rel_to_abs(p, u->faction, getint(), 1);
  const char *c = getstrtoken();
  variant token;
  void **tokens = get_translations(u->faction->locale, UT_TERRAINS);
  region *r;
  pnormalize(&x, &y, p);
  r = findregion(x, y);

  if (r == NULL || p != rplane(r)) {
    mistake(u, ord, "region is in another plane.");
    return;
  } else {
    /* checking permissions */
    attrib *permissions = a_find(u->faction->attribs, &at_permissions);
    if (!permissions || !has_permission(permissions, atoi36("gmterf")))
      return;
  }

  if (findtoken(*tokens, c, &token) != E_TOK_NOMATCH) {
    const terrain_type *terrain = (const terrain_type *)token.v;
    terraform_region(r, terrain);
  }
}
Beispiel #5
0
/**
 ** GM: GATE <id> <x> <y>
 ** requires: permission-key "gmgate"
 **/
static void gm_gate(const void *tnext, struct unit * u, struct order *ord)
{
  const struct plane *pl = rplane(u->region);
  int id = getid();
  int x = rel_to_abs(pl, u->faction, getint(), 0);
  int y = rel_to_abs(pl, u->faction, getint(), 1);
  building *b = findbuilding(id);
  region *r;

  pnormalize(&x, &y, pl);
  r = findregion(x, y);
  if (b == NULL || r == NULL || pl != rplane(b->region) || pl != rplane(r)) {
    mistake(u, ord, "the unit cannot transform this building.");
    return;
  } else {
    /* checking permissions */
    attrib *permissions = a_find(u->faction->attribs, &at_permissions);
    if (permissions && has_permission(permissions, atoi36("gmgate"))) {
      remove_triggers(&b->attribs, "timer", &tt_gate);
      remove_triggers(&b->attribs, "create", &tt_unguard);
      if (r != b->region) {
        add_trigger(&b->attribs, "timer", trigger_gate(b, r));
        add_trigger(&b->attribs, "create", trigger_unguard(b));
        fset(b, BLD_UNGUARDED);
      }
    }
  }
}
Beispiel #6
0
static int tolua_distance(lua_State * L)
{
    int x1 = (int)tolua_tonumber(L, 1, 0);
    int y1 = (int)tolua_tonumber(L, 2, 0);
    int x2 = (int)tolua_tonumber(L, 3, 0);
    int y2 = (int)tolua_tonumber(L, 4, 0);
    plane *pl = (plane *)tolua_tousertype(L, 5, 0);
    int result;

    if (!pl)
        pl = get_homeplane();
    pnormalize(&x1, &y1, pl);
    pnormalize(&x2, &y2, pl);
    result = koor_distance(x1, y1, x2, y2);
    lua_pushinteger(L, result);
    return 1;
}
Beispiel #7
0
static int tolua_plane_normalize(lua_State * L)
{
    plane *self = (plane *)tolua_tousertype(L, 1, 0);
    int x = (int)tolua_tonumber(L, 2, 0);
    int y = (int)tolua_tonumber(L, 3, 0);
    pnormalize(&x, &y, self);
    lua_pushinteger(L, x);
    lua_pushinteger(L, y);
    return 2;
}
Beispiel #8
0
static int tolua_faction_normalize(lua_State * L)
{
    faction *f = (faction *)tolua_tousertype(L, 1, 0);
    region *r = (region *)tolua_tousertype(L, 2, 0);
    if (r) {
        plane *pl = rplane(r);
        int nx = r->x, ny = r->y;
        pnormalize(&nx, &ny, pl);
        adjust_coordinates(f, &nx, &ny, pl, r);
        tolua_pushnumber(L, (lua_Number)nx);
        tolua_pushnumber(L, (lua_Number)ny);
        return 2;
    }
    return 0;
}
Beispiel #9
0
static void oceans_around(region * r, region * rn[])
{
    int n;
    for (n = 0; n != MAXDIRECTIONS; ++n) {
        region *rx = rn[n];
        if (rx == NULL) {
            plane *pl = rplane(r);
            int x = r->x + delta_x[n];
            int y = r->y + delta_y[n];
            pnormalize(&x, &y, pl);
            rx = new_region(x, y, pl, 0);
            terraform_region(rx, newterrain(T_OCEAN));
            rn[n] = rx;
        }
    }
}
Beispiel #10
0
const char *write_regionname(const region * r, const faction * f, char *buffer,
    size_t size)
{
    char *buf = (char *)buffer;
    const struct locale *lang = f ? f->locale : 0;
    if (r == NULL) {
        strlcpy(buf, "(null)", size);
    }
    else {
        plane *pl = rplane(r);
        int nx = r->x, ny = r->y;
        pnormalize(&nx, &ny, pl);
        adjust_coordinates(f, &nx, &ny, pl, r);
        slprintf(buf, size, "%s (%d,%d)", rname(r, lang), nx, ny);
    }
    return buffer;
}
Beispiel #11
0
/* update_lighthouse: call this function whenever the size of a lighthouse changes
* it adds temporary markers to the surrounding regions.
* The existence of markers says nothing about the quality of the observer in
* the lighthouse, for this may change more frequently.
*/
void update_lighthouse(building * lh)
{
    if (is_building_type(lh->type, "lighthouse")) {
        region *r = lh->region;

        r->flags |= RF_LIGHTHOUSE;
        if (lh->size > 0) {
            int d = (int)log10(lh->size) + 1;
            int x;
            for (x = -d; x <= d; ++x) {
                int y;
                for (y = -d; y <= d; ++y) {
                    attrib *a;
                    region *r2;
                    int px = r->x + x, py = r->y + y;

                    pnormalize(&px, &py, rplane(r));
                    r2 = findregion(px, py);
                    if (!r2 || !fval(r2->terrain, SEA_REGION))
                        continue;
                    if (distance(r, r2) > d)
                        continue;
                    a = a_find(r2->attribs, &at_lighthouse);
                    while (a && a->type == &at_lighthouse) {
                        building *b = (building *)a->data.v;
                        if (b == lh)
                            break;
                        a = a->next;
                    }
                    if (!a) {
                        a = a_add(&r2->attribs, a_new(&at_lighthouse));
                        a->data.v = (void *)lh;
                    }
                }
            }
        }
    }
}
Beispiel #12
0
region *r_connect(const region * r, direction_t dir)
{
    region *result;
    int x, y;
#ifdef FAST_CONNECT
    region *rmodify = (region *)r;
    assert(dir >= 0 && dir < MAXDIRECTIONS);
    if (r->connect[dir])
        return r->connect[dir];
#endif
    assert(dir < MAXDIRECTIONS);
    x = r->x + delta_x[dir];
    y = r->y + delta_y[dir];
    pnormalize(&x, &y, rplane(r));
    result = rfindhash(x, y);
#ifdef FAST_CONNECT
    if (result) {
        rmodify->connect[dir] = result;
        result->connect[back[dir]] = rmodify;
    }
#endif
    return result;
}
Beispiel #13
0
int
random_neighbours(region * r, region_list ** rlist,
const terrain_type * (*terraformer) (direction_t))
{
    int nsize = 0;
    direction_t dir;
    for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
        region *rn = rconnect(r, dir);
        if (rn == NULL) {
            const terrain_type *terrain = terraformer(dir);
            plane *pl = rplane(r);
            int x = r->x + delta_x[dir];
            int y = r->y + delta_y[dir];
            pnormalize(&x, &y, pl);
            rn = new_region(x, y, pl, 0);
            terraform_region(rn, terrain);
            regionqueue_push(rlist, rn);
            if (rn->land) {
                ++nsize;
            }
        }
    }
    return nsize;
}
Beispiel #14
0
static void lua_paint_info(struct window *wnd, const struct state *st)
{
    struct lua_State *L = paint_state;
    int nx = st->cursor.x, ny = st->cursor.y;
    pnormalize(&nx, &ny, st->cursor.pl);
    lua_rawgeti(L, LUA_REGISTRYINDEX, paint_handle);
    lua_pushinteger(L, nx);
    lua_pushinteger(L, ny);
    if (lua_pcall(L, 2, 1, 0) != 0) {
        const char *error = lua_tostring(L, -1);
        log_error("paint function failed: %s\n", error);
        lua_pop(L, 1);
        tolua_error(L, TOLUA_CAST "event handler call failed", NULL);
    }
    else {
        const char *result = lua_tostring(L, -1);
        WINDOW *win = wnd->handle;
        int size = getmaxx(win) - 2;
        int line = 0, maxline = getmaxy(win) - 2;
        const char *str = result;
        wxborder(win);

        while (*str && line < maxline) {
            const char *end = strchr(str, '\n');
            if (!end)
                break;
            else {
                int bytes = (int)(end - str);
                if (bytes < size) bytes = size;
                mvwaddnstr(win, line++, 1, str, bytes);
                wclrtoeol(win);
                str = end + 1;
            }
        }
    }
}
Beispiel #15
0
kernel void sample_z(global int *cur_y,
		     global int *cur_z,
		     global int *cur_r,
		     global int *z_by_ry,
		     global int *z_col_sum,
		     global int *obs,
		     global float *rand, 
		     uint N, uint D, uint K, uint f_img_width,
		     float lambda, float epislon, float theta) {
  
  const uint V_SCALE = 0, H_SCALE = 1, V_TRANS = 2, H_TRANS = 3, NUM_TRANS = 4;
  uint h, w, new_index; // variables used in the for loop

  uint nth = get_global_id(0); // n is the index of data
  uint kth = get_global_id(1); // k is the index of features

  uint f_img_height = D / f_img_width;

  // calculate the prior probability of each cell is 1
  float on_prob_temp = (z_col_sum[kth] - cur_z[nth * K + kth]) / (float)N; 
  float off_prob_temp = 1 - (z_col_sum[kth] - cur_z[nth * K + kth]) / (float)N;

  // retrieve the transformation applied to this feature by this object
  int v_scale = cur_r[nth * (K * NUM_TRANS) + kth * NUM_TRANS + V_SCALE];
  int h_scale = cur_r[nth * (K * NUM_TRANS) + kth * NUM_TRANS + H_SCALE];
  int v_dist = cur_r[nth * (K * NUM_TRANS) + kth * NUM_TRANS + V_TRANS];
  int h_dist = cur_r[nth * (K * NUM_TRANS) + kth * NUM_TRANS + H_TRANS];
  int new_height = f_img_height + v_scale, new_width = f_img_width + h_scale;
  
  uint d, hh, ww;
  // extremely hackish way to calculate the likelihood
  for (d = 0; d < D; d++) {
    // if the kth feature can turn on a pixel at d
    if (cur_y[kth * D + d] == 1) {
      // unpack d into h and w and get new index
      h = d / f_img_width;
      w = d % f_img_width;

      for (hh = 0; hh < f_img_height; hh++) {
	for (ww = 0; ww < f_img_width; ww++) {
	  if ((int)round((float)hh / new_height * f_img_height) == h &
	      (int)round((float)ww / new_width * f_img_width) == w) {
	    new_index = ((v_dist + hh) % f_img_height) * f_img_width + (h_dist + ww) % f_img_width;
      
	    // then the corresponding observed pixel is at new_index
	    // so, if the observed pixel at new_index is on
	    if (obs[nth * D + new_index] == 1) {
	      // if the nth object previously has the kth feature
	      if (cur_z[nth * K + kth] == 1) {
		on_prob_temp *= 1 - pow(1 - lambda, z_by_ry[nth * D + new_index]) * (1 - epislon);
		off_prob_temp *= 1 - pow(1 - lambda, z_by_ry[nth * D + new_index] - 1) * (1 - epislon);
	      } else {
		on_prob_temp *= 1 - pow(1 - lambda, z_by_ry[nth * D + new_index] + 1) * (1 - epislon);
		off_prob_temp *= 1 - pow(1 - lambda, z_by_ry[nth * D + new_index]) * (1 - epislon);
	      }
	    } else {
	      on_prob_temp *= 1 - lambda;
	      off_prob_temp *= 1.0f;
	    }
	  } 
	}
      }
    }
  }
  
  //printf("index: %d post_on: %f post_off: %f\n", nth * K + kth, on_prob_temp, off_prob_temp);
  float post[2] = {on_prob_temp, off_prob_temp};
  uint labels[2] = {1, 0};
  pnormalize(post, 0, 2);
  //printf("before index: %d %f %f %d \n", nth * K + kth, post[0], post[1], cur_z[nth * K + kth]);
  cur_z[nth * K + kth] = sample(2, labels, post, 0, rand[nth * K + kth]);
  //printf("after index: %d %f %f %d \n", nth * K + kth, post[0], post[1], cur_z[nth * K + kth]);
}
Beispiel #16
0
/** create new island with up to nsize players
 * returns the number of players placed on the new island.
 */
int autoseed(newfaction ** players, int nsize, int max_agediff)
{
    region *r = NULL;
    region_list *rlist = NULL;
    int rsize = 0, tsize = 0;
    int isize = REGIONS_PER_FACTION;      /* target size for the island */
    int psize = 0;                /* players on this island */
    const terrain_type *volcano_terrain = get_terrain("volcano");
    static int nterrains = -1;
    static const terrain_type **terrainarr = 0;
    static int *distribution;

    assert(players);
    if (nterrains < 0) {
        int n = 0;
        const terrain_type *terrain = terrains();
        for (nterrains = 0; terrain; terrain = terrain->next) {
            if (terrain->distribution) {
                ++nterrains;
            }
        }
        terrainarr = malloc(sizeof(terrain_type *) * nterrains);
        distribution = malloc(sizeof(int) * nterrains);
        for (terrain = terrains(); terrain; terrain = terrain->next) {
            if (terrain->distribution) {
                terrainarr[n] = terrain;
                distribution[n++] = terrain->distribution;
            }
        }
    }
    frame_regions(16, newterrain(T_FIREWALL));

    if (listlen(*players) < MINFACTIONS)
        return 0;

    if (max_agediff > 0) {
        region *rmin = NULL;
        plane *hplane = get_homeplane();
        /* find a spot that's adjacent to the previous island, but virgin.
         * like the last land virgin ocean region adjacent to land.
         */
        for (r = regions; r; r = r->next) {
            struct plane *pl = rplane(r);
            if (r->age <= max_agediff && r->terrain == newterrain(T_OCEAN)
                && pl == hplane && virgin_region(r)) {
                direction_t d;
                for (d = 0; d != MAXDIRECTIONS; ++d) {
                    region *rn = rconnect(r, d);
                    if (rn && rn->land && rn->age <= max_agediff && virgin_region(rn)) {
                        /* only expand islands that aren't single-islands and not too big already */
                        int size, inhabitants, maxage;
                        get_island_info(rn, &size, &inhabitants, &maxage);
                        if (maxage <= max_agediff && size >= 2 && size < MAXISLANDSIZE) {
                            rmin = rn;
                            break;
                        }
                    }
                }
            }
        }
        if (rmin != NULL) {
            faction *f;
            quicklist *ql, *rlist = get_island(rmin);
            int qi;

            for (ql = rlist, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
                region *r = (region *)ql_get(ql, qi);
                unit *u;
                for (u = r->units; u; u = u->next) {
                    f = u->faction;
                    if (!fval(f, FFL_MARK)) {
                        ++psize;
                        fset(f, FFL_MARK);
                    }
                }
            }
            ql_free(rlist);
            if (psize > 0) {
                for (f = factions; f; f = f->next) {
                    freset(f, FFL_MARK);
                }
            }
            if (psize < PLAYERS_PER_ISLAND) {
                r = rmin;
            }
        }
    }
    if (r == NULL) {
        region *rmin = NULL;
        direction_t dmin = MAXDIRECTIONS;
        plane *hplane = get_homeplane();
        /* find an empty spot.
         * rmin = the youngest ocean region that has a missing neighbour
         * dmin = direction in which it's empty
         */
        for (r = regions; r; r = r->next) {
            struct plane *pl = rplane(r);
            if (r->terrain == newterrain(T_OCEAN) && pl == hplane && (rmin == NULL
                || r->age <= max_agediff)) {
                direction_t d;
                for (d = 0; d != MAXDIRECTIONS; ++d) {
                    region *rn = rconnect(r, d);
                    if (rn == NULL)
                        break;
                }
                if (d != MAXDIRECTIONS) {
                    rmin = r;
                    dmin = d;
                }
            }
        }

        /* create a new region where we found the empty spot, and make it the first
         * in our island. island regions are kept in rlist, so only new regions can
         * get populated, and old regions are not overwritten */
        if (rmin != NULL) {
            plane *pl = rplane(rmin);
            int x = rmin->x + delta_x[dmin];
            int y = rmin->y + delta_y[dmin];
            pnormalize(&x, &y, pl);
            assert(virgin_region(rconnect(rmin, dmin)));
            r = new_region(x, y, pl, 0);
            terraform_region(r, newterrain(T_OCEAN));
        }
    }
    if (r != NULL) {
        add_regionlist(&rlist, r);
        fset(r, RF_MARK);
        rsize = 1;
    }

    while (rsize && (nsize || isize >= REGIONS_PER_FACTION)) {
        int i = rng_int() % rsize;
        region_list **rnext = &rlist;
        region_list *rfind;
        direction_t d;
        while (i--)
            rnext = &(*rnext)->next;
        rfind = *rnext;
        r = rfind->data;
        freset(r, RF_MARK);
        *rnext = rfind->next;
        free(rfind);
        --rsize;
        for (d = 0; d != MAXDIRECTIONS; ++d) {
            region *rn = rconnect(r, d);
            if (rn && fval(rn, RF_MARK))
                continue;
            if (rn == NULL) {
                plane *pl = rplane(r);
                int x = r->x + delta_x[d];
                int y = r->y + delta_y[d];
                pnormalize(&x, &y, pl);
                rn = new_region(x, y, pl, 0);
                terraform_region(rn, newterrain(T_OCEAN));
            }
            if (virgin_region(rn)) {
                add_regionlist(&rlist, rn);
                fset(rn, RF_MARK);
                ++rsize;
            }
        }
        if (volcano_terrain != NULL && (rng_int() % VOLCANO_CHANCE == 0)) {
            terraform_region(r, volcano_terrain);
        }
        else if (nsize && (rng_int() % isize == 0 || rsize == 0)) {
            newfaction **nfp, *nextf = *players;
            faction *f;
            unit *u;

            isize += REGIONS_PER_FACTION;
            terraform_region(r, preferred_terrain(nextf->race));
            prepare_starting_region(r);
            ++tsize;
            assert(r->land && r->units == 0);
            u = addplayer(r, addfaction(nextf->email, nextf->password, nextf->race,
                nextf->lang, nextf->subscription));
            f = u->faction;
            fset(f, FFL_ISNEW);
            f->alliance = nextf->allies;

            /* remove duplicate email addresses */
            nfp = &nextf->next;
            while (*nfp) {
                newfaction *nf = *nfp;
                if (strcmp(nextf->email, nf->email) == 0) {
                    *nfp = nf->next;
                    free_newfaction(nf);
                }
                else
                    nfp = &nf->next;
            }
            *players = nextf->next;
            free_newfaction(nextf);

            ++psize;
            --nsize;
            --isize;
            if (psize >= PLAYERS_PER_ISLAND)
                break;
        }
        else {
            terraform_region(r, random_terrain(terrainarr, distribution, nterrains));
            --isize;
        }
    }

    if (nsize != 0) {
        log_error(
            ("Could not place all factions on the same island as requested\n"));
    }

    if (rlist) {
#define MINOCEANDIST 3
#define MAXOCEANDIST 6
#define MAXFILLDIST 10
#define SPECIALCHANCE 80
        region_list **rbegin = &rlist;
        int special = 1;
        int oceandist = MINOCEANDIST + (rng_int() % (MAXOCEANDIST - MINOCEANDIST));
        while (oceandist--) {
            region_list **rend = rbegin;
            while (*rend)
                rend = &(*rend)->next;
            while (rbegin != rend) {
                direction_t d;
                region *r = (*rbegin)->data;
                rbegin = &(*rbegin)->next;
                for (d = 0; d != MAXDIRECTIONS; ++d) {
                    region *rn = rconnect(r, d);
                    if (rn == NULL) {
                        const struct terrain_type *terrain = newterrain(T_OCEAN);
                        plane *pl = rplane(r);
                        int x = r->x + delta_x[d];
                        int y = r->y + delta_y[d];
                        pnormalize(&x, &y, pl);
                        rn = new_region(x, y, pl, 0);
                        if (rng_int() % SPECIALCHANCE < special) {
                            terrain = random_terrain(terrainarr, distribution, nterrains);
                            special = SPECIALCHANCE / 3;      /* 33% chance auf noch eines */
                        }
                        else {
                            special = 1;
                        }
                        terraform_region(rn, terrain);
                        /* the new region has an extra 20% chance to have mallorn */
                        if (rng_int() % 100 < 20)
                            fset(r, RF_MALLORN);
                        add_regionlist(rend, rn);
                    }
                }
            }

        }
        while (*rbegin) {
            region *r = (*rbegin)->data;
            plane *pl = rplane(r);
            direction_t d;
            rbegin = &(*rbegin)->next;
            for (d = 0; d != MAXDIRECTIONS; ++d)
                if (rconnect(r, d) == NULL) {
                    int i;
                    for (i = 1; i != MAXFILLDIST; ++i) {
                        int x = r->x + delta_x[d] * i;
                        int y = r->y + delta_y[d] * i;
                        pnormalize(&x, &y, pl);
                        if (findregion(x, y)) {
                            break;
                        }
                    }
                    if (i != MAXFILLDIST) {
                        while (--i) {
                            region *rn;
                            int x = r->x + delta_x[d] * i;
                            int y = r->y + delta_y[d] * i;
                            pnormalize(&x, &y, pl);
                            rn = new_region(x, y, pl, 0);
                            terraform_region(rn, newterrain(T_OCEAN));
                        }
                    }
                }
        }
        while (rlist) {
            region_list *self = rlist;
            rlist = rlist->next;
            freset(self->data, RF_MARK);
            free(self);
        }
    }
    return tsize;
}