register logic

This commit is contained in:
2026-08-29 23:59:56 +02:00
parent ddea3b0893
commit 94649a38fe
83 changed files with 830 additions and 699 deletions
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundAlley() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgAlley,
Path: "assets/bg/alley.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundBbsTerminal() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgBBSTerminal,
Path: "assets/bg/bbs_terminal.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundBvkBranch() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgBVKBranch,
Path: "assets/bg/bvk_branch.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundColumbarium() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgColumbarium,
Path: "assets/bg/columbarium.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundCuratorShop() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgCuratorShop,
Path: "assets/bg/curator_shop.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundHackerspace() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgHackerspace,
Path: "assets/bg/hackerspace.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundHospital() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgHospital,
Path: "assets/bg/hospital.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundIceCreamShop() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgIceCreamShop,
Path: "assets/bg/ice_cream_shop.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -30
View File
@@ -4,33 +4,6 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func registerBackground(w *World) {
for _, a := range []inkwell.Asset{
backgroundSelector(),
backgroundPaulShop(),
backgroundNoodleHouse(),
backgroundNormanApartment(),
backgroundPoliceStation(),
backgroundAlley(),
backgroundHackerspace(),
backgroundIceCreamShop(),
backgroundTrinketShop(),
backgroundSmallRestaurant(),
backgroundSecretClub(),
backgroundBbsTerminal(),
backgroundStreet(),
backgroundHospital(),
backgroundServerFarm(),
backgroundSecretLab(),
backgroundRooftopHideout(),
backgroundPublicBBS(),
backgroundBvkBranch(),
backgroundCuratorShop(),
backgroundScrapMarket(),
backgroundSamizdatPress(),
backgroundShowroom(),
backgroundColumbarium(),
} {
w.G.AssetManager.Register(a)
}
}
type Background = inkwell.Asset
var BackgroundManager = NewManager(func(entity Background) string { return entity.Name })
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundNoodleHouse() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgNoodleHouse,
Path: "assets/bg/noodle_house.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundNormanApartment() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgNormanApartment,
Path: "assets/bg/norman_apartment.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundPaulShop() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgPaulShop,
Path: "assets/bg/paul_shop.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundPoliceStation() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgPoliceStation,
Path: "assets/bg/police_station.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundPublicBBS() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgPublicBBS,
Path: "assets/bg/public_bbs.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundRooftopHideout() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgRooftopHideout,
Path: "assets/bg/rooftop_hideout.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundSamizdatPress() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgSamizdatPress,
Path: "assets/bg/samizdat_press.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundScrapMarket() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgScrapMarket,
Path: "assets/bg/scrap_market.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundSecretClub() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgSecretClub,
Path: "assets/bg/secret_club.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundSecretLab() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgSecretLab,
Path: "assets/bg/secret_lab.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundSelector() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgSelector,
Path: "assets/bg/selector.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundServerFarm() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgServerFarm,
Path: "assets/bg/server_farm.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundShowroom() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgShowroom,
Path: "assets/bg/showroom.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundSmallRestaurant() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgSmallRestaurant,
Path: "assets/bg/small_restaurant.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundStreet() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgStreet,
Path: "assets/bg/street.png",
Kind: inkwell.AssetImage,
}
})
}
+3 -3
View File
@@ -4,10 +4,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func backgroundTrinketShop() inkwell.Asset {
return inkwell.Asset{
func init() {
BackgroundManager.Register(Background{
Name: BgTrinketShop,
Path: "assets/bg/trinket_shop.png",
Kind: inkwell.AssetImage,
}
})
}
+7 -7
View File
@@ -18,21 +18,21 @@ func New(o Opts) *inkwell.Game {
g := inkwell.NewGame("Real World", ScreenW, ScreenH)
g.MaxLogLines = 64
w := newWorld(g)
registerTheme(g)
registerContent(w)
World.attach(g)
registerTheme()
registerContent()
g.UseTheme(RealWorld)
registerUI(w)
registerUI()
g.StartAt(start)
g.OnStart(inkwell.Seq(bootOpening(w, start, o.Finale)...))
g.OnStart(inkwell.Seq(bootOpening(start, o.Finale)...))
return g
}
func bootOpening(w *World, start string, finale bool) []inkwell.Action {
func bootOpening(start string, finale bool) []inkwell.Action {
acts := []inkwell.Action{
EnterScene(w, start),
EnterScene(start),
inkwell.SetFlag(FlagPoliceTip),
inkwell.Say(Paul, "Back alley. Just like the clerk said."),
TapeSay(Dex, "A government office tipped you off to remove something from a scene. That doesn't strike you as odd?"),
+3 -7
View File
@@ -1,12 +1,8 @@
package inc
import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func characterDex() inkwell.Character {
return inkwell.Character{
func init() {
CharacterManager.Register(Character{
Name: Dex,
SpeechColor: Amber,
}
})
}
+3 -10
View File
@@ -4,13 +4,6 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func registerCharacter(w *World) {
for _, c := range []inkwell.Character{
characterPaul(),
characterDex(),
characterMysteryTape(),
characterSupportTape(),
} {
w.G.CharacterManager.Register(c)
}
}
type Character = inkwell.Character
var CharacterManager = NewManager(func(entity Character) string { return entity.Name })
+3 -7
View File
@@ -1,12 +1,8 @@
package inc
import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func characterMysteryTape() inkwell.Character {
return inkwell.Character{
func init() {
CharacterManager.Register(Character{
Name: TapeMystery,
SpeechColor: RGB(0xB9A98A),
}
})
}
+3 -3
View File
@@ -4,8 +4,8 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func characterPaul() inkwell.Character {
return inkwell.Character{
func init() {
CharacterManager.Register(Character{
Name: Paul,
Speed: 96,
W: 28,
@@ -15,5 +15,5 @@ func characterPaul() inkwell.Character {
Y: 232,
},
SpeechColor: Ink,
}
})
}
+3 -7
View File
@@ -1,12 +1,8 @@
package inc
import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func characterSupportTape() inkwell.Character {
return inkwell.Character{
func init() {
CharacterManager.Register(Character{
Name: TapeSupport,
SpeechColor: RGB(0xE8C86A),
}
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func registerContent(w *World) {
registerBackground(w)
registerCharacter(w)
registerItem(w)
registerDialog(w)
registerScript(w)
registerScreen(w)
func registerContent() {
registerAll(BackgroundManager, World.G.AssetManager.Register)
registerAll(CharacterManager, World.G.CharacterManager.Register)
registerAll(ItemManager, World.G.ItemManager.Register)
registerAll(DialogManager, World.G.DialogueManager.Register)
registerAll(ScriptManager, World.G.ScriptManager.Register)
registerScreen()
}
+3 -3
View File
@@ -4,8 +4,8 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func dialogDexTalk() inkwell.Dialogue {
return inkwell.Dialogue{
func init() {
DialogManager.Register(Dialog{
Name: DlgDex,
Start: "root",
Nodes: []inkwell.DialogueNode{{
@@ -52,5 +52,5 @@ func dialogDexTalk() inkwell.Dialogue {
},
},
}},
}
})
}
+3 -8
View File
@@ -4,11 +4,6 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func registerDialog(w *World) {
for _, d := range []inkwell.Dialogue{
dialogDexTalk(),
dialogMysteryTapeSilent(),
} {
w.G.DialogueManager.Register(d)
}
}
type Dialog = inkwell.Dialogue
var DialogManager = NewManager(func(entity Dialog) string { return entity.Name })
+3 -3
View File
@@ -4,8 +4,8 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func dialogMysteryTapeSilent() inkwell.Dialogue {
return inkwell.Dialogue{
func init() {
DialogManager.Register(Dialog{
Name: DlgMysteryTape,
Start: "root",
Nodes: []inkwell.DialogueNode{{
@@ -28,5 +28,5 @@ func dialogMysteryTapeSilent() inkwell.Dialogue {
},
},
}},
}
})
}
+3 -3
View File
@@ -4,8 +4,8 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func itemBlackMarketArmilla() inkwell.Item {
return inkwell.Item{
func init() {
ItemManager.Register(Item{
Name: ItemBlackArmilla,
Description: "black-market Armilla",
OnUseSelf: inkwell.Seq(
@@ -18,5 +18,5 @@ func itemBlackMarketArmilla() inkwell.Item {
TapeSay(Dex, "Nothing. Which is what I'd charge for it."),
),
},
}
})
}
+3 -9
View File
@@ -4,12 +4,6 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func registerItem(w *World) {
for _, i := range []inkwell.Item{
itemNoodleLetter(),
itemBlackMarketArmilla(),
itemMysteryTape(),
} {
w.G.ItemManager.Register(i)
}
}
type Item = inkwell.Item
var ItemManager = NewManager(func(entity Item) string { return entity.Name })
+3 -3
View File
@@ -4,13 +4,13 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func itemMysteryTape() inkwell.Item {
return inkwell.Item{
func init() {
ItemManager.Register(Item{
Name: ItemMysteryTape,
Description: "unmarked Personal Tape",
OnUseSelf: inkwell.Seq(
inkwell.Say(Paul, "Password-locked. Of course."),
TapeSay(Dex, "Put it in the second slot if you care that much. I did warn you."),
),
}
})
}
+3 -3
View File
@@ -4,13 +4,13 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func itemNoodleLetter() inkwell.Item {
return inkwell.Item{
func init() {
ItemManager.Register(Item{
Name: ItemNoodleLetter,
Description: "Noodle's letter",
OnUseSelf: inkwell.Seq(
inkwell.Say(Paul, "“Come out, Paul. Not a phone conversation.” That's all it says."),
TapeSay(Dex, "And now you're here. And he isn't."),
),
}
})
}
+17
View File
@@ -0,0 +1,17 @@
package inc
type ManagerInterface[T any] interface {
Register(entity T)
GetByName(name string) (T, bool)
GetAll() []T
}
var (
_ ManagerInterface[Background] = BackgroundManager
_ ManagerInterface[Character] = CharacterManager
_ ManagerInterface[Dialog] = DialogManager
_ ManagerInterface[Item] = ItemManager
_ ManagerInterface[Script] = ScriptManager
_ ManagerInterface[Screen] = ScreenManager
_ ManagerInterface[Theme] = ThemeManager
)
+43
View File
@@ -0,0 +1,43 @@
package inc
type Manager[T any] struct {
nameOf func(T) string
entities []T
index map[string]int
}
func NewManager[T any](nameOf func(T) string) *Manager[T] {
return &Manager[T]{
nameOf: nameOf,
index: map[string]int{},
}
}
func (m *Manager[T]) Register(entity T) {
name := m.nameOf(entity)
if i, ok := m.index[name]; ok {
m.entities[i] = entity
return
}
m.index[name] = len(m.entities)
m.entities = append(m.entities, entity)
}
func (m *Manager[T]) GetByName(name string) (T, bool) {
i, ok := m.index[name]
if !ok {
var missing T
return missing, false
}
return m.entities[i], true
}
func (m *Manager[T]) GetAll() []T {
return m.entities
}
func registerAll[T any](m *Manager[T], register func(T)) {
for _, entity := range m.GetAll() {
register(entity)
}
}
+10 -10
View File
@@ -4,19 +4,19 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func screenAlley() screen {
return screen{
name: ScreenAlley,
title: "ALLEY — BEHIND NOODLE'S HOUSE",
background: BgAlley,
exits: []exit{
func init() {
ScreenManager.Register(Screen{
Name: ScreenAlley,
Title: "ALLEY — BEHIND NOODLE'S HOUSE",
Background: BgAlley,
Exits: []exit{
{
to: ScreenNoodleHouse,
label: "back out to the street",
side: sideLeft,
},
},
actors: []inkwell.SceneActor{
Actors: []inkwell.SceneActor{
{
CharacterName: Paul,
At: inkwell.Point{
@@ -25,9 +25,9 @@ func screenAlley() screen {
},
},
},
onEnter: setVarIfEmpty(VarArmillaStrip, "SRP: 1 tape"),
hotspots: []inkwell.Hotspot{hidingPlace(), backDoor(), bin(), fireEscape()},
}
OnEnter: setVarIfEmpty(VarArmillaStrip, "SRP: 1 tape"),
Hotspots: []inkwell.Hotspot{hidingPlace(), backDoor(), bin(), fireEscape()},
})
}
func hidingPlace() inkwell.Hotspot {
+7 -7
View File
@@ -1,15 +1,15 @@
package inc
func screenBbsTerminal() screen {
return screen{
name: ScreenBBSTerminal,
title: "TERMINAL — BBS ACCESS POINT",
background: BgBBSTerminal,
exits: []exit{
func init() {
ScreenManager.Register(Screen{
Name: ScreenBBSTerminal,
Title: "TERMINAL — BBS ACCESS POINT",
Background: BgBBSTerminal,
Exits: []exit{
{
label: "step back from the terminal",
side: sideNear,
},
},
}
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenBvkBranch() screen {
return screen{
name: ScreenBVKBranch,
title: "BVK — SAN FRANCISCO BRANCH",
background: BgBVKBranch,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenBVKBranch,
Title: "BVK — SAN FRANCISCO BRANCH",
Background: BgBVKBranch,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenColumbarium() screen {
return screen{
name: ScreenColumbarium,
title: "COLUMBARIUM — DEX'S MEMORIAL",
background: BgColumbarium,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenColumbarium,
Title: "COLUMBARIUM — DEX'S MEMORIAL",
Background: BgColumbarium,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenCuratorShop() screen {
return screen{
name: ScreenCuratorShop,
title: "CURATOR SERVICE — THE MASTER'S WORKSHOP",
background: BgCuratorShop,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenCuratorShop,
Title: "CURATOR SERVICE — THE MASTER'S WORKSHOP",
Background: BgCuratorShop,
OnSelector: true,
})
}
+2 -2
View File
@@ -52,10 +52,10 @@ func exitName(to string) string {
return "exit:" + to
}
func (e exit) hotspot(w *World) inkwell.Hotspot {
func (e exit) hotspot() inkwell.Hotspot {
var travel inkwell.Action = inkwell.GoTo(e.to)
if e.to == "" {
travel = Back(w)
travel = Back()
}
if e.needs != "" {
travel = inkwell.If(inkwell.Flag(e.needs), travel, inkwell.Say(Paul, e.blocked))
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenHackerspace() screen {
return screen{
name: ScreenHackerspace,
title: "HACKERSPACE",
background: BgHackerspace,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenHackerspace,
Title: "HACKERSPACE",
Background: BgHackerspace,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenHospital() screen {
return screen{
name: ScreenHospital,
title: "HOSPITAL — PSYCHIATRIC WING",
background: BgHospital,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenHospital,
Title: "HOSPITAL — PSYCHIATRIC WING",
Background: BgHospital,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenIceCreamShop() screen {
return screen{
name: ScreenIceCreamShop,
title: "ICE CREAM SHOP — WHERE THE BAR WAS",
background: BgIceCreamShop,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenIceCreamShop,
Title: "ICE CREAM SHOP — WHERE THE BAR WAS",
Background: BgIceCreamShop,
OnSelector: true,
})
}
+30 -57
View File
@@ -4,55 +4,28 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
type screen struct {
name string
title string
background string
type Screen struct {
Name string
Title string
Background string
exits []exit
Exits []exit
onSelector bool
OnSelector bool
hotspots []inkwell.Hotspot
actors []inkwell.SceneActor
walkboxes []inkwell.Polygon
onEnter inkwell.Action
Hotspots []inkwell.Hotspot
Actors []inkwell.SceneActor
Walkboxes []inkwell.Polygon
OnEnter inkwell.Action
}
var screenDeck = []func() screen{
screenPaulShop,
screenNoodleHouse,
screenAlley,
screenNormanApartment,
screenPoliceStation,
screenHackerspace,
screenIceCreamShop,
screenTrinketShop,
screenSmallRestaurant,
screenSecretClub,
screenBbsTerminal,
screenStreet,
screenHospital,
screenServerFarm,
screenSecretLab,
screenRooftopHideout,
screenPublicBBS,
screenBvkBranch,
screenCuratorShop,
screenScrapMarket,
screenSamizdatPress,
screenShowroom,
screenColumbarium,
}
var ScreenManager = NewManager(func(entity Screen) string { return entity.Name })
func registerScreen(w *World) {
screens := make([]screen, 0, len(screenDeck)+1)
for _, f := range screenDeck {
screens = append(screens, f())
}
for _, s := range append([]screen{screenSelector(screens)}, screens...) {
w.G.SceneManager.Register(screenBuild(w, s))
}
func registerScreen() {
fillSelectorPins()
registerAll(ScreenManager, func(entity Screen) {
World.G.SceneManager.Register(screenBuild(entity))
})
}
var screenFloor = []inkwell.Polygon{
@@ -74,18 +47,18 @@ var screenFloor = []inkwell.Polygon{
),
}
func screenBuild(w *World, s screen) inkwell.Scene {
exits := s.exits
if s.onSelector {
func screenBuild(s Screen) inkwell.Scene {
exits := s.Exits
if s.OnSelector {
exits = append(exits, toSelector())
}
hotspots := make([]inkwell.Hotspot, 0, len(exits)+len(s.hotspots))
hotspots = append(hotspots, s.hotspots...)
hotspots := make([]inkwell.Hotspot, 0, len(exits)+len(s.Hotspots))
hotspots = append(hotspots, s.Hotspots...)
for _, e := range exits {
hotspots = append(hotspots, e.hotspot(w))
hotspots = append(hotspots, e.hotspot())
}
actors := s.actors
actors := s.Actors
if actors == nil {
actors = []inkwell.SceneActor{
{
@@ -97,19 +70,19 @@ func screenBuild(w *World, s screen) inkwell.Scene {
},
}
}
walkboxes := s.walkboxes
walkboxes := s.Walkboxes
if walkboxes == nil {
walkboxes = screenFloor
}
onEnter := inkwell.Action(EnterScene(w, s.name))
if s.onEnter != nil {
onEnter = inkwell.Seq(onEnter, s.onEnter)
onEnter := inkwell.Action(EnterScene(s.Name))
if s.OnEnter != nil {
onEnter = inkwell.Seq(onEnter, s.OnEnter)
}
return inkwell.Scene{
Name: s.name,
Title: s.title,
Background: s.background,
Name: s.Name,
Title: s.Title,
Background: s.Background,
Actors: actors,
Walkboxes: walkboxes,
Hotspots: hotspots,
+8 -8
View File
@@ -1,17 +1,17 @@
package inc
func screenNoodleHouse() screen {
return screen{
name: ScreenNoodleHouse,
title: "NOODLE'S HOUSE — SEALED",
background: BgNoodleHouse,
onSelector: true,
exits: []exit{
func init() {
ScreenManager.Register(Screen{
Name: ScreenNoodleHouse,
Title: "NOODLE'S HOUSE — SEALED",
Background: BgNoodleHouse,
OnSelector: true,
Exits: []exit{
{
to: ScreenAlley,
label: "the alley behind the house",
side: sideRight,
},
},
}
})
}
+8 -8
View File
@@ -1,12 +1,12 @@
package inc
func screenNormanApartment() screen {
return screen{
name: ScreenNormanApartment,
title: "NORMAN'S APARTMENT",
background: BgNormanApartment,
onSelector: true,
exits: []exit{
func init() {
ScreenManager.Register(Screen{
Name: ScreenNormanApartment,
Title: "NORMAN'S APARTMENT",
Background: BgNormanApartment,
OnSelector: true,
Exits: []exit{
{
to: ScreenRooftopHideout,
label: "the stairs up to the roof",
@@ -18,5 +18,5 @@ func screenNormanApartment() screen {
side: sideRight,
},
},
}
})
}
+7 -7
View File
@@ -1,16 +1,16 @@
package inc
func screenPaulShop() screen {
return screen{
name: ScreenPaulShop,
title: "PAUL'S SHOP — JUNK AND GARAGE",
background: BgPaulShop,
exits: []exit{
func init() {
ScreenManager.Register(Screen{
Name: ScreenPaulShop,
Title: "PAUL'S SHOP — JUNK AND GARAGE",
Background: BgPaulShop,
Exits: []exit{
{
to: ScreenNoodleHouse,
label: "the bus to San Francisco",
side: sideNear,
},
},
}
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenPoliceStation() screen {
return screen{
name: ScreenPoliceStation,
title: "SFPD — STATION AND HOLDING",
background: BgPoliceStation,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenPoliceStation,
Title: "SFPD — STATION AND HOLDING",
Background: BgPoliceStation,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenPublicBBS() screen {
return screen{
name: ScreenPublicBBS,
title: "PUBLIC BBS TERMINAL",
background: BgPublicBBS,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenPublicBBS,
Title: "PUBLIC BBS TERMINAL",
Background: BgPublicBBS,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,11 +1,11 @@
package inc
func screenRooftopHideout() screen {
return screen{
name: ScreenRooftopHideout,
title: "NORMAN'S ROOFTOP HIDEOUT",
background: BgRooftopHideout,
exits: []exit{
func init() {
ScreenManager.Register(Screen{
Name: ScreenRooftopHideout,
Title: "NORMAN'S ROOFTOP HIDEOUT",
Background: BgRooftopHideout,
Exits: []exit{
{
to: ScreenNormanApartment,
label: "back down into the flat",
@@ -17,5 +17,5 @@ func screenRooftopHideout() screen {
side: sideRight,
},
},
}
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenSamizdatPress() screen {
return screen{
name: ScreenSamizdatPress,
title: "SAMIZDAT PRINTING HOUSE",
background: BgSamizdatPress,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenSamizdatPress,
Title: "SAMIZDAT PRINTING HOUSE",
Background: BgSamizdatPress,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenScrapMarket() screen {
return screen{
name: ScreenScrapMarket,
title: "SCRAP MARKET",
background: BgScrapMarket,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenScrapMarket,
Title: "SCRAP MARKET",
Background: BgScrapMarket,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,11 +1,11 @@
package inc
func screenSecretClub() screen {
return screen{
name: ScreenSecretClub,
title: "SECRET CLUB — THE UNDERWATER SUN",
background: BgSecretClub,
exits: []exit{
func init() {
ScreenManager.Register(Screen{
Name: ScreenSecretClub,
Title: "SECRET CLUB — THE UNDERWATER SUN",
Background: BgSecretClub,
Exits: []exit{
{
to: ScreenBBSTerminal,
label: "the terminal in the corner",
@@ -17,5 +17,5 @@ func screenSecretClub() screen {
side: sideNear,
},
},
}
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenSecretLab() screen {
return screen{
name: ScreenSecretLab,
title: "SECRET RESEARCH LABORATORY",
background: BgSecretLab,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenSecretLab,
Title: "SECRET RESEARCH LABORATORY",
Background: BgSecretLab,
OnSelector: true,
})
}
+21 -13
View File
@@ -6,26 +6,34 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func screenSelector(rest []screen) screen {
func init() {
ScreenManager.Register(Screen{
Name: ScreenSelector,
Title: "SAN FRANCISCO",
Background: BgSelector,
Actors: []inkwell.SceneActor{},
Walkboxes: []inkwell.Polygon{},
})
}
func fillSelectorPins() {
selector, ok := ScreenManager.GetByName(ScreenSelector)
if !ok {
return
}
var exits []exit
for _, s := range rest {
if !s.onSelector {
for _, entity := range ScreenManager.GetAll() {
if !entity.OnSelector {
continue
}
exits = append(exits, exit{
to: s.name,
label: pinLabel(s.title),
to: entity.Name,
label: pinLabel(entity.Title),
area: pin(len(exits)),
})
}
return screen{
name: ScreenSelector,
title: "SAN FRANCISCO",
background: BgSelector,
exits: exits,
actors: []inkwell.SceneActor{},
walkboxes: []inkwell.Polygon{},
}
selector.Exits = exits
ScreenManager.Register(selector)
}
const (
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenServerFarm() screen {
return screen{
name: ScreenServerFarm,
title: "SERVER FARM",
background: BgServerFarm,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenServerFarm,
Title: "SERVER FARM",
Background: BgServerFarm,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenShowroom() screen {
return screen{
name: ScreenShowroom,
title: "NEUMATRONIC SHOWROOM",
background: BgShowroom,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenShowroom,
Title: "NEUMATRONIC SHOWROOM",
Background: BgShowroom,
OnSelector: true,
})
}
+7 -7
View File
@@ -1,16 +1,16 @@
package inc
func screenSmallRestaurant() screen {
return screen{
name: ScreenSmallRestaurant,
title: "SMALL RESTAURANT — NEXT DOOR",
background: BgSmallRestaurant,
exits: []exit{
func init() {
ScreenManager.Register(Screen{
Name: ScreenSmallRestaurant,
Title: "SMALL RESTAURANT — NEXT DOOR",
Background: BgSmallRestaurant,
Exits: []exit{
{
to: ScreenTrinketShop,
label: "back to the trinket shop",
side: sideLeft,
},
},
}
})
}
+7 -7
View File
@@ -1,10 +1,10 @@
package inc
func screenStreet() screen {
return screen{
name: ScreenStreet,
title: "STREET",
background: BgStreet,
onSelector: true,
}
func init() {
ScreenManager.Register(Screen{
Name: ScreenStreet,
Title: "STREET",
Background: BgStreet,
OnSelector: true,
})
}
+8 -8
View File
@@ -1,12 +1,12 @@
package inc
func screenTrinketShop() screen {
return screen{
name: ScreenTrinketShop,
title: "CHINATOWN — TRINKET SHOP",
background: BgTrinketShop,
onSelector: true,
exits: []exit{
func init() {
ScreenManager.Register(Screen{
Name: ScreenTrinketShop,
Title: "CHINATOWN — TRINKET SHOP",
Background: BgTrinketShop,
OnSelector: true,
Exits: []exit{
{
to: ScreenSmallRestaurant,
label: "the eating place next door",
@@ -20,5 +20,5 @@ func screenTrinketShop() screen {
blocked: "Just a shop, as far as the man behind the counter is concerned.",
},
},
}
})
}
+4 -4
View File
@@ -4,11 +4,11 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func scriptAwakeningFinale(w *World) inkwell.Script {
return inkwell.Script{
func init() {
ScriptManager.Register(Script{
Name: ScriptFinale,
Actions: inkwell.Seq(
SetMode(w, ModeCutscene),
SetMode(ModeCutscene),
inkwell.Wait(0.6),
inkwell.Say(Paul, "I'm putting it in. That's all this is."),
inkwell.Wait(0.4),
@@ -19,5 +19,5 @@ func scriptAwakeningFinale(w *World) inkwell.Script {
inkwell.Wait(1.0),
inkwell.ShowEnd("REAL WORLD — end of game two"),
),
}
})
}
+3 -8
View File
@@ -4,11 +4,6 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func registerScript(w *World) {
for _, s := range []inkwell.Script{
scriptTapeInsert(w),
scriptAwakeningFinale(w),
} {
w.G.ScriptManager.Register(s)
}
}
type Script = inkwell.Script
var ScriptManager = NewManager(func(entity Script) string { return entity.Name })
+5 -5
View File
@@ -4,16 +4,16 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
func scriptTapeInsert(w *World) inkwell.Script {
return inkwell.Script{
func init() {
ScriptManager.Register(Script{
Name: ScriptTapeInsert,
Actions: inkwell.Seq(
Fn(func(ctx *inkwell.Ctx) {
item := w.TakePending()
item := World.TakePending()
if item == "" {
return
}
w.SetSlot2(item)
World.SetSlot2(item)
ctx.Game.Inventory.Remove(item)
ctx.Game.State.SetVar(VarArmillaStrip, "SLOT2: READING")
}),
@@ -21,5 +21,5 @@ func scriptTapeInsert(w *World) inkwell.Script {
TapeSay(Dex, "Clicked in. Spinning. And now: nothing."),
TapeSay(Dex, "A stranger's tape in your own Armilla, Paul. I hope you know what you're doing."),
),
}
})
}
+6 -93
View File
@@ -6,6 +6,10 @@ import (
inkwell "git.teletypegames.org/engines/inkwell"
)
type Theme = inkwell.Theme
var ThemeManager = NewManager(func(entity Theme) string { return entity.Name })
const (
RealWorld = "realworld-93"
NokiaPunk = "nokia-punk"
@@ -29,97 +33,6 @@ func RGBA(hex uint32, a uint8) color.Color {
}
}
var (
Ink = RGB(0xDCD5C4)
InkDim = RGB(0x8A806B)
Amber = RGB(0xE0A33E)
AmberLo = RGB(0xA8701A)
black = RGB(0x14120E)
panel = RGB(0x0D0B08)
sceneBG = RGB(0x241F18)
)
func realWorldTheme() inkwell.Theme {
return inkwell.Theme{
Name: RealWorld,
PanelBG: black,
StatusText: Ink,
FlashText: Amber,
VerbButtonBG: RGB(0x1E1A14),
VerbButtonSelectedBG: AmberLo,
VerbButtonText: Ink,
InventorySlotBG: RGB(0x1E1A14),
InventorySlotSelectedBG: AmberLo,
SpeechBubbleBG: RGBA(0x14120E, 0xDC),
SpeechDefaultText: Ink,
DialogBG: RGBA(0x0D0B08, 0xF0),
DialogBorder: AmberLo,
DialogChoiceBG: RGB(0x1E1A14),
DialogChoiceHover: Amber,
DialogSpeaker: Amber,
DialogText: Ink,
EndCardBG: RGBA(0x000000, 0xFA),
EndCardText: Ink,
CursorColor: Amber,
HotspotOutline: RGB(0x7A6A44),
SceneBackdrop: sceneBG,
TopBarBG: panel,
TopBarText: InkDim,
TopBarAccent: Amber,
ChatLogBG: panel,
ChatLogPrompt: InkDim,
ChatLogResponse: Amber,
ChatLogSystem: RGB(0x6B6353),
CharacterPanelBG: panel,
CharacterPanelBorder: AmberLo,
CharacterPanelTitle: Amber,
}
}
var (
Green = RGB(0x3BE86B)
GreenLo = RGB(0x1F7A39)
npBlack = RGB(0x030603)
)
func nokiaPunkTheme() inkwell.Theme {
return inkwell.Theme{
Name: NokiaPunk,
PanelBG: npBlack,
StatusText: Green,
FlashText: RGB(0xD8F06A),
VerbButtonBG: RGB(0x08140A),
VerbButtonSelectedBG: GreenLo,
VerbButtonText: Green,
InventorySlotBG: RGB(0x08140A),
InventorySlotSelectedBG: GreenLo,
SpeechBubbleBG: RGBA(0x030603, 0xDC),
SpeechDefaultText: Green,
DialogBG: RGBA(0x030603, 0xF0),
DialogBorder: Green,
DialogChoiceBG: RGB(0x08140A),
DialogChoiceHover: RGB(0xB4FFC8),
DialogSpeaker: RGB(0xB4FFC8),
DialogText: Green,
EndCardBG: RGBA(0x000000, 0xFA),
EndCardText: Green,
CursorColor: Green,
HotspotOutline: GreenLo,
SceneBackdrop: npBlack,
TopBarBG: RGB(0x061006),
TopBarText: GreenLo,
TopBarAccent: Green,
ChatLogBG: RGB(0x040A04),
ChatLogPrompt: GreenLo,
ChatLogResponse: Green,
ChatLogSystem: RGB(0x156030),
CharacterPanelBG: RGB(0x040A04),
CharacterPanelBorder: Green,
CharacterPanelTitle: RGB(0xB4FFC8),
}
}
func registerTheme(g *inkwell.Game) {
g.ThemeManager.Register(realWorldTheme())
g.ThemeManager.Register(nokiaPunkTheme())
func registerTheme() {
registerAll(ThemeManager, World.G.ThemeManager.Register)
}
+44
View File
@@ -0,0 +1,44 @@
package inc
var (
Green = RGB(0x3BE86B)
GreenLo = RGB(0x1F7A39)
npBlack = RGB(0x030603)
)
func init() {
ThemeManager.Register(Theme{
Name: NokiaPunk,
PanelBG: npBlack,
StatusText: Green,
FlashText: RGB(0xD8F06A),
VerbButtonBG: RGB(0x08140A),
VerbButtonSelectedBG: GreenLo,
VerbButtonText: Green,
InventorySlotBG: RGB(0x08140A),
InventorySlotSelectedBG: GreenLo,
SpeechBubbleBG: RGBA(0x030603, 0xDC),
SpeechDefaultText: Green,
DialogBG: RGBA(0x030603, 0xF0),
DialogBorder: Green,
DialogChoiceBG: RGB(0x08140A),
DialogChoiceHover: RGB(0xB4FFC8),
DialogSpeaker: RGB(0xB4FFC8),
DialogText: Green,
EndCardBG: RGBA(0x000000, 0xFA),
EndCardText: Green,
CursorColor: Green,
HotspotOutline: GreenLo,
SceneBackdrop: npBlack,
TopBarBG: RGB(0x061006),
TopBarText: GreenLo,
TopBarAccent: Green,
ChatLogBG: RGB(0x040A04),
ChatLogPrompt: GreenLo,
ChatLogResponse: Green,
ChatLogSystem: RGB(0x156030),
CharacterPanelBG: RGB(0x040A04),
CharacterPanelBorder: Green,
CharacterPanelTitle: RGB(0xB4FFC8),
})
}
+48
View File
@@ -0,0 +1,48 @@
package inc
var (
Ink = RGB(0xDCD5C4)
InkDim = RGB(0x8A806B)
Amber = RGB(0xE0A33E)
AmberLo = RGB(0xA8701A)
black = RGB(0x14120E)
panel = RGB(0x0D0B08)
sceneBG = RGB(0x241F18)
)
func init() {
ThemeManager.Register(Theme{
Name: RealWorld,
PanelBG: black,
StatusText: Ink,
FlashText: Amber,
VerbButtonBG: RGB(0x1E1A14),
VerbButtonSelectedBG: AmberLo,
VerbButtonText: Ink,
InventorySlotBG: RGB(0x1E1A14),
InventorySlotSelectedBG: AmberLo,
SpeechBubbleBG: RGBA(0x14120E, 0xDC),
SpeechDefaultText: Ink,
DialogBG: RGBA(0x0D0B08, 0xF0),
DialogBorder: AmberLo,
DialogChoiceBG: RGB(0x1E1A14),
DialogChoiceHover: Amber,
DialogSpeaker: Amber,
DialogText: Ink,
EndCardBG: RGBA(0x000000, 0xFA),
EndCardText: Ink,
CursorColor: Amber,
HotspotOutline: RGB(0x7A6A44),
SceneBackdrop: sceneBG,
TopBarBG: panel,
TopBarText: InkDim,
TopBarAccent: Amber,
ChatLogBG: panel,
ChatLogPrompt: InkDim,
ChatLogResponse: Amber,
ChatLogSystem: RGB(0x6B6353),
CharacterPanelBG: panel,
CharacterPanelBorder: AmberLo,
CharacterPanelTitle: Amber,
})
}
+8 -9
View File
@@ -7,26 +7,25 @@ import (
"github.com/hajimehoshi/ebiten/v2/vector"
)
type Letterbox struct {
type letterbox struct {
Name string
W *World
Bar float64
}
func (l *Letterbox) GetName() string { return l.Name }
func (l *letterbox) GetName() string { return l.Name }
func (l *Letterbox) Tick(ctx *inkwell.UICtx) {
if l.W.Mode() != ModeCutscene || !l.W.TapeWaiting() {
func (l *letterbox) Tick(ctx *inkwell.UICtx) {
if World.Mode() != ModeCutscene || !World.TapeWaiting() {
return
}
if inpututil.IsKeyJustPressed(ebiten.KeySpace) {
l.W.TakeTapeOffer()
World.TakeTapeOffer()
}
}
func (l *Letterbox) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
if l.W.Mode() != ModeCutscene {
func (l *letterbox) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
if World.Mode() != ModeCutscene {
return
}
g := ctx.Game
@@ -40,7 +39,7 @@ func (l *Letterbox) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
vector.DrawFilledRect(dst, 0, 0, w, float32(bar), black, false)
vector.DrawFilledRect(dst, 0, h-float32(bar), w, float32(bar), black, false)
if l.W.TapeWaiting() {
if World.TapeWaiting() {
msg := "SPACE — " + TapeDisplayName(Dex) + " has something to say"
drawTextC(dst, msg, g.Width-textW(msg)-4, g.Height-int(bar)+4, th.ChatLogResponse)
}
+17 -27
View File
@@ -27,20 +27,17 @@ const (
invGap = 4
)
func registerUI(w *World) {
g := w.G
func registerUI() {
g := World.G
g.UIManager.Register(&UseWithGuard{
g.UIManager.Register(&useWithGuard{
Name: "usewith_guard",
W: w,
})
g.UIManager.Register(&ActionPump{
g.UIManager.Register(&actionPump{
Name: "pump",
W: w,
})
g.UIManager.Register(&screenNav{
Name: "screen_nav",
W: w,
})
g.UIManager.Register(&windowSizer{
Name: "window",
@@ -55,26 +52,24 @@ func registerUI(w *World) {
Height: TopBarH,
TimeVar: VarArmillaStrip,
}
w.SetTopBar(top)
g.UIManager.Register(gated(w, "topbar_gate", top))
World.SetTopBar(top)
g.UIManager.Register(gated("topbar_gate", top))
g.UIManager.Register(&Letterbox{
g.UIManager.Register(&letterbox{
Name: "letterbox",
W: w,
Bar: 36,
})
g.UIManager.Register(&hudFrame{
Name: "hudframe",
W: w,
})
g.UIManager.Register(gated(w, "status_gate", &inkwell.StatusLine{
g.UIManager.Register(gated("status_gate", &inkwell.StatusLine{
Name: "status",
Y: statusY,
Align: inkwell.AlignLeft,
ScreenWidth: DividerX,
}))
g.UIManager.Register(gated(w, "inventory_gate", &inkwell.InventoryBar{
g.UIManager.Register(gated("inventory_gate", &inkwell.InventoryBar{
Name: "inventory",
Origin: inkwell.Point{
X: Pad + 2,
@@ -85,14 +80,12 @@ func registerUI(w *World) {
SlotSize: invSlot,
Gap: invGap,
}))
g.UIManager.Register(&TapeSlots{
g.UIManager.Register(&tapeSlots{
Name: "tapes",
W: w,
Bounds: inkwell.Rect(192, slotsY, 194, slotsH),
})
g.UIManager.Register(&TapeChannel{
g.UIManager.Register(&tapeChannel{
Name: "channel",
W: w,
Bounds: inkwell.Rect(DividerX+2, HUDTop+2, ScreenW-DividerX-4, ScreenH-HUDTop-4),
})
@@ -150,14 +143,12 @@ func (s *windowSizer) Tick(ctx *inkwell.UICtx) {
type gate struct {
Name string
W *World
Inner inkwell.Widget
}
func gated(w *World, name string, inner inkwell.Widget) inkwell.Widget {
func gated(name string, inner inkwell.Widget) inkwell.Widget {
return &gate{
Name: name,
W: w,
Inner: inner,
}
}
@@ -165,19 +156,19 @@ func gated(w *World, name string, inner inkwell.Widget) inkwell.Widget {
func (n *gate) GetName() string { return n.Name }
func (n *gate) Tick(ctx *inkwell.UICtx) {
if n.W.HUDVisible() {
if World.HUDVisible() {
n.Inner.Tick(ctx)
}
}
func (n *gate) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
if n.W.HUDVisible() {
if World.HUDVisible() {
n.Inner.Draw(dst, ctx)
}
}
func (n *gate) BlocksClickAt(p inkwell.Point) bool {
if !n.W.HUDVisible() {
if !World.HUDVisible() {
return false
}
b, ok := n.Inner.(interface{ BlocksClickAt(inkwell.Point) bool })
@@ -186,14 +177,13 @@ func (n *gate) BlocksClickAt(p inkwell.Point) bool {
type hudFrame struct {
Name string
W *World
}
func (h *hudFrame) GetName() string { return h.Name }
func (h *hudFrame) Tick(ctx *inkwell.UICtx) {}
func (h *hudFrame) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
if !h.W.HUDVisible() {
if !World.HUDVisible() {
return
}
th := ctx.Game.Theme()
@@ -205,5 +195,5 @@ func (h *hudFrame) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
}
func (h *hudFrame) BlocksClickAt(p inkwell.Point) bool {
return h.W.HUDVisible() && p.Y >= HUDTop
return World.HUDVisible() && p.Y >= HUDTop
}
+3 -4
View File
@@ -8,14 +8,13 @@ import (
type screenNav struct {
Name string
W *World
}
func (n *screenNav) GetName() string { return n.Name }
func (n *screenNav) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {}
func (n *screenNav) Tick(ctx *inkwell.UICtx) {
if !n.W.HUDVisible() || n.W.Paused() {
if !World.HUDVisible() || World.Paused() {
return
}
step := 0
@@ -29,7 +28,7 @@ func (n *screenNav) Tick(ctx *inkwell.UICtx) {
return
}
if next := n.neighbour(ctx.Game, step); next != "" {
n.W.Do(inkwell.GoTo(next))
World.Do(inkwell.GoTo(next))
}
}
@@ -39,7 +38,7 @@ func (n *screenNav) neighbour(g *inkwell.Game, step int) string {
return ""
}
for i, name := range deck {
if name == n.W.Scene() {
if name == World.Scene() {
return deck[((i+step)%len(deck)+len(deck))%len(deck)]
}
}
+8 -9
View File
@@ -8,22 +8,21 @@ import (
"github.com/hajimehoshi/ebiten/v2/vector"
)
type TapeChannel struct {
type tapeChannel struct {
Name string
W *World
Bounds inkwell.Rectangle
}
func (t *TapeChannel) GetName() string { return t.Name }
func (t *tapeChannel) GetName() string { return t.Name }
func (t *TapeChannel) Tick(ctx *inkwell.UICtx) {}
func (t *tapeChannel) Tick(ctx *inkwell.UICtx) {}
func (t *TapeChannel) BlocksClickAt(p inkwell.Point) bool {
return t.W.HUDVisible() && t.Bounds.Contains(p)
func (t *tapeChannel) BlocksClickAt(p inkwell.Point) bool {
return World.HUDVisible() && t.Bounds.Contains(p)
}
func (t *TapeChannel) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
if !t.W.HUDVisible() {
func (t *tapeChannel) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
if !World.HUDVisible() {
return
}
g := ctx.Game
@@ -84,7 +83,7 @@ func (t *TapeChannel) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
}
}
func (t *TapeChannel) lastSpeaker(g *inkwell.Game, th inkwell.Theme) (string, color.Color) {
func (t *tapeChannel) lastSpeaker(g *inkwell.Game, th inkwell.Theme) (string, color.Color) {
msgs := g.Messages()
for i := len(msgs) - 1; i >= 0; i-- {
m := msgs[i]
+23 -24
View File
@@ -6,26 +6,25 @@ import (
"github.com/hajimehoshi/ebiten/v2/vector"
)
type TapeSlots struct {
type tapeSlots struct {
Name string
W *World
Bounds inkwell.Rectangle
}
func (t *TapeSlots) GetName() string { return t.Name }
func (t *tapeSlots) GetName() string { return t.Name }
func (t *TapeSlots) BlocksClickAt(p inkwell.Point) bool {
return t.W.HUDVisible() && t.Bounds.Contains(p)
func (t *tapeSlots) BlocksClickAt(p inkwell.Point) bool {
return World.HUDVisible() && t.Bounds.Contains(p)
}
func (t *TapeSlots) slotRects() (inkwell.Rectangle, inkwell.Rectangle) {
func (t *tapeSlots) slotRects() (inkwell.Rectangle, inkwell.Rectangle) {
b := t.Bounds
w := (b.W - Pad) / 2
return inkwell.Rect(b.X, b.Y, w, b.H), inkwell.Rect(b.X+w+Pad, b.Y, w, b.H)
}
func (t *TapeSlots) Tick(ctx *inkwell.UICtx) {
if !t.W.HUDVisible() {
func (t *tapeSlots) Tick(ctx *inkwell.UICtx) {
if !World.HUDVisible() {
return
}
g := ctx.Game
@@ -36,7 +35,7 @@ func (t *TapeSlots) Tick(ctx *inkwell.UICtx) {
case r1.Contains(mp):
g.SetHoverLabel(TapeDisplayName(Dex))
case r2.Contains(mp):
if s := t.W.Slot2(); s != "" {
if s := World.Slot2(); s != "" {
g.SetHoverLabel(itemLabel(g, s))
} else {
g.SetHoverLabel("empty tape slot")
@@ -57,45 +56,45 @@ func (t *TapeSlots) Tick(ctx *inkwell.UICtx) {
if slot2 && sel != "" {
g.Inventory.Select("")
if IsTapeItem(sel) {
t.W.SetPending(sel)
t.W.Do(inkwell.RunScript(ScriptTapeInsert))
World.SetPending(sel)
World.Do(inkwell.RunScript(ScriptTapeInsert))
return
}
t.W.Do(TapeSay(Dex, "That isn't a tape, Paul. That's an object. There is a difference."))
World.Do(TapeSay(Dex, "That isn't a tape, Paul. That's an object. There is a difference."))
return
}
if !slot2 && sel != "" {
g.Inventory.Select("")
t.W.Do(TapeSay(Dex, "The first slot is mine. I'm not moving."))
World.Do(TapeSay(Dex, "The first slot is mine. I'm not moving."))
return
}
switch g.SelectedVerb() {
case "talk":
if !slot2 {
t.W.Do(Paused(t.W, inkwell.RunDialogue(DlgDex)))
World.Do(Paused(inkwell.RunDialogue(DlgDex)))
return
}
if s := t.W.Slot2(); s != "" {
t.W.Do(Paused(t.W, inkwell.RunDialogue(TapeDialogue(s))))
if s := World.Slot2(); s != "" {
World.Do(Paused(inkwell.RunDialogue(TapeDialogue(s))))
return
}
t.W.Do(TapeSay(Dex, "Empty. Nobody to talk to."))
World.Do(TapeSay(Dex, "Empty. Nobody to talk to."))
default:
if !slot2 {
t.W.Do(TapeSay(Dex, "Me. Four kilobytes of a dead man. Be grateful."))
World.Do(TapeSay(Dex, "Me. Four kilobytes of a dead man. Be grateful."))
return
}
if s := t.W.Slot2(); s != "" {
t.W.Do(TapeSay(Dex, "That is the second slot. Be careful what you let in."))
if s := World.Slot2(); s != "" {
World.Do(TapeSay(Dex, "That is the second slot. Be careful what you let in."))
return
}
t.W.Do(TapeSay(Dex, "The second slot is empty. That's the rarer state."))
World.Do(TapeSay(Dex, "The second slot is empty. That's the rarer state."))
}
}
func (t *TapeSlots) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
if !t.W.HUDVisible() {
func (t *tapeSlots) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
if !World.HUDVisible() {
return
}
g := ctx.Game
@@ -116,7 +115,7 @@ func (t *TapeSlots) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {
}
drawSlot(r1, "SLOT 1", TapeDisplayName(Dex), true)
if s := t.W.Slot2(); s != "" {
if s := World.Slot2(); s != "" {
drawSlot(r2, "SLOT 2", itemLabel(g, s), true)
} else {
drawSlot(r2, "SLOT 2", "empty", false)
+6 -7
View File
@@ -7,17 +7,16 @@ import (
"github.com/hajimehoshi/ebiten/v2"
)
type UseWithGuard struct {
type useWithGuard struct {
Name string
W *World
}
func (u *UseWithGuard) GetName() string { return u.Name }
func (u *UseWithGuard) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {}
func (u *useWithGuard) GetName() string { return u.Name }
func (u *useWithGuard) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {}
func (u *UseWithGuard) Tick(ctx *inkwell.UICtx) {
func (u *useWithGuard) Tick(ctx *inkwell.UICtx) {
g := ctx.Game
if !u.W.HUDVisible() || !g.Input.LeftClicked() {
if !World.HUDVisible() || !g.Input.LeftClicked() {
return
}
sel := g.Inventory.Selected()
@@ -42,7 +41,7 @@ func (u *UseWithGuard) Tick(ctx *inkwell.UICtx) {
g.State.NoteTalked(key)
n := g.State.Talked(key)
u.W.Do(inkwell.Seq(
World.Do(inkwell.Seq(
inkwell.Say(Paul, pick(paulFails, n)),
TapeSay(Dex, dexFail(n)),
))
+23 -26
View File
@@ -5,13 +5,13 @@ import (
"github.com/hajimehoshi/ebiten/v2"
)
func (w *World) Do(a inkwell.Action) {
func (w *world) Do(a inkwell.Action) {
if a != nil {
w.queue = append(w.queue, a)
}
}
func (w *World) PumpTick(dt float64) {
func (w *world) PumpTick(dt float64) {
if w.top != nil {
title := w.sceneTitle()
@@ -40,7 +40,7 @@ func (w *World) PumpTick(dt float64) {
}
}
func (w *World) sceneTitle() string {
func (w *world) sceneTitle() string {
s, ok := w.G.SceneManager.Get(w.scene)
if !ok {
return ""
@@ -51,14 +51,13 @@ func (w *World) sceneTitle() string {
return s.Name
}
type ActionPump struct {
type actionPump struct {
Name string
W *World
}
func (p *ActionPump) GetName() string { return p.Name }
func (p *ActionPump) Tick(ctx *inkwell.UICtx) { p.W.PumpTick(ctx.DT) }
func (p *ActionPump) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {}
func (p *actionPump) GetName() string { return p.Name }
func (p *actionPump) Tick(ctx *inkwell.UICtx) { World.PumpTick(ctx.DT) }
func (p *actionPump) Draw(dst *ebiten.Image, ctx *inkwell.UICtx) {}
type fnAction struct{ fn func(*inkwell.Ctx) }
@@ -85,25 +84,25 @@ func UseTheme(name string) inkwell.Action {
return Fn(func(ctx *inkwell.Ctx) { ctx.Game.UseTheme(name) })
}
func SetMode(w *World, m Mode) inkwell.Action {
return Fn(func(*inkwell.Ctx) { w.SetMode(m) })
func SetMode(m Mode) inkwell.Action {
return Fn(func(*inkwell.Ctx) { World.SetMode(m) })
}
func EnterScene(w *World, name string) inkwell.Action {
func EnterScene(name string) inkwell.Action {
return Fn(func(*inkwell.Ctx) {
if name != w.scene {
w.prev = w.scene
if name != World.scene {
World.prev = World.scene
}
w.scene = name
World.scene = name
})
}
func Back(w *World) inkwell.Action {
func Back() inkwell.Action {
return Fn(func(ctx *inkwell.Ctx) {
if w.prev == "" {
if World.prev == "" {
return
}
inkwell.GoTo(w.prev).Start().Tick(ctx)
inkwell.GoTo(World.prev).Start().Tick(ctx)
})
}
@@ -143,14 +142,14 @@ func (r *tapeSayRunner) Tick(ctx *inkwell.Ctx) inkwell.Status {
return inkwell.StatusRunning
}
func TapeOffer(w *World, line inkwell.Action) inkwell.Action {
func TapeOffer(line inkwell.Action) inkwell.Action {
return Fn(func(*inkwell.Ctx) {
w.tapeLine = line
w.tapeWaiting = true
World.tapeLine = line
World.tapeWaiting = true
})
}
func (w *World) TakeTapeOffer() {
func (w *world) TakeTapeOffer() {
if !w.tapeWaiting {
return
}
@@ -160,15 +159,13 @@ func (w *World) TakeTapeOffer() {
w.Do(line)
}
func Paused(w *World, inner inkwell.Action) inkwell.Action {
func Paused(inner inkwell.Action) inkwell.Action {
return &pausedAction{
w: w,
inner: inner,
}
}
type pausedAction struct {
w *World
inner inkwell.Action
}
@@ -188,11 +185,11 @@ type pausedRunner struct {
func (r *pausedRunner) Tick(ctx *inkwell.Ctx) inkwell.Status {
if !r.started {
r.started = true
r.spec.w.paused = true
World.paused = true
}
s := r.inner.Tick(ctx)
if s != inkwell.StatusRunning {
r.spec.w.paused = false
World.paused = false
}
return s
}
+27 -18
View File
@@ -12,7 +12,7 @@ const (
ModeMenu Mode = "menu"
)
type World struct {
type world struct {
G *inkwell.Game
mode Mode
@@ -29,42 +29,51 @@ type World struct {
tapeLine inkwell.Action
}
func newWorld(g *inkwell.Game) *World {
return &World{
G: g,
mode: ModePlay,
}
var World = &world{}
func (w *world) attach(g *inkwell.Game) {
w.G = g
w.mode = ModePlay
w.scene = ""
w.prev = ""
w.paused = false
w.pending = ""
w.queue = nil
w.running = nil
w.top = nil
w.tapeWaiting = false
w.tapeLine = nil
}
func (w *World) Mode() Mode { return w.mode }
func (w *world) Mode() Mode { return w.mode }
func (w *World) SetMode(m Mode) { w.mode = m }
func (w *world) SetMode(m Mode) { w.mode = m }
func (w *World) HUDVisible() bool { return w.mode == ModePlay }
func (w *world) HUDVisible() bool { return w.mode == ModePlay }
func (w *World) Scene() string { return w.scene }
func (w *world) Scene() string { return w.scene }
func (w *World) Previous() string { return w.prev }
func (w *world) Previous() string { return w.prev }
func (w *World) Paused() bool { return w.paused }
func (w *world) Paused() bool { return w.paused }
func (w *World) SetTopBar(t *inkwell.TopBar) { w.top = t }
func (w *world) SetTopBar(t *inkwell.TopBar) { w.top = t }
func (w *World) Slot2() string {
func (w *world) Slot2() string {
if v, ok := w.G.State.Var(VarSlot2).(string); ok {
return v
}
return ""
}
func (w *World) SetSlot2(item string) { w.G.State.SetVar(VarSlot2, item) }
func (w *world) SetSlot2(item string) { w.G.State.SetVar(VarSlot2, item) }
func (w *World) SetPending(item string) { w.pending = item }
func (w *world) SetPending(item string) { w.pending = item }
func (w *World) TakePending() string {
func (w *world) TakePending() string {
item := w.pending
w.pending = ""
return item
}
func (w *World) TapeWaiting() bool { return w.tapeWaiting }
func (w *world) TapeWaiting() bool { return w.tapeWaiting }