Browse Source

Attempting to get a editor

An editor to modify the world and tiles is needed... I'm not done yet,
we're not rendering the first line right (the panel boarder is being
eaten).
Apollo 10 months ago
parent
commit
d6813a130d
6 changed files with 150 additions and 63 deletions
  1. 18 0
      camera.go
  2. 55 0
      editor.go
  3. 3 0
      go.mod
  4. 4 0
      go.sum
  5. 69 62
      main.go
  6. 1 1
      world.go

+ 18 - 0
camera.go

@@ -1,5 +1,7 @@
 package main
 package main
 
 
+import door "git.red-green.com/RedGreen/doorgo"
+
 type Camera struct {
 type Camera struct {
 	Size *Vec2
 	Size *Vec2
 }
 }
@@ -22,3 +24,19 @@ func (c *Camera) debugView(at *Vec2, w *World) string {
 	}
 	}
 	return out
 	return out
 }
 }
+
+func (c *Camera) View(at *Vec2, offset *Vec2, w *World) string {
+	out := ""
+	t := at.Clone()
+	t.X -= c.Size.X / 2
+	t.Y -= c.Size.Y / 2
+	for y := range make([]byte, c.Size.Y) {
+		for x := range make([]byte, c.Size.X) {
+			id := w.Get(uint64(t.X)+uint64(x), uint64(t.Y)+uint64(y))
+			if id != 0 {
+				out += door.GotoS(int(offset.X)+x, int(offset.Y)+y) + door.ColorTextS(w.TileIndex.Tiles[id].Color) + w.TileIndex.Tiles[id].Symbol + door.Reset
+			}
+		}
+	}
+	return out
+}

+ 55 - 0
editor.go

@@ -0,0 +1,55 @@
+package main
+
+import (
+	"fmt"
+
+	door "git.red-green.com/RedGreen/doorgo"
+)
+
+type Editor struct {
+	World  *World
+	Camera *Camera
+	Pos    *Vec2
+}
+
+func NewEditor(w *World, cam_size, pos *Vec2) *Editor {
+	e := &Editor{
+		World: w,
+		Camera: &Camera{
+			Size: cam_size.Clone(),
+		},
+		Pos: pos.Clone(),
+	}
+	if w == nil || cam_size == nil || pos == nil {
+		return nil
+	}
+	return e
+}
+
+func (e *Editor) TileMenu() *door.Menu {
+	m := &door.Menu{
+		Chosen:      0,
+		SelectedR:   door.MakeMenuRender(door.ColorText("BRI WHI ON BLU"), door.ColorText("BRI WHI ON BLU"), door.ColorText("BRI WHI ON BLU"), door.ColorText("BRI WHI ON BLU")),
+		UnselectedR: door.MakeMenuRender(door.ColorText("BRI BLA ON BLA"), door.ColorText("BRI CYA ON BLA"), door.ColorText("BRI WHI ON BLA"), door.ColorText("WHI ON BLA")),
+		Panel: door.Panel{
+			X:           1,
+			Y:           1,
+			Width:       door.Width - 2,
+			Style:       door.SINGLE,
+			BorderColor: door.ColorText("BRI CYA ON BLA"),
+			Title:       " Tiles ",
+			TitleColor:  door.ColorText("BRI WHI ON BLA"),
+			TitleOffset: 4,
+		},
+	}
+	if len(e.World.TileIndex.Tiles) != 0 {
+		for idx, t := range e.World.TileIndex.Tiles {
+			if t == nil {
+				continue
+			}
+			m.AddSelection(fmt.Sprintf("%d", idx), fmt.Sprintf("'%s' in '%s'", t.Symbol, t.Color))
+		}
+	}
+	m.AddSelection("A", "Add Tile")
+	return m
+}

+ 3 - 0
go.mod

