Ejemplo n.º 1
0
void reduce_skill_days(unit *u, skill_t sk, int days) {
    skill *sv = unit_skill(u, sk);
    if (sv) {
        while (days > 0) {
            if (days >=  STUDYDAYS * u->number) {
                reduce_skill(u, sv, 1);
                days -= STUDYDAYS;
            }
            else {
                if (chance (days / ((double) STUDYDAYS * u->number))) /* (rng_int() % (30 * u->number) < days)*/
                    reduce_skill(u, sv, 1);
                days = 0;
            }
        }
    }
}
Ejemplo n.º 2
0
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;
                    double dmg = config_get_flt("rules.ship.damage.godcurse", 0.1);
                    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;
                }
            }
        }
    }

}
Ejemplo n.º 3
0
/** Talente von Dämonen verschieben sich.
 */
static void demon_skillchanges(void)
{
  region *r;

  for (r = regions; r; r = r->next) {
    unit *u;
    for (u = r->units; u; u = u->next) {
        if (u_race(u) == get_race(RC_DAEMON)) {
        skill *sv = u->skills;
        int upchance = 15;
        int downchance = 10;

        if (fval(u, UFL_HUNGER)) {
          /* hungry demons only go down, never up in skill */
          static int rule_hunger = -1;
          if (rule_hunger < 0) {
            rule_hunger =
              get_param_int(global.parameters, "hunger.demon.skill", 0);
          }
          if (rule_hunger) {
            upchance = 0;
            downchance = 15;
          }
        }

        while (sv != u->skills + u->skill_size) {
          int roll = rng_int() % 100;
          if (sv->level > 0 && roll < upchance + downchance) {
            int weeks = 1 + rng_int() % 3;
            if (roll < downchance) {
              reduce_skill(u, sv, weeks);
              if (sv->level < 1) {
                /* demons should never forget below 1 */
                set_level(u, sv->id, 1);
              }
            } else {
              while (weeks--)
                learn_skill(u, sv->id, 1.0);
            }
            if (sv->old > sv->level) {
              if (verbosity >= 3) {
                log_printf(stdout, "%s dropped from %u to %u:%u in %s\n",
                  unitname(u), sv->old, sv->level, sv->weeks, skillname(sv->id,
                    NULL));
              }
            }
          }
          ++sv;
        }
      }
    }
  }
}
Ejemplo n.º 4
0
/** Talente von Daemonen verschieben sich.
*/
void demon_skillchange(unit *u)
{
    skill *sv = u->skills;
    int upchance = 15, downchance = 10;
    static int config;
    static bool rule_hunger;
    static int cfgup, cfgdown;

    if (config_changed(&config)) {
        rule_hunger = config_get_int("hunger.demon.skills", 0) != 0;
        cfgup = config_get_int("skillchange.demon.up", 15);
        cfgdown = config_get_int("skillchange.demon.down", 10);
    }
    if (cfgup == 0) {
        /* feature is disabled */
        return;
    }
    upchance = cfgup;
    downchance = cfgdown;

    if (fval(u, UFL_HUNGER)) {
        /* hungry demons only go down, never up in skill */
        if (rule_hunger) {
            downchance = upchance;
            upchance = 0;
        }
    }

    while (sv != u->skills + u->skill_size) {
        int roll = rng_int() % 100;
        if (sv->level > 0 && roll < upchance + downchance) {
            int weeks = 1 + rng_int() % 3;
            if (roll < downchance) {
                reduce_skill(u, sv, weeks);
                if (sv->level < 1) {
                    /* demons should never forget below 1 */
                    set_level(u, sv->id, 1);
                }
            }
            else {
                learn_skill(u, sv->id, STUDYDAYS * u->number * weeks);
            }
        }
        ++sv;
    }
}
Ejemplo n.º 5
0
static int
use_wand_of_tears(unit * user, const struct item_type *itype, int amount,
  order * ord)
{
  int n;
  unused(ord);
  for (n = 0; n != amount; ++n) {
    unit *u;
    for (u = user->region->units; u; u = u->next) {
      if (u->faction != user->faction) {
        int i;

        for (i = 0; i != u->skill_size; ++i) {
          if (rng_int() % 3)
            reduce_skill(u, u->skills + i, 1);
        }
        ADDMSG(&u->faction->msgs, msg_message("wand_of_tears_effect",
            "unit", u));
      }
    }
  }
  ADDMSG(&user->region->msgs, msg_message("wand_of_tears_usage", "unit", user));
  return 0;
}
Ejemplo n.º 6
0
Archivo: shock.c Proyecto: mideg/server
static void do_shock(unit * u, const char *reason)
{
  int i;

  if (u->number > 0) {
    /* HP - Verlust */
    u->hp = (unit_max_hp(u) * u->number) / 10;
    u->hp = _max(1, u->hp);
  }

  /* Aura - Verlust */
  if (is_mage(u)) {
    set_spellpoints(u, max_spellpoints(u->region, u) / 10);
  }

  /* Evt. Talenttageverlust */
  for (i = 0; i != u->skill_size; ++i)
    if (rng_int() % 5 == 0) {
      skill *sv = u->skills + i;
      int weeks = (sv->level * sv->level - sv->level) / 2;
      int change = (weeks + 9) / 10;
      reduce_skill(u, sv, change);
    }

  /* Dies ist ein Hack, um das skillmod und familiar-Attribut beim Mage
   * zu löschen wenn der Familiar getötet wird. Da sollten wir über eine
   * saubere Implementation nachdenken. */

  if (strcmp(reason, "trigger") == 0) {
    remove_familiar(u);
  }
  if (u->faction != NULL) {
    ADDMSG(&u->faction->msgs, msg_message("shock",
        "mage reason", u, _strdup(reason)));
  }
}
Ejemplo n.º 7
0
/** A mind blast spell for monsters.
 * This spell PERMANENTLY reduces the skill of the victims or kills them
 * when they have no skills left. Not currently in use.
 */
