haven.GameUI.java Source code

Java tutorial

Introduction

Here is the source code for haven.GameUI.java

Source

/*
 *  This file is part of the Haven & Hearth game client.
 *  Copyright (C) 2009 Fredrik Tolf <fredrik@dolda2000.com>, and
 *                     Bjrn Johannessen <johannessen.bjorn@gmail.com>
 *
 *  Redistribution and/or modification of this file is subject to the
 *  terms of the GNU Lesser General Public License, version 3, as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  Other parts of this source tree adhere to other copying
 *  rights. Please see the file `COPYING' in the root directory of the
 *  source tree for details.
 *
 *  A copy the GNU Lesser General Public License is distributed along
 *  with the source tree of which this file is a part in the file
 *  `doc/LPGL-3'. If it is missing for any reason, please see the Free
 *  Software Foundation's website at <http://www.fsf.org/>, or write
 *  to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 *  Boston, MA 02111-1307 USA
 */

package haven;

import java.awt.image.BufferedImage;
import haven.minimap.CustomIconGroup;
import haven.minimap.CustomIconMatch;
import haven.minimap.CustomIconWnd;
import haven.tasks.*;
import haven.tasks.AutoStudy;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.util.*;
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.image.WritableRaster;

import static haven.GameUILayout.*;
import static haven.Inventory.invsq;

import haven.stuff.HarvesterSelection;

public class GameUI extends ConsoleHost implements Console.Directory {
    public static final Text.Foundry msgfoundry = new Text.Foundry(Text.dfont, 14);
    private static final int blpw = 0, brpw = 142;
    public final String chrid;
    public final long plid;
    private final Hidepanel ulpanel, urpanel, brpanel, menupanel;
    public Avaview portrait;
    public MenuGrid menu;
    public MapView map;
    public LocalMiniMap mmap;
    public MinimapWnd mmapwnd;
    public Fightview fv;
    private List<Widget> meters = new LinkedList<Widget>();
    private List<Widget> cmeters = new LinkedList<Widget>();
    private Text lastmsg;
    private long msgtime;
    private Window invwnd, equwnd;
    public Inventory maininv;
    public CharWnd chrwdg;
    public BuddyWnd buddies;
    public EquipBelt eqbelt;
    public DraggableBelt fkeybelt;
    private Widget qqview;
    private final Zergwnd zerg;
    public Polity polity;
    public HelpWnd help;
    public OptWnd opts;
    public Collection<DraggedItem> hand = new LinkedList<DraggedItem>();
    public Collection<DraggedItem> handSave = new LinkedList<DraggedItem>();
    private WItem vhand;
    public ChatUI chat;
    public ChatUI.Channel syslog;
    public double prog = -1;
    private boolean afk = false;
    @SuppressWarnings("unchecked")
    public Indir<Resource>[] belt = new Indir[144];
    public DefaultBelt beltwdg;
    public String polowner;
    public Bufflist buffs;
    public StudyWnd studywnd;
    public ActWnd craftwnd;
    public ActWnd buildwnd;
    public Window iconwnd;
    public final Cal cal;
    public Window deckwnd;
    public final CraftWindow makewnd;
    public static TaskManager tasks;
    public ChatHidePanel chatHidePanel;
    private final GameUILayout layout;
    private boolean ignoreTrackingSound;
    public static GameUI instance;
    public boolean lowStam;

    public abstract class Belt extends Widget {
        public Belt(Coord sz) {
            super(sz);
        }

        public void keyact(final int slot) {
            if (map != null) {
                Coord mvc = map.rootxlate(ui.mc);
                if (mvc.isect(Coord.z, map.sz)) {
                    map.delay(map.new Hittest(mvc) {
                        protected void hit(Coord pc, Coord mc, MapView.ClickInfo inf) {
                            if (inf == null)
                                GameUI.this.wdgmsg("belt", slot, 1, ui.modflags(), mc);
                            else
                                GameUI.this.wdgmsg("belt", slot, 1, ui.modflags(), mc, (int) inf.gob.id,
                                        inf.gob.rc);
                        }

                        protected void nohit(Coord pc) {
                            GameUI.this.wdgmsg("belt", slot, 1, ui.modflags());
                        }
                    });
                }
            }
        }
    }

    @RName("gameui")
    public static class $_ implements Factory {
        public Widget create(Widget parent, Object[] args) {
            String chrid = (String) args[0];
            int plid = (Integer) args[1];
            return (new GameUI(chrid, plid));
        }
    }

