body & combat primitives wip

This commit is contained in:
thefish 2022-10-12 15:50:38 +03:00
parent bf13c9c7a2
commit 20ba03c758
9 changed files with 569 additions and 336 deletions

View File

@ -1,26 +1,26 @@
package main package main
import ( import (
"context" "context"
"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/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"
"lab.zaar.be/thefish/alchemyst-go/engine/items" "lab.zaar.be/thefish/alchemyst-go/engine/items"
"lab.zaar.be/thefish/alchemyst-go/engine/mob" "lab.zaar.be/thefish/alchemyst-go/engine/mob"
"lab.zaar.be/thefish/alchemyst-go/engine/mob/movement" "lab.zaar.be/thefish/alchemyst-go/engine/mob/movement"
"lab.zaar.be/thefish/alchemyst-go/engine/screens" "lab.zaar.be/thefish/alchemyst-go/engine/screens"
"lab.zaar.be/thefish/alchemyst-go/engine/types" "lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/ui" "lab.zaar.be/thefish/alchemyst-go/ui"
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow" "lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
"lab.zaar.be/thefish/alchemyst-go/util" "lab.zaar.be/thefish/alchemyst-go/util"
"lab.zaar.be/thefish/alchemyst-go/util/appctx" "lab.zaar.be/thefish/alchemyst-go/util/appctx"
blt "lab.zaar.be/thefish/bearlibterminal" blt "lab.zaar.be/thefish/bearlibterminal"
"os" "os"
"runtime" "runtime"
"time" "time"
) )
var modifiers = []int{blt.TK_SHIFT, blt.TK_ALT, blt.TK_CONTROL} var modifiers = []int{blt.TK_SHIFT, blt.TK_ALT, blt.TK_CONTROL}
@ -28,7 +28,7 @@ var modifiers = []int{blt.TK_SHIFT, blt.TK_ALT, blt.TK_CONTROL}
// Рецепт чтобы убежать от [fatal] 'refresh' was not called from the main thread // Рецепт чтобы убежать от [fatal] 'refresh' was not called from the main thread
// https://github.com/golang/go/wiki/LockOSThread // https://github.com/golang/go/wiki/LockOSThread
func init() { func init() {
runtime.LockOSThread() runtime.LockOSThread()
} }
//we can run logic in separate goroutines //we can run logic in separate goroutines
@ -45,252 +45,252 @@ func init() {
// } // }
var State = gamestate.GameState{ var State = gamestate.GameState{
Mainfunc: make(chan func()), Mainfunc: make(chan func()),
Exit: make(chan struct{}, 1), Exit: make(chan struct{}, 1),
Input: make(chan string, 1), Input: make(chan string, 1),
RawInput: make(chan int, 1), RawInput: make(chan int, 1),
FovRecompute: make(chan struct{}, 1), FovRecompute: make(chan struct{}, 1),
Redraw: make(chan struct{}, 1), Redraw: make(chan struct{}, 1),
} }
func main() { func main() {
config := util.LoadConfig() config := util.LoadConfig()
var logLevels = map[string]zerolog.Level{"debug": zerolog.DebugLevel, "info": zerolog.InfoLevel, "warn": zerolog.WarnLevel} var logLevels = map[string]zerolog.Level{"debug": zerolog.DebugLevel, "info": zerolog.InfoLevel, "warn": zerolog.WarnLevel}
var logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}).Level(logLevels[config.Verbosity]) var logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}).Level(logLevels[config.Verbosity])
// set up context // set up context
mainCtx := appctx.NewClientContext(config, &logger) mainCtx := appctx.NewClientContext(config, &logger)
//set up main window //set up main window
mw := mainwindow.Init(mainCtx) mw := mainwindow.Init(mainCtx)
defer mw.Close() defer mw.Close()
setupLayers(mw) setupLayers(mw)
//set up input decoder //set up input decoder
go decodeInput(mainCtx, mw.GetLayer("base")) go decodeInput(mainCtx, mw.GetLayer("base"))
//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 := _default.DefaultGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1)) //level, rooms := _default.DefaultGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
//level, rooms := mapgens.DelaunayMstGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1)) //level, rooms := mapgens.DelaunayMstGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
level, rooms := mapgens.DelaunayMstExtGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1)) level, rooms := mapgens.DelaunayMstExtGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
//level, rooms := mapgens.DelaunayPureGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1)) //level, rooms := mapgens.DelaunayPureGen(mainCtx, gamemap.NewLevel(mainCtx, "test", 1))
State.Level = level State.Level = level
sidebarWidth := 0 sidebarWidth := 0
//Set up viewport //Set up viewport
vp := mainwindow.NewViewPort(sidebarWidth, 0, (mw.W - sidebarWidth), (mw.H - 0)) vp := mainwindow.NewViewPort(sidebarWidth, 0, (mw.W - sidebarWidth), (mw.H - 0))
//set up controller //set up controller
controller := ecs.NewController(mainCtx) controller := ecs.NewController(mainCtx)
controller.MapComponentClass(ecs.CoordsComponent, types.Coords{}) controller.MapComponentClass(ecs.CoordsComponent, types.Coords{})
controller.MapComponentClass(ecs.AppearanceComponent, types.Appearance{}) controller.MapComponentClass(ecs.AppearanceComponent, types.Appearance{})
controller.MapComponentClass(ecs.MobComponent, mob.Mob{}) controller.MapComponentClass(ecs.MobComponent, mob.Mob{})
controller.MapComponentClass(ecs.MoveableComponent, movement.Moveable{}) controller.MapComponentClass(ecs.MoveableComponent, movement.Moveable{})
controller.MapComponentClass(ecs.CarriedComponent, movement.Moveable{}) controller.MapComponentClass(ecs.CarriedComponent, movement.Moveable{})
controller.MapComponentClass(ecs.UsableComponent, movement.Moveable{}) controller.MapComponentClass(ecs.UsableComponent, movement.Moveable{})
controller.MapComponentClass(ecs.BackpackComponent, items.Backpack{}) controller.MapComponentClass(ecs.BackpackComponent, items.Backpack{})
moveable := movement.Moveable{ moveable := movement.Moveable{
Controller: controller, Controller: controller,
Level: level, Level: level,
} }
items.Init(controller) items.Init(controller)
bp := items.Backpack{MaxMass:100, MaxBulk:100} bp := items.Backpack{MaxMass: 100, MaxBulk: 100}
//Set up Screen Manager //Set up Screen Manager
screenMgr := types.NewScreenManager(mainCtx) screenMgr := types.NewScreenManager(mainCtx)
screenMgr.AddScreen("title", screens.NewTitleScreen(mw, screenMgr)) screenMgr.AddScreen("title", screens.NewTitleScreen(mw, screenMgr))
screenMgr.AddScreen("game", screens.NewGameScreen(mainCtx, mw, &State, vp, controller, screenMgr)) screenMgr.AddScreen("game", screens.NewGameScreen(mainCtx, mw, &State, vp, controller, screenMgr))
screenMgr.AddScreen("help", screens.NewMenuScreen( screenMgr.AddScreen("help", screens.NewMenuScreen(
mw, mw,
screenMgr, screenMgr,
"Help", "Help",
"Keybindings:", "Keybindings:",
//"[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{}{
"hjklyubn, NumPad 12346789, arrow keys - move", "hjklyubn, NumPad 12346789, arrow keys - move",
"s or . - pass turn", "s or . - pass turn",
"g or , - pick up item", "g or , - pick up item",
"i - inventory", "i - inventory",
"? - this screen", "? - this screen",
"Ctrl+q - exit", "Ctrl+q - exit",
"f or F - fire or throw weapon", "f or F - fire or throw weapon",
"z or Z - cast a spell", "z or Z - cast a spell",
"p - pray", "p - pray",
"Ctrl+p - message log", "Ctrl+p - message log",
}).MakeList(), }).MakeList(),
) )
inv := screens.InventoryScreen{ inv := screens.InventoryScreen{
MenuScreen: screens.NewMenuScreen( MenuScreen: screens.NewMenuScreen(
mw, mw,
screenMgr, screenMgr,
"Inventory", "Inventory",
"Items in your backpack:", "Items in your backpack:",
//"[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"),
} }
screenMgr.AddScreen("devmenu", screens.NewDevmenuScreen( screenMgr.AddScreen("devmenu", screens.NewDevmenuScreen(
mw, mainCtx,
controller, mw,
screenMgr, controller,
&State, screenMgr,
types.NewCenteredRect(mw.Rect, 70, 25), &State,
true, types.NewCenteredRect(mw.Rect, 70, 25),
).SetBgColor("#ef6d559d"). true,
SetFgColor("white"), ).SetBgColor("#ef6d559d").
) SetFgColor("white"),
)
screenMgr.SetScreenByName("title") screenMgr.SetScreenByName("title")
//fixme set up (load / generate) player - move to game / enter or title / exit //fixme set up (load / generate) player - move to game / enter or title / exit
player := controller.CreateEntity([]ecs.Component{}) player := controller.CreateEntity([]ecs.Component{})
controller.AddComponent(player, types.Appearance{ controller.AddComponent(player, types.Appearance{
Glyph: types.PlainGlyphHolder{"@"}, Glyph: types.PlainGlyphHolder{"@"},
ColorSet: types.TileColorSet{ ColorSet: types.TileColorSet{
Fg: types.PlainColorHolder{255, 255, 255, 255}, Fg: types.PlainColorHolder{255, 255, 255, 255},
}, },
}) })
controller.AddComponent(player, rooms[0].Center) //implicit Coords controller.AddComponent(player, rooms[0].Center) //implicit Coords
controller.AddComponent(player, moveable) controller.AddComponent(player, moveable)
controller.AddComponent(player, bp) controller.AddComponent(player, bp)
//fixme adding items //fixme adding items
potion := controller.CreateEntity([]ecs.Component{}) potion := controller.CreateEntity([]ecs.Component{})
controller.AddComponent(potion, types.Appearance{ controller.AddComponent(potion, types.Appearance{
Glyph: types.PlainGlyphHolder{"!"}, Glyph: types.PlainGlyphHolder{"!"},
ColorSet: types.TileColorSet{ ColorSet: types.TileColorSet{
Fg: types.PlainColorHolder{255, 55, 255, 222}, Fg: types.PlainColorHolder{255, 55, 255, 222},
}, },
}) })
controller.AddComponent(potion, rooms[0].Center) //implicit Coords controller.AddComponent(potion, rooms[0].Center) //implicit Coords
controller.AddComponent(potion, items.Carried{Mass:5, Bulk:3}) controller.AddComponent(potion, items.Carried{Mass: 5, Bulk: 3})
controller.AddComponent(potion, items.Usable{}) controller.AddComponent(potion, items.Usable{})
controller.AddComponent(potion, items.Consumable{}) controller.AddComponent(potion, items.Consumable{})
controller.AddComponent(potion, ecs.Named{Name:"first potion"}) controller.AddComponent(potion, ecs.Named{Name: "first potion"})
potion2 := controller.CreateEntity([]ecs.Component{}) potion2 := controller.CreateEntity([]ecs.Component{})
controller.AddComponent(potion2, types.Appearance{ controller.AddComponent(potion2, types.Appearance{
Glyph: types.PlainGlyphHolder{"!"}, Glyph: types.PlainGlyphHolder{"!"},
ColorSet: types.TileColorSet{ ColorSet: types.TileColorSet{
Fg: types.PlainColorHolder{255, 222, 255, 55}, Fg: types.PlainColorHolder{255, 222, 255, 55},
}, },
}) })
controller.AddComponent(potion2, rooms[1].Center) //implicit Coords controller.AddComponent(potion2, rooms[1].Center) //implicit Coords
controller.AddComponent(potion2, items.Carried{Mass:5, Bulk:3}) controller.AddComponent(potion2, items.Carried{Mass: 5, Bulk: 3})
controller.AddComponent(potion2, items.Usable{}) controller.AddComponent(potion2, items.Usable{})
controller.AddComponent(potion2, items.Consumable{}) controller.AddComponent(potion2, items.Consumable{})
controller.AddComponent(potion2, ecs.Named{Name:"second potion"}) controller.AddComponent(potion2, ecs.Named{Name: "second potion"})
//fixme end setting up items //fixme end setting up items
State.Player = player State.Player = player
State.Controller = controller State.Controller = controller
screenMgr.AddScreen("inventory", inv.MakeInverntory(player)) screenMgr.AddScreen("inventory", inv.MakeInverntory(player))
//but every call to bearlibterminal must be wrapped to closure and passed to mainfunc
var exit = false
for !exit {
//but every call to bearlibterminal must be wrapped to closure and passed to mainfunc select {
var exit = false case State.RawInput <- ui.ReadKeyCode():
for !exit { break
case pressed := <-State.Input:
screenMgr.CurrentScreen.HandleInput(pressed)
break
//case f := <-State.mainfunc:
// f()
// break
case <-State.Exit:
appctx.Logger(mainCtx).Warn().Msg("quitting NOW")
exit = true
break
// не оставляйте default в бесконечном select {} - сожрет всё CPU
default:
screenMgr.CurrentScreen.Render()
blt.Layer(0) //return to base layer
blt.Refresh()
}
select { }
case State.RawInput <- ui.ReadKeyCode(): appctx.Logger(mainCtx).Info().Msg("pre-shutdown sequence")
break
case pressed := <-State.Input:
screenMgr.CurrentScreen.HandleInput(pressed)
break
//case f := <-State.mainfunc:
// f()
// break
case <-State.Exit:
appctx.Logger(mainCtx).Warn().Msg("quitting NOW")
exit = true
break
// не оставляйте default в бесконечном select {} - сожрет всё CPU
default:
screenMgr.CurrentScreen.Render()
blt.Layer(0) //return to base layer
blt.Refresh()
}
}
appctx.Logger(mainCtx).Info().Msg("pre-shutdown sequence")
} }
func setupLayers(mainwindow *mainwindow.MainWindow) { func setupLayers(mainwindow *mainwindow.MainWindow) {
mainwindow.AddLayer("base", 0, "white") mainwindow.AddLayer("base", 0, "white")
mainwindow.AddLayer("overlay", 1, "white") mainwindow.AddLayer("overlay", 1, "white")
mainwindow.AddLayer("menubg", 2, "white") mainwindow.AddLayer("menubg", 2, "white")
mainwindow.AddLayer("menu", 3, "white") mainwindow.AddLayer("menu", 3, "white")
} }
func decodeInput(ctx context.Context, baseLayer *mainwindow.Layer) { func decodeInput(ctx context.Context, baseLayer *mainwindow.Layer) {
var exit = false var exit = false
var waitForWCspam = true var waitForWCspam = true
for !exit { for !exit {
select { select {
case keycode := <-State.RawInput: case keycode := <-State.RawInput:
if keycode == blt.TK_NONE { if keycode == blt.TK_NONE {
continue continue
} }
if keycode == blt.TK_CLOSE && !waitForWCspam { if keycode == blt.TK_CLOSE && !waitForWCspam {
appctx.Logger(ctx).Warn().Msg("exiting on window close...") appctx.Logger(ctx).Warn().Msg("exiting on window close...")
State.Exit <- struct{}{} State.Exit <- struct{}{}
appctx.Logger(ctx).Warn().Msg("...done") appctx.Logger(ctx).Warn().Msg("...done")
return return
} }
var pressed = "" var pressed = ""
var isModifier, _ = util.IntInSlice(keycode, modifiers) var isModifier, _ = util.IntInSlice(keycode, modifiers)
if !isModifier { if !isModifier {
pressed = ui.Scancodemap[keycode] pressed = ui.Scancodemap[keycode]
if blt.Check(blt.TK_SHIFT) != 0 { if blt.Check(blt.TK_SHIFT) != 0 {
pressed = "Shift+" + pressed pressed = "Shift+" + pressed
} }
if blt.Check(blt.TK_ALT) != 0 { if blt.Check(blt.TK_ALT) != 0 {
pressed = "Alt+" + pressed pressed = "Alt+" + pressed
} }
if blt.Check(blt.TK_CONTROL) != 0 { if blt.Check(blt.TK_CONTROL) != 0 {
pressed = "Ctrl+" + pressed pressed = "Ctrl+" + pressed
} }
//global hotkeys //global hotkeys
switch pressed { switch pressed {
case "Ctrl+q": case "Ctrl+q":
//fallthrough //fallthrough
//case "Escape": //case "Escape":
appctx.Logger(ctx).Info().Msg("exiting on quit command...") appctx.Logger(ctx).Info().Msg("exiting on quit command...")
State.Exit <- struct{}{} State.Exit <- struct{}{}
appctx.Logger(ctx).Info().Msg("...done") appctx.Logger(ctx).Info().Msg("...done")
exit = true exit = true
return return
default: default:
if pressed != "" { if pressed != "" {
waitForWCspam = false; waitForWCspam = false
State.Input <- pressed State.Input <- pressed
} }
} }
} }
} }
} }
} }

