/** callback to initialize a familiar from lua. */ static int lua_initfamiliar(unit * u) { lua_State *L = (lua_State *)global.vm_state; char fname[64]; int result = -1; strlcpy(fname, "initfamiliar_", sizeof(fname)); strlcat(fname, u_race(u)->_name, sizeof(fname)); lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, u, TOLUA_CAST "unit"); if (lua_pcall(L, 1, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("familiar(%s) calling '%s': %s.\n", unitname(u), fname, error); lua_pop(L, 1); } else { result = (int)lua_tonumber(L, -1); lua_pop(L, 1); } } else { log_warning("familiar(%s) calling '%s': not a function.\n", unitname(u), fname); lua_pop(L, 1); } create_mage(u, M_GRAY); strlcpy(fname, u_race(u)->_name, sizeof(fname)); strlcat(fname, "_familiar", sizeof(fname)); equip_unit(u, get_equipment(fname)); return result; }
static int lua_maintenance(const unit * u) { lua_State *L = (lua_State *)global.vm_state; const char *fname = "maintenance"; int result = -1; lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); if (lua_pcall(L, 1, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("maintenance(%s) calling '%s': %s.\n", unitname(u), fname, error); lua_pop(L, 1); } else { result = (int)lua_tonumber(L, -1); lua_pop(L, 1); } } else { log_error("maintenance(%s) calling '%s': not a function.\n", unitname(u), fname); lua_pop(L, 1); } return result; }
static int lua_equipmentcallback(const struct equipment *eq, unit * u) { lua_State *L = (lua_State *)global.vm_state; char fname[64]; int result = -1; strlcpy(fname, "equip_", sizeof(fname)); strlcat(fname, eq->name, sizeof(fname)); lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); if (lua_pcall(L, 1, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("equip(%s) calling '%s': %s.\n", unitname(u), fname, error); lua_pop(L, 1); } else { result = (int)lua_tonumber(L, -1); lua_pop(L, 1); } } else { log_error("equip(%s) calling '%s': not a function.\n", unitname(u), fname); lua_pop(L, 1); } return result; }
/** callback for an item-use function written in lua. */ int lua_useitem(struct unit *u, const struct item_type *itype, int amount, struct order *ord) { lua_State *L = (lua_State *)global.vm_state; int result = 0; char fname[64]; strlcpy(fname, "use_", sizeof(fname)); strlcat(fname, itype->rtype->_name, sizeof(fname)); lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); lua_pushinteger(L, amount); lua_pushstring(L, getstrtoken()); tolua_pushusertype(L, (void *)ord, TOLUA_CAST "order"); if (lua_pcall(L, 4, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error); lua_pop(L, 1); } else { result = (int)lua_tonumber(L, -1); lua_pop(L, 1); } } else { log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname); lua_pop(L, 1); } return result; }
static int lua_changeresource(unit * u, const struct resource_type *rtype, int delta) { lua_State *L = (lua_State *)global.vm_state; int len, result = -1; char fname[64]; len = snprintf(fname, sizeof(fname), "%s_changeresource", rtype->_name); if (len > 0 && (size_t)len < sizeof(fname)) { lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, u, TOLUA_CAST "unit"); lua_pushinteger(L, delta); if (lua_pcall(L, 2, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("change(%s) calling '%s': %s.\n", unitname(u), fname, error); lua_pop(L, 1); } else { result = (int)lua_tonumber(L, -1); lua_pop(L, 1); } } else { log_error("change(%s) calling '%s': not a function.\n", unitname(u), fname); lua_pop(L, 1); } } return result; }
static int lua_getresource(unit * u, const struct resource_type *rtype) { lua_State *L = (lua_State *)global.vm_state; int result = -1; char fname[64]; strlcpy(fname, rtype->_name, sizeof(fname)); strlcat(fname, "_getresource", sizeof(fname)); lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, u, TOLUA_CAST "unit"); if (lua_pcall(L, 1, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("get(%s) calling '%s': %s.\n", unitname(u), fname, error); lua_pop(L, 1); } else { result = (int)lua_tonumber(L, -1); lua_pop(L, 1); } } else { log_error("get(%s) calling '%s': not a function.\n", unitname(u), fname); lua_pop(L, 1); } return result; }
static bool lua_canuse_item(const unit * u, const struct item_type *itype) { bool result = true; lua_State *L = (lua_State *)global.vm_state; const char *fname = "item_canuse"; lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); tolua_pushstring(L, itype->rtype->_name); if (lua_pcall(L, 2, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error); lua_pop(L, 1); } else { result = lua_toboolean(L, -1); lua_pop(L, 1); } } else { log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname); lua_pop(L, 1); } return result; }
/** callback to use lua for spell functions */ static int lua_callspell(castorder * co, const char *fname) { lua_State *L = (lua_State *)global.vm_state; unit *caster = co_get_caster(co); region * r = co_get_region(co); int result = -1; lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { int nparam = 4; tolua_pushusertype(L, r, TOLUA_CAST "region"); tolua_pushusertype(L, caster, TOLUA_CAST "unit"); lua_pushinteger(L, co->level); lua_pushnumber(L, co->force); if (co->sp->parameter && co->par->length) { const char *synp = co->sp->parameter; int i = 0; ++nparam; lua_newtable(L); while (*synp && i < co->par->length) { spllprm *param = co->par->param[i]; char c = *synp; if (c == '+') { push_param(L, *(synp - 1), param); } else { push_param(L, c, param); ++synp; } lua_rawseti(L, -2, ++i); } } if (lua_pcall(L, nparam, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("spell(%s) calling '%s': %s.\n", unitname(caster), fname, error); lua_pop(L, 1); } else { result = (int)lua_tonumber(L, -1); lua_pop(L, 1); } } else { int ltype = lua_type(L, -1); log_error("spell(%s) calling '%s': not a function, has type %d.\n", unitname(caster), fname, ltype); lua_pop(L, 1); } return result; }
/** callback to use lua functions isntead of equipment */ static bool lua_equipunit(unit *u, const char *eqname, int mask) { lua_State *L = (lua_State *)global.vm_state; bool result = false; static bool disabled = false; if (disabled) { return false; } lua_getglobal(L, "equip_unit"); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, u, TOLUA_CAST "unit"); lua_pushstring(L, eqname); lua_pushinteger(L, mask); if (lua_pcall(L, 3, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("equip(%s) with '%s/%d': %s.\n", unitname(u), eqname, mask, error); lua_pop(L, 1); } else { result = lua_toboolean(L, -1) != 0; lua_pop(L, 1); } } else { disabled = true; } return result; }
static order *monster_seeks_target(region * r, unit * u) { direction_t d; unit *target = NULL; int dist, dist2; direction_t i; region *nr; /* Das Monster sucht ein bestimmtes Opfer. Welches, steht * in einer Referenz/attribut * derzeit gibt es nur den alp */ switch (old_race(u_race(u))) { case RC_ALP: target = alp_target(u); break; default: assert(!"Seeker-Monster gibt kein Ziel an"); } /* TODO: prüfen, ob target überhaupt noch existiert... */ if (!target) { log_error("Monster '%s' hat kein Ziel!\n", unitname(u)); return NULL; /* this is a bug workaround! remove!! */ } if (r == target->region) { /* Wir haben ihn! */ if (u_race(u) == get_race(RC_ALP)) { alp_findet_opfer(u, r); } else { assert(!"Seeker-Monster hat keine Aktion fuer Ziel"); } return NULL; } /* Simpler Ansatz: Nachbarregion mit gerinster Distanz suchen. * Sinnvoll momentan nur bei Monstern, die sich nicht um das * Terrain kümmern. Nebelwände & Co machen derzeit auch nix... */ dist2 = distance(r, target->region); d = NODIRECTION; for (i = 0; i < MAXDIRECTIONS; i++) { nr = rconnect(r, i); assert(nr); dist = distance(nr, target->region); if (dist < dist2) { dist2 = dist; d = i; } } assert(d != NODIRECTION); return create_order(K_MOVE, u->faction->locale, "%s", LOC(u->faction->locale, directions[d])); }
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; }
inline std::string unitTypeName(const UnitLink *pUnit) { std::ostringstream convert; if (pUnit && pUnit->id()) { std::wstring unitname(pUnit->name()); std::string un(unitname.begin(), unitname.end()); convert << un; } else { convert << "unit"; } return convert.str(); }
/** 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; } } } } }
void unit_add_spell(unit * u, sc_mage * m, struct spell * sp, int level) { sc_mage *mage = m ? m : get_mage(u); if (!mage) { log_debug("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u)); mage = create_mage(u, u->faction?u->faction->magiegebiet:M_GRAY); } if (!mage->spellbook) { mage->spellbook = create_spellbook(0); } spellbook_add(mage->spellbook, sp, level); }
static int lua_giveitem(unit * s, unit * d, const item_type * itype, int n, struct order *ord) { lua_State *L = (lua_State *)global.vm_state; char fname[64]; int result = -1; const char *iname = itype->rtype->_name; assert(s != NULL); strlcpy(fname, iname, sizeof(fname)); strlcat(fname, "_give", sizeof(fname)); lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, s, TOLUA_CAST "unit"); tolua_pushusertype(L, d, TOLUA_CAST "unit"); tolua_pushstring(L, iname); lua_pushinteger(L, n); if (lua_pcall(L, 4, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("unit %s calling '%s': %s.\n", unitname(s), fname, error); lua_pop(L, 1); } else { result = (int)lua_tonumber(L, -1); lua_pop(L, 1); } } else { log_error("unit %s trying to call '%s' : not a function.\n", unitname(s), fname); lua_pop(L, 1); } return result; }
/** callback for an item-use function written in lua. */ static int lua_use_item(unit *u, const item_type *itype, const char * fname, int amount, struct order *ord) { lua_State *L = (lua_State *)global.vm_state; lua_getglobal(L, fname); if (lua_isfunction(L, -1)) { tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); lua_pushinteger(L, amount); lua_pushstring(L, getstrtoken()); tolua_pushusertype(L, (void *)ord, TOLUA_CAST "order"); if (lua_pcall(L, 4, 1, 0) != 0) { const char *error = lua_tostring(L, -1); log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error); } else { int result = (int)lua_tonumber(L, -1); lua_pop(L, 1); return result; } } lua_pop(L, 1); return 0; }
static int use_item_callback(unit *u, const item_type *itype, int amount, struct order *ord) { int len; char fname[64]; len = snprintf(fname, sizeof(fname), "use_%s", itype->rtype->_name); if (len > 0 && (size_t)len < sizeof(fname)) { int result; int(*callout)(unit *, const item_type *, int, struct order *); /* check if we have a register_item_use function */ callout = (int(*)(unit *, const item_type *, int, struct order *))get_function(fname); if (callout) { return callout(u, itype, amount, ord); } /* check if we have a matching lua function */ result = lua_use_item(u, itype, fname, amount, ord); if (result != 0) { return result; } /* if the item is a potion, try use_potion, the generic function for * potions that add an effect: */ if (itype->flags & ITF_POTION) { return use_potion(u, itype, amount, ord); } else { log_error("no such callout: %s", fname); } log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname); } return 0; }
static int aoegen(Chan *c, char *, Dirtab *, int, int s, Dir *dp) { int i; Aoedev *d; Qid q; if(c->qid.path == 0){ switch(s){ case DEVDOTDOT: q.path = 0; q.type = QTDIR; devdir(c, q, "#æ", 0, eve, 0555, dp); break; case 0: q.path = Qtopdir; q.type = QTDIR; devdir(c, q, "aoe", 0, eve, 0555, dp); break; default: return -1; } return 1; } switch(TYPE(c->qid)){ default: return -1; case Qtopdir: if(s == DEVDOTDOT){ mkqid(&q, Qzero, 0, QTDIR); devdir(c, q, "aoe", 0, eve, 0555, dp); return 1; } if(s < Qtopfiles) return topgen(c, Qtopbase + s, dp); s -= Qtopfiles; if(s >= units.ref) return -1; mkqid(&q, QID(s, Qunitdir), 0, QTDIR); d = unit2dev(s); assert(d != nil); devdir(c, q, unitname(d), 0, eve, 0555, dp); return 1; case Qtopctl: case Qtoplog: return topgen(c, TYPE(c->qid), dp); case Qunitdir: if(s == DEVDOTDOT){ mkqid(&q, QID(0, Qtopdir), 0, QTDIR); uprint("%uld", UNIT(c->qid)); devdir(c, q, up->genbuf, 0, eve, 0555, dp); return 1; } return unitgen(c, Qunitbase+s, dp); case Qctl: case Qdata: case Qconfig: case Qident: return unitgen(c, TYPE(c->qid), dp); case Qdevlinkdir: i = UNIT(c->qid); if(s == DEVDOTDOT){ mkqid(&q, QID(i, Qunitdir), 0, QTDIR); devdir(c, q, "devlink", 0, eve, 0555, dp); return 1; } if(i >= units.ref) return -1; d = unit2dev(i); if(s >= d->ndl) return -1; uprint("%d", s); mkqid(&q, Q3(s, i, Qdevlink), 0, QTFILE); devdir(c, q, up->genbuf, 0, eve, 0755, dp); return 1; case Qdevlink: uprint("%d", s); mkqid(&q, Q3(s, UNIT(c->qid), Qdevlink), 0, QTFILE); devdir(c, q, up->genbuf, 0, eve, 0755, dp); return 1; } }