int sp_mindblast(struct castorder * co)
{
    fighter * fi = co->magician.fig;
    int level = co->level;
    double power = co->force;
    const spell * sp = co->sp;
    battle *b = fi->side->battle;
    unit *mage = fi->unit;
    int killed = 0, k = 0, reset = 0;
    message *m;
    int force = lovar(power * 25);
    int enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);

    if (!enemies) {
        m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
        message_all(b, m);
        msg_release(m);
        return 0;
    }

    while (enemies > 0 && force > 0) {
        unit *du;
        troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);

        assert(dt.fighter);
        du = dt.fighter->unit;
        if (du->flags & UFL_MARK) {
            /* not this one again */
            continue;
        }

        if (humanoidrace(u_race(du)) && force >= du->number) {
            if (!is_magic_resistant(mage, du, 0)) {
                skill_t sk = random_skill(du, false);
                if (sk != NOSKILL) {
                    skill *sv = unit_skill(du, sk);
                    if (sv) {
                        int n = 1 + rng_int() % 3;

                        reduce_skill(du, sv, n);
                        k += du->number;
                    }
                }
                else {
                    /* unit has no skill. kill it. */
                    kill_troop(dt);
                    ++killed;
                }
            }
            force -= du->number;
        }
        else {
            /* only works against humanoids, don't try others. but do remove them
             * from 'force' once or we may never terminate. */
            du->flags |= UFL_MARK;
            reset = 1;
        }
        enemies -= du->number;
    }

    if (reset) {
        unit *u;
        for (u = b->region->units; u; u = u->next) {
            u->flags &= ~UFL_MARK;
        }
    }

    m =
        msg_message("sp_mindblast_effect", "mage spell amount dead", mage, sp, k,
        killed);
    message_all(b, m);
    msg_release(m);
    return level;
}