View File

@ -1,37 +1,37 @@
package alchemyst_go package alchemyst_go
import ( import (
"lab.zaar.be/thefish/alchemyst-go/engine/types" "lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/util/delaunay" "lab.zaar.be/thefish/alchemyst-go/util/delaunay"
"testing" "testing"
) )
func TestDelaunay(t *testing.T) { func TestDelaunay(t *testing.T) {
coords := []types.Coords{ coords := []types.Coords{
{10,10}, {10, 10},
{10,60}, {10, 60},
{30,10}, {30, 10},
{40,20}, {40, 20},
{60,10}, {60, 10},
{40,60}, {40, 60},
} }
expected := []types.Edge{ expected := []types.Edge{
{types.Coords{10, 60}, types.Coords{10, 10}}, {types.Coords{10, 60}, types.Coords{10, 10}},
{types.Coords{30, 10}, types.Coords{40, 20}}, {types.Coords{30, 10}, types.Coords{40, 20}},
{types.Coords{60, 10}, types.Coords{40, 60}}, {types.Coords{60, 10}, types.Coords{40, 60}},
{types.Coords{40, 20}, types.Coords{40, 60}}, {types.Coords{40, 20}, types.Coords{40, 60}},
{types.Coords{10, 10,}, types.Coords{30, 10}}, {types.Coords{10, 10}, types.Coords{30, 10}},
} }
result := delaunay.GetMst(coords, 100, 100) result := delaunay.GetMst(coords, 100, 100, 0)
for idx, _ := range result { for idx, _ := range result {
if result[idx] != expected[idx] { if result[idx] != expected[idx] {
t.Errorf("Failed, expected %v. got %v", result[idx], expected[idx]) t.Errorf("Failed, expected %v. got %v", result[idx], expected[idx])
} }
} }
t.Log("output: ", result) t.Log("output: ", result)
} }

