Example #1
0
bool InfHex8::contains_point (const Point& p, Real tol) const
{
  /*
   * For infinite elements with linear base interpolation:
   *
   * make use of the fact that infinite elements do not
   * live inside the envelope.  Use a fast scheme to
   * check whether point \p p is inside or outside
   * our relevant part of the envelope.  Note that
   * this is not exclusive: only when the distance is less,
   * we are safe.  Otherwise, we cannot say anything. The
   * envelope may be non-spherical, the physical point may lie
   * inside the envelope, outside the envelope, or even inside
   * this infinite element.  Therefore if this fails,
   * fall back to the FEInterface::inverse_map()
   */
  const Point my_origin (this->origin());

  /*
   * determine the minimal distance of the base from the origin
   * Use size_sq() instead of size(), it is faster
   */
  const Real min_distance_sq = std::min((Point(this->point(0)-my_origin)).size_sq(),
                                        std::min((Point(this->point(1)-my_origin)).size_sq(),
                                                 std::min((Point(this->point(2)-my_origin)).size_sq(),
                                                          (Point(this->point(3)-my_origin)).size_sq())));

  /*
   * work with 1% allowable deviation.  We can still fall
   * back to the InfFE::inverse_map()
   */
  const Real conservative_p_dist_sq = 1.01 * (Point(p-my_origin).size_sq());



  if (conservative_p_dist_sq < min_distance_sq)
    {
      /*
       * the physical point is definitely not contained in the element
       */
      return false;
    }
  else
    {
      /*
       * Declare a basic FEType.  Will use default in the base,
       * and something else (not important) in radial direction.
       */
      FEType fe_type(default_order());

      const Point mapped_point = FEInterface::inverse_map(dim(),
                                                          fe_type,
                                                          this,
                                                          p,
                                                          tol,
                                                          false);

      return FEInterface::on_reference_element(mapped_point, this->type(), tol);
    }
}
Example #2
0
  BASKER_INLINE
  int Basker<Int, Entry, Exe_Space>::Order(Int option)
  {

    //Option = 0, FAIL NATURAL WITHOUT BOX
    //Option = 1, BASKER Standard
    //Option = 2, BTF BASKER

    if(option == 1)
      {	
	default_order();
      }
    else if(option == 2)
      {
	//printf("btf_order called \n");
	btf_order();
	//printf("btf_order returned \n");
      }
    else
      {
	printf("\n\n ERROR---No Order Selected \n\n");
	return -1;
      }

    basker_barrier.init(num_threads, 16, tree.nlvls );

    order_flag = true;
    return 0;
  }//end Order()
