Exemple #1
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;
                }
            }
        }
    }

}
Exemple #2
0
static 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 =
                        create_unit(r, get_monsters(), rng_int() % 8 + 1,
                        get_race(RC_FIREDRAGON), 0, NULL, NULL);
                    break;
                case 1:
                    mfac = 500;
                    u =
                        create_unit(r, get_monsters(), rng_int() % 4 + 1,
                        get_race(RC_DRAGON), 0, NULL, NULL);
                    break;
                default:
                    mfac = 1000;
                    u =
                        create_unit(r, get_monsters(), rng_int() % 2 + 1,
                        get_race(RC_WYRM), 0, NULL, NULL);
                    break;
                }
                if (mfac)
                    set_money(u, u->number * (rng_int() % mfac));
                fset(u, UFL_ISNEW | UFL_MOVED);
            }
            break;
        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;
                            double dmg =
                                config_get_flt("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());
                    }
                }
            }
        }
    }
}
Exemple #3
0
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 */
                double dmg = config_get_flt("rules.ship.damage.intoiceberg", 0.1);
                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) {
                double dmg = config_get_flt("rules.ship.damage.withiceberg", 0.1);
                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));
                }
        }
    }
}