    public GameUI(String chrid, long plid) {
        instance = this;
        this.chrid = chrid;
        this.plid = plid;
        setcanfocus(true);
        setfocusctl(true);
        chat = add(new ChatUI(0, 0));
        chat.visible = Utils.getprefb("chatvis", true);
        if (chat.visible) {
            chat.move(chat.savedpos);
            chat.resize(chat.savedw, chat.savedh);
        }
        beltwdg.raise();
        eqbelt = add(new EquipBelt("equip", 6, 7));
        ulpanel = add(new Hidepanel("gui-ul", null, new Coord(-1, -1), false));
        urpanel = add(new Hidepanel("gui-ur", null, new Coord(1, -1), false));
        brpanel = add(new Hidepanel("gui-br", null, new Coord(1, 1), true) {
            public void move(double a) {
                super.move(a);
                menupanel.move();
            }
        });
        menupanel = add(new Hidepanel("menu", new Indir<Coord>() {
            public Coord get() {
                return (new Coord(GameUI.this.sz.x, Math.min(brpanel.c.y - 79, GameUI.this.sz.y - menupanel.sz.y)));
            }
        }, new Coord(1, 0), true));
        menu = brpanel.add(new MenuGrid() {
            // HACK:
            // intercept menu item usage and notify craft window about it to be able
            // to determine which crafting receipt caused creation of Makewindow
            @Override
            public boolean use(Glob.Pagina pagina) {
                boolean result = super.use(pagina);
                if (result)
                    makewnd.setLastAction(pagina);
                return result;
            }
        }, 20, 34);
        brpanel.add(new Img(Resource.loadtex("gfx/hud/brframe")), 0, 0);
        menupanel.add(new MainMenu(), 0, 0);
        foldbuttons();
        portrait = ulpanel.add(new Avaview(Avaview.dasz, plid, "avacam") {
            public boolean mousedown(Coord c, int button) {
                return (true);
            }
        }, new Coord(10, 10));
        buffs = ulpanel.add(new Bufflist(), new Coord(95, 65));
        syslog = chat.add(new ChatUI.Log("System"));
        opts = add(new OptWnd());
        opts.hide();
        zerg = add(new Zergwnd(), 187, 50);
        zerg.hide();

        studywnd = add(new StudyWnd(Coord.z), Config.studyPosition.get());
        studywnd.visible = Config.studyVisible.get();

        craftwnd = add(new ActWnd("Craft...", "paginae/craft/") {
            protected void act(Glob.Pagina pagina) {
                GameUI.this.menu.use(pagina);
            }
        });
        craftwnd.hide();
        buildwnd = add(new ActWnd("Build...", "paginae/bld/") {
            protected void act(Glob.Pagina pagina) {
                GameUI.this.menu.use(pagina);
            }
        });
        buildwnd.hide();

        iconwnd = add(new CustomIconWnd());
        iconwnd.hide();

        deckwnd = add(new DeckSelector() {
            public int getSelectedDeck() {
                FightWnd fight = GameUI.this.chrwdg.fgt.findchild(FightWnd.class);
                return (fight != null) ? fight.usesave : -1;
            }

            public void setSelectedDeck(int deckIndex) {
                FightWnd fight = GameUI.this.chrwdg.fgt.findchild(FightWnd.class);
                if (fight != null)
                    fight.use(deckIndex);
            }
        });
        deckwnd.hide();

        cal = add(new Cal());
        makewnd = add(new CraftWindow(), new Coord(400, 200));
        makewnd.hide();

        chatHidePanel = add(new ChatHidePanel(chat));

        layout = new GameUILayout();
        layout.addDraggable(beltwdg, new RelativePosition(HAlign.Left, VAlign.Top, new Coord(10, 180)), false,
                true);
        layout.addDraggable(eqbelt, new RelativePosition(HAlign.Left, VAlign.Top, new Coord(10, 220)), false, true);
        layout.addDraggable(studywnd, new RelativePosition(HAlign.Left, VAlign.Top, new Coord(100, 100)), true,
                true);
        layout.addDraggable(chat, new RelativePosition(HAlign.Left, VAlign.Bottom, new Coord(15, 30)), true, true);
    }

    @Override
    protected void attach(UI ui) {
        super.attach(ui);
        ui.gui = this;
        tasks = new TaskManager(ui);
        tasks.add(new AutoStudy());
        fkeybelt = add(new CustomBelt.FKeys("custom-fkeys", ui.sess.username, ui.sess.charname));
        fkeybelt.visible = Config.showCustomFKeysBelt.get();
        layout.addDraggable(fkeybelt, new RelativePosition(HAlign.Left, VAlign.Top, new Coord(10, 280)), false,
                true);
    }

    public Equipory getEquipory() {
        if (equwnd != null) {
            Iterator<Equipory> iterator = equwnd.children(Equipory.class).iterator();
            if (iterator.hasNext()) {
                return iterator.next();
            }
        }
        return null;
    }

    /* Ice cream */
    private final IButton[] fold_br = new IButton[4];

    private void updfold(boolean reset) {
        int br;
        if (brpanel.tvis && menupanel.tvis)
            br = 0;
        else if (brpanel.tvis && !menupanel.tvis)
            br = 1;
        else if (!brpanel.tvis && !menupanel.tvis)
            br = 2;
        else
            br = 3;
        for (int i = 0; i < fold_br.length; i++)
            fold_br[i].show(i == br);

        if (reset)
            resetui();
    }

    private void foldbuttons() {
        final Tex rdnbg = Resource.loadtex("gfx/hud/rbtn-maindwn");
        final Tex rupbg = Resource.loadtex("gfx/hud/rbtn-upbg");
        fold_br[0] = new IButton("gfx/hud/rbtn-dwn", "", "-d", "-h") {
            public void draw(GOut g) {
                g.image(rdnbg, Coord.z);
                super.draw(g);
            }

            public void click() {
                menupanel.cshow(false);
                updfold(true);
            }
        };
        fold_br[1] = new IButton("gfx/hud/rbtn-dwn", "", "-d", "-h") {
            public void draw(GOut g) {
                g.image(rdnbg, Coord.z);
                super.draw(g);
            }

            public void click() {
                brpanel.cshow(false);
                updfold(true);
            }
        };
        fold_br[2] = new IButton("gfx/hud/rbtn-up", "", "-d", "-h") {
            public void draw(GOut g) {
                g.image(rupbg, Coord.z);
                super.draw(g);
            }

            public void click() {
                menupanel.cshow(true);
                updfold(true);
            }

            public void presize() {
                this.c = parent.sz.sub(this.sz);
            }
        };
        fold_br[3] = new IButton("gfx/hud/rbtn-dwn", "", "-d", "-h") {
            public void draw(GOut g) {
                g.image(rdnbg, Coord.z);
                super.draw(g);
            }

            public void click() {
                brpanel.cshow(true);
                updfold(true);
            }
        };
        menupanel.add(fold_br[0], 0, 0);
        fold_br[0].lower();
        brpanel.adda(fold_br[1], brpanel.sz.x, 32, 1, 1);
        adda(fold_br[2], 1, 1);
        fold_br[2].lower();
        menupanel.add(fold_br[3], 0, 0);
        fold_br[3].lower();

        updfold(false);
    }

    protected void added() {
        resize(parent.sz);
        ui.cons.out = new java.io.PrintWriter(new java.io.Writer() {
            StringBuilder buf = new StringBuilder();

            public void write(char[] src, int off, int len) {
                buf.append(src, off, len);
                int p;
                while ((p = buf.indexOf("\n")) >= 0) {
                    syslog.append(buf.substring(0, p), Color.WHITE);
                    buf.delete(0, p + 1);
                }
            }

            public void close() {
            }

            public void flush() {
            }
        });
        Debug.log = ui.cons.out;
        opts.c = sz.sub(opts.sz).div(2);
        craftwnd.c = sz.sub(craftwnd.sz).div(2);
        buildwnd.c = sz.sub(buildwnd.sz).div(2);
        iconwnd.c = sz.sub(iconwnd.sz).div(2);
    }

    public class Hidepanel extends Widget {
        public final String id;
        public final Coord g;
        public final Indir<Coord> base;
        public boolean tvis;
        private double cur;
        private boolean persist;

