Ejemplo n.º 1
0
int luaX_script_unload(lua_State *L)
{
    const char *file = luaL_checkstring(L, 1);
    luna_script *result;

    luna_state *state = api_getstate(L);

    result = list_find(state->scripts, file, &script_cmp);

    if (!result)
    {
        return luaL_error(L, "script '%s' not loaded", file);
    }
    else
    {
        luna_script script = *result;

        if (script.state == L)
            return luaL_error(L, "cannot unload self");

        if (!script_unload(state, file))
            return luaX_push_scriptinfo(L, &script);
        else
            return luaL_error(L, "failed to load script '%s'", file);
    }
    return 0;
}
Ejemplo n.º 2
0
/*
 * Loads (or reloads) the Script created in the given Lua stack.  
 *
 * Assume a Script definition table (table_ref) has the form of
 *  { 'module' [, arg1 [, ... [, argn]]] }
 *
 * The module is `required' and then the function `new` is called on the table
 * that is returned from `require`. The args supplied in the script definition
 * are passed into the `new` function.
 *
 * Returns 0 if successful, 1 if an error occurs. If an error occurs, an error
 * string is pushed onto A.
 */
int
script_load (Script *script, lua_State *A)
{
    const char *module_name;
    const int table_index = lua_gettop(A) + 1; /* we push it onto the stack */
    int args, ret = 1;

    if (script->is_loaded)
        script_unload(script, A);

    lua_rawgeti(A, LUA_REGISTRYINDEX, script->table_ref);

    /* module = require 'module_name' */
    lua_getglobal(A, "require");
    utils_push_table_head(A, table_index);
    module_name = lua_tostring(A, -1);

    if (lua_pcall(A, 1, 1, 0)) {
        lua_pushfstring(A, "Cannot load module `%s': %s", 
                module_name, lua_tostring(A, -1));
        /* push error message beneath pcall error and table */
        lua_insert(A, lua_gettop(A) - 2);
        lua_pop(A, 2); /* pcall error and table */
        goto exit;
    }

    /* object = module.new(...) */
    lua_getfield(A, -1, "new");

    if (!lua_isfunction(A, -1)) {
        lua_pop(A, 3); /* 'new', item returned by `require`, and table */
        lua_pushfstring(A, "Cannot load module `%s': `new' is not a function!", 
                module_name);
        goto exit;
    }

    args = utils_push_table_data(A, table_index);

    if (lua_pcall(A, args, 1, 0)) {
        lua_pop(A, 2); /* pcall error, item returned by `require`, and table */
        lua_pushfstring(A, 
                "Cannot load module `%s': call to `new` failed with args", 
                module_name);
        goto exit;
    }

    script->object_ref = luaL_ref(A, LUA_REGISTRYINDEX);
    script->is_loaded = 1;
    ret = 0;
    lua_pop(A, 2); /* table returned from require and definition table */

exit:
    script->be_loaded = 0;
    return ret;
}
Ejemplo n.º 3
0
/*
 * Sends a Message to the object created from script_load.
 *
 * Assumes a message definition table at -1 in the form of
 *  { 'message' [, arg1 [, ... [, argn]]], author}
 *
 * The 'message' is some method of the instantiated object which was created in
 * script_load. If it doesn't exist it actually isn't an error. This is one of
 * those "it's a feature, not a bug" things -- by willing to say this isn't an
 * error we gain the ability to very easily add new message primitives (the
 * methods themselves) to the system.
 *
 * Returns 0 if successful, 1 if an error occurs. If an error occurs, an error
 * string is pushed onto A.
 */
int
script_send (Script *script, lua_State *A)
{
    const int message_index = lua_gettop(A);
    const int object_index = message_index + 1;
    const char *message = NULL;
    int args = 0;
    int ret = 1;

    /* 
     * object[message_title]:(arg1, arg2, ..., argN)
     */
    lua_rawgeti(A, LUA_REGISTRYINDEX, script->object_ref);

    utils_push_table_head(A, message_index);
    message = lua_tostring(A, -1);
    lua_gettable(A, -2);

    /* it's not an error if the function doesn't exist */
    if (!lua_isfunction(A, -1)) {
        lua_pop(A, 2); /* whatever isn't a function and the object_ref */
        goto success;
    }

    /* push `self' reference and tail of message which includes the author. */
    lua_pushvalue(A, object_index);
    args = utils_push_table_data(A, message_index);

    if (lua_pcall(A, args + 1, 0, 0)) {
        /* TODO: Figure out why the 'Cannot send message' isn't appearing */
        lua_pushfstring(A, "Cannot send message `%s': %s", 
                message, lua_tostring(A, -1));
        /* push error message beneath pcall error and object_ref */
        lua_insert(A, lua_gettop(A) - 2);
        lua_pop(A, 2); /* pcall error and object_ref */
        
        /* unload after the object has been popped or it won't gc */
        script_unload(script, A);
        goto exit;
    }
    
    lua_pop(A, 1); /* object_ref */

success:
    ret = 0;
exit:
    return ret;
}
Ejemplo n.º 4
0
Archivo: menu.c Proyecto: atrinik/dwc
/**
 * Analyze /cmd type commands the player has typed in the console or bound to a key.
 * Sort out the "client intern" commands and expand or pre process them for the server.
 * @param cmd Command to check
 * @return 0 to send command to server, 1 to not send it */