Example #3
0
unit *addplayer(region * r, faction * f)
{
    unit *u;
    const char * name;

    assert(r->land);
    if (rpeasants(r) < PEASANT_MIN) {
        rsetpeasants(r, PEASANT_MIN + rng_int() % (PEASANT_MAX - PEASANT_MIN));
    }

    assert(f->units == NULL);
    faction_setorigin(f, 0, r->x, r->y);
    u = create_unit(r, f, 1, f->race, 0, NULL, NULL);
    u->thisorder = default_order(f->locale);
    unit_addorder(u, copy_order(u->thisorder));
    name = config_get("rules.equip_first");
    if (!equip_unit(u, name ? name : "first_unit")) {
        /* give every unit enough money to survive the first turn */
        i_change(&u->items, get_resourcetype(R_SILVER)->itype, maintenance_cost(u));
    }
    u->hp = unit_max_hp(u) * u->number;
    fset(u, UFL_ISNEW);
    if (f->race == get_race(RC_DAEMON)) {
        race_t urc;
        const race *rc;
        do {
            urc = (race_t)(rng_int() % MAXRACES);
            rc = get_race(urc);
        } while (rc == NULL || urc == RC_DAEMON || !playerrace(rc));
        u->irace = rc;
    }
    f->lastorders = 0;
    return u;
}
Example #4
0
bool InfQuad4::contains_point (const Point& p, Real tol) const
{
  /*
   * make use of the fact that infinite elements do not
   * live inside the envelope.  Use a fast scheme to
   * check whether point \p p is inside or outside
   * our relevant part of the envelope.  Note that
   * this is not exclusive: the point may be outside
   * the envelope, but contained in another infinite element.
   * Therefore, if the distance is greater, do fall back
   * to the scheme of using FEInterface::inverse_map().
   */
  const Point origin (this->origin());

  /*
   * determine the minimal distance of the base from the origin
   * use size_sq() instead of size(), it is slightly faster
   */
  const Real min_distance_sq = std::min((Point(this->point(0)-origin)).size_sq(),
					(Point(this->point(1)-origin)).size_sq());

  /*
   * work with 1% allowable deviation.  Can still fall
   * back to the InfFE::inverse_map()
   */
  const Real conservative_p_dist_sq = 1.01 * (Point(p-origin).size_sq());

  if (conservative_p_dist_sq < min_distance_sq)
    {
      /*
       * the physical point is definitely not contained
       * in the element, return false.
       */
      return false;
    }
  else
    {
      /*
       * cannot say anything, fall back to the FEInterface::inverse_map()
       *
       * Declare a basic FEType.  Will use default in the base,
       * and something else (not important) in radial direction.
       */
      FEType fe_type(default_order());

      const Point mapped_point = FEInterface::inverse_map(dim(),
							  fe_type,
							  this,
							  p,
							  tol,
							  false);

      return FEInterface::on_reference_element(mapped_point, this->type(), tol);
    }
}
    // Note that left/right do NOT correspond to m_geometry1/m_geometry2
    // but to the "indexed_turn_operation"
    inline bool operator()(Indexed const& left, Indexed const& right) const
    {
        if (! (left.subject->seg_id == right.subject->seg_id))
        {
            return left.subject->seg_id < right.subject->seg_id;
        }

        // Both left and right are located on the SAME segment.

        if (! (left.subject->fraction == right.subject->fraction))
        {
            return left.subject->fraction < right.subject->fraction;
        }


        typedef typename boost::range_value<Turns>::type turn_type;
        turn_type const& left_turn = m_turns[left.turn_index];
        turn_type const& right_turn = m_turns[right.turn_index];

        // First check "real" intersection (crosses)
        // -> distance zero due to precision, solve it by sorting
        if (left_turn.method == method_crosses
            && right_turn.method == method_crosses)
        {
            return consider_relative_order(left, right);
        }

        bool const left_both_xx = left_turn.both(operation_blocked);
        bool const right_both_xx = right_turn.both(operation_blocked);
        if (left_both_xx && ! right_both_xx)
        {
            return true;
        }
        if (! left_both_xx && right_both_xx)
        {
            return false;
        }

        bool const left_both_uu = left_turn.both(operation_union);
        bool const right_both_uu = right_turn.both(operation_union);
        if (left_both_uu && ! right_both_uu)
        {
            return true;
        }
        if (! left_both_uu && right_both_uu)
        {
            return false;
        }

        return default_order(left, right);
    }
    inline bool consider_relative_order(Indexed const& left,
                    Indexed const& right) const
    {
        point_type pi, pj, ri, rj, si, sj;

        geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
            left.subject->seg_id,
            pi, pj);
        geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
            *left.other_seg_id,
            ri, rj);
        geometry::copy_segment_points<Reverse1, Reverse2>(m_geometry1, m_geometry2,
            *right.other_seg_id,
            si, sj);

        int const side_rj_p = m_strategy.apply(pi, pj, rj);
        int const side_sj_p = m_strategy.apply(pi, pj, sj);

        // Put the one turning left (1; right == -1) as last
        if (side_rj_p != side_sj_p)
        {
            return side_rj_p < side_sj_p;
        }

        int const side_sj_r = m_strategy.apply(ri, rj, sj);
        int const side_rj_s = m_strategy.apply(si, sj, rj);

        // If they both turn left: the most left as last
        // If they both turn right: this is not relevant, but take also here most left
        if (side_rj_s != side_sj_r)
        {
            return side_rj_s < side_sj_r;
        }

        return default_order(left, right);
    }