        public Hidepanel(String id, Indir<Coord> base, Coord g, boolean persist) {
            this.id = id;
            this.base = base;
            this.g = g;
            this.persist = persist;
            this.tvis = persist ? Utils.getprefb(id + "-visible", true) : true;
            cur = show(tvis) ? 0 : 1;
        }

        public <T extends Widget> T add(T child) {
            super.add(child);
            pack();
            if (parent != null)
                move();
            return (child);
        }

        public Coord base() {
            if (base != null)
                return (base.get());
            return (new Coord((g.x > 0) ? parent.sz.x : 0, (g.y > 0) ? parent.sz.y : 0));
        }

        public void move(double a) {
            cur = a;
            Coord c = new Coord(base());
            if (g.x < 0)
                c.x -= (int) (sz.x * a);
            else if (g.x > 0)
                c.x -= (int) (sz.x * (1 - a));
            if (g.y < 0)
                c.y -= (int) (sz.y * a);
            else if (g.y > 0)
                c.y -= (int) (sz.y * (1 - a));
            this.c = c;
        }

        public void move() {
            move(cur);
        }

        public void presize() {
            move();
        }

        public boolean mshow(final boolean vis) {
            clearanims(Anim.class);
            if (vis)
                show();
            new NormAnim(0.25) {
                final double st = cur, f = vis ? 0 : 1;

                public void ntick(double a) {
                    if ((a == 1.0) && !vis)
                        hide();
                    move(st + (Utils.smoothstep(a) * (f - st)));
                }
            };
            tvis = vis;
            updfold(false);
            return (vis);
        }

        public boolean mshow() {
            return (mshow(persist ? Utils.getprefb(id + "-visible", true) : true));
        }

        public boolean cshow(boolean vis) {
            if (persist)
                Utils.setprefb(id + "-visible", vis);
            if (vis != tvis)
                mshow(vis);
            return (vis);
        }

        public void cdestroy(Widget w) {
            parent.cdestroy(w);
        }
    }

    static class Hidewnd extends Window {
        Hidewnd(Coord sz, String cap, boolean lg) {
            super(sz, cap, lg);
        }

        Hidewnd(Coord sz, String cap) {
            super(sz, cap);
        }

        public void wdgmsg(Widget sender, String msg, Object... args) {
            if ((sender == this) && msg.equals("close")) {
                this.hide();
                return;
            }
            super.wdgmsg(sender, msg, args);
        }
    }

    static class Zergwnd extends Hidewnd {
        Tabs tabs = new Tabs(Coord.z, Coord.z, this);
        final TButton kin, pol;

        class TButton extends IButton {
            Tabs.Tab tab = null;
            final Tex inv;

            TButton(String nm, boolean g) {
                super(Resource.loadimg("gfx/hud/buttons/" + nm + "u"),
                        Resource.loadimg("gfx/hud/buttons/" + nm + "d"));
                if (g)
                    inv = Resource.loadtex("gfx/hud/buttons/" + nm + "g");
                else
                    inv = null;
            }

            public void draw(GOut g) {
                if ((tab == null) && (inv != null))
                    g.image(inv, Coord.z);
                else
                    super.draw(g);
            }

            public void click() {
                if (tab != null) {
                    tabs.showtab(tab);
                    repack();
                }
            }
        }

        Zergwnd() {
            super(Coord.z, "Kith & Kin", true);
            kin = add(new TButton("kin", false));
            kin.tooltip = Text.render("Kin");
            pol = add(new TButton("pol", true));
        }

        private void repack() {
            tabs.indpack();
            kin.c = new Coord(0, tabs.curtab.contentsz().y + 20);
            pol.c = new Coord(kin.c.x + kin.sz.x + 10, kin.c.y);
            this.pack();
        }

        Tabs.Tab ntab(Widget ch, TButton btn) {
            Tabs.Tab tab = add(tabs.new Tab() {
                public void cresize(Widget ch) {
                    repack();
                }
            }, tabs.c);
            tab.add(ch, Coord.z);
            btn.tab = tab;
            repack();
            return (tab);
        }

        void dtab(TButton btn) {
            btn.tab.destroy();
            btn.tab = null;
            repack();
        }
    }

    public static class DraggedItem {
        public final GItem item;
        public final Coord dc;

        DraggedItem(GItem item, Coord dc) {
            this.item = item;
            this.dc = dc;
        }
    }

    private void updhand() {
        if ((hand.isEmpty() && (vhand != null)) || ((vhand != null) && !hand.contains(vhand.item))) {
            ui.destroy(vhand);
            vhand = null;
        }
        if (!hand.isEmpty() && (vhand == null)) {
            DraggedItem fi = hand.iterator().next();
            vhand = add(new ItemDrag(fi.dc, fi.item));
        }
    }