View File

@ -0,0 +1,21 @@
package itemprops
import "github.com/shopspring/decimal"
type ArmorProfile struct {
LayerExtra Armored
LayerOuter Armored
LayerMiddle Armored
LayerInner Armored
}
type Armored struct {
ItemPhysics
Coverage Coverage
}
//Coverage is set of partial coverage from 0 to 1 (0 to 100%)
type Coverage struct {
Frontal decimal.Decimal
Rear decimal.Decimal
}

View File

@ -0,0 +1,148 @@
package itemprops
//MedicalSystem организм
// Humanoid
// Circuits
// Intake
//
// Breathe: Vessel: Air intake >> mouth/nose -> trachea -> lungs
// Vessel: Blood >> heart -> lungs -> brain -> heart
// Eat:
// Vessel: food >> mouth -> jaws
// Vessel: pulp >> esophagus -> stomach
// Congestion:
// Vessel: Blood >> heart -> guts -> system -> liver -> heart
// Vessel: pulp >> stomach -> guts -> output
// Vessel: bile >> liver -> stomach -> guts
// Fast Congestion
// Vessel: liquid >> stomach -> guts -> kidney -> bladder -> pulp output
// Vessel: Blood >> heart -> guts -> system -> kidney -> heart
// Blood сirculation:
// Vessel: blood >> heart -> system -> spleen -> heart
// -> brain -> heart
// Vision:
// Vessel: Nerve signal >> eye -> brain
// Smell:
// Vessel: Air intake >> nose
// Vessel: Nerve signal >> nose -> brain
// Hearing:
// Vessel: Air pressure >> ear
// Vessel: Nerve signal >> ear -> brain
// Touching:
// Vessel: Phys pressure/Temperature/Solvent >> skin -> nerve tissue -> brain
// Motion Sense:
// Vessel: Air pressure >> ear/nose -> inner ear -> brain [feeling fast-moving items]
// Motion:
// Vessel: Gravity >> inner ear -> brain [equilibrium]
// Vessel: Nerve signal >> brain -> major nerve -> [...muscle -> tendon -> bone/joint] -> nerve tissue -> brain
// Structural:
// Vessel: Nerve signal >> brain -> spinal brain -> [...muscle] -> nerve tissue -> brain
// Psychic:
// Vessel: Nerve signal >> brain -> spinal brain -> brain
// Consciousness:
// Vessel: Nerve signal >> brain -> brain
// Misc
// Hand Grip ???:
// Vessel: Nerve signal >> palm -> fingers with off-thumb
// Stance
// Body structure:
// BasePart -> chest -> spine -> joint -> head
// -> spine -> lowerbody
// -> [left] joint -> shoulder -> joint -> arm -> joint -> palm -> 5 x finger
// -> [right] joint -> shoulder -> joint -> arm -> joint -> palm -> 5 x finger
// -> lowerbody
// -> [left] joint -> leg -> joint -> hip -> joint -> foot -> 5 x finger
// -> [right] joint -> leg -> joint -> hip -> joint -> foot -> 5 x finger
// -> head -> joint -> jaw
//MedicalSystem Организм
type MedicalSystem struct {
BasePart BodyPart
}
//MedicalCircuit Система обращения
type MedicalCircuit struct {
Provides MedicalAbility
DependsOn Organ
Vessel MedicalVessel
Contains []Organ
}
//MedicalVessel кровь, желчь, пульпа, воздух, еда
type MedicalVessel struct {
Name string
Material
Pressure DimensionItemDensity
}
//BodyPart часть тела
type BodyPart struct {
LayerExtra MedicalMaterial
LayerOuter MedicalMaterial
LayerMiddle MedicalMaterial
LayerInner MedicalMaterial
Joints []Joint
Contains []InnerOrgan
Exposes []OuterOrgan
}
//Joint суставы, к чему и что крепится
type Joint struct {
Name string
ConnectsFrom BodyPart
ConnectsTo BodyPart
}
type Organ struct {
Name string
Material
}
//InnerOrgan ливер, селезёнка, сердце, кишки итп
type InnerOrgan struct {
Organ
DependsOn MedicalCircuit
BelongsTo MedicalCircuit
}
//OuterOrgan глаза, уши, волосы, когти итп
type OuterOrgan struct {
Organ
DependsOn MedicalCircuit
BelongsTo MedicalCircuit
}
//слой части тела - кожа/чешуя/роговые пластины/хитиновый панцирь, жир, мускулы, кости
type MedicalMaterial struct {
Name string
Material
MedicalSystemFlags
}
//@todo заменить на Medical Circuit
type MedicalSystemFlags struct {
//Structural является ли опорным аппаратом
Structural bool
//Содежит ли кровь/ихор/
MajorVeins bool //вход на мотор, сломаешь - быстро выйдет из строя если будет двигаться
MajorArteria bool //выход, то же самое + высокое давление
Veins bool //вход на мотор
Arteria bool //выход из мотора, высокое давление
MajorNerve bool //повредишь - ниже по суставам не работает
NerveTissue bool //повредишь - ниже по суставамс болит
OxygenTube bool //трахея
OxygenPump bool //лёгкое
BloodPump bool //мотор
ContainsCongestionLiquid bool
IsMainCongestionPump bool
}
//MedicalAbility спсобность есть, стоять, не терять равновесие, дышать, выздоравливать, лечить свои органы, видеть итп
type MedicalAbility string

