Skip to content

Commit

Permalink
WIP: not quite past lint
Browse files Browse the repository at this point in the history
  • Loading branch information
jcorbin committed Dec 14, 2017
1 parent 50b5bc2 commit eb9a4b8
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 136 deletions.
22 changes: 22 additions & 0 deletions internal/cops/display/display.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,28 @@ func (d *Display) SetRGBA(x, y int, t string, f, b color.RGBA) {
}
}

// MergeRGBA sets the given string and colors if they are
// non-empty and not transparent respectively.
func (d *Display) MergeRGBA(x, y int, t string, f, b color.RGBA) {
if i := d.Text.StringsOffset(x, y); i >= 0 && i < len(d.Text.Strings) {
if t != "" {
d.Text.Strings[i] = t
}
if f.A < 0xff {
d.Foreground.Pix[i] = f.R
d.Foreground.Pix[i+1] = f.G
d.Foreground.Pix[i+2] = f.B
d.Foreground.Pix[i+3] = f.A
}
if b.A < 0xff {
d.Background.Pix[i] = b.R
d.Background.Pix[i+1] = b.G
d.Background.Pix[i+2] = b.B
d.Background.Pix[i+3] = b.A
}
}
}

// TODO func (d *Display) Merge(x, y, t, f, b)

func (d *Display) setrgbai(i int, t string, f, b color.RGBA) {
Expand Down
30 changes: 21 additions & 9 deletions internal/point/box.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package point

import "image"

// Bx is a convenience constructor for Box.
func Bx(tlx, tly int, brx, bry int) Box {
return Box{Point{tlx, tly}, Point{brx, bry}}
Expand All @@ -19,19 +21,29 @@ func (b Box) Size() Point {
// ExpandTo expands a copy of the box to include the given point, returning the
// copy.
func (b Box) ExpandTo(pt Point) Box {
if pt.X < b.TopLeft.X {
b.TopLeft.X = pt.X
r := ExpandTo(image.Rect(
b.TopLeft.X, b.TopLeft.Y,
b.BottomRight.X, b.BottomRight.Y,
), image.Point(pt))
return Box{Point(r.Min), Point(r.Max)}
}

// ExpandTo expands a rectangle to include the given point, returning the
// (maybe larger) rectangle.
func ExpandTo(r image.Rectangle, pt image.Point) image.Rectangle {
if pt.X < r.Min.X {
r.Min.X = pt.X
}
if pt.Y < b.TopLeft.Y {
b.TopLeft.Y = pt.Y
if pt.Y < r.Min.Y {
r.Min.Y = pt.Y
}
if pt.X >= b.BottomRight.X {
b.BottomRight.X = pt.X + 1
if pt.X >= r.Max.X {
r.Max.X = pt.X + 1
}
if pt.Y >= b.BottomRight.Y {
b.BottomRight.Y = pt.Y + 1
if pt.Y >= r.Max.Y {
r.Max.Y = pt.Y + 1
}
return b
return r
}

// ExpandBy symmetrically expands a copy of the box by a given x/y
Expand Down
50 changes: 29 additions & 21 deletions proofs/deathroom/colors.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
package main

import (
"image"
"image/color"
"math/rand"

termbox "github.com/nsf/termbox-go"

"github.com/borkshop/bork/internal/cops/display"
"github.com/borkshop/bork/internal/ecs"
"github.com/borkshop/bork/internal/markov"
"github.com/borkshop/bork/internal/point"
)

func pullColors(ix ...int) []color.RGBA {
r := make([]color.RGBA, 0, len(ix))
for _, i := range ix {
r = append(r, display.Colors[i])
}
return r
}

var (
aiColors = []termbox.Attribute{124, 160, 196, 202, 208, 214}
soulColors = []termbox.Attribute{19, 20, 21, 27, 33, 39}
itemColors = []termbox.Attribute{22, 23, 29, 35, 41, 47}
wallColors = []termbox.Attribute{233, 234, 235, 236, 237, 238, 239}
floorColors = []termbox.Attribute{232, 233, 234}
aiColors = pullColors(124, 160, 196, 202, 208, 214)
soulColors = pullColors(19, 20, 21, 27, 33, 39)
itemColors = pullColors(22, 23, 29, 35, 41, 47)
wallColors = pullColors(233, 234, 235, 236, 237, 238, 239)
floorColors = pullColors(232, 233, 234)

wallTable = newColorTable()
floorTable = newColorTable()
Expand All @@ -33,15 +41,15 @@ const (
type colorTable struct {
ecs.Core
*markov.Table
color []termbox.Attribute
lookup map[termbox.Attribute]ecs.EntityID
color []color.RGBA
lookup map[color.RGBA]ecs.EntityID
}

func newColorTable() *colorTable {
ct := &colorTable{
// TODO: consider eliminating the padding for EntityID(0)
color: []termbox.Attribute{0},
lookup: make(map[termbox.Attribute]ecs.EntityID, 1),
color: []color.RGBA{color.RGBA{0xff, 0xff, 0xff, 0xff}},
lookup: make(map[color.RGBA]ecs.EntityID, 1),
}
ct.Table = markov.NewTable(&ct.Core)
ct.RegisterAllocator(componentTableColor, ct.allocTableColor)
Expand All @@ -59,7 +67,7 @@ func (ct *colorTable) destroyTableColor(id ecs.EntityID, t ecs.ComponentType) {
}

func (ct *colorTable) addLevelTransitions(
colors []termbox.Attribute,
colors []color.RGBA,
zeroOn, zeroUp int,
oneDown, oneOn, oneUp int,
) {
Expand All @@ -85,7 +93,7 @@ func (ct *colorTable) addLevelTransitions(
}
}

func (ct *colorTable) toEntity(a termbox.Attribute) ecs.Entity {
func (ct *colorTable) toEntity(a color.RGBA) ecs.Entity {
if id, def := ct.lookup[a]; def {
return ct.Ref(id)
}
Expand All @@ -96,30 +104,30 @@ func (ct *colorTable) toEntity(a termbox.Attribute) ecs.Entity {
return ent
}

func (ct *colorTable) toColor(ent ecs.Entity) (termbox.Attribute, bool) {
func (ct *colorTable) toColor(ent ecs.Entity) (color.RGBA, bool) {
if !ent.Type().HasAll(componentTableColor) {
return 0, false
}
return ct.color[ent.ID()], true
}

func (ct *colorTable) addTransition(a, b termbox.Attribute, w int) (ae, be ecs.Entity) {
func (ct *colorTable) addTransition(a, b color.RGBA, w int) (ae, be ecs.Entity) {
ae, be = ct.toEntity(a), ct.toEntity(b)
ct.AddTransition(ae, be, w)
return
}

func (ct *colorTable) genTile(
rng *rand.Rand,
box point.Box,
f func(point.Point, termbox.Attribute),
box image.Rectangle,
f func(image.Point, color.RGBA),
) {
// TODO: better 2d generation
last := floorTable.Ref(1)
var pos point.Point
for pos.Y = box.TopLeft.Y + 1; pos.Y < box.BottomRight.Y; pos.Y++ {
var pos image.Point
for pos.Y = box.Min.Y + 1; pos.Y < box.Max.Y; pos.Y++ {
first := last
for pos.X = box.TopLeft.X + 1; pos.X < box.BottomRight.X; pos.X++ {
for pos.X = box.Min.X + 1; pos.X < box.Max.X; pos.X++ {
c, _ := floorTable.toColor(last)
f(pos, c)
last = floorTable.ChooseNext(rng, last)
Expand Down
60 changes: 23 additions & 37 deletions proofs/deathroom/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ package main
import (
"fmt"
"image"
"image/color"
"log"
"math/rand"
"os"
"strings"

termbox "github.com/nsf/termbox-go"

"github.com/borkshop/bork/internal/ecs"
"github.com/borkshop/bork/internal/ecs/eps"
"github.com/borkshop/bork/internal/ecs/time"
Expand Down Expand Up @@ -79,9 +78,9 @@ type world struct {
timers time.Facility

Names []string
Glyphs []rune
BG []termbox.Attribute
FG []termbox.Attribute
Glyphs []string
BG []color.RGBA
FG []color.RGBA
bodies []*body
items []worldItem

Expand Down Expand Up @@ -145,9 +144,9 @@ func (w *world) init(v *view.View) {

// TODO: consider eliminating the padding for EntityID(0)
w.Names = []string{""}
w.Glyphs = []rune{0}
w.BG = []termbox.Attribute{0}
w.FG = []termbox.Attribute{0}
w.Glyphs = []string{""}
w.BG = []color.RGBA{{0, 0, 0, 0xff}}
w.FG = []color.RGBA{{0, 0, 0, 0xff}}
w.bodies = []*body{nil}
w.items = []worldItem{nil}

Expand Down Expand Up @@ -209,7 +208,7 @@ func (rc *rangeChooser) chosen(prior prompt.Prompt, n int) (next prompt.Prompt,

func (w *world) allocWorld(id ecs.EntityID, t ecs.ComponentType) {
w.Names = append(w.Names, "")
w.Glyphs = append(w.Glyphs, 0)
w.Glyphs = append(w.Glyphs, "")
w.BG = append(w.BG, 0)
w.FG = append(w.FG, 0)
w.bodies = append(w.bodies, nil)
Expand Down Expand Up @@ -246,11 +245,10 @@ func (w *world) destroyInput(id ecs.EntityID, t ecs.ComponentType) {
}
}

func (w *world) extent() point.Box {
var bbox point.Box
func (w *world) extent() (bbox image.Rectangle) {
for it := w.Iter(renderMask.All()); it.Next(); {
pos, _ := w.pos.Get(it.Entity())
bbox = bbox.ExpandTo(point.Point(pos))
bbox = point.ExpandTo(bbox, pos)
}
return bbox
}
Expand Down Expand Up @@ -491,7 +489,7 @@ func (w *world) nextWaiting() ecs.Entity {
return w.waiting.Entity()
}
w.enemyCounter++
return w.newChar(fmt.Sprintf("enemy%d", w.enemyCounter), 'X', wcAI)
return w.newChar(fmt.Sprintf("enemy%d", w.enemyCounter), "X", wcAI)
}

func soulInvolved(a, b ecs.Entity) bool {
Expand Down Expand Up @@ -537,7 +535,7 @@ func (w *world) dealAttackDamage(
targName := w.getName(targ, "nameless")
name := fmt.Sprintf("remains of %s", targName)
pos, _ := w.pos.Get(targ)
item := w.newItem(pos, name, '%', severed)
item := w.newItem(pos, name, "%", severed)
w.timers.Every(item, 5, w.decayRemains)
if severed.Len() > 0 {
w.log("%s's remains have dropped on the floor", targName)
Expand All @@ -550,18 +548,6 @@ func (w *world) dealAttackDamage(

bPart.Destroy()

// var xx []string
// for _, root := range targBo.rel.Roots(ecs.AllRel(brControl), nil) {
// xx = append(xx, targBo.DescribePart(root))
// }
// w.log("roots: %v", xx)
// for cur := targBo.rel.Cursor(ecs.AllRel(brControl), nil); cur.Scan(); {
// w.log("%v => %v (%v)",
// targBo.DescribePart(cur.A()),
// targBo.DescribePart(cur.B()),
// cur.Entity())
// }

if bo := w.bodies[targ.ID()]; bo.Iter(bcPart.All()).Count() > 0 {
return leftover, false
}
Expand All @@ -574,7 +560,7 @@ func (w *world) dealAttackDamage(
}
if spi > 0 {
targ.Delete(wcBody | wcSolid)
w.Glyphs[targ.ID()] = '⟡'
w.Glyphs[targ.ID()] = "⟡"
for _, head := range heads {
head.Add(bcDerived)
severed.derived[head.ID()] = targ
Expand Down Expand Up @@ -678,9 +664,9 @@ func (w *world) chooseAttackedPart(ent ecs.Entity) ecs.Entity {
})
}

func (w *world) addBox(box point.Box, glyph rune) {
func (w *world) addBox(box image.Rectangle, glyph string) {
// TODO: the box should be an entity, rather than each cell
last, sz, pos := wallTable.Ref(1), box.Size(), image.Point(box.TopLeft)
last, sz, pos := wallTable.Ref(1), box.Size(), image.Point(box.Min)
for _, r := range []struct {
n int
d image.Point
Expand All @@ -702,14 +688,14 @@ func (w *world) addBox(box point.Box, glyph rune) {
}
}

floorTable.genTile(w.rng, box, func(pos point.Point, bg termbox.Attribute) {
floorTable.genTile(w.rng, box, func(pos image.Point, bg color.RGBA) {
floor := w.AddEntity(wcPosition | wcBG | wcFloor)
w.pos.Set(floor, image.Point(pos))
w.pos.Set(floor, pos)
w.BG[floor.ID()] = bg
})
}

func (w *world) newItem(pos image.Point, name string, glyph rune, val worldItem) ecs.Entity {
func (w *world) newItem(pos image.Point, name string, glyph string, val worldItem) ecs.Entity {
ent := w.AddEntity(wcPosition | wcName | wcGlyph | wcItem)
w.pos.Set(ent, pos)
w.Glyphs[ent.ID()] = glyph
Expand All @@ -718,7 +704,7 @@ func (w *world) newItem(pos image.Point, name string, glyph rune, val worldItem)
return ent
}

func (w *world) newChar(name string, glyph rune, t ecs.ComponentType) ecs.Entity {
func (w *world) newChar(name string, glyph string, t ecs.ComponentType) ecs.Entity {
ent := w.AddEntity(charMask | wcWaiting | t)
w.Glyphs[ent.ID()] = glyph
w.Names[ent.ID()] = name
Expand Down Expand Up @@ -787,7 +773,7 @@ func (w *world) getAgro(a, b ecs.Entity) (n int) {
func (w *world) addSpawn(x, y int) ecs.Entity {
spawn := w.AddEntity(wcPosition | wcGlyph | wcFG | wcSpawn)
w.pos.Set(spawn, image.Pt(x, y))
w.Glyphs[spawn.ID()] = '✖' // ×
w.Glyphs[spawn.ID()] = "✖" // ×
w.FG[spawn.ID()] = 54
return spawn
}
Expand All @@ -799,14 +785,14 @@ func main() {
return nil, err
}

pt := point.Point{X: 12, Y: 8}
w.addBox(point.Box{TopLeft: pt.Neg(), BottomRight: pt}, '#')
pt := image.Point{X: 12, Y: 8}
w.addBox(image.Rect(-12, -8, 12, 8), "#")

w.addSpawn(0, -5)
w.addSpawn(-8, 5)
w.addSpawn(8, 5)

player := w.newChar("you", 'X', wcSoul)
player := w.newChar("you", "X", wcSoul)
w.ui.bar.addAction(newRangeChooser(w, player))

w.Process()
Expand Down
Loading

0 comments on commit eb9a4b8

Please sign in to comment.