    public void addchild(Widget child, Object... args) {
        String place = ((String) args[0]).intern();
        if (place == "mapview") {
            child.resize(sz);
            map = add((MapView) child, Coord.z);
            map.lower();
            if (mmap != null)
                ui.destroy(mmap);
            if (mmapwnd != null) {
                ui.destroy(mmapwnd);
                layout.removeDraggable(mmapwnd);
            }
            mmap = new LocalMiniMap(Config.minimapSize.get(), map);
            mmapwnd = new MinimapWnd(Config.minimapPosition.get(), mmap.sz, map, mmap);
            layout.addDraggable(mmapwnd, new RelativePosition(HAlign.Left, VAlign.Top, new Coord(500, 100)), true,
                    true);
            add(mmapwnd);
            mmapwnd.pack();
        } else if (place == "fight") {
            fv = urpanel.add((Fightview) child, 0, 0);
        } else if (place == "fsess") {
            add(child, Coord.z);
        } else if (place == "inv") {
            invwnd = new Hidewnd(Coord.z, "Inventory") {
                public void cresize(Widget ch) {
                    pack();
                }
            };
            invwnd.add(maininv = (Inventory) child, Coord.z);
            invwnd.pack();
            invwnd.show();
            add(invwnd, new Coord(100, 100));
        } else if (place == "equ") {
            equwnd = new Hidewnd(Coord.z, "Equipment");
            equwnd.add(child, Coord.z);
            equwnd.pack();
            equwnd.hide();
            add(equwnd, new Coord(400, 10));
        } else if (place == "hand") {
            GItem g = add((GItem) child);
            Coord lc = (Coord) args[1];
            hand.add(new DraggedItem(g, lc));
            updhand();
        } else if (place == "chr") {
            chrwdg = add((CharWnd) child, new Coord(300, 50));
            chrwdg.hide();
            // custom meter for hunger level
            if (Config.showHungerMeter.get())
                addcmeter(new HungerMeter(chrwdg.glut));
            // custom meter for FEPs
            if (Config.showFepMeter.get())
                addcmeter(new FepMeter(chrwdg.feps));
        } else if (place == "craft") {
            makewnd.add(child);
            makewnd.pack();
            makewnd.raise();
            makewnd.show();
        } else if (place == "buddy") {
            zerg.ntab(buddies = (BuddyWnd) child, zerg.kin);
        } else if (place == "pol") {
            zerg.ntab(polity = (Polity) child, zerg.pol);
            zerg.pol.tooltip = Text.render(polity.cap);
        } else if (place == "chat") {
            chat.addchild(child);
        } else if (place == "party") {
            add(child, 10, 95);
        } else if (place == "meter") {
            int x = (meters.size() % 3) * (IMeter.fsz.x + 5);
            int y = (meters.size() / 3) * (IMeter.fsz.y + 2);
            ulpanel.add(child, portrait.c.x + portrait.sz.x + 10 + x, portrait.c.y + y);
            meters.add(child);
            updcmeters();
        } else if (place == "buff") {
            buffs.addchild(child);
        } else if (place == "qq") {
            if (qqview != null)
                qqview.reqdestroy();
            final Widget cref = qqview = child;
            add(new AlignPanel() {
                {
                    add(cref);
                }

                protected Coord getc() {
                    return (new Coord(10, GameUI.this.sz.y - this.sz.y - 10));
                }

                public void cdestroy(Widget ch) {
                    qqview = null;
                    destroy();
                }
            });
        } else if (place == "misc") {
            add(child, (Coord) args[1]);
        } else {
            throw (new UI.UIException("Illegal gameui child", place, args));
        }
    }

    public void cdestroy(Widget w) {
        if (w instanceof GItem) {
            for (Iterator<DraggedItem> i = hand.iterator(); i.hasNext();) {
                DraggedItem di = i.next();
                if (di.item == w) {
                    i.remove();
                    updhand();
                }
            }
            for (Iterator<DraggedItem> i = handSave.iterator(); i.hasNext();) {
                DraggedItem di = i.next();
                if (di.item == w) {
                    i.remove();
                }
            }
        } else if (w == polity) {
            polity = null;
            zerg.dtab(zerg.pol);
        } else if (w == chrwdg) {
            chrwdg = null;
        }
        if (meters.remove(w))
            updcmeters();
        cmeters.remove(w);
    }

    private static final Resource.Anim progt = Resource.local().loadwait("gfx/hud/prog").layer(Resource.animc);
    private Tex curprog = null;
    private int curprogf, curprogb;

    private void drawprog(GOut g, double prog) {
        int fr = Utils.clip((int) Math.floor(prog * progt.f.length), 0, progt.f.length - 2);
        int bf = Utils.clip((int) (((prog * progt.f.length) - fr) * 255), 0, 255);
        if ((curprog == null) || (curprogf != fr) || (curprogb != bf)) {
            if (curprog != null)
                curprog.dispose();
            WritableRaster buf = PUtils.imgraster(progt.f[fr][0].sz);
            PUtils.blit(buf, progt.f[fr][0].img.getRaster(), Coord.z);
            PUtils.blendblit(buf, progt.f[fr + 1][0].img.getRaster(), Coord.z, bf);
            BufferedImage img = PUtils.rasterimg(buf);

            if (Config.showHourglassPercentage.get()) {
                BufferedImage txt = Text.renderstroked(String.format("%d%%", (int) (100 * prog)), Color.WHITE,
                        Color.BLACK).img;
                img.getGraphics().drawImage(txt, 24 - txt.getWidth() / 2, 9 - txt.getHeight() / 2, null);
            }

            curprog = new TexI(img);
            curprogf = fr;
            curprogb = bf;
        }
        g.aimage(curprog, new Coord(sz.x / 2, (sz.y * 4) / 10), 0.5, 0.5);
    }

    public void draw(GOut g) {
        if (Config.screenshotMode) {
            if (map != null)
                map.draw(g);
            return;
        }
        super.draw(g);
        if (prog >= 0)
            drawprog(g, prog);
        int by = sz.y;
        if (chat.visible)
            by = Math.min(by, chat.c.y);
        if (cmdline != null) {
            drawcmd(g, new Coord(chat.c.x, by -= 20));
        } else if (lastmsg != null) {
            if ((System.currentTimeMillis() - msgtime) > 3000) {
                lastmsg = null;
            } else {
                g.chcolor(0, 0, 0, 192);
                g.frect(new Coord(chat.c.x, by - 25), lastmsg.sz().add(8, 4));
                g.chcolor();
                g.image(lastmsg.tex(), new Coord(chat.c.x + 5, by -= 23));
            }
        }
        if (!chat.visible) {
            chat.drawsmall(g, new Coord(chat.c.x, by), 50);
        }
    }

    public void tick(double dt) {
        super.tick(dt);
        if (!afk && (System.currentTimeMillis() - ui.lastevent > 300000)) {
            afk = true;
            wdgmsg("afk");
        } else if (afk && (System.currentTimeMillis() - ui.lastevent < 300000)) {
            afk = false;
        }
        if (lowStam) {
            tasks.add(new Drunkard());
            lowStam = false;
        }
        tasks.tick(dt);
    }

    private void togglebuff(String err, String name, Resource res) {
        if (err.endsWith("on.") && buffs.gettoggle(name) == null) {
            buffs.addchild(new BuffToggle(name, res));
        } else if (err.endsWith("off.")) {
            BuffToggle tgl = buffs.gettoggle(name);
            if (tgl != null)
                tgl.reqdestroy();
        }
    }