View File

@ -0,0 +1,37 @@
package itemprops
import "github.com/shopspring/decimal"
type ItemPhysics struct {
Material Material
Rigidity DimensionItemRigidity
Size DimensionItemSize
Temperature DimensionItemTemperature
}
//DimensionItemSize length in m (1 mm = 1/1000 of 1m)
type DimensionItemSize struct {
Width decimal.Decimal
Height decimal.Decimal
// if item is solid - depth in m (1mm = 1/1000 of m)
Depth decimal.NullDecimal
//Thickness if item is hollow - thickness of outer item shell, ie for armor, in m (1 mm = 1/1000 of m)
Thickness decimal.NullDecimal
}
//Area is frontal area
func (d *DimensionItemSize) Area() decimal.Decimal {
return d.Width.Mul(d.Height)
}
//DimensionItemDensity density in kg/m3
type DimensionItemDensity decimal.Decimal
//DimensionItemRigidity rigidity жёсткость, способность твёрдого тела, конструкции или её элементов сопротивляться деформации in N/m
type DimensionItemRigidity decimal.Decimal
//NotchFractureToughness ударная вязкость по Шарпи, Дж (надо ли?)
type NotchFractureToughness decimal.Decimal
//DimensionItemTemperature in celsius, -273 to 10000
type DimensionItemTemperature decimal.Decimal