Example #7
0
/** creates a new unit.
*
* @param dname: name, set to NULL to get a default.
* @param creator: unit to inherit stealth, group, building, ship, etc. from
*/
unit *create_unit(region * r, faction * f, int number, const struct race *urace,
  int id, const char *dname, unit * creator)
{
  unit *u = (unit *)calloc(1, sizeof(unit));

  assert(urace);
  if (f) {
    assert(f->alive);
    u_setfaction(u, f);

    if (f->locale) {
      order *deford = default_order(f->locale);
      if (deford) {
        set_order(&u->thisorder, NULL);
        addlist(&u->orders, deford);
      }
    }
  }
  u_seteffstealth(u, -1);
  u_setrace(u, urace);
  u->irace = NULL;

  set_number(u, number);

  /* die nummer der neuen einheit muss vor name_unit generiert werden,
   * da der default name immer noch 'Nummer u->no' ist */
  createunitid(u, id);

  /* zuerst in die Region setzen, da zb Drachennamen den Regionsnamen
   * enthalten */
  if (r)
    move_unit(u, r, NULL);

  /* u->race muss bereits gesetzt sein, wird für default-hp gebraucht */
  /* u->region auch */
  u->hp = unit_max_hp(u) * number;

  if (!dname) {
    name_unit(u);
  } else {
    u->name = _strdup(dname);
  }

  if (creator) {
    attrib *a;

    /* erbt Kampfstatus */
    setstatus(u, creator->status);

    /* erbt Gebäude/Schiff */
    if (creator->region == r) {
      if (creator->building) {
        u_set_building(u, creator->building);
      }
      if (creator->ship && fval(u_race(u), RCF_CANSAIL)) {
        u_set_ship(u, creator->ship);
      }
    }

    /* Tarnlimit wird vererbt */
    if (fval(creator, UFL_STEALTH)) {
      attrib *a = a_find(creator->attribs, &at_stealth);
      if (a) {
        int stealth = a->data.i;
        a = a_add(&u->attribs, a_new(&at_stealth));
        a->data.i = stealth;
      }
    }

    /* Temps von parteigetarnten Einheiten sind wieder parteigetarnt */
    if (fval(creator, UFL_ANON_FACTION)) {
      fset(u, UFL_ANON_FACTION);
    }
    /* Daemonentarnung */
    set_racename(&u->attribs, get_racename(creator->attribs));
    if (fval(u_race(u), RCF_SHAPESHIFT) && fval(u_race(creator), RCF_SHAPESHIFT)) {
      u->irace = creator->irace;
    }

    /* Gruppen */
    if (creator->faction == f && fval(creator, UFL_GROUP)) {
      a = a_find(creator->attribs, &at_group);
      if (a) {
        group *g = (group *) a->data.v;
        set_group(u, g);
      }
    }
    a = a_find(creator->attribs, &at_otherfaction);
    if (a) {
      a_add(&u->attribs, make_otherfaction(get_otherfaction(a)));
    }

    a = a_add(&u->attribs, a_new(&at_creator));
    a->data.v = creator;
  }

  return u;
}
Example #8
0
bool InfHex::contains_point (const Point & p, Real tol) const
{
  // For infinite elements with linear base interpolation:
  // make use of the fact that infinite elements do not
  // live inside the envelope.  Use a fast scheme to
  // check whether point \p p is inside or outside
  // our relevant part of the envelope.  Note that
  // this is not exclusive: only when the distance is less,
  // we are safe.  Otherwise, we cannot say anything. The
  // envelope may be non-spherical, the physical point may lie
  // inside the envelope, outside the envelope, or even inside
  // this infinite element.  Therefore if this fails,
  // fall back to the FEInterface::inverse_map()
  const Point my_origin (this->origin());

  // determine the minimal distance of the base from the origin
  // Use norm_sq() instead of norm(), it is faster
  Point pt0_o(this->point(0) - my_origin);
  Point pt1_o(this->point(1) - my_origin);
  Point pt2_o(this->point(2) - my_origin);
  Point pt3_o(this->point(3) - my_origin);
  const Real min_distance_sq = std::min(pt0_o.norm_sq(),
                                        std::min(pt1_o.norm_sq(),
                                                 std::min(pt2_o.norm_sq(),
                                                          pt3_o.norm_sq())));

  // work with 1% allowable deviation.  We can still fall
  // back to the InfFE::inverse_map()
  const Real conservative_p_dist_sq = 1.01 * (Point(p - my_origin).norm_sq());



  if (conservative_p_dist_sq < min_distance_sq)
    {
      // the physical point is definitely not contained in the element
      return false;
    }

  // this captures the case that the point is not (almost) in the direction of the element.:
  // first, project the problem onto the unit sphere:
  Point p_o(p - my_origin);
  pt0_o /= pt0_o.norm();
  pt1_o /= pt1_o.norm();
  pt2_o /= pt2_o.norm();
  pt3_o /= pt3_o.norm();
  p_o /= p_o.norm();


  // now, check if it is in the projected face; using that the diagonal contains
  // the largest distance between points in it
  Real max_h = std::max((pt0_o - pt2_o).norm_sq(),
                        (pt1_o - pt2_o).norm_sq())*1.01;

  if ((p_o - pt0_o).norm_sq() > max_h ||
      (p_o - pt1_o).norm_sq() > max_h ||
      (p_o - pt2_o).norm_sq() > max_h ||
      (p_o - pt3_o).norm_sq() > max_h )
    {
      // the physical point is definitely not contained in the element
      return false;
    }

  // Declare a basic FEType.  Will use default in the base,
  // and something else (not important) in radial direction.
  FEType fe_type(default_order());

  const Point mapped_point = FEInterface::inverse_map(dim(),
                                                      fe_type,
                                                      this,
                                                      p,
                                                      tol,
                                                      false);

  return FEInterface::on_reference_element(mapped_point, this->type(), tol);
}
Example #9
0
int
build_building(unit * u, const building_type * btype, int id, int want, order * ord)
{
    region *r = u->region;
    int n = want, built = 0;
    building *b = NULL;
    /* einmalige Korrektur */
    const char *btname;
    order *new_order = NULL;
    const struct locale *lang = u->faction->locale;
    static int rule_other = -1;

    assert(u->number);
    assert(btype->construction);
    if (eff_skill(u, SK_BUILDING, r) == 0) {
        cmistake(u, ord, 101, MSG_PRODUCE);
        return 0;
    }

    /* Falls eine Nummer angegeben worden ist, und ein Gebaeude mit der
     * betreffenden Nummer existiert, ist b nun gueltig. Wenn keine Burg
     * gefunden wurde, dann wird nicht einfach eine neue erbaut. Ansonsten
     * baut man an der eigenen burg weiter. */

    /* Wenn die angegebene Nummer falsch ist, KEINE Burg bauen! */
    if (id > 0) {                 /* eine Nummer angegeben, keine neue Burg bauen */
        b = findbuilding(id);
        if (!b || b->region != u->region) { /* eine Burg mit dieser Nummer gibt es hier nicht */
            /* vieleicht Tippfehler und die eigene Burg ist gemeint? */
            if (u->building && u->building->type == btype) {
                b = u->building;
            }
            else {
                /* keine neue Burg anfangen wenn eine Nummer angegeben war */
                cmistake(u, ord, 6, MSG_PRODUCE);
                return 0;
            }
        }
    }
    else if (u->building && u->building->type == btype) {
        b = u->building;
    }

    if (b)
        btype = b->type;

    if (fval(btype, BTF_UNIQUE) && buildingtype_exists(r, btype, false)) {
        /* only one of these per region */
        cmistake(u, ord, 93, MSG_PRODUCE);
        return 0;
    }
    if (besieged(u)) {
        /* units under siege can not build */
        cmistake(u, ord, 60, MSG_PRODUCE);
        return 0;
    }
    if (btype->flags & BTF_NOBUILD) {
        /* special building, cannot be built */
        cmistake(u, ord, 221, MSG_PRODUCE);
        return 0;
    }
    if ((r->terrain->flags & LAND_REGION) == 0) {
        /* special terrain, cannot build */
        cmistake(u, ord, 221, MSG_PRODUCE);
        return 0;
    }
    if (btype->flags & BTF_ONEPERTURN) {
        if (b && fval(b, BLD_EXPANDED)) {
            cmistake(u, ord, 318, MSG_PRODUCE);
            return 0;
        }
        n = 1;
    }
    if (b) {
        if (rule_other < 0) {
            rule_other =
                get_param_int(global.parameters, "rules.build.other_buildings", 1);
        }
        if (!rule_other) {
            unit *owner = building_owner(b);
            if (!owner || owner->faction != u->faction) {
                cmistake(u, ord, 1222, MSG_PRODUCE);
                return 0;
            }
        }
    }

    if (b)
        built = b->size;
    if (n <= 0 || n == INT_MAX) {
        if (b == NULL) {
            if (btype->maxsize > 0) {
                n = btype->maxsize - built;
            }
            else {
                n = INT_MAX;
            }
        }
        else {
            if (b->type->maxsize > 0) {
                n = b->type->maxsize - built;
            }
            else {
                n = INT_MAX;
            }
        }
    }
    built = build(u, btype->construction, built, n);

    switch (built) {
    case ECOMPLETE:
        /* the building is already complete */
        cmistake(u, ord, 4, MSG_PRODUCE);
        break;
    case ENOMATERIALS:
        ADDMSG(&u->faction->msgs, msg_materials_required(u, ord,
            btype->construction, want));
        break;
    case ELOWSKILL:
    case ENEEDSKILL:
        /* no skill, or not enough skill points to build */
        cmistake(u, ord, 50, MSG_PRODUCE);
        break;
    }
    if (built <= 0) {
        return built;
    }
    /* at this point, the building size is increased. */
    if (b == NULL) {
        /* build a new building */
        b = new_building(btype, r, lang);
        b->type = btype;
        fset(b, BLD_MAINTAINED | BLD_WORKING);

        /* Die Einheit befindet sich automatisch im Inneren der neuen Burg. */
        if (u->number && leave(u, false)) {
            u_set_building(u, b);
        }
    }

    btname = LOC(lang, btype->_name);

    if (want - built <= 0) {
        /* gebäude fertig */
        new_order = default_order(lang);
    }
    else if (want != INT_MAX) {
        /* reduzierte restgröße */
        const char *hasspace = strchr(btname, ' ');
        if (hasspace) {
            new_order =
                create_order(K_MAKE, lang, "%d \"%s\" %i", n - built, btname, b->no);
        }
        else {
            new_order =
                create_order(K_MAKE, lang, "%d %s %i", n - built, btname, b->no);
        }
    }
    else if (btname) {
        /* Neues Haus, Befehl mit Gebäudename */
        const char *hasspace = strchr(btname, ' ');
        if (hasspace) {
            new_order = create_order(K_MAKE, lang, "\"%s\" %i", btname, b->no);
        }
        else {
            new_order = create_order(K_MAKE, lang, "%s %i", btname, b->no);
        }
    }

    if (new_order) {
        replace_order(&u->orders, ord, new_order);
        free_order(new_order);
    }

    b->size += built;
    fset(b, BLD_EXPANDED);

    update_lighthouse(b);

    ADDMSG(&u->faction->msgs, msg_message("buildbuilding",
        "building unit size", b, u, built));
    return built;
}