    public void uimsg(String msg, Object... args) {
        if (msg == "err") {
            String err = (String) args[0];
            error(err);
            if (err.startsWith("Swimming is now turned"))
                togglebuff(err, "swim", Bufflist.buffswim);
            else if (err.startsWith("Tracking is now turned"))
                togglebuff(err, "track", Bufflist.bufftrack);
            else if (err.startsWith("Criminal acts are now turned"))
                togglebuff(err, "crime", Bufflist.buffcrime);
        } else if (msg == "msg") {
            String text = (String) args[0];
            msg(text);
        } else if (msg == "prog") {
            if (args.length > 0)
                prog = ((Number) args[0]).doubleValue() / 100.0;
            else
                prog = -1;
        } else if (msg == "setbelt") {
            int slot = (Integer) args[0];
            if (args.length < 2) {
                belt[slot] = null;
            } else {
                belt[slot] = ui.sess.getres((Integer) args[1]);
            }
        } else if (msg == "polowner") {
            String o = (String) args[0];
            boolean n = ((Integer) args[1]) != 0;
            if (o.length() == 0)
                o = null;
            else
                o = o.intern();
            if (o != polowner) {
                if (map != null) {
                    if (o == null) {
                        if (polowner != null)
                            map.setpoltext("Leaving " + polowner);
                    } else {
                        map.setpoltext("Entering " + o);
                    }
                }
                polowner = o;
            }
        } else if (msg == "showhelp") {
            Indir<Resource> res = ui.sess.getres((Integer) args[0]);
            if (help == null)
                help = adda(new HelpWnd(res), 0.5, 0.5);
            else
                help.res = res;
        } else {
            super.uimsg(msg, args);
        }
    }

    public void wdgmsg(Widget sender, String msg, Object... args) {
        if (sender == menu) {
            wdgmsg(msg, args);
            return;
        } else if ((sender == chrwdg) && (msg == "close")) {
            chrwdg.hide();
        } else if ((sender == help) && (msg == "close")) {
            ui.destroy(help);
            help = null;
            return;
        }
        super.wdgmsg(sender, msg, args);
    }

    private void fitwdg(Widget wdg) {
        if (wdg.c.x < 0)
            wdg.c.x = 0;
        if (wdg.c.y < 0)
            wdg.c.y = 0;
        if (wdg.c.x + wdg.sz.x > sz.x)
            wdg.c.x = sz.x - wdg.sz.x;
        if (wdg.c.y + wdg.sz.y > sz.y)
            wdg.c.y = sz.y - wdg.sz.y;
    }

    public static class MenuButton extends IButton {
        private final int gkey;

        MenuButton(String base, int gkey, String tooltip) {
            super("gfx/hud/" + base, "", "-d", "-h");
            this.gkey = (char) gkey;
            this.tooltip = RichText.render(tooltip, 0);
        }

        public void click() {
        }

        public boolean globtype(char key, KeyEvent ev) {
            if (Config.agroclosest.get() && key == 9)
                return super.globtype(key, ev);
            if ((gkey != -1) && (key == gkey)) {
                click();
                return (true);
            }
            return (super.globtype(key, ev));
        }
    }

    private static final Tex menubg = Resource.loadtex("gfx/hud/rbtn-bg");

    public class MainMenu extends Widget {
        public MainMenu() {
            super(menubg.sz());
            add(new MenuButton("rbtn-inv", 9, "Inventory ($col[255,255,0]{Tab})") {
                public void click() {
                    if ((invwnd != null) && invwnd.show(!invwnd.visible)) {
                        invwnd.raise();
                        fitwdg(invwnd);
                    }
                }
            }, 0, 0);
            add(new MenuButton("rbtn-equ", 5, "Equipment ($col[255,255,0]{Ctrl+E})") {
                public void click() {
                    if ((equwnd != null) && equwnd.show(!equwnd.visible)) {
                        equwnd.raise();
                        fitwdg(equwnd);
                    }
                }
            }, 0, 0);
            add(new MenuButton("rbtn-chr", 20, "Character Sheet ($col[255,255,0]{Ctrl+T})") {
                public void click() {
                    if ((chrwdg != null) && chrwdg.show(!chrwdg.visible)) {
                        chrwdg.raise();
                        fitwdg(chrwdg);
                    }
                }
            }, 0, 0);
            add(new MenuButton("rbtn-bud", 2, "Kith & Kin ($col[255,255,0]{Ctrl+B})") {
                public void click() {
                    if (zerg.show(!zerg.visible)) {
                        zerg.raise();
                        fitwdg(zerg);
                        setfocus(zerg);
                    }
                }
            }, 0, 0);
            add(new MenuButton("rbtn-opt", 15, "Options ($col[255,255,0]{Ctrl+O})") {
                public void click() {
                    if (opts.show(!opts.visible)) {
                        opts.raise();
                        fitwdg(opts);
                        setfocus(opts);
                    }
                }
            }, 0, 0);
        }

        public void draw(GOut g) {
            g.image(menubg, Coord.z);
            super.draw(g);
        }
    }