int client_command_check(char *cmd)
{
	if (!strncasecmp(cmd, "/ready_spell", 12))
	{
		cmd = strchr(cmd, ' ');

		if (!cmd || *++cmd == 0)
		{
			draw_info("Usage: /ready_spell <spell name>", COLOR_GREEN);
		}
		else
		{
			int i, ii;

			for (i = 0; i < SPELL_LIST_MAX; i++)
			{
				for (ii = 0; ii < DIALOG_LIST_ENTRY; ii++)
				{
					if (spell_list[i].entry[0][ii].flag >= LIST_ENTRY_USED)
					{
						if (!strcmp(spell_list[i].entry[0][ii].name, cmd))
						{
							if (spell_list[i].entry[0][ii].flag == LIST_ENTRY_KNOWN)
							{
								fire_mode_tab[FIRE_MODE_SPELL].spell = &spell_list[i].entry[0][ii];
								RangeFireMode = FIRE_MODE_SPELL;
								sound_play_effect("scroll.ogg", MENU_SOUND_VOL);
								draw_info("Spell ready.", COLOR_GREEN);
								return 1;
							}
						}
					}

					if (spell_list[i].entry[1][ii].flag >= LIST_ENTRY_USED)
					{
						if (!strcmp(spell_list[i].entry[1][ii].name, cmd))
						{
							if (spell_list[i].entry[1][ii].flag==LIST_ENTRY_KNOWN)
							{
								fire_mode_tab[FIRE_MODE_SPELL].spell = &spell_list[i].entry[1][ii];
								RangeFireMode = FIRE_MODE_SPELL;
								sound_play_effect("scroll.ogg", MENU_SOUND_VOL);
								draw_info("Spell ready.", COLOR_GREEN);
								return 1;
							}
						}
					}
				}
			}
		}

		draw_info("Unknown spell.", COLOR_GREEN);
		return 1;
	}
	else if (!strncasecmp(cmd, "/pray", 5))
	{
		/* Give out "You are at full grace." when needed -
		 * server will not send us anything when this happens */
		if (cpl.stats.grace == cpl.stats.maxgrace)
			draw_info("You are at full grace. You stop praying.", COLOR_WHITE);
	}
	else if (!strncasecmp(cmd, "/keybind", 8))
	{
		map_udate_flag = 2;

		if (cpl.menustatus != MENU_KEYBIND)
		{
			keybind_status = KEYBIND_STATUS_NO;
			cpl.menustatus = MENU_KEYBIND;
		}
		else
		{
			save_keybind_file(KEYBIND_FILE);
			cpl.menustatus = MENU_NO;
		}

		sound_play_effect("scroll.ogg", 100);
		reset_keys();
		return 1;
	}
	else if (!strncmp(cmd, "/target", 7))
	{
		/* Logic is: if first parameter char is a digit, is enemy, friend or self.
		 * If first char a character - then it's a name of a living object. */
		if (!strncmp(cmd, "/target friend", 14))
			strcpy(cmd, "/target 1");
		else if (!strncmp(cmd,"/target enemy", 13))
			strcpy(cmd, "/target 0");
		else if (!strncmp(cmd, "/target self", 12))
			strcpy(cmd, "/target 2");
	}
	else if (!strncmp(cmd, "/help", 5))
	{
		cmd += 5;

		if (cmd == NULL || strcmp(cmd, "") == 0)
			show_help("main");
		else
			show_help(cmd + 1);

		return 1;
	}
	else if (!strncmp(cmd, "/script ", 8))
	{
		cmd += 8;

		if (!strncmp(cmd, "load ", 5))
		{
			cmd += 5;

			script_load(cmd);
		}
		if (!strncmp(cmd, "unload ", 7))
		{
			cmd += 7;

			script_unload(cmd);
		}
		else if (!strncmp(cmd, "list", 4))
		{
			script_list();
		}
		else if (!strncmp(cmd, "send ", 5))
		{
			cmd += 5;

			script_send(cmd);
		}

		return 1;
	}
	else if (!strncmp(cmd, "/shop", 5))
	{
		if (!shop_gui)
		{
			initialize_shop(SHOP_STATE_NONE);
		}
		else
		{
			draw_info("You must close the shop window before trying to set up another shop.", COLOR_RED);
		}

		return 1;
	}
	else if (!strncmp(cmd, "/ignore", 7))
	{
		ignore_command(cmd + 7);
		return 1;
	}
	else if (!strncmp(cmd, "/reply", 6))
	{
		cmd = strchr(cmd, ' ');

		if (!cmd || *++cmd == '\0')
		{
			draw_info("Usage: /reply <message>", COLOR_RED);
		}
		else
		{
			if (!cpl.player_reply[0])
			{
				draw_info("There is no one you can /reply.", COLOR_RED);
			}
			else
			{
				char buf[2048];

				snprintf(buf, sizeof(buf), "/tell %s %s", cpl.player_reply, cmd);
				send_command(buf);
			}
		}

		return 1;
	}
	else if (!strncmp(cmd, "/resetwidgets", 13))
	{
		reset_widget(NULL);
		return 1;
	}
	else if (!strncmp(cmd, "/resetwidget", 12))
	{
		cmd = strchr(cmd, ' ');

		if (!cmd || *++cmd == '\0')
		{
			draw_info("Usage: /resetwidget <name>", COLOR_RED);
		}
		else
		{
			reset_widget(cmd);
		}

		return 1;
	}

	return 0;
}