Beispiel #1
0
static void test_get_monsters(CuTest *tc) {
    faction *f;

    free_gamedata();
    CuAssertPtrNotNull(tc, (f = get_monsters()));
    CuAssertPtrEquals(tc, f, get_monsters());
    CuAssertIntEquals(tc, 666, f->no);
    CuAssertStrEquals(tc, "Monster", f->name);
    test_cleanup();
}
Beispiel #2
0
void save_special_items(unit *usrc)
{
    unit *u;
    region *r = usrc->region;
    faction *fm = get_monsters();
    static const race *rc_ghost;
    static int cache;

    if (rc_changed(&cache)) {
        rc_ghost = get_race(RC_TEMPLATE);
    }
    for (u = r->units; u; u = u->next) {
        if (u->faction == fm) {
            give_special_items(u, &usrc->items);
            return;
        }
    }
    u = create_unit(r, fm, 1, rc_ghost, 0, NULL, NULL);
    unit_setname(u, unit_getname(usrc));
    if (usrc->number > 1) {
        /* some units have plural names, it would be neat if they aren't single: */
        scale_number(u, 2);
    }
    set_racename(&u->attribs, "ghost");
    give_special_items(u, &usrc->items);
}
Beispiel #3
0
void make_zombie(unit * u)
{
  u_setfaction(u, get_monsters());
  scale_number(u, 1);
  u_setrace(u, new_race[RC_ZOMBIE]);
  u->irace = NULL;
}
Beispiel #4
0
void make_zombie(unit * u)
{
    u_setfaction(u, get_monsters());
    scale_number(u, 1);
    u->hp = unit_max_hp(u) * u->number;
    u_setrace(u, get_race(RC_ZOMBIE));
    u->irace = NULL;
}
Beispiel #5
0
void randomevents(void)
{
    region *r;
    faction *monsters = get_monsters();

    icebergs();
    godcurse();
    orc_growth();
    demon_skillchanges();
    volcano_update();
    /* Monumente zerfallen, Schiffe verfaulen */

    for (r = regions; r; r = r->next) {
        building **blist = &r->buildings;
        while (*blist) {
            building *b = *blist;
            if (fval(b->type, BTF_DECAY) && !building_owner(b)) {
                b->size -= _max(1, (b->size * 20) / 100);
                if (b->size == 0) {
                    remove_building(blist, r->buildings);
                }
            }
            if (*blist == b)
                blist = &b->next;
        }
    }

    /* monster-einheiten desertieren */
    if (monsters) {
        for (r = regions; r; r = r->next) {
            unit *u;

            for (u = r->units; u; u = u->next) {
                if (u->faction && !is_monsters(u->faction)
                        && (u_race(u)->flags & RCF_DESERT)) {
                    if (fval(u, UFL_ISNEW))
                        continue;
                    if (rng_int() % 100 < 5) {
                        ADDMSG(&u->faction->msgs, msg_message("desertion",
                                                              "unit region", u, r));
                        u_setfaction(u, monsters);
                    }
                }
            }
        }
    }

    chaos_update();
#ifdef HERBS_ROT
    rotting_herbs();
#endif

    dissolve_units();
}
Beispiel #6
0
static void test_remove_dead_factions(CuTest *tc) {
    faction *f, *fm;
    region *r;
    int fno;

    test_cleanup();
    r = test_create_region(0, 0, 0);
    fm = get_or_create_monsters();
    f = test_create_faction(0);
    assert(fm && r && f);
    test_create_unit(f, r);
    test_create_unit(fm, r);
    remove_empty_factions();
    CuAssertPtrEquals(tc, f, findfaction(f->no));
    CuAssertPtrNotNull(tc, get_monsters());
    fm->units = 0;
    f->_alive = false;
    fno = f->no;
    remove_empty_factions();
    CuAssertPtrEquals(tc, 0, findfaction(fno));
    CuAssertPtrEquals(tc, fm, get_monsters());
    test_cleanup();
}
Beispiel #7
0
static void test_remove_empty_factions(CuTest *tc) {
    faction *f, *fm;
    int fno;

    test_cleanup();
    fm = get_or_create_monsters();
    assert(fm);
    f = test_create_faction(0);
    fno = f->no;
    remove_empty_factions();
    CuAssertIntEquals(tc, false, f->_alive);
    CuAssertPtrEquals(tc, fm, factions);
    CuAssertPtrEquals(tc, NULL, fm->next);
    CuAssertPtrEquals(tc, 0, findfaction(fno));
    CuAssertPtrEquals(tc, fm, get_monsters());
    test_cleanup();
}
Beispiel #8
0
int sp_summon_alp(struct castorder *co)
{
  unit *alp, *opfer;
  region *r = co_get_region(co);
  unit *mage = co->magician.u;
  int cast_level = co->level;
  spellparameter *pa = co->par;
  const struct race *rc = get_race(RC_ALP);
  struct faction *f = get_monsters();
  struct message *msg;

  opfer = pa->param[0]->data.u;

  /* Der Alp gehört den Monstern, darum erhält der Magier auch keine
   * Regionsberichte von ihm.  Er erhält aber später eine Mitteilung,
   * sobald der Alp sein Opfer erreicht hat.
   */
  alp = create_unit(r, f, 1, rc, 0, NULL, NULL);
  set_level(alp, SK_STEALTH, 7);
  setstatus(alp, ST_FLEE);      /* flieht */

  {
    attrib *a = a_add(&alp->attribs, a_new(&at_alp));
    alp_data *ad = (alp_data *) a->data.v;
    ad->mage = mage;
    ad->target = opfer;
  }

  {
    /* Wenn der Alp stirbt, den Magier nachrichtigen */
    add_trigger(&alp->attribs, "destroy", trigger_unitmessage(mage,
        "trigger_alp_destroy", MSG_EVENT, ML_INFO));
    /* Wenn Opfer oder Magier nicht mehr existieren, dann stirbt der Alp */
    add_trigger(&mage->attribs, "destroy", trigger_killunit(alp));
    add_trigger(&opfer->attribs, "destroy", trigger_killunit(alp));
  }
  msg = msg_message("summon_alp_effect", "mage alp target", mage, alp, opfer);
  r_addmessage(r, mage->faction, msg);
  msg_release(msg);

  return cast_level;
}
Beispiel #9
0
void age_undead(unit * u)
{
  region *r = u->region;
  int n = 0;

  /* untote, die einer partei angehoeren, koennen sich
   * absplitten, anstatt sich zu vermehren. monster
   * untote vermehren sich nur noch */

  if (u->number > UNDEAD_MIN && !is_monsters(u->faction)
    && rng_int() % 100 < UNDEAD_BREAKUP) {
    int m;
    unit *u2;

    n = 0;
    for (m = u->number; m; m--) {
      if (rng_int() % 100 < UNDEAD_BREAKUP_FRACTION)
        ++n;
    }
    u2 = create_unit(r, get_monsters(), 0, get_race(RC_UNDEAD), 0, NULL, u);
    make_undead_unit(u2);
    transfermen(u, u2, u->number - n);
  }
}
Beispiel #10
0
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());
            }
          }
        }
    }
  }
}
Beispiel #11
0
void randomevents(void)
{
  region *r;
  faction *monsters = get_monsters();

  icebergs();
  godcurse();
  orc_growth();
  demon_skillchanges();

  /* Orkifizierte Regionen mutieren und mutieren zurück */

  for (r = regions; r; r = r->next) {
    if (fval(r, RF_ORCIFIED)) {
      direction_t dir;
      double probability = 0.0;
      for (dir = 0; dir < MAXDIRECTIONS; dir++) {
        region *rc = rconnect(r, dir);
        if (rc && rpeasants(rc) > 0 && !fval(rc, RF_ORCIFIED))
          probability += 0.02;
      }
      if (chance(probability)) {
        ADDMSG(&r->msgs, msg_message("deorcified", "region", r));
        freset(r, RF_ORCIFIED);
      }
    } else {
      attrib *a = a_find(r->attribs, &at_orcification);
      if (a != NULL) {
        double probability = 0.0;
        if (rpeasants(r) <= 0)
          continue;
        probability = a->data.i / (double)rpeasants(r);
        if (chance(probability)) {
          fset(r, RF_ORCIFIED);
          a_remove(&r->attribs, a);
          ADDMSG(&r->msgs, msg_message("orcified", "region", r));
        } else {
          a->data.i -= _max(10, a->data.i / 10);
          if (a->data.i <= 0)
            a_remove(&r->attribs, a);
        }
      }
    }
  }

  /* Vulkane qualmen, brechen aus ... */
  for (r = regions; r; r = r->next) {
    if (r->terrain == newterrain(T_VOLCANO_SMOKING)) {
      if (a_find(r->attribs, &at_reduceproduction)) {
        ADDMSG(&r->msgs, msg_message("volcanostopsmoke", "region", r));
        rsetterrain(r, T_VOLCANO);
      } else {
        if (rng_int() % 100 < 12) {
          ADDMSG(&r->msgs, msg_message("volcanostopsmoke", "region", r));
          rsetterrain(r, T_VOLCANO);
        } else if (r->age > 20 && rng_int() % 100 < 8) {
          volcano_outbreak(r);
        }
      }
    } else if (r->terrain == newterrain(T_VOLCANO)) {
      if (rng_int() % 100 < 4) {
        ADDMSG(&r->msgs, msg_message("volcanostartsmoke", "region", r));
        rsetterrain(r, T_VOLCANO_SMOKING);
      }
    }
  }

  /* Monumente zerfallen, Schiffe verfaulen */

  for (r = regions; r; r = r->next) {
    building **blist = &r->buildings;
    while (*blist) {
      building *b = *blist;
      if (fval(b->type, BTF_DECAY) && !building_owner(b)) {
        b->size -= _max(1, (b->size * 20) / 100);
        if (b->size == 0) {
          remove_building(blist, r->buildings);
        }
      }
      if (*blist == b)
        blist = &b->next;
    }
  }

  /* monster-einheiten desertieren */
  if (monsters) {
      for (r = regions; r; r = r->next) {
          unit *u;

          for (u = r->units; u; u = u->next) {
              if (u->faction && !is_monsters(u->faction)
                  && (u_race(u)->flags & RCF_DESERT)) {
                  if (fval(u, UFL_ISNEW))
                      continue;
                  if (rng_int() % 100 < 5) {
                      ADDMSG(&u->faction->msgs, msg_message("desertion",
                          "unit region", u, r));
                      u_setfaction(u, monsters);
                  }
              }
          }
      }
  }

  /* Chaos */
  for (r = regions; r; r = r->next) {
    int i;

    if (fval(r, RF_CHAOTIC)) {
      chaos(r);
    }
    i = chaoscount(r);
    if (i) {
      chaoscounts(r, -(int)(i * ((double)(rng_int() % 10)) / 100.0));
    }
  }
#ifdef HERBS_ROT
  rotting_herbs();
#endif

  dissolve_units();
}
Beispiel #12
0
/** Untote können entstehen */
void spawn_undead(void)
{
    region *r;
    faction *monsters = get_monsters();

    for (r = regions; r; r = r->next) {
        int unburied = deathcount(r);
        static const curse_type *ctype = NULL;

        if (!ctype)
            ctype = ct_find("holyground");
        if (ctype && curse_active(get_curse(r->attribs, ctype)))
            continue;

        /* Chance 0.1% * chaosfactor */
        if (r->land && unburied > r->land->peasants / 20
            && rng_int() % 10000 < (100 + 100 * chaosfactor(r))) {
            message *msg;
            unit *u;
            /* es ist sinnfrei, wenn irgendwo im Wald 3er-Einheiten Untote entstehen.
             * Lieber sammeln lassen, bis sie mindestens 5% der Bevölkerung sind, und
             * dann erst auferstehen. */
            int undead = unburied / (rng_int() % 2 + 1);
            const race *rc = NULL;
            int i;
            if (r->age < 100)
                undead = undead * r->age / 100; /* newbie-regionen kriegen weniger ab */

            if (!undead || r->age < 20)
                continue;

            switch (rng_int() % 3) {
            case 0:
                rc = get_race(RC_SKELETON);
                break;
            case 1:
                rc = get_race(RC_ZOMBIE);
                break;
            default:
                rc = get_race(RC_GHOUL);
                break;
            }

            u = create_unit(r, monsters, undead, rc, 0, NULL, NULL);
            fset(u, UFL_ISNEW | UFL_MOVED);
            if ((rc == get_race(RC_SKELETON) || rc == get_race(RC_ZOMBIE))
                && rng_int() % 10 < 4) {
                equip_unit(u, get_equipment("rising_undead"));
            }

            for (i = 0; i < MAXSKILLS; i++) {
                if (rc->bonus[i] >= 1) {
                    set_level(u, (skill_t)i, 1);
                }
            }
            u->hp = unit_max_hp(u) * u->number;

            deathcounts(r, -undead);
            name_unit(u);

            log_debug("spawning %d %s in %s.\n", u->number,
                LOC(default_locale,
                rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL)), regionname(r, NULL));
          msg = msg_message("undeadrise", "region", r);
          add_message(&r->msgs, msg);
          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))
                  continue;
              fset(u->faction, FFL_SELECT);
              add_message(&u->faction->msgs, msg);
          }
          msg_release(msg);
        }
        else {
            int i = deathcount(r);
            if (i) {
                /* Gräber verwittern, 3% der Untoten finden die ewige Ruhe */
                deathcounts(r, (int)(-i * 0.03));
            }
        }
    }
}