    public boolean globtype(char key, KeyEvent ev) {
        if (key == ':') {
            entercmd();
            return (true);
        } else if (key == ' ') {
            toggleui();
            return (true);
        } else if (key == 3) {
            if (chat.visible && !chat.hasfocus) {
                setfocus(chat);
            } else {
                if (chat.sz.y == 0) {
                    chat.resize(chat.savedw, chat.savedh);
                    setfocus(chat);
                } else {
                    chat.resize(0, 0);
                }
            }
            Utils.setprefb("chatvis", chat.sz.y != 0);
        } else if (key == 16) {
            /*
            if((polity != null) && polity.show(!polity.visible)) {
            polity.raise();
            fitwdg(polity);
            setfocus(polity);
            }
            */
            return (true);
        } else if ((key == 27) && (map != null) && !map.hasfocus) {
            setfocus(map);
            return (true);
        } else if (key != 0) {
            boolean alt = ev.isAltDown();
            boolean ctrl = ev.isControlDown();
            boolean shift = ev.isShiftDown();
            int keycode = ev.getKeyCode();
            if (alt && keycode >= KeyEvent.VK_0 && keycode <= KeyEvent.VK_9) {
                beltwdg.setCurrentBelt(Utils.floormod(keycode - KeyEvent.VK_0 - 1, 10));
                return true;
            } else if (alt && keycode == KeyEvent.VK_S) {
                studywnd.show(!studywnd.visible);
                if (studywnd.visible)
                    studywnd.raise();
                return true;
            } else if (alt && keycode == KeyEvent.VK_M) {
                if (mmapwnd != null) {
                    mmapwnd.togglefold();
                    return true;
                }
            } else if (alt && keycode == KeyEvent.VK_C) {
                craftwnd.show(!craftwnd.visible);
                if (craftwnd.visible)
                    craftwnd.raise();
                return true;
            } else if (alt && keycode == KeyEvent.VK_B) {
                buildwnd.toggle();
                if (buildwnd.visible)
                    buildwnd.raise();
                return true;
            } else if (alt && keycode == KeyEvent.VK_N) {
                Config.nightvision.set(!Config.nightvision.get());
            } else if (alt && keycode == KeyEvent.VK_G) {
                if (map != null)
                    map.gridOverlay.setVisible(!map.gridOverlay.isVisible());
                return true;
            } else if (alt && keycode == KeyEvent.VK_R) {
                if (mmap != null)
                    mmap.toggleCustomIcons();
                return true;
            } else if (alt && keycode == KeyEvent.VK_D) {
                if (map != null)
                    map.toggleGobRadius();
                return true;
            } else if (alt && keycode == KeyEvent.VK_Q) {
                Config.showQuality.set(!Config.showQuality.get());
                return true;
            } else if (alt && keycode == KeyEvent.VK_K) {
                deckwnd.show(!deckwnd.visible);
                deckwnd.c = new Coord(sz.sub(deckwnd.sz).div(2));
                if (deckwnd.visible)
                    deckwnd.raise();
                return true;
            } else if (alt && keycode == KeyEvent.VK_F) {
                if (map != null) {
                    map.toggleFriendlyFire();
                    msg("Friendly fire prevention is now turned "
                            + (map.isPreventFriendlyFireEnabled() ? "on" : "off"));
                }
                return true;
            } else if (alt && keycode == KeyEvent.VK_I) {
                Config.showGobInfo.set(!Config.showGobInfo.get());
                return true;
            } else if (alt && keycode == KeyEvent.VK_W) {
                Config.screenshotMode = !Config.screenshotMode;
                return true;
            } else if (alt && keycode == KeyEvent.VK_T) {
                Config.disableTileTransitions.set(!Config.disableTileTransitions.get());
                ui.sess.glob.map.rebuild();
                return true;
            } else if (keycode == KeyEvent.VK_Q && ev.getModifiers() == 0) {
                /*
                // get all forageables from config
                List<String> names = new ArrayList<String>();
                for (CustomIconGroup group : ui.sess.glob.icons.config.groups) {
                    if ("Forageables".equals(group.name)) {
                for (CustomIconMatch match : group.matches)
                    if (match.show)
                        names.add(match.value);
                break;
                    }
                }
                tasks.add(new Forager(11 * Config.autopickRadius.get(), 1, names.toArray(new String[names.size()]))); 
                */
                ContextTaskFinder.checkForageables(tasks, ui);
                return true;
            } else if (keycode == KeyEvent.VK_E && ev.getModifiers() == 0) {
                ContextTaskFinder.findHandTask(tasks, ui);
                return true;
            } else if (keycode == KeyEvent.VK_F && ev.getModifiers() == 0) {
                ContextTaskFinder.findBuilding(tasks, ui);
                return true;
            } else if (keycode >= KeyEvent.VK_NUMPAD1 && keycode <= KeyEvent.VK_NUMPAD4) {
                tasks.add(new MileStoneTask(Utils.floormod(keycode - KeyEvent.VK_NUMPAD0 - 1, 10)));
                return true;
            } else if (keycode == KeyEvent.VK_W && ev.getModifiers() == 0) {
                tasks.add(new Drunkard());
                return true;
            } else if (shift && keycode == KeyEvent.VK_I) {
                Config.hideKinInfoForNonPlayers.set(!Config.hideKinInfoForNonPlayers.get());
                return true;
            } else if (ctrl && keycode == KeyEvent.VK_H) {
                Config.hideModeEnabled.set(!Config.hideModeEnabled.get());
                return true;
            } else if (alt && keycode == KeyEvent.VK_P) {
                Config.showGobPaths.set(!Config.showGobPaths.get());
                return true;
            } else if (shift && keycode == KeyEvent.VK_W) {
                if (Config.showQualityMode.get() == 1) {
                    Config.showQualityMode.set(2);
                } else {
                    Config.showQualityMode.set(1);
                }
                return true;
            } else if (keycode == KeyEvent.VK_TAB && Config.agroclosest.get()) {
                if (map != null)
                    map.aggroclosest();
                return true;
            } else if (ctrl && keycode == KeyEvent.VK_F) {
                Config.displayFPS.set(!Config.displayFPS.get());
                return true;
            } else if (keycode == KeyEvent.VK_Z && ev.getModifiers() == 0) {
                tasks.killAllTasks();
                return true;
            } else if (keycode == 192 && ev.getModifiers() == 0) {
                getparent(GameUI.class).menu.wdgmsg("act", "travel", "hearth");
                return true;
            } else if (shift && keycode == KeyEvent.VK_S) {
                HavenPanel.screenshot = true;
                return true;
            }
        }
        return (super.globtype(key, ev));
    }

    public boolean mousedown(Coord c, int button) {
        return (super.mousedown(c, button));
    }

    private int uimode = 1;

    public void toggleui(int mode) {
        Hidepanel[] panels = { brpanel, ulpanel, urpanel, menupanel };
        switch (uimode = mode) {
        case 0:
            for (Hidepanel p : panels)
                p.mshow(true);
            break;
        case 1:
            for (Hidepanel p : panels)
                p.mshow();
            break;
        case 2:
            for (Hidepanel p : panels)
                p.mshow(false);
            break;
        }
    }

    public void resetui() {
        Hidepanel[] panels = { brpanel, ulpanel, urpanel, menupanel };
        for (Hidepanel p : panels)
            p.cshow(p.tvis);
        uimode = 1;
    }

    public void toggleui() {
        toggleui((uimode + 1) % 3);
    }

    public void resize(Coord sz) {
        this.sz = sz;
        chatHidePanel.c = new Coord(0, sz.y - chatHidePanel.sz.y);
        if (map != null)
            map.resize(sz);
        iconwnd.c = sz.sub(iconwnd.sz).div(2);
        cal.c = new Coord((sz.x - cal.sz.x) / 2, 10);
        layout.update(sz);
        super.resize(sz);
    }

    public void presize() {
        resize(parent.sz);
    }

    public void msg(String msg, Color color, Color logcol) {
        msgtime = System.currentTimeMillis();
        lastmsg = msgfoundry.render(msg, color);
        syslog.append(msg, logcol);
    }

    public void msg(String msg, Color color) {
        msg(msg, color, color);
        Audio.play(errsfx);
    }

    private static final Resource errsfx = Resource.local().loadwait("sfx/error");