@@ -11,8 +11,11 @@ require (
 )
 )
 
 
 require (
 require (
+	git.red-green.com/RedGreen/doorgo v0.0.0-20230521205550-1aab0f75bdd6 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
 	github.com/mattn/go-sqlite3 v1.14.22 // indirect
 	github.com/mattn/go-sqlite3 v1.14.22 // indirect
+	golang.org/x/sys v0.22.0 // indirect
+	golang.org/x/term v0.22.0 // indirect
 	golang.org/x/text v0.16.0 // indirect
 	golang.org/x/text v0.16.0 // indirect
 )
 )

+ 4 - 0
go.sum

@@ -6,6 +6,10 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o
 github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
 golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
 golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
 golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
+golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
+golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
 golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
 golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
 golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
 golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
 gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
 gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=

+ 69 - 62
main.go

@@ -1,85 +1,92 @@
 package main
 package main
 
 
 import (
 import (
+	"bytes"
 	"fmt"
 	"fmt"
 	"path"
 	"path"
+	"strings"
+
+	door "git.red-green.com/RedGreen/doorgo"
+)
+
+var (
+	d door.Door
 )
 )
 
 
 func main() {
 func main() {
-	// The UserDB would be run on the server
-	// But since most/100% of this is examples, we'll setup one up
-	db := &UserDB{}
-	err := db.Open(path.Join("test_data", "test_users.db3"))
+	d.Init("CyberRealms")
+	defer d.Close()
+	d.WriteS(door.Clrscr)
+	w, err := LoadWorld(path.Join("data", "world"))
 	if err != nil {
 	if err != nil {
 		fmt.Println("Err:", err)
 		fmt.Println("Err:", err)
-		return
-	}
-	defer db.Close()
-
-	// Example query
-	dummy, err := db.FindUser("Test Dummy")
-	if err != nil {
-		// Of course, we'd ask the user for their name and a password then use those
-		// But for our Test Dummy let's just make a dumb and simple setup
-		err = db.CreateUser("Test Dummy", "12345")
+		w = NewWorld("Overworld", NewVec2(100))
+		err := w.Save(path.Join("data", "world"))
 		if err != nil {
 		if err != nil {
-			fmt.Println("Err:", err)
-			return
-		}
-		dummy, err = db.FindUser("Test Dummy")
-		if err != nil {
-			fmt.Println("Err:", err)
+			d.WriteS(door.ColorTextS("BRI RED ON BLA") + "Err: " + err.Error() + door.Reset + door.CRNL)
+			d.WaitKey(door.Inactivity)
 			return
 			return
 		}
 		}
 	}
 	}
-	//fmt.Printf("%#v\r\n", dummy)
-	// Example verification process
-	// I'd also want to verify they aren't trying to login in 2+ places at once
-	err = dummy.VerifyPassword("12345")
-	if err != nil {
-		fmt.Println("Wrong password?")
-	} else {
-		fmt.Printf("Yay, %s has logged in\r\n", dummy.Name)
-	}
-	fmt.Printf("%s is at %s\r\n", dummy.Name, dummy.Loc.String())
-
-	ti, err := ParseTileIndex(path.Join("test_data", "world1", "tiles.txt"))
-	if err != nil {
-		fmt.Println("Err:", err)
+	editor := NewEditor(w, NewVec2(int64(door.Width-2), int64(door.Height-2)), NewVec2())
+	if editor == nil {
+		d.WriteS(door.ColorTextS("BRI RED ON BLA") + "Err: Failed initializing editor" + door.Reset + door.CRNL)
+		d.WaitKey(door.Inactivity)
 		return
 		return
 	}
 	}
-	fmt.Printf("Loaded %d tiles from 'world1'\r\n", len(ti.Tiles)-1)
-	for i, t := range ti.Tiles {
-		if i == 0 {
-			continue
-		}
-		fmt.Printf("Id=%d Symbol='%s' Color='%s'\r\n", i, t.Symbol, t.Color)
+	p := door.Panel{
+		X:           1,
+		Y:           1,
+		Width:       door.Width - 2,
+		Style:       door.SINGLE,
+		BorderColor: door.ColorText("WHI ON BLA"),
 	}
 	}
-	w, err := LoadWorld(path.Join("test_data", "world1"))
-	if err != nil {
-		fmt.Println("Err:", err)
-		return
+	for range make([]byte, door.Height-2) {
+		p.Lines = append(p.Lines, &door.Line{
+			Text: bytes.NewBufferString(strings.Repeat(" ", door.Width-2)),
+		})
 	}
 	}
-	fmt.Println("Loaded", w.Name, "a", w.Width, "x", w.Height)
-	/*err = w.Save(path.Join("test_data", "world2"))
-	if err != nil {
-		fmt.Println("Err:", err)
-		return
-	}*/
-	c := &Camera{Size: NewVec2(20)}
-	fmt.Println(c.debugView(NewVec2(10), w))
-	w2, err := LoadWorld(path.Join("test_data", "world3"))
-	if err != nil {
-		w2 = NewWorld("Test World 3", NewVec2(20))
-		w2.AddTile(".", "BRI GRE ON BLA")
-		w2.AddTile("^", "BRI WHI ON BLA")
-		w2.AddTile("^", "WHI ON BLA")
-		w2.Set(1, 1, 1)
-		err = w2.Save(path.Join("test_data", "world3"))
+	tile_menu := editor.TileMenu()
+EDITOR_LOOP:
+	for {
+		d.Write(p.Output())
+		d.WriteS(editor.Camera.View(editor.Pos, NewVec2(1, 2), editor.World) + door.GotoS(door.Width/2, door.Height/2))
+		r, ext, err := d.WaitKey(door.Inactivity)
 		if err != nil {
 		if err != nil {
-			fmt.Println("Err:", err)
+			d.WriteS(door.ColorTextS("BRI RED ON BLA") + "Err: " + err.Error() + door.Reset + door.CRNL)
+			d.WaitKey(door.Inactivity)
 			return
 			return
 		}
 		}
+		if ext != door.NOP {
+			switch ext {
+			case door.UP_ARROW:
+				editor.Pos.Translate(0, -1)
+			case door.DOWN_ARROW:
+				editor.Pos.Translate(0, 1)
+			case door.LEFT_ARROW:
+				editor.Pos.Translate(-1, 0)
+			case door.RIGHT_ARROW:
+				editor.Pos.Translate(1, 0)
+			}
+		}
+		if r != 0 {
+			switch r {
+			case 't':
+				fmt.Println("Show the tile menu, and jump to handling options for it")
+				d.Write(tile_menu.Output())
+				d.WaitKey(door.Inactivity)
+			case '5', '\r', '\n':
+				fmt.Println("Allow selecting a tile index number to place a tile at current position")
+				editor.World.Set(uint64(editor.Pos.X), uint64(editor.Pos.Y-1), 1)
+			case 'q':
+				break EDITOR_LOOP
+			}
+		}
+	}
+	err = editor.World.Save(path.Join("data", "world"))
+	if err != nil {
+		d.WriteS(door.ColorTextS("BRI RED ON BLA") + "Err: " + err.Error() + door.Reset + door.CRNL)
+		d.WaitKey(door.Inactivity)
+		return
 	}
 	}
-	fmt.Println(c.debugView(NewVec2(10), w2))
 }
 }

+ 1 - 1
world.go

@@ -63,7 +63,7 @@ func LoadWorld(worlddir string) (*World, error) {
 	for _, b := range payload {
 	for _, b := range payload {
 		if b == '\n' {
 		if b == '\n' {
 			linenum += 1
 			linenum += 1
-			parts := strings.Split(line, " ")
+			parts := strings.Split(strings.TrimSpace(line), " ")
 			if len(parts) != int(w.Width) {
 			if len(parts) != int(w.Width) {
 				return nil, fmt.Errorf("%d]: Failed parsing Map Data, not enough parts (expected=%d, got=%d), '%s'", linenum, w.Width, len(parts), line)
 				return nil, fmt.Errorf("%d]: Failed parsing Map Data, not enough parts (expected=%d, got=%d), '%s'", linenum, w.Width, len(parts), line)
 			}
 			}