示例#1
0
void display_popup_win (INPUT_POPUP *ipu, const char* label)
{
	widget_list *wok;
	widget_list *wno;

	if(ipu->popup_win < 0)
	{
		Uint32 flags = ELW_WIN_DEFAULT & ~ELW_CLOSE_BOX;
		ipu->popup_win = create_window (win_prompt, ipu->parent, 0, ipu->x, ipu->y, ipu->popup_x_len, ipu->popup_y_len, flags);

		// clear the buffer
		init_text_message (&ipu->popup_text, ipu->maxlen);
		set_text_message_color (&ipu->popup_text, 0.77f, 0.57f, 0.39f);

		// Label
		ipu->popup_label = label_add (ipu->popup_win, NULL, label, 5, 5);
		widget_set_color (ipu->popup_win, ipu->popup_label, 0.77f, 0.57f, 0.39f);

		// Input
		ipu->popup_field = text_field_add_extended (ipu->popup_win, 101, NULL, 5, 28, ipu->popup_x_len - 10, 28*ipu->rows, ipu->text_flags, 1.0f, 0.77f, 0.57f, 0.39f, &ipu->popup_text, 1, FILTER_ALL, 5, 5);
		widget_set_color (ipu->popup_win, ipu->popup_field, 0.77f, 0.57f, 0.39f);

		// Accept
		ipu->popup_ok = button_add (ipu->popup_win, NULL, button_okay, 0, 0);
		widget_set_OnClick (ipu->popup_win, ipu->popup_ok, popup_ok_button_handler);
		widget_set_color (ipu->popup_win, ipu->popup_ok, 0.77f, 0.57f, 0.39f);

		// Reject
		ipu->popup_no = button_add (ipu->popup_win, NULL, button_cancel, 0, 0);
		widget_set_OnClick (ipu->popup_win, ipu->popup_no, popup_cancel_button_handler);
		widget_set_color (ipu->popup_win, ipu->popup_no, 0.77f, 0.57f, 0.39f);

		// align the buttons
		wok = widget_find(ipu->popup_win, ipu->popup_ok);
		wno = widget_find(ipu->popup_win, ipu->popup_no);
		widget_move(ipu->popup_win, ipu->popup_ok, (ipu->popup_x_len - wok->len_x - wno->len_x)/3, ipu->popup_y_len - (wok->len_y + 5));
		widget_move(ipu->popup_win, ipu->popup_no, wok->len_x + 2*(ipu->popup_x_len - wok->len_x - wno->len_x)/3, ipu->popup_y_len - (wno->len_y + 5));

		set_window_handler (ipu->popup_win, ELW_HANDLER_KEYPRESS, popup_keypress_handler);

		if ((ipu->popup_win > -1) && (ipu->popup_win < windows_list.num_windows))
			windows_list.window[ipu->popup_win].data = ipu;
	}
	else
	{
		if ((ipu->parent > -1) && (ipu->parent < windows_list.num_windows))
		{
			window_info *win = &windows_list.window[ipu->parent];
			move_window(ipu->popup_win, ipu->parent, 0, win->pos_x+ipu->x, win->pos_y+ipu->y);
		}
		text_field_clear(ipu->popup_win, ipu->popup_field);
		label_set_text (ipu->popup_win, ipu->popup_label, label);
		show_window (ipu->popup_win);
		select_window (ipu->popup_win);
	}
}
示例#2
0
void fill_notepad_window()
{
	int i, tmp;
	widget_list *wnew;
	widget_list *wsave;

	int note_tabs_width = notepad_win_x_len;
	int note_tabs_height = notepad_win_y_len - 5;

	note_button_scroll_height = note_tabs_height - 55 - 20; // -20 for the tab tags
	note_button_width = (note_tabs_width - note_button_scroll_width - note_button_x_space - 15) / 2;

	set_window_handler(notepad_win, ELW_HANDLER_DISPLAY, &display_notepad_handler);
	set_window_handler(notepad_win, ELW_HANDLER_CLICK, &click_buttonwin_handler);

	note_tabcollection_id = tab_collection_add (notepad_win, NULL, 0, 5, note_tabs_width, note_tabs_height, 20);
	widget_set_size (notepad_win, note_tabcollection_id, 0.7);
	widget_set_color (notepad_win, note_tabcollection_id, 0.77f, 0.57f, 0.39f);
	main_note_tab_id = tab_add (notepad_win, note_tabcollection_id, tab_main, 0, 0, 0);
	widget_set_color (notepad_win, main_note_tab_id, 0.77f, 0.57f, 0.39f);
	set_window_handler(main_note_tab_id, ELW_HANDLER_CLICK, &click_buttonwin_handler);

	// Add Category
	new_note_button_id = button_add(main_note_tab_id, NULL, button_new_category, 0, 0);
	widget_set_OnClick(main_note_tab_id, new_note_button_id, notepad_add_category);
	widget_set_color(main_note_tab_id, new_note_button_id, 0.77f, 0.57f, 0.39f);

	// Save Notes
	save_notes_button_id = button_add(main_note_tab_id, NULL, button_save_notes, 0, 0);
	widget_set_OnClick(main_note_tab_id, save_notes_button_id, click_save_handler);
	widget_set_color(main_note_tab_id, save_notes_button_id, 0.77f, 0.57f, 0.39f);

	// align the buttons
	wnew = widget_find(main_note_tab_id, new_note_button_id);
	wsave = widget_find(main_note_tab_id, save_notes_button_id);
	tmp = (notepad_win_x_len - note_button_scroll_width)/2;
	widget_move(main_note_tab_id, new_note_button_id, (tmp - wnew->len_x)/2, 10);
	widget_move(main_note_tab_id, save_notes_button_id, tmp + (tmp - wsave->len_x)/2, 10);

	notepad_load_file ();

	init_ipu (&popup_str, main_note_tab_id, NOTE_NAME_LEN*DEFAULT_FONT_X_LEN, 100, NOTE_NAME_LEN, 1, NULL, notepad_add_continued);
	popup_str.x = (notepad_win_x_len - popup_str.popup_x_len) / 2;
	popup_str.y = (notepad_win_y_len - popup_str.popup_y_len) / 2;

	note_button_scroll_id = vscrollbar_add (main_note_tab_id, NULL, note_tabs_width - note_button_scroll_width - 5, 50, note_button_scroll_width, note_button_scroll_height);
	widget_set_OnClick (main_note_tab_id, note_button_scroll_id, note_button_scroll_handler);
	widget_set_OnDrag (main_note_tab_id, note_button_scroll_id, note_button_scroll_handler);

	// Add the note selection buttons and their scroll bar
	for(i = 0; i < nr_notes; i++)
		note_button_add (i, i);

	update_note_button_scrollbar (0);
}
示例#3
0
static void notepad_add_continued(const char *name, void* UNUSED(data))
{
	int i = nr_notes++;
	int potential_id, next_id = 0;

	if (i >= note_list_size)
		increase_note_storage();

	for (potential_id = 0; potential_id < nr_notes; potential_id++)
	{
		int test_id;
		int found_id = 0;
		for (test_id=0; test_id<nr_notes; test_id++)
		{
			widget_list *w = widget_find(main_note_tab_id,
				note_list[test_id].button_id);
			if (w && w->id == potential_id)
			{
				found_id = 1;
				break;
			}
		}
		if (!found_id)
		{
			next_id = potential_id;
			break;
		}
	}

	init_note (i, name, NULL);
	note_button_add (i, next_id);

	open_note_tab_continued (i);
}
// "The girl is dead."
// "Level completed."
void game_pyjama_party_ask_next(struct gamedata * gamedata)
{
  window = NULL;
  if(gamedata->pyjama_party_girls_passed < gamedata->girls)
    {
      if(gamedata->pyjama_party_control == PARTYCONTROLLER_PLAYER || gamedata->pyjama_party_control == PARTYCONTROLLER_GIRL)
        { /* Ask the player how to continue the party. */
          struct widget * obj;
          struct widget_factory_data wfd[] =
            {
              { WFDT_ON_RELEASE, "on_button_clicked", gppan_on_button_clicked },
              { WFDT_ON_RELEASE, "on_save_clicked",   gppan_on_save_clicked   },
              { WFDT_ON_RELEASE, "on_quit_clicked",   gppan_on_quit_clicked   },
              { WFDT_SIZEOF_,    NULL,                NULL                    }
            };

          if(gamedata->ai != NULL)
            gamedata->ai = ai_free(gamedata->ai);

          window = widget_factory(wfd, NULL, "game_pyjama_party_ask_next");
          widget_center(window);
          widget_set_gamedata_pointer(window, "gamedata", gamedata);
          
          obj = widget_find(window, "gppan_yes");
          widget_set_ulong(obj, "party", PARTYCONTROLLER_PLAYER);

          obj = widget_find(window, "gppan_no");
          widget_set_ulong(obj, "party", PARTYCONTROLLER_GIRL);

          obj = widget_find(window, "gppan_partyrun");
          widget_set_ulong(obj, "party", PARTYCONTROLLER_PARTY);
      
          ui_push_handlers();
          ui_set_navigation_handlers();
          ui_set_handler(UIC_EXIT,   gppan_on_exit);
          ui_set_handler(UIC_CANCEL, gppan_on_exit);
        }
      else
        { /* Party on non-stop until the next level. */
          pyjama_party_next(gamedata);
        }
    }
  else
    { /* All girls has passed the level, next level. */
      pyjama_party_next(gamedata);
    }
}
示例#5
0
LOCAL ICACHE_FLASH_ATTR int handleCommandAdd(clientInfo_t *cl)
{
    int x, y;
    char *end;

    if (cl->argc<5) {
        client_senderror(cl,"INVALIDARGS");
    }
    screen_t *s = screen_find(cl->argv[0]);
    if (!s) {
        client_senderror(cl,"NOTFOUND");
        return -1;
    }

    const widgetdef_t *c = widgetdef_find(cl->argv[1]);
    if (!c) {
        client_senderror(cl,"INVALID");
        return -1;
    }

    widget_t *w = widget_find(cl->argv[2]);
    if (w) {
        client_senderror(cl,"ALREADY");
        return -1;
    }

    x = (int)strtol(cl->argv[3],&end,10);
    if (*end !='\0') {
        client_senderror(cl,"INVALID");
        return -1;
    }

    y = (int)strtol(cl->argv[4],&end,10);
    if (*end !='\0') {
        client_senderror(cl,"INVALID");
        return -1;
    }

    /* Ok, create it. */

    w = widget_create(cl->argv[1], cl->argv[2]);
    if (!w) {
        client_senderror(cl,"INVALID");
        return -1;
    }

    screen_add_widget(s, w, x, y);
    client_sendOK(cl,"ADD");
    return 0;
}
示例#6
0
static int click_buttonwin_handler(window_info* UNUSED(win),
	int UNUSED(mx), int UNUSED(my), Uint32 flags)
{
	widget_list *w = widget_find(main_note_tab_id, note_button_scroll_id);
	if ((w == NULL) || (w->Flags & WIDGET_INVISIBLE))
		return 0;
	if (flags&ELW_WHEEL_UP)
	{
		vscrollbar_scroll_up(main_note_tab_id, note_button_scroll_id);
		note_button_scroll_handler();
	}
	else if(flags&ELW_WHEEL_DOWN)
	{
		vscrollbar_scroll_down(main_note_tab_id, note_button_scroll_id);
		note_button_scroll_handler();
	}
	return 1;
}
示例#7
0
LOCAL ICACHE_FLASH_ATTR int handleCommandPropset(clientInfo_t *cl)
{
    if (cl->argc!=3) {
        client_senderror(cl, "INVALIDARGS");
        return -1;
    }

    widget_t *w = widget_find(cl->argv[0]);
    if (!w) {
        client_senderror(cl,"NOTFOUND");
        return -1;
    }

    if (widget_set_property( w, cl->argv[1], cl->argv[2])<0) {
        client_senderror(cl,"INVALIDPROP");
        return -1;
    }
    client_sendOK(cl,"PROPSET");
    return 0;
}
示例#8
0
static int popup_keypress_handler(window_info *win,
	int UNUSED(mx), int UNUSED(my), Uint32 key, Uint32 unikey)
{
	INPUT_POPUP *ipu = ipu_from_window(win);
	if (ipu == NULL) return 0;

	if (key == SDLK_RETURN)
	{
		accept_popup_window (ipu);
		return 1;
	}
	else if (key == SDLK_ESCAPE)
	{
		if (ipu->popup_cancel != NULL)
			(*ipu->popup_cancel) (ipu->data);
		clear_popup_window (ipu);
		return 1;
	}
	else
	{
		// send other key presses to the text field
		widget_list *tfw = widget_find (win->window_id, ipu->popup_field);
		if (tfw != NULL)
		{
			// FIXME? This is a bit hackish, we don't allow the
			// widget to process keypresses, so that we end up
			// in this handler. But now we need the default
			// widget handler to take care of this keypress, so
			// we clear the flag, let the widget handle it, then
			// set the flag again.
			int res;
			tfw->Flags &= ~TEXT_FIELD_NO_KEYPRESS;
			res = widget_handle_keypress (tfw, mx - tfw->pos_x, my - tfw->pos_y, key, unikey);
			tfw->Flags |= TEXT_FIELD_NO_KEYPRESS;
			return res;
		}
	}

	// shouldn't get here
	return 0;
}
示例#9
0
/* fill the URL window created as a tab. */
void fill_url_window(void)
{
	const Uint32 scroll_width = 20;
	const Uint32 cross_height = 20;
	int clear_all_button = 101;
	widget_list *widget;

	/* create the main window */
	url_win_x_len = INFO_TAB_WIDTH;
	url_win_y_len = INFO_TAB_HEIGHT;
	url_win_max_string_width = url_win_x_len - (2*url_win_sep + scroll_width);
	set_window_handler(url_win, ELW_HANDLER_DISPLAY, &display_url_handler );
	set_window_handler(url_win, ELW_HANDLER_CLICK, &click_url_handler );

	/* create the clear all button */
	clear_all_button = button_add_extended (url_win, clear_all_button, NULL,
		url_win_sep, url_win_sep, 0, 0, 0, 0.75, 0.77f, 0.57f, 0.39f, "CLEAR ALL ");
	widget_set_OnClick(url_win, clear_all_button, url_win_click_clear_all);
	widget = widget_find(url_win, clear_all_button);
	widget_set_OnMouseover(url_win, clear_all_button, url_win_mouseover_clear_all);
	
	/* calc text and help postions from size of other stuff */
	url_win_text_start_y = 2*url_win_sep + ((widget->len_y > cross_height) ?widget->len_y :cross_height);
	url_win_line_step = (int)(3 + DEFAULT_FONT_Y_LEN * url_win_text_zoom);
	url_win_text_len_y = 12 * url_win_line_step;
	url_win_full_url_y_len = url_win_sep + 3 * SMALL_FONT_Y_LEN;
	url_win_y_len = url_win_text_start_y + url_win_text_len_y + url_win_sep + url_win_full_url_y_len;
	url_win_help_x = widget->len_x + 2 * url_win_sep;
	url_win_url_y_start = url_win_y_len - url_win_full_url_y_len - url_win_sep/2;
	resize_window (url_win, url_win_x_len, url_win_y_len);
	
	/* create the scroll bar */
	url_scroll_id = vscrollbar_add_extended(url_win, url_scroll_id, NULL, 
		url_win_x_len - scroll_width, url_win_text_start_y, scroll_width,
		url_win_text_len_y, 0, 1.0, 0.77f, 0.57f, 0.39f, 0, 1, have_url_count);
	widget_set_OnDrag(url_win, url_scroll_id, url_win_scroll_drag);
	widget_set_OnClick(url_win, url_scroll_id, url_win_scroll_click);
}
示例#10
0
LOCAL ICACHE_FLASH_ATTR int handleCommandClone(clientInfo_t *cl)
{
    int x, y;
    char *end;

    if (cl->argc<4) {
        client_senderror(cl,"INVALIDARGS");
    }
    screen_t *s = screen_find(cl->argv[1]);
    if (!s) {
        client_senderror(cl,"NOTFOUND");
        return -1;
    }

    widget_t *w = widget_find(cl->argv[0]);
    if (!w) {
        client_senderror(cl,"NOTFOUND");
        return -1;
    }

    x = (int)strtol(cl->argv[2],&end,10);
    if (*end !='\0') {
        client_senderror(cl,"INVALID");
        return -1;
    }

    y = (int)strtol(cl->argv[3],&end,10);
    if (*end !='\0') {
        client_senderror(cl,"INVALID");
        return -1;
    }

    /* Ok, create it. */
    screen_add_widget(s, w, x, y);
    client_sendOK(cl,"CLONE");
    return 0;
}
示例#11
0
文件: skills.c 项目: liwcezar/atrinik
/** @copydoc list_struct::post_column_func */
static void list_post_column(list_struct *list, uint32_t row, uint32_t col)
{
    size_t skill_id;
    SDL_Rect box;

    skill_id = row * list->cols + col;

    if (skill_id >= skill_list_num) {
        return;
    }

    if (!FaceList[skill_list[skill_id]->skill->face].sprite) {
        return;
    }

    box.x = list->x + list->frame_offset + INVENTORY_ICON_SIZE * col;
    box.y = LIST_ROWS_START(list) + (LIST_ROW_OFFSET(row, list) * LIST_ROW_HEIGHT(list));
    box.w = INVENTORY_ICON_SIZE;
    box.h = INVENTORY_ICON_SIZE;

    surface_show(list->surface, box.x, box.y, NULL, FaceList[skill_list[skill_id]->skill->face].sprite->bitmap);

    if (selected_skill != skill_id) {
        return;
    }
    border_create_color(list->surface, &box, 1, "ff0000");

    char buf[MAX_BUF];
    snprintf(VS(buf), "%s", skill_list[skill_id]->skill->s_name);
    string_title(buf);

    box.w = 160;
    text_show(list->surface,
              FONT_SERIF12,
              buf,
              150,
              18,
              COLOR_HGOLD,
              TEXT_ALIGN_CENTER | TEXT_OUTLINE,
              &box);

    box.h = 100;
    text_show(list->surface,
              FONT_ARIAL11,
              skill_list[skill_id]->msg,
              150,
              38,
              COLOR_WHITE,
              TEXT_WORD_WRAP,
              &box);

    if (skill_list[skill_id]->level == 0) {
        return;
    }

    widgetdata *widget = widget_find(NULL, -1, NULL, list->surface);
    SOFT_ASSERT(widget != NULL, "Could not find widget");

    text_show(list->surface, FONT("arial", 10), "[b]Experience[/b]", 167, widget->h - 47, COLOR_WHITE, TEXT_MARKUP, NULL);
    player_draw_exp_progress(list->surface, 160, widget->h - 32, skill_list[skill_id]->exp, skill_list[skill_id]->level);

    box.h = 30;
    box.w = 35;
    text_show(list->surface,
              FONT("arial", 10),
              "[b]Level[/b]",
              widget->w - 45,
              widget->h - 47,
              COLOR_WHITE,
              TEXT_MARKUP | TEXT_ALIGN_CENTER,
              &box);
    text_show_format(list->surface,
                     FONT_SERIF18,
                     widget->w - 45,
                     widget->h - 30,
                     COLOR_HGOLD,
                     TEXT_MARKUP | TEXT_OUTLINE | TEXT_ALIGN_CENTER,
                     &box,
                     "%" PRIu8,
                     skill_list[skill_id]->level);
}
示例#12
0
文件: menu.c 项目: atrinik/atrinik
/**
 * 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(const char *cmd)
{
    if (cmd_aliases_handle(cmd)) {
        return 1;
    } else if (strncasecmp(cmd, "/ready_spell", 12) == 0) {
        cmd = strchr(cmd, ' ');

        if (!cmd || *++cmd == '\0') {
            draw_info(COLOR_RED, "Usage: /ready_spell <spell name>");
            return 1;
        } else {
            object *tmp;

            for (tmp = cpl.ob->inv; tmp; tmp = tmp->next) {
                if (tmp->itype == TYPE_SPELL && strncasecmp(tmp->s_name, cmd, strlen(cmd)) == 0) {
                    if (!(tmp->flags & CS_FLAG_APPLIED)) {
                        client_send_apply(tmp);
                    }

                    return 1;
                }
            }
        }

        draw_info(COLOR_RED, "Unknown spell.");
        return 1;
    } else if (strncasecmp(cmd, "/ready_skill", 12) == 0) {
        cmd = strchr(cmd, ' ');

        if (!cmd || *++cmd == '\0') {
            draw_info(COLOR_RED, "Usage: /ready_skill <skill name>");
            return 1;
        } else {
            object *tmp;

            for (tmp = cpl.ob->inv; tmp; tmp = tmp->next) {
                if (tmp->itype == TYPE_SKILL && strncasecmp(tmp->s_name, cmd, strlen(cmd)) == 0) {
                    if (!(tmp->flags & CS_FLAG_APPLIED)) {
                        client_send_apply(tmp);
                    }

                    return 1;
                }
            }
        }

        draw_info(COLOR_RED, "Unknown skill.");
        return 1;
    } else if (!strncmp(cmd, "/help", 5)) {
        cmd += 5;

        if (*cmd == '\0') {
            help_show("main");
        } else {
            help_show(cmd + 1);
        }

        return 1;
    } else if (!strncmp(cmd, "/resetwidgets", 13)) {
        widgets_reset();
        return 1;
    } else if (!strncmp(cmd, "/effect ", 8)) {
        if (!strcmp(cmd + 8, "none")) {
            effect_stop();
            draw_info(COLOR_GREEN, "Stopped effect.");
            return 1;
        }

        if (effect_start(cmd + 8)) {
            draw_info_format(COLOR_GREEN, "Started effect %s.", cmd + 8);
        } else {
            draw_info_format(COLOR_RED, "No such effect %s.", cmd + 8);
        }

        return 1;
    } else if (!strncmp(cmd, "/d_effect ", 10)) {
        effect_debug(cmd + 10);
        return 1;
    } else if (!strncmp(cmd, "/music_pause", 12)) {
        sound_pause_music();
        return 1;
    } else if (!strncmp(cmd, "/music_resume", 13)) {
        sound_resume_music();
        return 1;
    } else if (!strncmp(cmd, "/party joinpassword ", 20)) {
        cmd += 20;

        if (cpl.partyjoin[0] != '\0') {
            char buf[MAX_BUF];

            snprintf(VS(buf), "/party join %s\t%s", cpl.partyjoin, cmd);
            send_command(buf);
        }

        return 1;
    } else if (!strncmp(cmd, "/invfilter ", 11)) {
        inventory_filter_set_names(cmd + 11);
        return 1;
    } else if (!strncasecmp(cmd, "/screenshot", 11)) {
        SDL_Surface *surface_save;

        cmd += 11;

        if (!strncasecmp(cmd, " map", 4)) {
            surface_save = cur_widget[MAP_ID]->surface;
        } else {
            surface_save = ScreenSurface;
        }

        if (!surface_save) {
            draw_info(COLOR_RED, "No surface to save.");
            return 1;
        }

        screenshot_create(surface_save);
        return 1;
    } else if (!strncasecmp(cmd, "/console-load ", 14)) {
        FILE *fp;
        char path[HUGE_BUF], buf[HUGE_BUF * 4], *cp;
        StringBuffer *sb;

        cmd += 14;

        snprintf(path, sizeof(path), "%s/.atrinik/console/%s", get_config_dir(), cmd);

        fp = fopen(path, "r");

        if (!fp) {
            draw_info_format(COLOR_RED, "Could not read %s.", path);
            return 1;
        }

        send_command("/console noinf::");

        while (fgets(buf, sizeof(buf) - 1, fp)) {
            cp = strchr(buf, '\n');

            if (cp) {
                *cp = '\0';
            }

            sb = stringbuffer_new();
            stringbuffer_append_string(sb, "/console noinf::");
            stringbuffer_append_string(sb, buf);
            cp = stringbuffer_finish(sb);
            send_command(cp);
            efree(cp);
        }

        send_command("/console noinf::");

        fclose(fp);

        return 1;
    } else if (strncasecmp(cmd, "/console-obj", 11) == 0) {
        menu_inventory_loadtoconsole(cpl.inventory_focus, NULL, NULL);
        return 1;
    } else if (strncasecmp(cmd, "/patch-obj", 11) == 0) {
        menu_inventory_patch(cpl.inventory_focus, NULL, NULL);
        return 1;
    } else if (string_startswith(cmd, "/cast ") || string_startswith(cmd, "/use_skill ")) {
        object *tmp;
        uint8_t type;

        type = string_startswith(cmd, "/cast ") ? TYPE_SPELL : TYPE_SKILL;
        cmd = strchr(cmd, ' ') + 1;

        if (string_isempty(cmd)) {
            return 1;
        }

        for (tmp = cpl.ob->inv; tmp; tmp = tmp->next) {
            if (tmp->itype == type && strncasecmp(tmp->s_name, cmd, strlen(cmd)) == 0) {
                client_send_fire(5, tmp->tag);
                return 1;
            }
        }

        draw_info_format(COLOR_RED, "Unknown %s.", type == TYPE_SPELL ? "spell" : "skill");
        return 1;
    } else if (strncasecmp(cmd, "/clearcache", 11) == 0) {
        cmd += 12;

        if (string_isempty(cmd)) {
            return 1;
        }

        if (strcasecmp(cmd, "sound") == 0) {
            sound_clear_cache();
            draw_info(COLOR_GREEN, "Sound cache cleared.");
        } else if (strcasecmp(cmd, "textures") == 0) {
            texture_reload();
            draw_info(COLOR_GREEN, "Textures reloaded.");
        }

        return 1;
    } else if (string_startswith(cmd, "/droptag ") ||
            string_startswith(cmd, "/gettag ")) {
        char *cps[3];
        unsigned long int loc, tag, num;

        if (string_split(strchr(cmd, ' ') + 1, cps, arraysize(cps), ' ') !=
                arraysize(cps)) {
            return 1;
        }

        loc = strtoul(cps[0], NULL, 10);
        tag = strtoul(cps[1], NULL, 10);
        num = strtoul(cps[2], NULL, 10);
        client_send_move(loc, tag, num);

        if (string_startswith(cmd, "/gettag ")) {
            sound_play_effect("get.ogg", 100);
        } else {
            sound_play_effect("drop.ogg", 100);
        }

        return 1;
    } else if (string_startswith(cmd, "/talk")) {
        char type[MAX_BUF], npc_name[MAX_BUF];
        size_t pos;
        uint8_t type_num;
        packet_struct *packet;

        pos = 5;

        if (!string_get_word(cmd, &pos, ' ', type, sizeof(type), 0) || string_isempty(cmd + pos)) {
            return 1;
        }

        type_num = atoi(type);

        if (type_num == CMD_TALK_NPC_NAME && (!string_get_word(cmd, &pos, ' ', npc_name, sizeof(npc_name), '"') || string_isempty(cmd + pos))) {
            return 1;
        }

        packet = packet_new(SERVER_CMD_TALK, 64, 64);
        packet_append_uint8(packet, type_num);

        if (type_num == CMD_TALK_NPC || type_num == CMD_TALK_NPC_NAME) {
            if (type_num == CMD_TALK_NPC_NAME) {
                packet_append_string_terminated(packet, npc_name);
            }

            packet_append_string_terminated(packet, cmd + pos);
        } else {
            char tag[MAX_BUF];

            if (!string_get_word(cmd, &pos, ' ', tag, sizeof(tag), 0) || string_isempty(cmd + pos)) {
                packet_free(packet);
                return 1;
            }

            packet_append_uint32(packet, atoi(tag));
            packet_append_string_terminated(packet, cmd + pos);
        }

        socket_send_packet(packet);

        return 1;
    } else if (string_startswith(cmd, "/widget_toggle")) {
        size_t pos;
        char word[MAX_BUF], *cps[2];
        int widget_id;

        pos = 14;

        while (string_get_word(cmd, &pos, ' ', word, sizeof(word), 0)) {
            if (string_split(word, cps, arraysize(cps), ':') < 1) {
                continue;
            }

            widget_id = widget_id_from_name(cps[0]);

            /* Invalid widget ID */
            if (widget_id == -1) {
                continue;
            }

            /* Redraw all or a specific one identified by its UID */
            if (cps[1] == NULL) {
                WIDGET_SHOW_TOGGLE_ALL(widget_id);
            } else {
                widgetdata *widget;

                widget = widget_find(NULL, widget_id, cps[1], NULL);

                if (widget) {
                    WIDGET_SHOW_TOGGLE(widget);
                }
            }
        }

        return 1;
    } else if (string_startswith(cmd, "/widget_focus")) {
        size_t pos;
        char word[MAX_BUF], *cps[2];
        int widget_id;

        pos = 14;

        while (string_get_word(cmd, &pos, ' ', word, sizeof(word), 0)) {
            if (string_split(word, cps, arraysize(cps), ':') < 1) {
                continue;
            }

            widget_id = widget_id_from_name(cps[0]);
            if (widget_id == -1) {
                /* Invalid widget ID */
                continue;
            }

            widget_switch_focus(widget_id, cps[1]);
        }

        return 1;
    } else if (string_startswith(cmd, "/ping")) {
        keepalive_ping_stats();
        return 1;
    } else if (string_startswith(cmd, "/region_map")) {
        region_map_open();
        return 1;
    }

    return 0;
}