Exemplo n.º 1
0
static void mistake(const unit * u, struct order *ord, const char *comment)
{
  if (!is_monsters(u->faction)) {
    ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "mistake",
        "error", comment));
  }
}
Exemplo n.º 2
0
int update_nmrs(void)
{
    int i, newplayers = 0;
    faction *f;
    int turn = global.data_turn;

    if (nmrs == NULL)
        nmrs = malloc(sizeof(int) * (NMRTimeout() + 1));
    for (i = 0; i <= NMRTimeout(); ++i) {
        nmrs[i] = 0;
    }

    for (f = factions; f; f = f->next) {
        if (fval(f, FFL_ISNEW)) {
            ++newplayers;
        }
        else if (!is_monsters(f) && f->alive) {
            int nmr = turn - f->lastorders + 1;
            if (nmr < 0 || nmr > NMRTimeout()) {
                log_error("faction %s has %d NMRS\n", factionid(f), nmr);
                nmr = _max(0, nmr);
                nmr = _min(nmr, NMRTimeout());
            }
            ++nmrs[nmr];
        }
    }
    return newplayers;
}
Exemplo n.º 3
0
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);
    }
}
Exemplo n.º 4
0
void age_ghoul(unit * u)
{
  if (is_monsters(u->faction) && rng_int() % 100 < age_chance(u->age, 27, 1)) {
    int n = _max(1, u->number / 2);
    double q = (double)u->hp / (double)(unit_max_hp(u) * u->number);
    u_setrace(u, get_race(RC_GHOUL_LORD));
    u->irace = NULL;
    scale_number(u, n);
    u->hp = (int)(unit_max_hp(u) * u->number * q);
  }
}
Exemplo n.º 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();
}
Exemplo n.º 6
0
void age_zombie(unit * u)
{
    if (is_monsters(u->faction) && rng_int() % 100 < age_chance(u->age, 27, 1)) {
        int n = u->number / 2;
        double q = (double)u->hp / (double)(unit_max_hp(u) * u->number);
        if (n < 1) n = 1;
        u_setrace(u, get_race(RC_ZOMBIE_LORD));
        u->irace = NULL;
        scale_number(u, n);
        u->hp = (int)(unit_max_hp(u) * u->number * q);
    }
}
Exemplo n.º 7
0
guard_t can_start_guarding(const unit * u)
{
    if (u->status >= ST_FLEE || fval(u, UFL_FLEEING))
        return E_GUARD_FLEEING;
    /* Monster der Monsterpartei duerfen immer bewachen */
    if (is_monsters(u->faction) || fval(u_race(u), RCF_UNARMEDGUARD))
        return E_GUARD_OK;
    if (!armedmen(u, true))
        return E_GUARD_UNARMED;
    if (IsImmune(u->faction))
        return E_GUARD_NEWBIE;
    return E_GUARD_OK;
}
Exemplo n.º 8
0
int lifestyle(const unit * u)
{
    int need;
    plane *pl;
    static int gamecookie = -1;
    if (gamecookie != global.cookie) {
        gamecookie = global.cookie;
    }

    if (is_monsters(u->faction))
        return 0;

    need = maintenance_cost(u);

    pl = rplane(u->region);
    if (pl && fval(pl, PFL_NOFEED))
        return 0;

    return need;
}
Exemplo n.º 9
0
static bool is_guardian_r(const unit * guard)
{
    if (guard->number == 0)
        return false;
    if (besieged(guard))
        return false;

    /* if region_owners exist then they may be guardians: */
    if (guard->building && rule_region_owners() && guard == building_owner(guard->building)) {
        faction *owner = region_get_owner(guard->region);
        if (owner == guard->faction) {
            building *bowner = largestbuilding(guard->region, &cmp_taxes, false);
            if (bowner == guard->building) {
                return true;
            }
        }
    }

    if ((guard->flags & UFL_GUARD) == 0)
        return false;
    return fval(u_race(guard), RCF_UNARMEDGUARD) || is_monsters(guard->faction) || (armedmen(guard, true) > 0);
}
Exemplo n.º 10
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);
  }
}
Exemplo n.º 11
0
summary *make_summary(void)
{
    faction *f;
    region *r;
    unit *u;
    summary *s = calloc(1, sizeof(summary));
    const struct resource_type *rhorse = get_resourcetype(R_HORSE);

  for (f = factions; f; f = f->next) {
    const struct locale *lang = f->locale;
    struct language *plang = s->languages;
    while (plang && plang->locale != lang)
      plang = plang->next;
    if (!plang) {
      plang = calloc(sizeof(struct language), 1);
      plang->next = s->languages;
      s->languages = plang;
      plang->locale = lang;
    }
    ++plang->number;
    f->nregions = 0;
    f->num_total = 0;
    f->money = 0;
    if (f->alive && f->units) {
      s->factions++;
      /* Problem mit Monsterpartei ... */
      if (!is_monsters(f)) {
        s->factionrace[old_race(f->race)]++;
      }
    }
  }

  /* count everything */

  for (r = regions; r; r = r->next) {
    s->pferde += rhorses(r);
    s->schiffe += listlen(r->ships);
    s->gebaeude += listlen(r->buildings);
    if (!fval(r->terrain, SEA_REGION)) {
      s->landregionen++;
      if (r->units) {
        s->landregionen_mit_spielern++;
      }
      if (fval(r, RF_ORCIFIED)) {
        s->orkifizierte_regionen++;
      }
      if (r->terrain == newterrain(T_VOLCANO)) {
        s->inactive_volcanos++;
      } else if (r->terrain == newterrain(T_VOLCANO_SMOKING)) {
        s->active_volcanos++;
      }
    }
    if (r->units) {
      s->regionen_mit_spielern++;
    }
    if (rpeasants(r) || r->units) {
      s->inhabitedregions++;
      s->peasants += rpeasants(r);
      s->peasantmoney += rmoney(r);

      /* Einheiten Info. nregions darf nur einmal pro Partei
       * incrementiert werden. */

      for (u = r->units; u; u = u->next)
        freset(u->faction, FFL_SELECT);
      for (u = r->units; u; u = u->next) {
        f = u->faction;
        if (!is_monsters(u->faction)) {
          skill *sv;
          item *itm;

          s->nunits++;
          s->playerpop += u->number;
          if (u->flags & UFL_HERO) {
            s->heroes += u->number;
          }
          s->spielerpferde += i_get(u->items, rhorse->itype);
          s->playermoney += get_money(u);
          s->armed_men += armedmen(u, true);
          for (itm = u->items; itm; itm = itm->next) {
            if (itm->type->rtype->wtype) {
              s->waffen += itm->number;
            }
            if (itm->type->rtype->atype) {
              s->ruestungen += itm->number;
            }
          }

          s->spielerpferde += i_get(u->items, rhorse->itype);

          for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
            skill_t sk = sv->id;
            int aktskill = eff_skill(u, sk, r);
            if (aktskill > s->maxskill)
              s->maxskill = aktskill;
          }
          if (!fval(f, FFL_SELECT)) {
            f->nregions++;
            fset(f, FFL_SELECT);
          }
        }

        f->num_total += u->number;
        f->money += get_money(u);
        s->poprace[old_race(u_race(u))] += u->number;
      }
    }
  }

  return s;
}
Exemplo n.º 12
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();
}
Exemplo n.º 13
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();
}