int sl_doscript_stackargs(char *root, char *method, int nargs) { int argsindex = lua_gettop(sl_gstate) - (nargs - 1), errhandler, i; ; lua_getglobal(sl_gstate, "_errhandler"); errhandler = lua_gettop(sl_gstate); lua_getglobal(sl_gstate, root); if(lua_isnil(sl_gstate, -1)) { lua_pop(sl_gstate, 2 + nargs); // pop _errhandler, the table, and the args /*ntop=lua_gettop(sl_gstate); dif=ntop-top; printf("1Difference is %d\n",ntop-top); */ return 0; } lua_getfield(sl_gstate, -1, method); lua_replace(sl_gstate, -2); // essentially remove the table leaving only the field if(lua_isnil(sl_gstate, -1)) { lua_pop(sl_gstate, 2 + nargs); // pop _errhandler, the field, and the args /*ntop=lua_gettop(sl_gstate); dif=ntop-top; printf("2Difference is %d\n",ntop-top); */ return 0; } // push copies of the arguments onto the stack for(i = 0; i < nargs; ++i) lua_pushvalue(sl_gstate, argsindex + i); if(lua_pcall(sl_gstate, nargs, 0, errhandler) != 0) { sl_err_print(sl_gstate); lua_pop(sl_gstate, 1); // pop the error string /*ntop=lua_gettop(sl_gstate); dif=ntop-top; //if(dif<(nargs+2)) printf("3Difference is %d\n",dif);*/ } lua_pop(sl_gstate, nargs+1); // pop the original arguments, and _errhandler /*ntop=lua_gettop(sl_gstate); dif=ntop-top; printf("Difference is %d\n",dif);*/ return 1; } int sl_doscript_blargs(char *root, char *method, int nargs, ...) { int i; struct block_list *bl=NULL; va_list argp; va_start(argp, nargs); for(i = 0; i < nargs; ++i) { bl=NULL; bl = va_arg(argp, struct block_list *); bll_pushinst(sl_gstate, bl, 0); //if(bl) newargs++; } va_end(argp); return sl_doscript_stackargs(root, method, nargs); } void bll_pushinst(lua_State *state, struct block_list *bl, void *param) { if(!bl) { lua_pushnil(state); return; } if(bl->type == BL_PC) { struct map_sessiondata *sd = map_id2sd(bl->id); typel_pushinst(state, &pcl_type, sd, param); } else if(bl->type == BL_MOB) { struct mobspawn_data *mob = (struct mobspawn_data *)bl; typel_pushinst(state, &mobl_type, mob, param); } else if(bl->type == BL_NPC) { struct npc_data *nd = (struct npc_data *)bl; typel_pushinst(state, &npcl_type, nd, param); } else if(bl->type == BL_ITEM) { struct flooritem_data *fl = (struct flooritem_data*)bl; typel_pushinst(state, &fll_type, fl, param); } else lua_pushnil(state); // TODO: should this be an error? } void typel_pushinst(lua_State *state, typel_class *type, void *self, void *param) { typel_inst *inst = lua_newuserdata(state, sizeof(typel_inst)); inst->self = self; inst->type = type; sl_pushref(state, typel_mtref); // set the metatable lua_setmetatable(state, -2); lua_newtable(state); // create a new data table and store a ref inst->dataref = luaL_ref(state, LUA_REGISTRYINDEX); if(type->init && inst->self) { type->init(state, inst->self, inst->dataref, param); } //else { luaL_error(state,"dataref no longer exists"); } }