示例#1
0
static void test_param_flt(CuTest * tc)
{
    struct param *par = 0;
    test_cleanup();
    CuAssertDblEquals(tc, 13, get_param_flt(par, "foo", 13), 0.01);
    set_param(&par, "foo", "23.0");
    set_param(&par, "bar", "42.0");
    CuAssertDblEquals(tc, 23.0, get_param_flt(par, "foo", 0.0), 0.01);
    CuAssertDblEquals(tc, 42.0, get_param_flt(par, "bar", 0.0), 0.01);
}
示例#2
0
文件: randenc.c 项目: hochl/server
static void godcurse(void)
{
  region *r;

  for (r = regions; r; r = r->next) {
    if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) {
      unit *u;
      for (u = r->units; u; u = u->next) {
        skill *sv = u->skills;
        while (sv != u->skills + u->skill_size) {
          int weeks = 1 + rng_int() % 3;
          reduce_skill(u, sv, weeks);
          ++sv;
        }
      }
      if (fval(r->terrain, SEA_REGION)) {
        ship *sh;
        for (sh = r->ships; sh;) {
          ship *shn = sh->next;
          float dmg =
            get_param_flt(global.parameters, "rules.ship.damage.godcurse",
            0.10F);
          damage_ship(sh, dmg);
          if (sh->damage >= sh->size * DAMAGE_SCALE) {
            unit *u = ship_owner(sh);
            if (u)
              ADDMSG(&u->faction->msgs,
                msg_message("godcurse_destroy_ship", "ship", sh));
            remove_ship(&sh->region->ships, sh);
          }
          sh = shn;
        }
      }
    }
  }

}
示例#3
0
文件: randenc.c 项目: hochl/server
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));
        }
    }
  }
}
示例#4
0
文件: randenc.c 项目: hochl/server
void chaos(region * r)
{
  if (rng_int() % 100 < 8) {
    switch (rng_int() % 3) {
      case 0:                  /* Untote */
        if (!fval(r->terrain, SEA_REGION)) {
          unit *u = random_unit(r);
          if (u && playerrace(u_race(u))) {
            ADDMSG(&u->faction->msgs, msg_message("chaos_disease", "unit", u));
            u_setfaction(u, get_monsters());
            u_setrace(u, get_race(RC_GHOUL));
          }
        }
        break;
      case 1:                  /* Drachen */
        if (random_unit(r)) {
          int mfac = 0;
          unit *u;
          switch (rng_int() % 3) {
            case 0:
              mfac = 100;
              u =
                createunit(r, get_monsters(), rng_int() % 8 + 1,
                get_race(RC_FIREDRAGON));
              break;
            case 1:
              mfac = 500;
              u =
                createunit(r, get_monsters(), rng_int() % 4 + 1,
                get_race(RC_DRAGON));
              break;
            default:
              mfac = 1000;
              u =
                createunit(r, get_monsters(), rng_int() % 2 + 1,
                get_race(RC_WYRM));
              break;
          }
          if (mfac)
            set_money(u, u->number * (rng_int() % mfac));
          fset(u, UFL_ISNEW | UFL_MOVED);
        }
      case 2:                  /* Terrainveränderung */
        if (!fval(r->terrain, FORBIDDEN_REGION)) {
          if (!fval(r->terrain, SEA_REGION)) {
            direction_t dir;
            for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
              region *rn = rconnect(r, dir);
              if (rn && fval(rn->terrain, SEA_REGION))
                break;
            }
            if (dir != MAXDIRECTIONS) {
              ship *sh = r->ships;
              unit **up;

              while (sh) {
                ship *nsh = sh->next;
                float dmg =
                  get_param_flt(global.parameters, "rules.ship.damage.atlantis",
                  0.50);
                damage_ship(sh, dmg);
                if (sh->damage >= sh->size * DAMAGE_SCALE) {
                  remove_ship(&sh->region->ships, sh);
                }
                sh = nsh;
              }

              for (up = &r->units; *up;) {
                unit *u = *up;
                if (u_race(u) != get_race(RC_SPELL) && u->ship == 0 && !canfly(u)) {
                  ADDMSG(&u->faction->msgs, msg_message("tidalwave_kill",
                      "region unit", r, u));
                  remove_unit(up, u);
                }
                if (*up == u)
                  up = &u->next;
              }
              ADDMSG(&r->msgs, msg_message("tidalwave", "region", r));

              while (r->buildings) {
                remove_building(&r->buildings, r->buildings);
              }
              terraform_region(r, newterrain(T_OCEAN));
            }
          } else {
            direction_t dir;
            for (dir = 0; dir != MAXDIRECTIONS; ++dir) {
              region *rn = rconnect(r, dir);
              if (rn && fval(rn->terrain, SEA_REGION))
                break;
            }
            if (dir != MAXDIRECTIONS) {
              terraform_region(r, chaosterrain());
            }
          }
        }
    }
  }
}
示例#5
0
void plan_monsters(faction * f)
{
    region *r;
    
    assert(f);
    attack_chance = get_param_flt(global.parameters, "rules.monsters.attack_chance", 0.4);
    f->lastorders = turn;

    for (r = regions; r; r = r->next) {
        unit *u;
        bool attacking = false;

        for (u = r->units; u; u = u->next) {
            attrib *ta;
            order *long_order = NULL;

            /* Ab hier nur noch Befehle für NPC-Einheiten. */
            if (!is_monsters(u->faction))
                continue;

            /* Befehle müssen jede Runde neu gegeben werden: */
            free_orders(&u->orders);
            if (skill_enabled(SK_PERCEPTION)) {
                /* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */
                /* TODO: this only works for playerrace */
                produceexp(u, SK_PERCEPTION, u->number);
            }

            if (!attacking) {
                if (chance(attack_chance)) attacking = true;
            }
            if (u->status > ST_BEHIND) {
                setstatus(u, ST_FIGHT);
                /* all monsters fight */
            }
            if (attacking && (!r->land || is_guard(u, GUARD_TAX))) {
                monster_attacks(u);
            }
            /* units with a plan to kill get ATTACK orders: */
            ta = a_find(u->attribs, &at_hate);
            if (ta && !monster_is_waiting(u)) {
                unit *tu = (unit *)ta->data.v;
                if (tu && tu->region == r) {
                    order * ord = monster_attack(u, tu);
                    if (ord) {
                        addlist(&u->orders, ord);
                    }
                }
                else if (tu) {
                    tu = findunitg(ta->data.i, NULL);
                    if (tu != NULL) {
                        long_order = make_movement_order(u, tu->region, 2, allowed_walk);
                    }
                }
                else
                    a_remove(&u->attribs, ta);
            }

            /* All monsters guard the region: */
            if (!monster_is_waiting(u) && r->land) {
                addlist(&u->orders, create_order(K_GUARD, u->faction->locale, NULL));
            }

            /* Einheiten mit Bewegungsplan kriegen ein NACH: */
            if (long_order == NULL) {
                attrib *ta = a_find(u->attribs, &at_targetregion);
                if (ta) {
                    if (u->region == (region *)ta->data.v) {
                        a_remove(&u->attribs, ta);
                    }
                }
                else if (u_race(u)->flags & RCF_MOVERANDOM) {
                    if (rng_int() % 100 < MOVECHANCE || check_overpopulated(u)) {
                        long_order = monster_move(r, u);
                    }
                }
            }

            if (long_order == NULL && unit_can_study(u)) {
                /* Einheiten, die Waffenlosen Kampf lernen könnten, lernen es um
                 * zu bewachen: */
                if (u_race(u)->bonus[SK_WEAPONLESS] != -99) {
                    if (effskill(u, SK_WEAPONLESS, 0) < 1) {
                        long_order =
                            create_order(K_STUDY, f->locale, "'%s'",
                            skillname(SK_WEAPONLESS, f->locale));
                    }
                }
            }

            if (long_order == NULL) {
                /* Ab hier noch nicht generalisierte Spezialbehandlungen. */

                if (!u->orders) {
                    handle_event(u->attribs, "ai_move", u);
                }

                switch (old_race(u_race(u))) {
                case RC_SEASERPENT:
                    long_order = create_order(K_PIRACY, f->locale, NULL);
                    break;
#ifdef TODO_ALP
                case RC_ALP:
                    long_order = monster_seeks_target(r, u);
                    break;
#endif
                case RC_FIREDRAGON:
                case RC_DRAGON:
                case RC_WYRM:
                    long_order = plan_dragon(u);
                    break;
                default:
                    if (u_race(u)->flags & RCF_LEARN) {
                        long_order = monster_learn(u);
                    }
                    break;
                }
            }
            if (long_order) {
                addlist(&u->orders, long_order);
            }
        }
    }
    pathfinder_cleanup();
}