// startTalking() // startTalking opens the conversation screen and returns its interface. int talk_lua_start(lua_State *L) { lua_getfield(L, LUA_REGISTRYINDEX, "game/stateStack"); if (lua_isnil(L, -1)) { return luaL_error(L, "game not initialized yet"); } state_stack *stack = (state_stack*) lua_touserdata(L, -1); lua_pop(L, 1); state_desc *top = (state_desc*) table_ind(stack, stack->m_len-1); int i; if (lua_getctx(L, &i) == LUA_OK) { top->m_fnPushChild = _talk_push; top->m_pChildData = (void*) L; return lua_yieldk(L, 0, 0, talk_lua_start); } luaL_Reg funcs[] = { { "resetChoices", _lua_resetchoices }, { "addChoice", _lua_addchoice }, { "offerChoice", _lua_offerchoice }, { "wait", _lua_wait }, { "say", _lua_say }, { "stop", _lua_stop }, { nullptr, nullptr }, }; luaL_newlibtable(L, funcs); top = (state_desc*) table_ind(stack, stack->m_len-1); lua_pushlightuserdata(L, top->m_pData); luaL_setfuncs(L, funcs, 1); return 1; }
static int pcallcont (lua_State *L) { int errfunc = 0; /* =0 to avoid warnings */ int status = lua_getctx(L, &errfunc); lua_assert(status != LUA_OK); lua_pushboolean(L, (status == LUA_YIELD)); /* first result (status) */ if (errfunc) /* came from xpcall? */ lua_replace(L, 1); /* put first result in place of error function */ else /* came from pcall */ lua_insert(L, 1); /* open space for first result */ return lua_gettop(L); }
static int try_protected(lua_State *L){ int status; lua_KContext ctx; #if LUA_VERSION_NUM == 502 status = lua_getctx(L, &ctx); #else status = LUA_OK; ctx = 0; #endif return try_protected_k(L, status, ctx); }
// wait() // wait blocks (yields to the C code), waiting until the user is ready to continue. // Call this in situations where a "press any key to continue" prompt would be appropriate. int _lua_wait(lua_State *L) { _talk_state *st = (_talk_state*) lua_touserdata(L, lua_upvalueindex(1)); int ctx, status; if (st->m_iState == _STOPPED) { return luaL_error(L, "conversation is already stopped"); } status = lua_getctx(L, &ctx); if (status == LUA_YIELD) { return 0; } st->m_iState = _WAIT_ANY; st->m_pThread = L; return lua_yieldk(L, 0, 0, _lua_wait); }
// offerChoice() // offerChoice blocks (yields to the C code) until the user makes a choice, returning // the 1-based index of the chosen option. int _lua_offerchoice(lua_State *L) { _talk_state *st = (_talk_state*) lua_touserdata(L, lua_upvalueindex(1)); int ctx, status; if (st->m_iState == _STOPPED) { return luaL_error(L, "conversation is already stopped"); } status = lua_getctx(L, &ctx); if (status == LUA_YIELD) { return 1; // choice should be pushed on the stack before resuming } if (status != LUA_OK) { sys_abort(); } menu_auto_resize(st->m_pChoices); st->m_iState = _WAIT_CHOICE; st->m_pThread = L; return lua_yieldk(L, 0, 0, _lua_offerchoice); }
static int pcallcont (lua_State *L) { int status = lua_getctx(L, NULL); return finishpcall(L, (status == LUA_YIELD)); }
static int protected_cont(lua_State *L) { int ctx = 0; int status = lua_getctx(L, &ctx); return protected_finish(L, status, ctx); }