/* * This file is part of the Haven & Hearth game client. * Copyright (C) 2009 Fredrik Tolf <fredrik@dolda2000.com>, and * Björn 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.Color; import java.awt.image.BufferedImage; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import ender.CurioInfo; public class Item extends Widget implements DTarget { static Coord shoff = new Coord(1, 3); static final Pattern patt = Pattern.compile("quality (\\d+) ", Pattern.CASE_INSENSITIVE); static Map<Integer, Tex> qmap; static Resource missing = Resource.load("gfx/invobjs/missing"); static Color outcol = new Color(0,0,0,255); boolean dm = false; public int q, q2; boolean hq; Coord doff; String tooltip; int num = -1; Indir<Resource> res; Tex sh; Color olcol = null; Tex mask = null; int meter = 0; String curioStr = null; static { Widget.addtype("item", new WidgetFactory() { public Widget create(Coord c, Widget parent, Object[] args) { int res = (Integer)args[0]; int q = (Integer)args[1]; int num = -1; String tooltip = null; int ca = 3; Coord drag = null; if((Integer)args[2] != 0) drag = (Coord)args[ca++]; if(args.length > ca) tooltip = (String)args[ca++]; if((tooltip != null) && tooltip.equals("")) tooltip = null; if(args.length > ca) num = (Integer)args[ca++]; Item item = new Item(c, res, q, parent, drag, num); item.settip(tooltip); return(item); } }); missing.loadwait(); qmap = new HashMap<Integer, Tex>(); } public void settip(String t){ tooltip = t; q2 = -1; if(tooltip != null){ try{ Matcher m =patt.matcher(tooltip); while(m.find()){ q2 = Integer.parseInt(m.group(1)); } } catch(IllegalStateException e){ System.out.println(e.getMessage()); } } calcFEP(); calcCurio(); shorttip = longtip = null; } private void fixsize() { if(res.get() != null) { Tex tex = res.get().layer(Resource.imgc).tex(); sz = tex.sz().add(shoff); } else { sz = new Coord(30, 30); } } public void draw(GOut g) { final Resource ttres; if(res.get() == null) { sh = null; sz = new Coord(30, 30); g.image(missing.layer(Resource.imgc).tex(), Coord.z, sz); ttres = missing; } else { Tex tex = res.get().layer(Resource.imgc).tex(); fixsize(); if(dm) { g.chcolor(255, 255, 255, 128); g.image(tex, Coord.z); g.chcolor(); } else { g.image(tex, Coord.z); } if(num >= 0) { //g.chcolor(Color.WHITE); //g.atext(Integer.toString(num), new Coord(0, 30), 0, 1); g.aimage(getqtex(num), Coord.z, 0, 0); } if(meter > 0) { double a = ((double)meter) / 100.0; int r = (int) ((1-a)*255); int gr = (int) (a*255); int b = 0; g.chcolor(r, gr, b, 255); //g.fellipse(sz.div(2), new Coord(15, 15), 90, (int)(90 + (360 * a))); g.frect(new Coord(sz.x-5,(int) ((1-a)*sz.y)), new Coord(5,(int) (a*sz.y))); g.chcolor(); } int tq = (q2>0)?q2:q; if(Config.showq && (tq > 0)){ tex = getqtex(tq); g.aimage(tex, sz.sub(1,1), 1, 1); } ttres = res.get(); } if(olcol != null) { Tex bg = ttres.layer(Resource.imgc).tex(); if((mask == null) && (bg instanceof TexI)) { mask = ((TexI)bg).mkmask(); } if(mask != null) { g.chcolor(olcol); g.image(mask, Coord.z); g.chcolor(); } } if(FEP == null){calcFEP();} if(curioStr == null){calcCurio();} } static Tex getqtex(int q){ synchronized (qmap) { if(qmap.containsKey(q)){ return qmap.get(q); } else { BufferedImage img = Text.render(Integer.toString(q)).img; img = Utils.outline2(img, outcol, true); Tex tex = new TexI(img); qmap.put(q, tex); return tex; } } } static Tex makesh(Resource res) { BufferedImage img = res.layer(Resource.imgc).img; Coord sz = Utils.imgsz(img); BufferedImage sh = new BufferedImage(sz.x, sz.y, BufferedImage.TYPE_INT_ARGB); for(int y = 0; y < sz.y; y++) { for(int x = 0; x < sz.x; x++) { long c = img.getRGB(x, y) & 0x00000000ffffffffL; int a = (int)((c & 0xff000000) >> 24); sh.setRGB(x, y, (a / 2) << 24); } } return(new TexI(sh)); } public String name() { Resource res = this.res.get(); if(res != null){ if(res.layer(Resource.tooltip) != null) { return res.layer(Resource.tooltip).t; } else { return(this.tooltip); } } return null; } public String shorttip() { if(this.tooltip != null) return(this.tooltip); Resource res = this.res.get(); if((res != null) && (res.layer(Resource.tooltip) != null)) { String tt = res.layer(Resource.tooltip).t; if(tt != null) { if(q > 0) { tt = tt + ", quality " + q; if(hq) tt = tt + "+"; } return(tt); } } return(null); } long hoverstart; Text shorttip = null, longtip = null; public double qmult; private String FEP = null; public Object tooltip(Coord c, boolean again) { long now = System.currentTimeMillis(); if(!again) hoverstart = now; Resource res = this.res.get(); Resource.Pagina pg = (res!=null)?res.layer(Resource.pagina):null; if(((now - hoverstart) < 500)||(pg == null)) { if(shorttip == null) { String tt = shorttip(); if(tt != null) { tt = RichText.Parser.quote(tt); if(meter > 0) { tt = tt + " (" + meter + "%)"; } if(FEP != null){ tt += FEP; } if(curioStr != null){ tt += curioStr; } shorttip = RichText.render(tt, 200); } } return(shorttip); } else { if((longtip == null) && (res != null)) { String tip = shorttip(); if(tip == null) return(null); String tt = RichText.Parser.quote(tip); if(meter > 0) { tt = tt + " (" + meter + "%)"; } if(FEP != null){ tt += FEP; } if(curioStr != null){ tt += curioStr; } if(pg != null) tt += "\n\n" + pg.text; longtip = RichText.render(tt, 200); } return(longtip); } } private void resettt() { shorttip = null; longtip = null; } private void decq(int q) { if(q < 0) { this.q = q; hq = false; } else { int fl = (q & 0xff000000) >> 24; this.q = (q & 0xffffff); hq = ((fl & 1) != 0); } } public Item(Coord c, Indir<Resource> res, int q, Widget parent, Coord drag, int num) { super(c, Coord.z, parent); this.res = res; decq(q); fixsize(); this.num = num; if(drag == null) { dm = false; } else { dm = true; doff = drag; ui.grabmouse(this); this.c = ui.mc.add(doff.inv()); } qmult = Math.sqrt((float)q/10); calcFEP(); calcCurio(); } private void calcFEP() { Map<String, Float> fep; String name = name(); if(name == null){return;} if(name.equals("Ring of Brodgar")){ if(res.get().name.equals("gfx/invobjs/bread-brodgar")){name = "Ring of Brodgar (Baking)";} if(res.get().name.equals("gfx/invobjs/feast-rob")){name = "Ring of Brodgar (Seafood)";} } name = name.toLowerCase(); boolean isItem = false; if((fep = Config.FEPMap.get(name)) != null){ if(fep.containsKey("isItem")){ isItem = true; } FEP = "\n"; for(String key:fep.keySet()){ float val = (float) (fep.get(key)*qmult); if(key.equals("isItem")){continue;} if(isItem){ val = (float) Math.floor(val); FEP += String.format("%s:%.0f ", key, val); } else { FEP += String.format("%s:%.1f ", key, val); } } shorttip = longtip = null; } } public int getLP() { String name = name(); if(name == null){return 0;} name = name.toLowerCase(); CurioInfo curio; if((curio = Config.curios.get(name)) != null){ return (int) (curio.LP*qmult*ui.sess.glob.cattr.get("expmod").comp/100); } return 0; } private void calcCurio(){ String name = name(); if(name == null){return;} name = name.toLowerCase(); CurioInfo curio; if((curio = Config.curios.get(name)) != null){ int LP = (int) (curio.LP*qmult*ui.sess.glob.cattr.get("expmod").comp/100); int time = curio.time*(100 - meter)/100; int h = time/60; int m = time%60; curioStr = String.format("\nLP: %d, Weight: %d\nStudy time: %dh %2dm", LP,curio.weight,h,m); shorttip = longtip = null; } } public Item(Coord c, int res, int q, Widget parent, Coord drag, int num) { this(c, parent.ui.sess.getres(res), q, parent, drag, num); } public Item(Coord c, Indir<Resource> res, int q, Widget parent, Coord drag) { this(c, res, q, parent, drag, -1); } public Item(Coord c, int res, int q, Widget parent, Coord drag) { this(c, parent.ui.sess.getres(res), q, parent, drag); } public boolean dropon(Widget w, Coord c) { for(Widget wdg = w.lchild; wdg != null; wdg = wdg.prev) { if(wdg == this) continue; Coord cc = w.xlate(wdg.c, true); if(c.isect(cc, (wdg.hsz == null)?wdg.sz:wdg.hsz)) { if(dropon(wdg, c.add(cc.inv()))) return(true); } } if(w instanceof DTarget) { if(((DTarget)w).drop(c, c.add(doff.inv()))) return(true); } if(w instanceof DTarget2) { if(((DTarget2)w).drop(c, c.add(doff.inv()), this)) return(true); } return(false); } public boolean interact(Widget w, Coord c) { for(Widget wdg = w.lchild; wdg != null; wdg = wdg.prev) { if(wdg == this) continue; Coord cc = w.xlate(wdg.c, true); if(c.isect(cc, (wdg.hsz == null)?wdg.sz:wdg.hsz)) { if(interact(wdg, c.add(cc.inv()))) return(true); } } if(w instanceof DTarget) { if(((DTarget)w).iteminteract(c, c.add(doff.inv()))) return(true); } return(false); } public void chres(Indir<Resource> res, int q) { this.res = res; sh = null; decq(q); } public void uimsg(String name, Object... args) { if(name == "num") { num = (Integer)args[0]; } else if(name == "chres") { chres(ui.sess.getres((Integer)args[0]), (Integer)args[1]); resettt(); } else if(name == "color") { olcol = (Color)args[0]; } else if(name == "tt") { if((args.length > 0) && (((String)args[0]).length() > 0)) settip((String)args[0]); else settip(null); resettt(); } else if(name == "meter") { meter = (Integer)args[0]; shorttip = null; longtip = null; calcCurio(); } } public boolean mousedown(Coord c, int button) { if(!dm) { if(button == 1) { if(ui.modshift) if(ui.modmeta) wdgmsg("transfer-same", name(), false); else wdgmsg("transfer", c); else if(ui.modctrl) if(ui.modmeta) wdgmsg("drop-same", name(), false); else wdgmsg("drop", c); else wdgmsg("take", c); return(true); } else if(button == 3) { if(ui.modmeta){ if(ui.modshift){ wdgmsg("transfer-same", name(), true); } else if(ui.modctrl){ wdgmsg("drop-same", name(), true); } } else { wdgmsg("iact", c); } return(true); } } else { if(button == 1) { dropon(parent, c.add(this.c)); } else if(button == 3) { interact(parent, c.add(this.c)); } return(true); } return(false); } public void mousemove(Coord c) { if(dm) this.c = this.c.add(c.add(doff.inv())); } public boolean drop(Coord cc, Coord ul) { return(false); } public boolean iteminteract(Coord cc, Coord ul) { wdgmsg("itemact", ui.modflags()); return(true); } }