View File

@ -0,0 +1,20 @@
package itemprops
type Material struct {
Name string
Flags MaterialFlags
Density DimensionItemDensity
FractureToughness NotchFractureToughness
MeltingPoint DimensionItemTemperature
BoilingPoint DimensionItemTemperature
}
type MaterialFlags struct {
ConductsElictricity bool
BlocksLiquid bool
AcidResistant bool
BlocksGas bool
Flammable bool
ConductsHeat bool
Radiates bool
}

View File

@ -1,48 +1,52 @@
package screens package screens
import ( import (
"fmt" "context"
"lab.zaar.be/thefish/alchemyst-go/effects" "fmt"
"lab.zaar.be/thefish/alchemyst-go/engine/ecs" "lab.zaar.be/thefish/alchemyst-go/effects"
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate" "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
"lab.zaar.be/thefish/alchemyst-go/engine/types" "lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow" "lab.zaar.be/thefish/alchemyst-go/engine/types"
"strings" "lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
"lab.zaar.be/thefish/alchemyst-go/util/appctx"
"strings"
) )
type DevmenuScreen struct { type DevmenuScreen struct {
mw *mainwindow.MainWindow ctx context.Context
controller *ecs.Controller mw *mainwindow.MainWindow
scm *types.ScreenManager controller *ecs.Controller
state *gamestate.GameState scm *types.ScreenManager
types.Rect state *gamestate.GameState
types.Rect
renderParent bool renderParent bool
bgColor string bgColor string
fgColor string fgColor string
} }
func NewDevmenuScreen(mw *mainwindow.MainWindow, controller *ecs.Controller, scm *types.ScreenManager, state *gamestate.GameState, rect types.Rect, renderParent bool) *DevmenuScreen { func NewDevmenuScreen(ctx context.Context, mw *mainwindow.MainWindow, controller *ecs.Controller, scm *types.ScreenManager, state *gamestate.GameState, rect types.Rect, renderParent bool) *DevmenuScreen {
return &DevmenuScreen{ return &DevmenuScreen{
mw: mw, ctx: ctx,
controller: controller, mw: mw,
scm: scm, controller: controller,
state: state, scm: scm,
state: state,
Rect: rect, Rect: rect,
renderParent: renderParent, renderParent: renderParent,
} }
} }
func (devm *DevmenuScreen) SetBgColor(color string) *DevmenuScreen { func (devm *DevmenuScreen) SetBgColor(color string) *DevmenuScreen {
devm.bgColor = color devm.bgColor = color
return devm return devm
} }
func (devm *DevmenuScreen) SetFgColor(color string) *DevmenuScreen { func (devm *DevmenuScreen) SetFgColor(color string) *DevmenuScreen {
devm.fgColor = color devm.fgColor = color
return devm return devm
} }
func (devm *DevmenuScreen) UseEcs() bool { return false } func (devm *DevmenuScreen) UseEcs() bool { return false }
@ -50,66 +54,66 @@ func (devm *DevmenuScreen) Enter() {
} }
func (devm *DevmenuScreen) HandleInput(input string) { func (devm *DevmenuScreen) HandleInput(input string) {
switch input { switch input {
case "i": case "i":
level := devm.state.Level level := devm.state.Level
for idx, _ := range level.Tiles { for idx, _ := range level.Tiles {
level.Tiles[idx].Visible = false level.Tiles[idx].Visible = false
level.Tiles[idx].Explored = false level.Tiles[idx].Explored = false
} }
devm.scm.SetScreen(devm.scm.PreviousScreen) devm.scm.SetScreen(devm.scm.PreviousScreen)
break break
case "v": case "v":
level := devm.state.Level level := devm.state.Level
for idx, _ := range level.Tiles { for idx, _ := range level.Tiles {
level.Tiles[idx].Visible = true level.Tiles[idx].Visible = true
level.Tiles[idx].Explored = true level.Tiles[idx].Explored = true
} }
fmt.Printf("making everything visible!") appctx.Logger(devm.ctx).Warn().Msg("making everything visible!")
devm.scm.SetScreen(devm.scm.PreviousScreen) devm.scm.SetScreen(devm.scm.PreviousScreen)
break break
case "p": case "p":
if devm.controller.HasComponent(devm.state.Player, effects.BuffPassWall) { if devm.controller.HasComponent(devm.state.Player, effects.BuffPassWall) {
devm.controller.RemoveComponent(devm.state.Player, effects.BuffPassWall) devm.controller.RemoveComponent(devm.state.Player, effects.BuffPassWall)
} else { } else {
devm.controller.AddComponent(devm.state.Player, effects.PassWall{}) devm.controller.AddComponent(devm.state.Player, effects.PassWall{})
} }
case "Escape": case "Escape":
fallthrough fallthrough
case "Space": case "Space":
devm.scm.SetScreen(devm.scm.PreviousScreen) devm.scm.SetScreen(devm.scm.PreviousScreen)
break break
} }
} }
func (devm *DevmenuScreen) Exit() { func (devm *DevmenuScreen) Exit() {
if devm.renderParent { if devm.renderParent {
devm.scm.PreviousScreen.Render() devm.scm.PreviousScreen.Render()
} }
menuLayer := devm.mw.GetLayer("menu") menuLayer := devm.mw.GetLayer("menu")
menuLayer.ClearRect(devm.Rect) menuLayer.ClearRect(devm.Rect)
bgLayer := devm.mw.GetLayer("menubg") bgLayer := devm.mw.GetLayer("menubg")
bgLayer.ClearRect(devm.Rect) bgLayer.ClearRect(devm.Rect)
} }
func (devm *DevmenuScreen) Render() { func (devm *DevmenuScreen) Render() {
menuLayer := devm.mw.GetLayer("menu") menuLayer := devm.mw.GetLayer("menu")
menuLayer.ClearRect(devm.Rect) menuLayer.ClearRect(devm.Rect)
bgLayer := devm.mw.GetLayer("menubg") bgLayer := devm.mw.GetLayer("menubg")
bgLayer.ClearRect(devm.Rect) bgLayer.ClearRect(devm.Rect)
bgLayer.WithColor(devm.bgColor).NewWindow(devm.Rect).NoBorder() bgLayer.WithColor(devm.bgColor).NewWindow(devm.Rect).NoBorder()
menuLayer.WithColor(devm.fgColor).PrintInside( menuLayer.WithColor(devm.fgColor).PrintInside(
devm.Rect, devm.Rect,
strings.Join([]string{ strings.Join([]string{
"Действия для разработчика:", "Действия для разработчика:",
"[color=green]v[/color] - set all tiles visible", "[color=green]v[/color] - set all tiles visible",
"[color=green]i[/color] - set all tiles invisible", "[color=green]i[/color] - set all tiles invisible",
fmt.Sprintf("[color=green]p[/color] - toggle passwall: %v", fmt.Sprintf("[color=green]p[/color] - toggle passwall: %v",
devm.controller.HasComponent(devm.state.Player, effects.BuffPassWall), devm.controller.HasComponent(devm.state.Player, effects.BuffPassWall),
), ),
}, "\n"), }, "\n"),
1, 1,
) )
menuLayer.Print(devm.X+2, devm.Y+devm.H-1, "[color=green]Space[/color] to close") menuLayer.Print(devm.X+2, devm.Y+devm.H-1, "[color=green]Space[/color] to close")
} }

1
go.mod
View File

@ -5,5 +5,6 @@ go 1.12
require ( require (
github.com/gammazero/deque v0.0.0-20190521012701-46e4ffb7a622 github.com/gammazero/deque v0.0.0-20190521012701-46e4ffb7a622
github.com/rs/zerolog v1.15.0 github.com/rs/zerolog v1.15.0
github.com/shopspring/decimal v1.3.1
lab.zaar.be/thefish/bearlibterminal v0.0.0-20191018101635-dd37bbc90d77 lab.zaar.be/thefish/bearlibterminal v0.0.0-20191018101635-dd37bbc90d77
) )

2
go.sum
View File

@ -5,6 +5,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY= github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=