Beispiel #1
0
static int limit_resource(const region * r, const resource_type * rtype)
{
    char fname[64];
    int result = -1;
    lua_State *L = (lua_State *)global.vm_state;

    strlcpy(fname, rtype->_name, sizeof(fname));
    strlcat(fname, "_limit", sizeof(fname));

    lua_getglobal(L, fname);
    if (lua_isfunction(L, -1)) {
        tolua_pushusertype(L, (void *)r, TOLUA_CAST "region");

        if (lua_pcall(L, 1, 1, 0) != 0) {
            const char *error = lua_tostring(L, -1);
            log_error("limit(%s) calling '%s': %s.\n", regionname(r, NULL), fname, error);
            lua_pop(L, 1);
        }
        else {
            result = (int)lua_tonumber(L, -1);
            lua_pop(L, 1);
        }
    }
    else {
        log_error("limit(%s) calling '%s': not a function.\n", regionname(r, NULL), fname);
        lua_pop(L, 1);
    }

    return result;
}
Beispiel #2
0
static int
lua_wage(const region * r, const faction * f, const race * rc, int in_turn)
{
    lua_State *L = (lua_State *)global.vm_state;
    const char *fname = "wage";
    int result = -1;

    lua_getglobal(L, fname);
    if (lua_isfunction(L, -1)) {
        tolua_pushusertype(L, (void *)r, TOLUA_CAST "region");
        tolua_pushusertype(L, (void *)f, TOLUA_CAST "faction");
        tolua_pushstring(L, rc ? rc->_name : 0);
        lua_pushinteger(L, in_turn);

        if (lua_pcall(L, 3, 1, 0) != 0) {
            const char *error = lua_tostring(L, -1);
            log_error("wage(%s) calling '%s': %s.\n", regionname(r, NULL), fname, error);
            lua_pop(L, 1);
        }
        else {
            result = (int)lua_tonumber(L, -1);
            lua_pop(L, 1);
        }
    }
    else {
        log_error("wage(%s) calling '%s': not a function.\n", regionname(r, NULL), fname);
        lua_pop(L, 1);
    }

    return result;
}
Beispiel #3
0
static void
produce_resource(region * r, const resource_type * rtype, int norders)
{
    lua_State *L = (lua_State *)global.vm_state;
    char fname[64];

    strlcpy(fname, rtype->_name, sizeof(fname));
    strlcat(fname, "_produce", sizeof(fname));

    lua_getglobal(L, fname);
    if (lua_isfunction(L, -1)) {
        tolua_pushusertype(L, (void *)r, TOLUA_CAST "region");
        lua_pushinteger(L, norders);

        if (lua_pcall(L, 2, 0, 0) != 0) {
            const char *error = lua_tostring(L, -1);
            log_error("produce(%s) calling '%s': %s.\n", regionname(r, NULL), fname, error);
            lua_pop(L, 1);
        }
    }
    else {
        log_error("produce(%s) calling '%s': not a function.\n", regionname(r, NULL), fname);
        lua_pop(L, 1);
    }
}
Beispiel #4
0
region *new_region(int x, int y, struct plane *pl, int uid)
{
    region *r;

    pnormalize(&x, &y, pl);
    r = rfindhash(x, y);

    if (r) {
        log_error("duplicate region discovered: %s(%d,%d)\n", regionname(r, NULL), x, y);
        if (r->units)
            log_error("duplicate region contains units\n");
        return r;
    }
    r = calloc(1, sizeof(region));
    r->x = x;
    r->y = y;
    r->uid = uid;
    r->age = 1;
    r->_plane = pl;
    rhash(r);
    hash_uid(r);
    if (last)
        addlist(&last, r);
    else
        addlist(&regions, r);
    last = r;
    assert(r->next == NULL);
    r->index = ++max_index;
    return r;
}
Beispiel #5
0
int sp_igjarjuk(castorder *co) {
    unit *u;
    fighter *fm = co->magician.fig, *fi;
    const race *rc = get_race(RC_WYRM);
    fi = summon_allies(fm, rc, 1);
    u = fi->unit;
    unit_setname(u, "Igjarjuk");
    log_info("%s summons Igjarjuk in %s", unitname(fm->unit), regionname(u->region, 0));
    return co->level;
}
Beispiel #6
0
static int tolua_region_tostring(lua_State * L)
{
    region *self = (region *)tolua_tousertype(L, 1, 0);
    lua_pushstring(L, regionname(self, NULL));
    return 1;
}
Beispiel #7
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));
            }
        }
    }
}
Beispiel #8
0
/** Drachen und Seeschlangen können entstehen */
void spawn_dragons(void)
{
    region *r;
    faction *monsters = get_or_create_monsters();

    for (r = regions; r; r = r->next) {
        unit *u;

        if (fval(r->terrain, SEA_REGION) && rng_int() % 10000 < 1) {
            u = create_unit(r, monsters, 1, get_race(RC_SEASERPENT), 0, NULL, NULL);
            fset(u, UFL_ISNEW | UFL_MOVED);
            equip_unit(u, get_equipment("monster_seaserpent"));
        }

        if ((r->terrain == newterrain(T_GLACIER)
            || r->terrain == newterrain(T_SWAMP)
            || r->terrain == newterrain(T_DESERT))
            && rng_int() % 10000 < (5 + 100 * chaosfactor(r))) {
            if (chance(0.80)) {
                u = create_unit(r, monsters, nrand(60, 20) + 1, get_race(RC_FIREDRAGON), 0, NULL, NULL);
            }
            else {
                u = create_unit(r, monsters, nrand(30, 20) + 1, get_race(RC_DRAGON), 0, NULL, NULL);
            }
            fset(u, UFL_ISNEW | UFL_MOVED);
            equip_unit(u, get_equipment("monster_dragon"));

            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));

            name_unit(u);

            /* add message to the region */
            ADDMSG(&r->msgs,
                msg_message("sighting", "region race number", r, u_race(u), u->number));
        }
    }
}
int read_borders(gamedata *data)
{
    struct storage *store = data->store;
    for (;;) {
        int bid = 0;
        char zText[32];
        region *from, *to;
        border_type *type;

        READ_TOK(store, zText, sizeof(zText));
        if (!strcmp(zText, "end"))
            break;
        READ_INT(store, &bid);
        if (data->version < UIDHASH_VERSION) {
            int fx, fy, tx, ty;
            READ_INT(store, &fx);
            READ_INT(store, &fy);
            READ_INT(store, &tx);
            READ_INT(store, &ty);
            from = findregion(fx, fy);
            to = findregion(tx, ty);
        }
        else {
            int fid, tid;
            READ_INT(store, &fid);
            READ_INT(store, &tid);
            from = findregionbyid(fid);
            to = findregionbyid(tid);
            if (!to || !from) {
                log_warning("%s connection between incomplete regions %d and %d", zText, fid, tid);
                continue;
            }
        }

        type = find_bordertype(zText);
        if (type == NULL) {
            log_error("[read_borders] unknown connection type '%s' in %s\n", zText, regionname(from, NULL));
            assert(type || !"connection type not registered");
        }

        if (to == from && type && from) {
            direction_t dir = (direction_t)(rng_int() % MAXDIRECTIONS);
            region *r = rconnect(from, dir);
            log_error("[read_borders] invalid %s in %s\n", type->__name, regionname(from, NULL));
            if (r != NULL)
                to = r;
        }
        if ((type->read && !type->write)) {
            log_warning("ignore invalid border '%s' between '%s' and '%s'\n", zText, regionname(from, 0), regionname(to, 0));
        }
        else {
            connection *b = new_border(type, from, to);
            nextborder--;               /* new_border erhöht den Wert */
            b->id = bid;
            assert(bid <= nextborder);
            if (type->read) {
                type->read(b, data);
            }
            if (data->version < NOBORDERATTRIBS_VERSION) {
                attrib *a = NULL;
                int result = read_attribs(data, &a, b);
                if (border_convert_cb) {
                    border_convert_cb(b, a);
                }
                while (a) {
                    a_remove(&a, a);
                }
                if (result < 0) {
                    return result;
                }
            }
        }
    }
    return 0;
}