Пример #1
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;
}
Пример #2
0
static void smooth_island(region_list * island)
{
    region *rn[MAXDIRECTIONS];
    region_list *rlist = NULL;
    for (rlist = island; rlist; rlist = rlist->next) {
        region *r = rlist->data;
        int n, nland = 0;

        if (r->land) {
            get_neighbours(r, rn);
            for (n = 0; n != MAXDIRECTIONS && nland <= 1; ++n) {
                if (rn[n]->land) {
                    ++nland;
                    r = rn[n];
                }
            }

            if (nland == 1) {
                get_neighbours(r, rn);
                oceans_around(r, rn);
                for (n = 0; n != MAXDIRECTIONS; ++n) {
                    int n1 = (n + 1) % MAXDIRECTIONS;
                    int n2 = (n + 1 + MAXDIRECTIONS) % MAXDIRECTIONS;
                    if (!rn[n]->land && rn[n1] != r && rn[n2] != r) {
                        r = rlist->data;
                        runhash(r);
                        runhash(rn[n]);
                        SWAP_INTS(r->x, rn[n]->x);
                        SWAP_INTS(r->y, rn[n]->y);
                        rhash(r);
                        rhash(rn[n]);
                        rlist->data = r;
                        oceans_around(r, rn);
                        break;
                    }
                }
            }
        }
    }
}
Пример #3
0
Файл: rip.c Проект: aahud/harvey
/*
 *  pass a route to the kernel or /ip.  Don't bother if it is just the default
 *  gateway.
 */
void
installroute(Route *r)
{
	int fd;
	uint32_t h;
	Route *hp;
	uint8_t net[Pasize];

	/*
	 *  don't install routes whose gateway is 00000000
	 */
	if(equivip(r->gate, ralloc.def.dest))
		return;

	fd = open(routefile, ORDWR);
	if(fd < 0){
		fprint(2, "can't open oproute\n");
		return;
	}
	h = rhash(r->dest);

	/*
	 *  if the gateway is the same as the default gateway
	 *  we may be able to avoid a entry in the kernel
	 */
	if(equivip(r->gate, ralloc.def.gate)){
		/*
		 *  look for a less specific match
		 */
		for(hp = ralloc.hash[h]; hp; hp = hp->next){
			v4maskip(hp->mask, r->dest, net);
			if(equivip(net, hp->dest) && !equivip(hp->gate, ralloc.def.gate))
				break;
		}
		/*
		 *  if no less specific match, just use the default
		 */
		if(hp == 0){
			if(!readonly)
				fprint(fd, "delete %V", r->dest);
			if(debug)
				fprint(2, "delete %V\n", r->dest);
			close(fd);
			return;
		}
	}
	if(!readonly)
		fprint(fd, "add %V %V %V", r->dest, r->mask, r->gate);
	if(debug)
		fprint(2, "add %V & %V -> %V\n", r->dest, r->mask, r->gate);
	close(fd);
}
Пример #4
0
Файл: rip.c Проект: aahud/harvey
/*
 *  consider installing a route.  Do so only if it is better than what
 *  we have.
 */
