func (c *ClientState) tickItemName() { item := c.playerInventory.Items[invPlayerHotbarOffset+c.currentHotbarSlot] if c.lastHotbarSlot != c.currentHotbarSlot || item != c.lastHotbarItem { c.lastHotbarSlot = c.currentHotbarSlot c.lastHotbarItem = item c.entity.SetCurrentItem(item) if item != nil { var name format.AnyComponent if di, ok := item.Type.(DisplayTag); ok && di.DisplayName() != "" { name = format.Wrap(&format.TextComponent{Text: di.DisplayName()}) format.ConvertLegacy(name) } else { name = format.Wrap(&format.TranslateComponent{Translate: item.Type.NameLocaleKey()}) } c.itemNameUI.Update(name) c.itemNameTimer = 120 } else { c.itemNameUI.Update(format.Wrap(&format.TextComponent{})) c.itemNameTimer = 0 } } c.itemNameTimer -= Client.delta if c.itemNameTimer < 0 { c.itemNameTimer = 0 } a := c.itemNameTimer / 30 if a > 1 { a = 1 } for _, txt := range c.itemNameUI.Text { txt.SetA(int(a * 255)) } }
// Text appends the passed formatted string plus a new line to // the log buffer. The formatting uses the same rules as fmt. func Text(f string, args ...interface{}) { _, file, line, ok := runtime.Caller(1) if !ok { file = "unknown" line = 0 } file = file[strings.LastIndex(file, "/")+1:] msg := &format.TextComponent{ Text: fmt.Sprintf("[%s:%d] ", file, line), Component: format.Component{ Color: format.Aqua, }, } msg.Extra = append(msg.Extra, format.Wrap(&format.TextComponent{ Text: fmt.Sprintf(f, args...), Component: format.Component{ Color: format.White, }, })) Component(format.Wrap(msg)) }
func (s *signComponent) create() { const yS = (6.0 / 16.0) / 4.0 const xS = yS / 16.0 var verts []*render.StaticVertex for i, line := range s.lines { if line.Value == nil { continue } format.ConvertLegacy(line) // Hijack ui.Formatted's component parsing to split // up components into ui.Text elements. // TODO(Think) Move this into some common place for // easier reuse in other places? wrap := &format.TextComponent{} wrap.Color = format.Black wrap.Extra = []format.AnyComponent{line} f := ui.NewFormatted(format.Wrap(wrap), 0, 0) offset := 0.0 for _, txt := range f.Text { str := txt.Value() for _, r := range str { tex := render.CharacterTexture(r) if tex == nil { continue } s := render.SizeOfCharacter(r) if r == ' ' { offset += (s + 2) * xS continue } for _, v := range faceVertices[direction.North].verts { vert := &render.StaticVertex{ X: float32(v.X)*float32(s*xS) - float32(offset+s*xS) + float32(f.Width*xS*0.5), Y: float32(v.Y)*yS - yS*float32(i-1), Z: -.6 / 16.0, Texture: tex, TextureX: float64(v.TOffsetX), TextureY: float64(v.TOffsetY), R: byte(txt.R()), G: byte(txt.G()), B: byte(txt.B()), A: 255, } verts = append(verts, vert) } offset += (s + 2) * xS } } } wood := render.GetTexture("blocks/planks_oak") // The backboard verts = appendBoxExtra(verts, -0.5, -4/16.0, -0.5/16.0, 1.0, 8/16.0, 1/16.0, [6]render.TextureInfo{ direction.Up: wood.Sub(0, 0, 16, 2), direction.Down: wood.Sub(0, 0, 16, 2), direction.East: wood.Sub(0, 0, 2, 12), direction.West: wood.Sub(0, 0, 2, 12), direction.North: wood.Sub(0, 4, 16, 12), direction.South: wood.Sub(0, 4, 16, 12), }, [6][2]float64{ direction.Up: {1.5, 1.0}, direction.Down: {1.5, 1.0}, direction.East: {1.0, 1.0}, direction.West: {1.0, 1.0}, direction.North: {1.5, 1.0}, direction.South: {1.5, 1.0}, }) if s.hasStand { // Stand log := render.GetTexture("blocks/log_oak") verts = appendBox(verts, -0.5/16.0, -0.25-9/16.0, -0.5/16.0, 1/16.0, 9/16.0, 1/16.0, [6]render.TextureInfo{ direction.Up: log.Sub(0, 0, 2, 2), direction.Down: log.Sub(0, 0, 2, 2), direction.East: log.Sub(0, 0, 2, 12), direction.West: log.Sub(0, 0, 2, 12), direction.North: log.Sub(0, 0, 2, 12), direction.South: log.Sub(0, 0, 2, 12), }) } s.model = render.NewStaticModel([][]*render.StaticVertex{ verts, }) s.model.Radius = 2 x, y, z := s.position.X, s.position.Y, s.position.Z s.model.X, s.model.Y, s.model.Z = -float32(x)-0.5, -float32(y)-0.5, float32(z)+0.5 s.model.Matrix[0] = mgl32.Translate3D( float32(x)+0.5, -float32(y)-0.5, float32(z)+0.5, ).Mul4(mgl32.Rotate3DY(float32(s.rotation)).Mat4()). Mul4(mgl32.Translate3D(float32(s.ox), float32(-s.oy), float32(s.oz))) }
func (rl *resourceList) redraw() { for _, s := range rl.packs { s.Hide() render.FreeIcon(s.id) } rl.packs = rl.packs[:0] os.MkdirAll("./resource-packs", 0777) files, _ := ioutil.ReadDir("./resource-packs") for i, f := range files { f := f if !strings.HasSuffix(f.Name(), ".zip") { continue } fullName := filepath.Join("./resource-packs", f.Name()) desc, iimg, ok := getPackInfo(fullName) if !ok { continue } sc := scene.New(true) container := ui.NewContainer(0, float64(i)*100, 700, 100). Attach(ui.Center, ui.Middle) r := make([]byte, 20) rand.Read(r) si := &resourceListItem{ Type: sc, container: container, offset: float64(i), id: "servericon:" + string(r), } si.updatePosition() rl.packs = append(rl.packs, si) var rr, gg, bb int if resource.IsActive(fullName) { rr = 200 gg = 200 } bck := ui.NewImage(render.GetTexture("solid"), 0, 0, 700, 100, 0, 0, 1, 1, rr, gg, bb).Attach(ui.Top, ui.Left) bck.SetA(100) bck.AttachTo(container) sc.AddDrawable(bck) txt := ui.NewText(f.Name(), 90+10, 5, 255, 255, 255).Attach(ui.Top, ui.Left) txt.AttachTo(container) sc.AddDrawable(txt) var tex render.TextureInfo if iimg == nil { tex = render.GetTexture("misc/unknown_pack") } else { render.AddIcon(si.id, iimg) tex = render.Icon(si.id) } icon := ui.NewImage(tex, 5, 5, 90, 90, 0, 0, 1, 1, 255, 255, 255). Attach(ui.Top, ui.Left) icon.AttachTo(container) sc.AddDrawable(icon) msg := format.Wrap(&format.TextComponent{Text: desc}) format.ConvertLegacy(msg) motd := ui.NewFormattedWidth(msg, 90+10, 5+18, 700-(90+10+5)).Attach(ui.Top, ui.Left) motd.AttachTo(container) sc.AddDrawable(motd) container.ClickFunc = func() { if resource.IsActive(fullName) { RemovePack(fullName) } else { AddPack(fullName) } setScreen(newResourceList(rl.ret)) } container.HoverFunc = func(over bool) { if over { bck.SetA(200) } else { bck.SetA(100) } } sc.AddDrawable(container) } }
func newClient() { c := &ClientState{ Bounds: vmath.AABB{ Min: mgl32.Vec3{-0.3, 0, -0.3}, Max: mgl32.Vec3{0.3, 1.8, 0.3}, }, scene: scene.New(true), } Client = c c.playerInventory = NewInventory(InvPlayer, 0, 45) c.hotbarScene = scene.New(true) c.network.init() c.currentBreakingBlock = Blocks.Air.Base c.blockBreakers = map[int]BlockEntity{} widgets := render.GetTexture("gui/widgets") icons := render.GetTexture("gui/icons") // Crosshair c.scene.AddDrawable( ui.NewImage(icons, 0, 0, 32, 32, 0, 0, 16.0/256.0, 16.0/256.0, 255, 255, 255). Attach(ui.Middle, ui.Center), ) // Hotbar hotbar := ui.NewImage(widgets, 0, 0, 182*2, 22*2, 0, 0, 182.0/256.0, 22.0/256.0, 255, 255, 255). Attach(ui.Bottom, ui.Center) c.scene.AddDrawable(hotbar) c.hotbar = hotbar c.hotbarUI = ui.NewImage(widgets, -22*2+4, -2, 24*2, 24*2, 0, 22.0/256.0, 24.0/256.0, 24.0/256.0, 255, 255, 255). Attach(ui.Bottom, ui.Center) c.scene.AddDrawable(c.hotbarUI) // Hearts / Food for i := 0; i < 10; i++ { l := ui.NewImage(icons, 16*float64(i), -16-8-10, 18, 18, 16.0/256.0, 0, 9.0/256.0, 9.0/256.0, 255, 255, 255). Attach(ui.Top, ui.Left) l.AttachTo(hotbar) c.scene.AddDrawable(l) c.lifeUI = append(c.lifeUI, l) l = ui.NewImage(icons, 16*float64(i), -16-8-10, 18, 18, (16+9*4)/256.0, 0, 9.0/256.0, 9.0/256.0, 255, 255, 255). Attach(ui.Top, ui.Left) l.AttachTo(hotbar) c.scene.AddDrawable(l) c.lifeFillUI = append(c.lifeFillUI, l) f := ui.NewImage(icons, 16*float64(i), -16-8-10, 18, 18, 16.0/256.0, 27.0/256.0, 9.0/256.0, 9.0/256.0, 255, 255, 255). Attach(ui.Top, ui.Right) f.AttachTo(hotbar) c.scene.AddDrawable(f) c.foodUI = append(c.foodUI, f) f = ui.NewImage(icons, 16*float64(i), -16-8-10, 18, 18, (16+9*4)/256.0, 27.0/256.0, 9.0/256.0, 9.0/256.0, 255, 255, 255). Attach(ui.Top, ui.Right) f.AttachTo(hotbar) c.scene.AddDrawable(f) c.foodFillUI = append(c.foodFillUI, f) } // Exp bar c.scene.AddDrawable( ui.NewImage(icons, 0, 22*2+4, 182*2, 10, 0, 64.0/256.0, 182.0/256.0, 5.0/256.0, 255, 255, 255). Attach(ui.Bottom, ui.Center), ) c.itemNameUI = ui.NewFormatted(format.Wrap(&format.TextComponent{}), 0, -16-8-10-16-20) c.itemNameUI.AttachTo(c.hotbar) c.scene.AddDrawable(c.itemNameUI.Attach(ui.Top, ui.Middle)) c.chat.init() c.initDebug() c.playerList.init() c.entities.init() c.initEntity(false) }
func (sl *serverList) pingServer(addr string, motd, version *ui.Formatted, icon *ui.Image, id string, ping *ui.Image, players *ui.Text) { conn, err := protocol.Dial(addr) if err != nil { syncChan <- func() { msg := &format.TextComponent{Text: err.Error()} msg.Color = format.Red motd.Update(format.Wrap(msg)) } return } defer conn.Close() resp, pingTime, err := conn.RequestStatus() syncChan <- func() { if err != nil { msg := &format.TextComponent{Text: err.Error()} msg.Color = format.Red motd.Update(format.Wrap(msg)) return } y := 0.0 pt := pingTime.Seconds() / 1000 switch { case pt <= 75: y = 16 / 256.0 case pt <= 150: y = 24 / 256.0 case pt <= 225: y = 32 / 256.0 case pt <= 350: y = 40 / 256.0 case pt < 999: y = 48 / 256.0 default: y = 56 / 256.0 } ping.SetTextureY(y) if resp.Version.Protocol == protocol.SupportedProtocolVersion { players.SetG(255) players.SetB(255) players.Update(fmt.Sprintf("%d/%d", resp.Players.Online, resp.Players.Max)) } else { players.SetG(85) players.SetB(85) players.Update(fmt.Sprintf("Out of date %d/%d", resp.Players.Online, resp.Players.Max)) } txt := &format.TextComponent{Text: resp.Version.Name} txt.Color = format.Yellow ver := format.Wrap(txt) format.ConvertLegacy(ver) version.Update(ver) desc := resp.Description format.ConvertLegacy(desc) motd.Update(desc) if strings.HasPrefix(resp.Favicon, "data:image/png;base64,") { favicon := resp.Favicon[len("data:image/png;base64,"):] data, err := base64.StdEncoding.DecodeString(favicon) if err != nil { fmt.Printf("error base64 decoding favicon: %s\n", err) return } img, err := png.Decode(bytes.NewReader(data)) if err != nil { fmt.Printf("error decoding favicon: %s\n", err) return } render.AddIcon(id, img) icon.SetTexture(render.Icon(id)) } } }
func (sl *serverList) redraw() { for _, s := range sl.servers { s.Hide() render.FreeIcon(s.id) } sl.servers = sl.servers[:0] for i, s := range Config.Servers { sc := scene.New(true) container := ui.NewContainer(0, float64(i)*100, 700, 100). Attach(ui.Center, ui.Middle) r := make([]byte, 20) rand.Read(r) si := &serverListItem{ Type: sc, container: container, offset: float64(i), id: "servericon:" + string(r), } si.updatePosition() sl.servers = append(sl.servers, si) bck := ui.NewImage(render.GetTexture("solid"), 0, 0, 700, 100, 0, 0, 1, 1, 0, 0, 0).Attach(ui.Top, ui.Left) bck.SetA(100) bck.AttachTo(container) sc.AddDrawable(bck) txt := ui.NewText(s.Name, 90+10, 5, 255, 255, 255).Attach(ui.Top, ui.Left) txt.AttachTo(container) sc.AddDrawable(txt) icon := ui.NewImage(render.GetTexture("misc/unknown_server"), 5, 5, 90, 90, 0, 0, 1, 1, 255, 255, 255). Attach(ui.Top, ui.Left) icon.AttachTo(container) sc.AddDrawable(icon) ping := ui.NewImage(render.GetTexture("gui/icons"), 5, 5, 20, 16, 0, 56/256.0, 10/256.0, 8/256.0, 255, 255, 255). Attach(ui.Top, ui.Right) ping.AttachTo(container) sc.AddDrawable(ping) players := ui.NewText("???", 30, 5, 255, 255, 255). Attach(ui.Top, ui.Right) players.AttachTo(container) sc.AddDrawable(players) msg := &format.TextComponent{Text: "Connecting..."} motd := ui.NewFormattedWidth(format.Wrap(msg), 90+10, 5+18, 700-(90+10+5)).Attach(ui.Top, ui.Left) motd.AttachTo(container) sc.AddDrawable(motd) msg = &format.TextComponent{Text: ""} version := ui.NewFormattedWidth(format.Wrap(msg), 90+10, 5, 700-(90+10+5)).Attach(ui.Bottom, ui.Left) version.AttachTo(container) sc.AddDrawable(version) s := s go sl.pingServer(s.Address, motd, version, icon, si.id, ping, players) container.ClickFunc = func() { PlaySound("random.click") sl.connect(s.Address) } container.HoverFunc = func(over bool) { if over { bck.SetA(200) } else { bck.SetA(100) } } sc.AddDrawable(container) index := i del, txt := newButtonText("X", 0, 0, 25, 25) del.AttachTo(container) sc.AddDrawable(del.Attach(ui.Bottom, ui.Right)) sc.AddDrawable(txt) del.AddClick(func() { Config.Servers = append(Config.Servers[:index], Config.Servers[index+1:]...) saveServers() sl.redraw() }) edit, txt := newButtonText("E", 25, 0, 25, 25) edit.AttachTo(container) sc.AddDrawable(edit.Attach(ui.Bottom, ui.Right)) sc.AddDrawable(txt) edit.AddClick(func() { setScreen(newEditServer(index)) }) } }