예제 #1
0
파일: faction.c 프로젝트: eressea/server
int count_faction(const faction * f, int flags)
{
    unit *u;
    int n = 0;
    for (u = f->units; u; u = u->nextF) {
        const race *rc = u_race(u);
        int x = u->number;
        if (f->race != rc) {
            if (!playerrace(rc)) {
                if (flags&COUNT_MONSTERS) {
                    n += x;
                }
            }
            else if (flags&COUNT_MIGRANTS) {
                if (!is_cursed(u->attribs, &ct_slavery)) {
                    n += x;
                }
            }
        }
        else if (flags&COUNT_DEFAULT) {
            n += x;
        }
    }
    return n;
}
예제 #2
0
파일: arena.c 프로젝트: UweKopf/server
static int age_hurting(attrib * a)
{
  building *b = (building *) a->data.v;
  unit *u;
  int active = 0;
  if (b == NULL)
    return AT_AGE_REMOVE;
  for (u = b->region->units; u; u = u->next) {
    if (u->building == b) {
      if (u->faction->magiegebiet == M_DRAIG) {
        active++;
        ADDMSG(&b->region->msgs, msg_message("praytoigjarjuk", "unit", u));
      }
    }
  }
  if (active)
    for (u = b->region->units; u; u = u->next)
      if (playerrace(u->faction->race)) {
        int i;
        if (u->faction->magiegebiet != M_DRAIG) {
          for (i = 0; i != active; ++i)
            u->hp = (u->hp + 1) / 2;    /* make them suffer, but not die */
          ADDMSG(&b->region->msgs, msg_message("cryinpain", "unit", u));
        }
      }
  return AT_AGE_KEEP;
}
예제 #3
0
파일: faction.c 프로젝트: eressea/server
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;
}
예제 #4
0
static void summarize_races(const summary *s, FILE *F, bool full) {
    int i;
    for (i = 0; i < MAXRACES; i++) {
        if (s->poprace[i] > 0) {
            const char *pad = "      ";
            int lpad = (int)strlen(pad);
            const race *rc = get_race(i);
            const char *rcname = LOC(default_locale, rc_name_s(rc, NAME_PLURAL));
            lpad -= count_umlaut(rcname);
            assert(lpad >= 0);
            if (full) {
                fputs(pad + lpad, F);
                fprintf(F, "%20s: ", rcname);
                fprintf(F, "%8d\n", s->poprace[i]);
            }
            else if (i != RC_TEMPLATE && i != RC_CLONE) {
                if (playerrace(rc)) {
                    fputs(pad + lpad, F);
                    fprintf(F, "%16s: ", rcname);
                    fprintf(F, "%8d\n", s->poprace[i]);
                }
            }
        }
    }
}
예제 #5
0
파일: study.c 프로젝트: ennorehling/eressea
void produceexp_ex(struct unit *u, skill_t sk, int n, learn_fun learn)
{
    assert(u && n <= u->number);
    if (n > 0 && (is_monsters(u->faction) || playerrace(u_race(u)))) {
        int days = produceexp_days();
        learn(u, sk, days * n);
    }
}
예제 #6
0
static bool select_hero(const side *vs, const fighter *fig, void *cbdata)
{
    UNUSED_ARG(cbdata);

    if (playerrace(u_race(fig->unit))) {
        int row = get_unitrow(fig, vs);
        if (row >= FIGHT_ROW && row <= AVOID_ROW) {
            return fig->alive + fig->run.number < fig->unit->number;
        }
    }
    return false;
}
예제 #7
0
파일: unit.c 프로젝트: UweKopf/server
/* vorsicht Sprüche können u->number == RS_FARVISION haben! */
void set_number(unit * u, int count)
{
  assert(count >= 0);
  assert(count <= UNIT_MAXSIZE);

  if (count == 0) {
    u->flags &= ~(UFL_HERO);
  }
  if (u->faction && playerrace(u_race(u))) {
    u->faction->num_people += count - u->number;
  }
  u->number = (unsigned short)count;
}
예제 #8
0
static int heal_fighters(selist * fgs, int *power, bool heal_monsters)
{
    int healhp = *power, healed = 0, qi;
    selist *ql;

    for (qi = 0, ql = fgs; ql; selist_advance(&ql, &qi, 1)) {
        fighter *df = (fighter *)selist_get(ql, qi);

        if (healhp <= 0)
            break;

        /* Untote kann man nicht heilen */
        if (df->unit->number == 0 || (u_race(df->unit)->flags & RCF_NOHEAL))
            continue;

        /* wir heilen erstmal keine Monster */
        if (heal_monsters || playerrace(u_race(df->unit))) {
            int n, hp = df->unit->hp / df->unit->number;
            int rest = df->unit->hp % df->unit->number;

            for (n = 0; n < df->unit->number; n++) {
                int wound = hp - df->person[n].hp;
                if (rest > n)
                    ++wound;

                if (wound > 0 && wound < hp) {
                    int heal = healhp;
                    if (heal > wound) {
                        heal = wound;
                    }
                    assert(heal >= 0);
                    df->person[n].hp += heal;
                    healhp -= heal;
                    if (healhp < 0) healhp = 0;
                    ++healed;
                    if (healhp <= 0)
                        break;
                }
            }
        }
    }

    *power = healhp;
    return healed;
}
예제 #9
0
static void summarize_players(const summary *s, FILE *F) {
    int i;
    const char * suffix = LOC(default_locale, "stat_tribe_p");

    for (i = 0; i < MAXRACES; i++) {
        if (i != RC_TEMPLATE && i != RC_CLONE && s->factionrace[i]) {
            const race *rc = get_race(i);
            if (rc && playerrace(rc)) {
                const char * pad = "      ";
                int lpad = (int)strlen(pad);
                const char *rccat = LOC(default_locale, rc_name_s(rc, NAME_CATEGORY));
                lpad -= count_umlaut(rccat);
                assert(lpad >= 0);
                fputs(pad + lpad, F);
                fprintf(F, "%16s%s:", rccat, suffix);
                fprintf(F, "%8d\n", s->factionrace[i]);
            }
        }
    }
}
예제 #10
0
파일: summary.c 프로젝트: hochl/server
void report_summary(summary * s, summary * o, bool full)
{
  FILE *F = NULL;
  int i, newplayers = 0;
  faction *f;
  char zText[MAX_PATH];

  if (full) {
    sprintf(zText, "%s/parteien.full", basepath());
  } else {
    sprintf(zText, "%s/parteien", basepath());
  }
  F = fopen(zText, "w");
  if (!F) {
    perror(zText);
    return;
  }
#ifdef SUMMARY_BOM
  else {
    const unsigned char utf8_bom[4] = { 0xef, 0xbb, 0xbf, 0 };
    fwrite(utf8_bom, 1, 3, F);
  }
#endif
  log_info("writing summary to file: parteien.\n");
  fprintf(F, "%s\n%s\n\n", game_name(), gamedate2(default_locale));
  fprintf(F, "Auswertung Nr:         %d\n\n", turn);
  fprintf(F, "Parteien:              %s\n", pcomp(s->factions, o->factions));
  fprintf(F, "Einheiten:             %s\n", pcomp(s->nunits, o->nunits));
  fprintf(F, "Spielerpopulation:     %s\n", pcomp(s->playerpop, o->playerpop));
  fprintf(F, " davon bewaffnet:      %s\n", pcomp(s->armed_men, o->armed_men));
  fprintf(F, " Helden:               %s\n", pcomp(s->heroes, o->heroes));

  if (full) {
    fprintf(F, "Regionen:              %d\n", listlen(regions));
    fprintf(F, "Bewohnte Regionen:     %d\n", s->inhabitedregions);
    fprintf(F, "Landregionen:          %d\n", s->landregionen);
    fprintf(F, "Spielerregionen:       %d\n", s->regionen_mit_spielern);
    fprintf(F, "Landspielerregionen:   %d\n", s->landregionen_mit_spielern);
    fprintf(F, "Orkifizierte Regionen: %d\n", s->orkifizierte_regionen);
    fprintf(F, "Inaktive Vulkane:      %d\n", s->inactive_volcanos);
    fprintf(F, "Aktive Vulkane:        %d\n\n", s->active_volcanos);
  }

  for (i = 0; i < MAXRACES; i++) {
      if (i != RC_TEMPLATE && i != RC_CLONE && s->factionrace[i]) {
          const race *rc = get_race(i);
          if (rc && playerrace(rc)) {
              fprintf(F, "%13s%s: %s\n", LOC(default_locale, rc_name(rc, NAME_CATEGORY)),
                  LOC(default_locale, "stat_tribe_p"), pcomp(s->factionrace[i],
                  o->factionrace[i]));
          }
      }
  }

  if (full) {
    fprintf(F, "\n");
    {
      struct language *plang = s->languages;
      while (plang != NULL) {
        struct language *olang = o->languages;
        int nold = 0;
        while (olang && olang->locale != plang->locale)
          olang = olang->next;
        if (olang)
          nold = olang->number;
        fprintf(F, "Sprache %12s: %s\n", locale_name(plang->locale),
          rcomp(plang->number, nold));
        plang = plang->next;
      }
    }
  }

  fprintf(F, "\n");
  if (full) {
    for (i = 0; i < MAXRACES; i++) {
      if (s->poprace[i]) {
          const race *rc = get_race(i);
          fprintf(F, "%20s: %s\n", LOC(default_locale, rc_name(rc, NAME_PLURAL)),
          rcomp(s->poprace[i], o->poprace[i]));
      }
    }
  } else {
      for (i = 0; i < MAXRACES; i++) {
          if (i != RC_TEMPLATE && i != RC_CLONE && s->poprace[i]) {
              const race *rc = get_race(i);
              if (playerrace(rc)) {
                  fprintf(F, "%20s: %s\n", LOC(default_locale, rc_name(rc, NAME_PLURAL)),
                      rcomp(s->poprace[i], o->poprace[i]));
              }
          }
      }
    }

  if (full) {
    fprintf(F, "\nWaffen:               %s\n", pcomp(s->waffen, o->waffen));
    fprintf(F, "Ruestungen:           %s\n",
      pcomp(s->ruestungen, o->ruestungen));
    fprintf(F, "ungezaehmte Pferde:   %s\n", pcomp(s->pferde, o->pferde));
    fprintf(F, "gezaehmte Pferde:     %s\n",
      pcomp(s->spielerpferde, o->spielerpferde));
    fprintf(F, "Schiffe:              %s\n", pcomp(s->schiffe, o->schiffe));
    fprintf(F, "Gebaeude:             %s\n", pcomp(s->gebaeude, o->gebaeude));

    fprintf(F, "\nBauernpopulation:     %s\n", pcomp(s->peasants, o->peasants));

    fprintf(F, "Population gesamt:    %d\n\n", s->playerpop + s->peasants);

    fprintf(F, "Reichtum Spieler:     %s Silber\n",
      pcomp(s->playermoney, o->playermoney));
    fprintf(F, "Reichtum Bauern:      %s Silber\n",
      pcomp(s->peasantmoney, o->peasantmoney));
    fprintf(F, "Reichtum gesamt:      %s Silber\n\n",
      pcomp(s->playermoney + s->peasantmoney,
        o->playermoney + o->peasantmoney));
  }

  fprintf(F, "\n\n");

  newplayers = update_nmrs();

  for (i = 0; i <= NMRTimeout(); ++i) {
    if (i == NMRTimeout()) {
      fprintf(F, "+ NMR:\t\t %d\n", nmrs[i]);
    } else {
      fprintf(F, "%d NMR:\t\t %d\n", i, nmrs[i]);
    }
  }
  if (age) {
    if (age[2] != 0) {
      fprintf(F, "Erstabgaben:\t %d%%\n", 100 - (dropouts[0] * 100 / age[2]));
    }
    if (age[3] != 0) {
      fprintf(F, "Zweitabgaben:\t %d%%\n", 100 - (dropouts[1] * 100 / age[3]));
    }
  }
  fprintf(F, "Neue Spieler:\t %d\n", newplayers);

  if (full) {
    if (factions)
      fprintf(F, "\nParteien:\n\n");

    for (f = factions; f; f = f->next) {
      out_faction(F, f);
    }

    if (NMRTimeout() && full) {
      fprintf(F, "\n\nFactions with NMRs:\n");
      for (i = NMRTimeout(); i > 0; --i) {
        for (f = factions; f; f = f->next) {
          if (i == NMRTimeout()) {
            if (turn - f->lastorders >= i) {
              out_faction(F, f);
            }
          } else {
            if (turn - f->lastorders == i) {
              out_faction(F, f);
            }
          }
        }
      }
    }
  }

  fclose(F);

  if (full) {
    log_info("writing date & turn\n");
    writeturn();
  }
  free(nmrs);
  nmrs = NULL;
}
예제 #11
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());
            }
          }
        }
    }
  }
}
예제 #12
0
파일: faction.c 프로젝트: eressea/server
void destroyfaction(faction ** fp)
{
    faction * f = *fp;
    unit *u = f->units;

    *fp = f->next;
    f->next = dead_factions;
    dead_factions = f;

    fset(f, FFL_QUIT);
    f->_alive = false;

    if (f->spellbook) {
        spellbook_clear(f->spellbook);
        free(f->spellbook);
        f->spellbook = 0;
    }

    if (f->seen_factions) {
        selist_free(f->seen_factions);
        f->seen_factions = 0;
    }

    while (u) {
        /* give away your stuff, to ghosts if you cannot (quest items) */
        if (u->items) {
            region *r = u->region;
            int result = gift_items(u, GIFT_FRIENDS | GIFT_PEASANTS);
            if (result != 0) {
                save_special_items(u);
            }
            if (r->land && !!playerrace(u_race(u))) {
                const race *rc = u_race(u);
                int m = rmoney(r);

                /* Personen gehen nur an die Bauern, wenn sie auch von dort
                    * stammen */
                if ((rc->ec_flags & ECF_REC_ETHEREAL) == 0) {
                    int p = rpeasants(u->region);
                    int h = rhorses(u->region);
                    item *itm;

                    p += (int)(u->number * rc->recruit_multi);
                    for (itm = u->items; itm; itm = itm->next) {
                        if (itm->type->flags & ITF_ANIMAL) {
                            h += itm->number;
                        }
                    }
                    rsetpeasants(r, p);
                    rsethorses(r, h);
                }
                m += get_money(u);
                rsetmoney(r, m);
            }
        }
        set_number(u, 0);
        u = u->nextF;
    }

    handle_event(f->attribs, "destroy", f);
    if (f->alliance) {
        setalliance(f, NULL);
    }

    funhash(f);

    /* units of other factions that were disguised as this faction
     * have their disguise replaced by ordinary faction hiding. */
    if (rule_stealth_other()) {
        region *rc;
        for (rc = regions; rc; rc = rc->next) {
            for (u = rc->units; u; u = u->next) {
                if (u->attribs && get_otherfaction(u) == f) {
                    a_removeall(&u->attribs, &at_otherfaction);
                    if (rule_stealth_anon()) {
                        fset(u, UFL_ANON_FACTION);
                    }
                }
            }
        }
    }
}
예제 #13
0
int sp_undeadhero(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    battle *b = fi->side->battle;
    unit *mage = fi->unit;
    region *r = b->region;
    quicklist *fgs, *ql;
    int qi, n, undead = 0;
    message *msg;
    int force = (int)get_force(power, 0);
    double c = 0.50 + 0.02 * power;

    /* Liste aus allen K�mpfern */
    fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY | FS_HELP);
    scramble_fighters(fgs);

    for (qi = 0, ql = fgs; ql; ql_advance(&ql, &qi, 1)) {
        fighter *df = (fighter *)ql_get(ql, qi);
        unit *du = df->unit;

        if (force <= 0)
            break;

        /* keine Monster */
        if (!playerrace(u_race(du)))
            continue;

        if (df->alive + df->run.number < du->number) {
            int j = 0;

            /* Wieviele Untote k�nnen wir aus dieser Einheit wecken? */
            for (n = df->alive + df->run.number; n != du->number; n++) {
                if (chance(c)) {
                    ++j;
                    if (--force <= 0)
                        break;
                }
            }

            if (j > 0) {
                item **ilist;
                unit *u =
                    create_unit(r, mage->faction, 0, get_race(RC_UNDEAD), 0, unit_getname(du),
                    du);

                /* new units gets some stats from old unit */

                if (du->display) {
                    unit_setinfo(u, du->display);
                }
                else {
                    unit_setinfo(u, NULL);
                }
                setstatus(u, du->status);
                setguard(u, false);
                for (ilist = &du->items; *ilist;) {
                    item *itm = *ilist;
                    int loot = itm->number * j / du->number;
                    if (loot != itm->number) {
                        int split = itm->number * j % du->number;
                        if (split > 0 && (rng_int() % du->number) < split) {
                            ++loot;
                        }
                    }
                    i_change(&u->items, itm->type, loot);
                    i_change(ilist, itm->type, -loot);
                    if (*ilist == itm) {
                        ilist = &itm->next;
                    }
                }

                /* inherit stealth from magician */
                if (mage->flags & UFL_ANON_FACTION) {
                    u->flags |= UFL_ANON_FACTION;
                }

                /* transfer dead people to new unit, set hitpoints to those of old unit */
                transfermen(du, u, j);
                u->hp = u->number * unit_max_hp(du);
                assert(j <= df->side->casualties);
                df->side->casualties -= j;
                df->side->dead -= j;

                /* counting total number of undead */
                undead += j;
            }
        }
    }
    ql_free(fgs);

    level = _min(level, undead);
    if (undead == 0) {
        msg =
            msg_message("summonundead_effect_0", "mage region", mage, mage->region);
    }
    else {
        msg =
            msg_message("summonundead_effect_1", "mage region amount", mage,
            mage->region, undead);
    }

    message_all(b, msg);
    msg_release(msg);
    return level;
}