void
considerroute(Route *r)
{
	uint32_t h;
	Route *hp;

	if(debug)
		fprint(2, "consider %16V & %16V -> %16V %d\n", r->dest, r->mask, r->gate, r->metric);

	r->next = 0;
	r->time = now;
	r->inuse = 1;

	/* don't allow our default route to be highjacked */
	if(equivip(r->dest, ralloc.def.dest) || equivip(r->mask, ralloc.def.mask))
		return;

	h = rhash(r->dest);
	for(hp = ralloc.hash[h]; hp; hp = hp->next){
		if(equivip(hp->dest, r->dest)){
			/*
			 *  found a match, replace if better (or much newer)
			 */
			if(r->metric < hp->metric || now-hp->time > 5*60){
				removeroute(hp);
				memmove(hp->mask, r->mask, Pasize);
				memmove(hp->gate, r->gate, Pasize);
				hp->metric = r->metric;
				installroute(hp);
			}
			if(equivip(hp->gate, r->gate))
				hp->time = now;
			return;
		}
	}

	/*
	 *  no match, look for space
	 */
	for(hp = ralloc.route; hp < &ralloc.route[Nroute]; hp++)
		if(hp->inuse == 0)
			break;

	if(hp == 0)
		fatal(0, "no more routes");

	memmove(hp, r, sizeof(Route));
	hp->next = ralloc.hash[h];
	ralloc.hash[h] = hp;
	installroute(hp);
}
Пример #5
0
static void move_iceberg(region * r)
{
  attrib *a;
  direction_t dir;
  region *rc;

  a = a_find(r->attribs, &at_iceberg);
  if (!a) {
    dir = (direction_t) (rng_int() % MAXDIRECTIONS);
    a = a_add(&r->attribs, make_iceberg(dir));
  } else {
    if (rng_int() % 100 < 20) {
      dir = (direction_t) (rng_int() % MAXDIRECTIONS);
      a->data.i = dir;
    } else {
      dir = (direction_t) a->data.i;
    }
  }

  rc = rconnect(r, dir);

  if (rc && !fval(rc->terrain, ARCTIC_REGION)) {
    if (fval(rc->terrain, SEA_REGION)) {        /* Eisberg treibt */
      ship *sh, *shn;
      unit *u;
      int x, y;

      for (u = r->units; u; u = u->next)
        freset(u->faction, FFL_SELECT);
      for (u = r->units; u; u = u->next)
        if (!fval(u->faction, FFL_SELECT)) {
          fset(u->faction, FFL_SELECT);
          ADDMSG(&u->faction->msgs, msg_message("iceberg_drift",
              "region dir", r, dir));
        }

      x = r->x;
      y = r->y;

      runhash(r);
      runhash(rc);
      r->x = rc->x;
      r->y = rc->y;
      rc->x = x;
      rc->y = y;
      rhash(rc);
      rhash(r);

      /* rc ist der Ozean (Ex-Eisberg), r der Eisberg (Ex-Ozean) */

      /* Schiffe aus dem Zielozean werden in den Eisberg transferiert
       * und nehmen Schaden. */

      for (sh = r->ships; sh; sh = sh->next)
        freset(sh, SF_SELECT);

      for (sh = r->ships; sh; sh = sh->next) {
        /* Meldung an Kapitän */
        float dmg =
          get_param_flt(global.parameters, "rules.ship.damage.intoiceberg",
          0.10F);
        damage_ship(sh, dmg);
        fset(sh, SF_SELECT);
      }

      /* Personen, Schiffe und Gebäude verschieben */
      while (rc->buildings) {
        rc->buildings->region = r;
        translist(&rc->buildings, &r->buildings, rc->buildings);
      }
      while (rc->ships) {
        float dmg =
          get_param_flt(global.parameters, "rules.ship.damage.withiceberg",
          0.10F);
        fset(rc->ships, SF_SELECT);
        damage_ship(rc->ships, dmg);
        move_ship(rc->ships, rc, r, NULL);
      }
      while (rc->units) {
        building *b = rc->units->building;
        u = rc->units;
        u->building = 0; /* prevent leaving in move_unit */
        move_unit(rc->units, r, NULL);
        u_set_building(u, b); /* undo leave-prevention */
      }

      /* Beschädigte Schiffe können sinken */

      for (sh = r->ships; sh;) {
        shn = sh->next;
        if (fval(sh, SF_SELECT)) {
          u = ship_owner(sh);
          if (sh->damage >= sh->size * DAMAGE_SCALE) {
            if (u != NULL) {
              ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg_des",
                  "ship", sh));
            }
            remove_ship(&sh->region->ships, sh);
          } else if (u != NULL) {
            ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg",
                "ship", sh));
          }
        }
        sh = shn;
      }

    } else if (rng_int() % 100 < 20) {  /* Eisberg bleibt als Gletscher liegen */
      unit *u;

      rsetterrain(r, T_GLACIER);
      a_remove(&r->attribs, a);

      for (u = r->units; u; u = u->next)
        freset(u->faction, FFL_SELECT);
      for (u = r->units; u; u = u->next)
        if (!fval(u->faction, FFL_SELECT)) {
          fset(u->faction, FFL_SELECT);
          ADDMSG(&u->faction->msgs, msg_message("iceberg_land", "region", r));
        }
    }
  }
}