    public void error(String msg) {
        msg(msg, new Color(192, 0, 0), new Color(255, 0, 0));
        // HACK: do not play annoying sound when game is starting
        if (ignoreTrackingSound && "Tracking is now turned on.".equals(msg)
                || "Criminal acts are now turned on.".equals(msg)) {
            ignoreTrackingSound = false;
            return;
        }
        Audio.play(errsfx);
    }

    public void msg(String msg) {
        msg(msg, Color.WHITE, Color.WHITE);
    }

    public void notification(String format, Object... args) {
        msg(String.format(format, args), Color.WHITE);
    }

    public void act(String... args) {
        wdgmsg("act", (Object[]) args);
    }

    public void act(int mods, Coord mc, Gob gob, String... args) {
        int n = args.length;
        Object[] al = new Object[n];
        System.arraycopy(args, 0, al, 0, n);
        if (mc != null) {
            al = Utils.extend(al, al.length + 2);
            al[n++] = mods;
            al[n++] = mc;
            if (gob != null) {
                al = Utils.extend(al, al.length + 2);
                al[n++] = (int) gob.id;
                al[n++] = gob.rc;
            }
        }
        wdgmsg("act", al);
    }

    public Window getwnd(String cap) {
        for (Widget w = lchild; w != null; w = w.prev) {
            if (w instanceof Window) {
                Window wnd = (Window) w;
                if (wnd.cap != null && cap.equals(wnd.cap.text))
                    return wnd;
            }
        }
        return null;
    }

    public List<IMeter.Meter> getmeters(String name) {
        for (Widget meter : meters) {
            if (meter instanceof IMeter) {
                IMeter im = (IMeter) meter;
                try {
                    Resource res = im.bg.get();
                    if (res != null && res.basename().equals(name))
                        return im.meters;
                } catch (Loading l) {
                }
            }
        }
        return null;
    }

    public IMeter.Meter getmeter(String name, int midx) {
        List<IMeter.Meter> meters = getmeters(name);
        if (meters != null || midx < meters.size())
            return meters.get(midx);
        return null;
    }

    public class FKeyBelt extends Belt implements DTarget, DropTarget {
        public final int beltkeys[] = { KeyEvent.VK_F1, KeyEvent.VK_F2, KeyEvent.VK_F3, KeyEvent.VK_F4,
                KeyEvent.VK_F5, KeyEvent.VK_F6, KeyEvent.VK_F7, KeyEvent.VK_F8, KeyEvent.VK_F9, KeyEvent.VK_F10,
                KeyEvent.VK_F11, KeyEvent.VK_F12 };
        public int curbelt = 0;

        public FKeyBelt() {
            super(new Coord(450, 34));
        }

        private Coord beltc(int i) {
            return (new Coord(((invsq.sz().x + 2) * i) + (10 * (i / 4)), 0));
        }

        private int beltslot(Coord c) {
            for (int i = 0; i < 12; i++) {
                if (c.isect(beltc(i), invsq.sz()))
                    return (i + (curbelt * 12));
            }
            return (-1);
        }

        public void draw(GOut g) {
            for (int i = 0; i < 12; i++) {
                int slot = i + (curbelt * 12);
                Coord c = beltc(i);
                g.image(invsq, beltc(i));
                try {
                    if (belt[slot] != null)
                        g.image(belt[slot].get().layer(Resource.imgc).tex(), c.add(1, 1));
                } catch (Loading e) {
                }
                g.chcolor(156, 180, 158, 255);
                FastText.aprintf(g, c.add(invsq.sz().sub(2, 0)), 1, 1, "F%d", i + 1);
                g.chcolor();
            }
        }

        public boolean mousedown(Coord c, int button) {
            int slot = beltslot(c);
            if (slot != -1) {
                if (button == 1)
                    GameUI.this.wdgmsg("belt", slot, 1, ui.modflags());
                if (button == 3)
                    GameUI.this.wdgmsg("setbelt", slot, 1);
                return (true);
            }
            return (false);
        }

        public boolean globtype(char key, KeyEvent ev) {
            if (key != 0)
                return (false);
            boolean M = (ev.getModifiersEx() & (KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)) != 0;
            for (int i = 0; i < beltkeys.length; i++) {
                if (ev.getKeyCode() == beltkeys[i]) {
                    if (M) {
                        curbelt = i;
                        return (true);
                    } else {
                        keyact(i + (curbelt * 12));
                        return (true);
                    }
                }
            }
            return (false);
        }

        public boolean drop(Coord c, Coord ul) {
            int slot = beltslot(c);
            if (slot != -1) {
                GameUI.this.wdgmsg("setbelt", slot, 0);
                return (true);
            }
            return (false);
        }

        public boolean iteminteract(Coord c, Coord ul) {
            return (false);
        }

        public boolean dropthing(Coord c, Object thing) {
            int slot = beltslot(c);
            if (slot != -1) {
                if (thing instanceof Resource) {
                    Resource res = (Resource) thing;
                    if (res.layer(Resource.action) != null) {
                        GameUI.this.wdgmsg("setbelt", slot, res.name);
                        return (true);
                    }
                }
            }
            return (false);
        }
    }

    private static final Tex nkeybg = Resource.loadtex("gfx/hud/hb-main");

    public class NKeyBelt extends Belt implements DTarget, DropTarget {
        public int curbelt = 0;
        final Coord pagoff = new Coord(5, 25);

        public NKeyBelt() {
            super(nkeybg.sz());
        }

        private Coord beltc(int i) {
            return (pagoff.add(((invsq.sz().x + 2) * i) + (10 * (i / 5)), 0));
        }

        private int beltslot(Coord c) {
            for (int i = 0; i < 10; i++) {
                if (c.isect(beltc(i), invsq.sz()))
                    return (i + (curbelt * 12));
            }
            return (-1);
        }

        public void draw(GOut g) {
            g.image(nkeybg, Coord.z);
            for (int i = 0; i < 10; i++) {
                int slot = i + (curbelt * 12);
                Coord c = beltc(i);
                g.image(invsq, beltc(i));
                try {
                    if (belt[slot] != null)
                        g.image(belt[slot].get().layer(Resource.imgc).tex(), c.add(1, 1));
                } catch (Loading e) {
                }
                g.chcolor(156, 180, 158, 255);
                FastText.aprintf(g, c.add(invsq.sz().sub(2, 0)), 1, 1, "%d", (i + 1) % 10);
                g.chcolor();
            }
            super.draw(g);
        }

