fix wu line iface, pending opacity

This commit is contained in:
2026-01-21 11:39:44 +03:00
parent 2be7717477
commit 378729616f
10 changed files with 108 additions and 51 deletions

View File

@@ -5,6 +5,7 @@ import (
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"lab.zaar.be/thefish/alchemyst-go/engine/ecs" "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
"lab.zaar.be/thefish/alchemyst-go/engine/gamelog"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap" "lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap/mapgens" "lab.zaar.be/thefish/alchemyst-go/engine/gamemap/mapgens"
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate" "lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
@@ -74,9 +75,9 @@ func main() {
//fixme set up (load / generate) level - move to game / enter or title / exit //fixme set up (load / generate) level - move to game / enter or title / exit
level, rooms := mapgens.DefaultGen(gamemap.NewLevel("test", 1)) level, rooms := mapgens.DefaultGen(gamemap.NewLevel("test", 1))
//level, rooms := mapgens.DelaunayMstGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1)) //level, rooms := mapgens.DelaunayMstGen(mainCtx, gamemap.NewLevel("test", 1))
//level, rooms := mapgens.DelaunayMstExtGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1)) //level, rooms := mapgens.DelaunayMstExtGen(gamemap.NewLevel("test", 1))
//level, rooms := mapgens.DelaunayPureGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1)) //level, rooms := mapgens.DelaunayPureGen(gamemap.NewLevel("test", 1))
State.Level = level State.Level = level
sidebarWidth := 0 sidebarWidth := 0
@@ -117,7 +118,7 @@ func main() {
//"[color=yellow]Note[/color]: Many of these are not implemented yet", //"[color=yellow]Note[/color]: Many of these are not implemented yet",
"[color=yellow]Note[/color]: Many of these are not implemented yet", "[color=yellow]Note[/color]: Many of these are not implemented yet",
types.NewCenteredRect(mw.Rect, 50, 15), types.NewCenteredRect(mw.Rect, 50, 15),
true, ). true).
SetBgColor("#ef1d494f"). SetBgColor("#ef1d494f").
SetFgColor("white"). SetFgColor("white").
SetItems([]interface{}{ SetItems([]interface{}{
@@ -143,7 +144,7 @@ func main() {
//"[color=yellow]Note[/color]: Many of these are not implemented yet", //"[color=yellow]Note[/color]: Many of these are not implemented yet",
"", "",
types.NewCenteredRect(mw.Rect, 70, 25), types.NewCenteredRect(mw.Rect, 70, 25),
true, ). true).
SetBgColor("#ef305c70"). SetBgColor("#ef305c70").
SetFgColor("white"), SetFgColor("white"),
} }
@@ -209,6 +210,13 @@ func main() {
screenMgr.AddScreen("inventory", inv.MakeInverntory(player)) screenMgr.AddScreen("inventory", inv.MakeInverntory(player))
gamelog.Log.SetMaxHeight(5)
gamelog.Log.Msg("2025-08-03T03:37:44+03:00 DBG Generating level of branch test depth 1")
gamelog.Log.Msg("2025-08-03T03:37:44+03:00 DBG adding")
gamelog.Log.Msg("2025-08-03T03:37:44+03:00 DBG adding")
gamelog.Log.Msg("2025-08-03T03:37:44+03:00 DBG adding")
gamelog.Log.Msg("TrOlolo")
gamelog.Log.Msg("[color=red]Game[/color] starting...")
//but every call to bearlibterminal must be wrapped to closure and passed to mainfunc //but every call to bearlibterminal must be wrapped to closure and passed to mainfunc
var exit = false var exit = false
@@ -224,7 +232,7 @@ func main() {
// f() // f()
// break // break
case <-State.Exit: case <-State.Exit:
appctx.Logger().Warn().Msg("quitting NOW") log.Warn().Msg("quitting NOW")
exit = true exit = true
break break
// не оставляйте default в бесконечном select {} - сожрет всё CPU // не оставляйте default в бесконечном select {} - сожрет всё CPU
@@ -235,7 +243,7 @@ func main() {
} }
} }
appctx.Logger().Info().Msg("pre-shutdown sequence") log.Info().Msg("pre-shutdown sequence")
} }
func setupLayers(mainwindow *mainwindow.MainWindow) { func setupLayers(mainwindow *mainwindow.MainWindow) {
@@ -288,7 +296,7 @@ func decodeInput(ctx context.Context, baseLayer *mainwindow.Layer) {
return return
default: default:
if pressed != "" { if pressed != "" {
waitForWCspam = false; waitForWCspam = false
State.Input <- pressed State.Input <- pressed
} }
} }

View File

@@ -1,5 +1,5 @@
{ {
"version": "v0.0.1.7-29-g4f18b6d", "version": "v0.0.1.7-35-g2be7717",
"title": "Alchemyst", "title": "Alchemyst",
"sizeX": 100, "sizeX": 100,
"sizeY": 47, "sizeY": 47,

View File

@@ -3,6 +3,7 @@ package ecs
// ECS system by jcerise, github.com/jcerise/gogue // ECS system by jcerise, github.com/jcerise/gogue
const TerrainRenderSystem = "levelrender" const TerrainRenderSystem = "levelrender"
const UiRenderSystem = "uirender"
type System interface { type System interface {
Process() Process()

View File

@@ -0,0 +1,36 @@
package gamelog
import (
"time"
)
var Log = &GameLog{RedrawLogs: true}
type GameLog struct {
Messages []Message
MaxHeight int
RedrawLogs bool
}
type Message struct {
GameTS uint64
RealTS time.Time
Message string
}
func (gl *GameLog) GetMaxHeight() int {
return gl.MaxHeight
}
func (gl *GameLog) SetMaxHeight(i int) {
gl.MaxHeight = i
}
func (gl *GameLog) Msg(msg string) {
gl.Messages = append(gl.Messages, Message{
GameTS: 0, //fixme
RealTS: time.Now(),
Message: msg,
})
gl.RedrawLogs = true
}

View File

@@ -1,14 +1,13 @@
package mapgens package mapgens
import ( import (
"context"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap" "lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/types" "lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/util" "lab.zaar.be/thefish/alchemyst-go/util"
"lab.zaar.be/thefish/alchemyst-go/util/delaunay" "lab.zaar.be/thefish/alchemyst-go/util/delaunay"
) )
func DelaunayPureGen(ctx context.Context, l *gamemap.Level) (*gamemap.Level, []gamemap.Room) { func DelaunayPureGen(l *gamemap.Level) (*gamemap.Level, []gamemap.Room) {
rng := util.NewRNG() rng := util.NewRNG()
@@ -33,6 +32,3 @@ func DelaunayPureGen(ctx context.Context, l *gamemap.Level) (*gamemap.Level, []g
return l, rooms return l, rooms
} }

View File

@@ -3,6 +3,7 @@ package items
import ( import (
"fmt" "fmt"
"lab.zaar.be/thefish/alchemyst-go/engine/ecs" "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
"lab.zaar.be/thefish/alchemyst-go/engine/gamelog"
"lab.zaar.be/thefish/alchemyst-go/engine/types" "lab.zaar.be/thefish/alchemyst-go/engine/types"
) )
@@ -52,6 +53,7 @@ func (c Carried) Pickup(who, what ecs.Entity) error {
//remove coords instead (does not exist on map anymore) //remove coords instead (does not exist on map anymore)
Controller.RemoveComponent(what, ecs.CoordsComponent) Controller.RemoveComponent(what, ecs.CoordsComponent)
bp.items = append(bp.items, what) bp.items = append(bp.items, what)
gamelog.Log.Msg(fmt.Sprintf("Picked up %s.", Controller.GetComponent(what, ecs.NamedComponent).(Named).GetName()))
//fuck that, we need to update constantly //fuck that, we need to update constantly
Controller.UpdateComponent(who, ecs.BackpackComponent, bp) Controller.UpdateComponent(who, ecs.BackpackComponent, bp)
return nil return nil

View File

@@ -1,6 +1,7 @@
package movement package movement
import ( import (
"lab.zaar.be/thefish/alchemyst-go/effects"
"lab.zaar.be/thefish/alchemyst-go/engine/ecs" "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap" "lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate" "lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
@@ -59,7 +60,7 @@ func Walk(entity ecs.Entity, state *gamestate.GameState, dx, dy int) {
return return
} }
if !movable.(Moveable).IsBlocked(newCoords) || if !movable.(Moveable).IsBlocked(newCoords) ||
controller.GetComponent(entity, "pass_wall") != nil { controller.GetComponent(entity, effects.BuffPassWall) != nil {
controller.UpdateComponent(state.Player, ecs.CoordsComponent, newCoords) controller.UpdateComponent(state.Player, ecs.CoordsComponent, newCoords)
} }

View File

@@ -5,6 +5,7 @@ import (
"lab.zaar.be/thefish/alchemyst-go/engine/ecs/systems" "lab.zaar.be/thefish/alchemyst-go/engine/ecs/systems"
"lab.zaar.be/thefish/alchemyst-go/engine/fov" "lab.zaar.be/thefish/alchemyst-go/engine/fov"
"lab.zaar.be/thefish/alchemyst-go/engine/fov/precomputed_shade" "lab.zaar.be/thefish/alchemyst-go/engine/fov/precomputed_shade"
"lab.zaar.be/thefish/alchemyst-go/engine/gamelog"
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate" "lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
"lab.zaar.be/thefish/alchemyst-go/engine/items" "lab.zaar.be/thefish/alchemyst-go/engine/items"
"lab.zaar.be/thefish/alchemyst-go/engine/mob/movement" "lab.zaar.be/thefish/alchemyst-go/engine/mob/movement"
@@ -38,6 +39,7 @@ func NewGameScreen(mw *mainwindow.MainWindow, state *gamestate.GameState, viewPo
renderLevel := systems.NewLevelRenderSystem(state, ts.controller, viewPort, ts.mw.GetLayer("base"), ts.fov) renderLevel := systems.NewLevelRenderSystem(state, ts.controller, viewPort, ts.mw.GetLayer("base"), ts.fov)
go renderLevel.Listen() go renderLevel.Listen()
ts.controller.AddSystem(renderLevel, 50) ts.controller.AddSystem(renderLevel, 50)
return ts return ts
} }
@@ -105,16 +107,16 @@ func (ts *GameScreen) HandleInput(input string) {
err := items.Carried.Pickup(cc, ts.state.Player, carrieds[0]) err := items.Carried.Pickup(cc, ts.state.Player, carrieds[0])
if err != nil { if err != nil {
// Message with error // Message with error
//gameLog.Log.Error(err) //gameLog.Msg.Error(err)
//@fixme! //@fixme!
appctx.Logger().Warn().Err(err) appctx.Logger().Warn().Err(err)
break; break
} }
} }
//log picked up //log picked up
//gameLog.Log.Message(err) //gameLog.Msg.Message(err)
break; break
case "i": case "i":
ts.scm.SetScreenByName("inventory") ts.scm.SetScreenByName("inventory")
@@ -123,11 +125,21 @@ func (ts *GameScreen) HandleInput(input string) {
ts.mw.GetLayer("base").ClearArea(0, 3, 40, 1) ts.mw.GetLayer("base").ClearArea(0, 3, 40, 1)
ts.mw.GetLayer("base").Print(1, 3, "Key: "+input) ts.mw.GetLayer("base").Print(1, 3, "Key: "+input)
ts.mw.GetLayer("base").Print(1, 6, "█") ts.mw.GetLayer("base").Print(1, 6, "█")
}
if gamelog.Log.RedrawLogs {
logRect := types.NewRect(1, ts.mw.H-gamelog.Log.MaxHeight-1, ts.mw.W-1, gamelog.Log.MaxHeight)
ts.mw.GetLayer("overlay").ClearRect(logRect)
count := 0
for i := len(gamelog.Log.Messages) - 1; i >= len(gamelog.Log.Messages)-gamelog.Log.MaxHeight; i-- {
//fmt.Println(gamelog.Log.Messages[i].Message)
ts.mw.GetLayer("overlay").PutStringInto(logRect, count-2, gamelog.Log.Messages[i].Message, 0)
count++
}
gamelog.Log.RedrawLogs = false
} }
//})
} }
func (ts *GameScreen) Render() { func (ts *GameScreen) Render() {
//ts.vp.Render(ts.state) ts.controller.Process(nil)
ts.controller.Process([]string{})
} }

2
go.mod
View File

@@ -7,5 +7,5 @@ require (
github.com/rs/zerolog v1.15.0 github.com/rs/zerolog v1.15.0
github.com/shopspring/decimal v1.3.1 github.com/shopspring/decimal v1.3.1
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0
lab.zaar.be/thefish/bearlibterminal.git v0.0.0-20191018101635-dd37bbc90d77 lab.zaar.be/thefish/bearlibterminal v0.0.0-20250802054216-21f184e55ce3
) )

View File

@@ -1,8 +1,9 @@
package wu package wu
import ( import (
"lab.zaar.be/thefish/alchemyst-go/engine/types"
"math" "math"
"lab.zaar.be/thefish/alchemyst-go/engine/types"
) )
func ipart(x float64) float64 { func ipart(x float64) float64 {
@@ -21,7 +22,7 @@ func rfpart(x float64) float64 {
return 1 - fpart(x) return 1 - fpart(x)
} }
func (Layer types.Putable) WuLine(x1, y1, x2, y2 float64, w int) { func WuLine(l types.Putable, x1, y1, x2, y2 float64, w int) {
dx := x2 - x1 dx := x2 - x1
dy := y2 - y1 dy := y2 - y1
ax := dx ax := dx
@@ -40,11 +41,11 @@ func (Layer types.Putable) WuLine(x1, y1, x2, y2 float64, w int) {
x2, y2 = y2, x2 x2, y2 = y2, x2
dx, dy = dy, dx dx, dy = dy, dx
plot = func(x, y int, c float64) { plot = func(x, y int, c float64) {
Layer.Put(y, x, uint8(255 * c)) l.Put(y, x, uint8(255*c))
} }
} else { } else {
plot = func(x, y int, c float64) { plot = func(x, y int, c float64) {
Layer.Put(x, y, uint8(255 * c)) l.Put(x, y, uint8(255*c))
} }
} }
if x2 < x1 { if x2 < x1 {