        public boolean mousedown(Coord c, int button) {
            int slot = beltslot(c);
            if (slot != -1) {
                if (button == 1)
                    GameUI.this.wdgmsg("belt", slot, 1, ui.modflags());
                if (button == 3)
                    GameUI.this.wdgmsg("setbelt", slot, 1);
                return (true);
            }
            return (super.mousedown(c, button));
        }

        public boolean globtype(char key, KeyEvent ev) {
            if (key != 0)
                return (false);
            int c = ev.getKeyChar();
            if ((c < KeyEvent.VK_0) || (c > KeyEvent.VK_9))
                return (false);
            int i = Utils.floormod(c - KeyEvent.VK_0 - 1, 10);
            boolean M = (ev.getModifiersEx() & (KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)) != 0;
            if (M) {
                curbelt = i;
            } else {
                keyact(i + (curbelt * 12));
            }
            return (false);
        }

        public boolean drop(Coord c, Coord ul) {
            int slot = beltslot(c);
            if (slot != -1) {
                GameUI.this.wdgmsg("setbelt", slot, 0);
                return (true);
            }
            return (false);
        }

        public boolean iteminteract(Coord c, Coord ul) {
            return (false);
        }

        public boolean dropthing(Coord c, Object thing) {
            int slot = beltslot(c);
            if (slot != -1) {
                if (thing instanceof Resource) {
                    Resource res = (Resource) thing;
                    if (res.layer(Resource.action) != null) {
                        GameUI.this.wdgmsg("setbelt", slot, res.name);
                        return (true);
                    }
                }
            }
            return (false);
        }
    }

    {
        String val = Utils.getpref("belttype", "n");
        if (val.equals("n")) {
            beltwdg = add(new DefaultBelt.NKeys("default"));
        } else if (val.equals("f")) {
            beltwdg = add(new DefaultBelt.FKeys("default"));
        } else {
            beltwdg = add(new DefaultBelt.NKeys("default"));
        }
    }

    public void addcmeter(Widget meter) {
        ulpanel.add(meter);
        cmeters.add(meter);
        updcmeters();
    }

    public <T extends Widget> void delcmeter(Class<T> cl) {
        Widget widget = null;
        for (Widget meter : cmeters) {
            if (cl.isAssignableFrom(meter.getClass())) {
                widget = meter;
                break;
            }
        }
        if (widget != null) {
            cmeters.remove(widget);
            widget.destroy();
            updcmeters();
        }
    }

    private void updcmeters() {
        int i = 0;
        for (Widget meter : cmeters) {
            int x = ((meters.size() + i) % 3) * (IMeter.fsz.x + 5);
            int y = ((meters.size() + i) / 3) * (IMeter.fsz.y + 2);
            meter.c = new Coord(portrait.c.x + portrait.sz.x + 10 + x, portrait.c.y + y);
            i++;
        }
    }

    public void swapHand() {
        if (hand.isEmpty()) {
            hand.addAll(handSave);
            handSave.clear();
            updhand();
        } else {
            handSave.addAll(hand);
            hand.clear();
            updhand();
        }
    }

    @Override
    public void bound() {
        if (Config.toggleTracking.get()) {
            act("tracking");
            ignoreTrackingSound = true;
        }
        if (Config.toggleCrime.get()) {
            act("crime");
            ignoreTrackingSound = true;
        }
    }

    public void actBelt(final int slot, boolean checkMapHit) {
        if (checkMapHit) {
            MapView map = ui.gui.map;
            if (map == null)
                return;
            Coord mvc = map.rootxlate(ui.mc);
            if (mvc.isect(Coord.z, map.sz)) {
                map.delay(map.new Hittest(mvc) {
                    protected void hit(Coord pc, Coord mc, MapView.ClickInfo inf) {
                        if (inf == null)
                            ui.gui.wdgmsg("belt", slot, 1, ui.modflags(), mc);
                        else
                            ui.gui.wdgmsg("belt", slot, 1, ui.modflags(), mc, (int) inf.gob.id, inf.gob.rc);
                    }

                    protected void nohit(Coord pc) {
                        ui.gui.wdgmsg("belt", slot, 1, ui.modflags());
                    }
                });
            }
        } else
            wdgmsg("belt", slot, 1, ui.modflags());

        if (belt[slot] != null) {
            makewnd.setLastAction(new Glob.Pagina(belt[slot]));
        }
    }

    public void refreshProgress() {
        curprog = null;
    }

    private Map<String, Console.Command> cmdmap = new TreeMap<String, Console.Command>();
    {
        cmdmap.put("kinfile", new Console.Command() {
            public void run(Console cons, String[] args) throws Exception {
                try {
                    StringBuffer path = new StringBuffer();
                    for (int i = 1; i < args.length; i++) {
                        path.append(args[i]);
                        if (i < args.length - 1)
                            path.append(" ");
                    }
                    if (path.length() > 0) {
                        List<String> lines = FileUtils.readLines(new File(path.toString()));
                        // use task that will add kins trying not to spam server
                        tasks.add(new AddKinsTask(lines));
                    }
                } catch (Exception e) {
                    error(e.getMessage());
                }
            }
        });
        cmdmap.put("afk", new Console.Command() {
            public void run(Console cons, String[] args) {
                afk = true;
                wdgmsg("afk");
            }
        });
        cmdmap.put("act", new Console.Command() {
            public void run(Console cons, String[] args) {
                Object[] ad = new Object[args.length - 1];
                System.arraycopy(args, 1, ad, 0, ad.length);
                wdgmsg("act", ad);
            }
        });
        cmdmap.put("belt", new Console.Command() {
            public void run(Console cons, String[] args) {
                if (args[1].equals("f")) {
                    beltwdg.destroy();
                    beltwdg = add(new DefaultBelt.FKeys("default"));
                    Utils.setpref("belttype", "f");
                    resize(sz);
                } else if (args[1].equals("n")) {
                    beltwdg.destroy();
                    beltwdg = add(new DefaultBelt.NKeys("default"));
                    Utils.setpref("belttype", "n");
                    resize(sz);
                }
            }
        });
        cmdmap.put("tool", new Console.Command() {
            public void run(Console cons, String[] args) {
                add(gettype(args[1]).create(GameUI.this, new Object[0]), 200, 200);
            }
        });
    }

    public Map<String, Console.Command> findcmds() {
        return (cmdmap);
    }
}