initial commit
This commit is contained in:
29
domain/build_test.go
Normal file
29
domain/build_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package domain
|
||||
|
||||
import "testing"
|
||||
|
||||
// TestBuildValidates is the headless smoke test described in PLAN.md:
|
||||
// it composes the full game and asks the library to cross-check every
|
||||
// name reference between managers. No window opens.
|
||||
func TestBuildValidates(t *testing.T) {
|
||||
g := Build()
|
||||
if err := g.Validate(); err != nil {
|
||||
t.Fatalf("validate: %v", err)
|
||||
}
|
||||
for _, name := range []string{"bedroom", "kitchen"} {
|
||||
if !g.SceneManager.Has(name) {
|
||||
t.Errorf("missing scene %q", name)
|
||||
}
|
||||
}
|
||||
for _, name := range []string{"key", "beans", "mug"} {
|
||||
if !g.ItemManager.Has(name) {
|
||||
t.Errorf("missing item %q", name)
|
||||
}
|
||||
}
|
||||
if !g.DialogueManager.Has("cat_morning") {
|
||||
t.Errorf("missing dialogue cat_morning")
|
||||
}
|
||||
if !g.ScriptManager.Has("intro") || !g.ScriptManager.Has("victory") {
|
||||
t.Errorf("missing intro/victory script")
|
||||
}
|
||||
}
|
||||
18
domain/character.cat.go
Normal file
18
domain/character.cat.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
|
||||
p "git.teletypegames.org/games/pncdsl"
|
||||
)
|
||||
|
||||
func defineCat(g *p.Game) {
|
||||
g.CharacterManager.Register(p.Character{
|
||||
Name: "cat",
|
||||
Sprite: "spr/cat",
|
||||
Speed: 40,
|
||||
SpeechColor: color.RGBA{200, 200, 255, 255},
|
||||
W: 34,
|
||||
H: 20,
|
||||
})
|
||||
}
|
||||
18
domain/character.player.go
Normal file
18
domain/character.player.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
|
||||
p "git.teletypegames.org/games/pncdsl"
|
||||
)
|
||||
|
||||
func definePlayer(g *p.Game) {
|
||||
g.CharacterManager.Register(p.Character{
|
||||
Name: "player",
|
||||
Sprite: "spr/player",
|
||||
Speed: 80,
|
||||
SpeechColor: color.RGBA{255, 230, 160, 255},
|
||||
W: 28,
|
||||
H: 62,
|
||||
})
|
||||
}
|
||||
45
domain/dialog.cat_morning.go
Normal file
45
domain/dialog.cat_morning.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
func defineCatMorning(g *p.Game) {
|
||||
g.DialogueManager.Register(p.Dialogue{
|
||||
Name: "cat_morning",
|
||||
Start: "start",
|
||||
Nodes: []p.DialogueNode{
|
||||
{
|
||||
Name: "start",
|
||||
Lines: []p.DialogueLine{
|
||||
{Speaker: "cat", Text: "Mióóóóóóóóu. Késő van."},
|
||||
},
|
||||
Choices: []p.DialogueChoice{
|
||||
{
|
||||
Text: "Mindjárt megy a kávé.",
|
||||
Actions: []p.Action{p.SetFlag(FlagPromisedCoffee), p.EndDialogue()},
|
||||
},
|
||||
{
|
||||
Text: "Te etted meg a babot?",
|
||||
Show: p.Not(p.Flag(FlagCupboardOpen)),
|
||||
Actions: []p.Action{p.GotoNode("beans")},
|
||||
},
|
||||
{
|
||||
Text: "Hagyj békén.",
|
||||
Actions: []p.Action{p.EndDialogue()},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "beans",
|
||||
Lines: []p.DialogueLine{
|
||||
{Speaker: "cat", Text: "A szekrényben van. Mindig ott szokott lenni."},
|
||||
},
|
||||
Choices: []p.DialogueChoice{
|
||||
{
|
||||
Text: "Köszi.",
|
||||
Actions: []p.Action{p.EndDialogue()},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
31
domain/domain.asset.go
Normal file
31
domain/domain.asset.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
// registerAssets declares every asset the game references. Files don't
|
||||
// need to exist on disk — the library will substitute deterministic
|
||||
// colored placeholders for anything missing.
|
||||
func registerAssets(g *p.Game) {
|
||||
imgs := []string{
|
||||
"bg/bedroom", "bg/kitchen",
|
||||
"spr/key", "spr/beans", "spr/mug",
|
||||
"spr/player", "spr/cat",
|
||||
}
|
||||
for _, name := range imgs {
|
||||
g.AssetManager.Register(p.Asset{
|
||||
Name: name,
|
||||
Path: "assets/" + name + ".png",
|
||||
Kind: p.AssetImage,
|
||||
})
|
||||
}
|
||||
audios := []string{
|
||||
"mus/wakeup", "mus/calm", "snd/coffee_done",
|
||||
}
|
||||
for _, name := range audios {
|
||||
g.AssetManager.Register(p.Asset{
|
||||
Name: name,
|
||||
Path: "assets/" + name + ".ogg",
|
||||
Kind: p.AssetAudio,
|
||||
})
|
||||
}
|
||||
}
|
||||
10
domain/domain.flag.go
Normal file
10
domain/domain.flag.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package domain
|
||||
|
||||
const (
|
||||
FlagKeyTaken = "key_taken"
|
||||
FlagCupboardOpen = "cupboard_open"
|
||||
FlagMugTaken = "mug_taken"
|
||||
FlagCoffeeHasBeans = "coffee_has_beans"
|
||||
FlagCoffeeHasMug = "coffee_has_mug"
|
||||
FlagPromisedCoffee = "promised_coffee"
|
||||
)
|
||||
46
domain/game.go
Normal file
46
domain/game.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
// Build assembles the full Reggeli Kávé game by registering every entity
|
||||
// into its matching manager on a fresh *Game. The order matters only for
|
||||
// readability — Validate() runs after Build to cross-check references.
|
||||
func Build() *p.Game {
|
||||
g := p.NewGame("Reggeli Kávé", 320, 200)
|
||||
|
||||
registerAssets(g)
|
||||
|
||||
definePlayer(g)
|
||||
defineCat(g)
|
||||
|
||||
defineKey(g)
|
||||
defineBeans(g)
|
||||
defineMug(g)
|
||||
|
||||
defineCatMorning(g)
|
||||
|
||||
defineIntroScript(g)
|
||||
defineVictoryScript(g)
|
||||
|
||||
defineBedroom(g)
|
||||
defineKitchen(g)
|
||||
|
||||
// Story-rich HUD: top bar + NPC character panel + chat log + permanent
|
||||
// verb wheel + small inventory. The player panel is skipped — the
|
||||
// player avatar is always visible in the scene, so the floating card
|
||||
// in the corner just gets in the way. Pass "player" as the second
|
||||
// arg to put it back.
|
||||
p.RegisterRichUI(g, "", "cat")
|
||||
g.MaxLogLines = 64
|
||||
|
||||
// initial HUD vars
|
||||
g.State.SetVar("score", 0)
|
||||
g.State.SetVar("time", "Nap 1 - 07:23")
|
||||
g.State.SetVar("player.state", "Ébren")
|
||||
g.State.SetVar("player.mood", "Álmos")
|
||||
g.State.SetVar("cat.state", "Várakozik")
|
||||
g.State.SetVar("cat.mood", "Türelmetlen")
|
||||
|
||||
g.StartAt("bedroom").OnStart(p.RunScript("intro"))
|
||||
return g
|
||||
}
|
||||
11
domain/item.beans.go
Normal file
11
domain/item.beans.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
func defineBeans(g *p.Game) {
|
||||
g.ItemManager.Register(p.Item{
|
||||
Name: "beans",
|
||||
Sprite: "spr/beans",
|
||||
Description: "őrölt kávébab",
|
||||
})
|
||||
}
|
||||
20
domain/item.key.go
Normal file
20
domain/item.key.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
func defineKey(g *p.Game) {
|
||||
g.ItemManager.Register(p.Item{
|
||||
Name: "key",
|
||||
Sprite: "spr/key",
|
||||
Description: "rozsdás kulcs",
|
||||
OnUseWith: map[string]p.Action{
|
||||
"cupboard": p.Seq(
|
||||
p.Say("player", "Klikk."),
|
||||
p.SetFlag(FlagCupboardOpen),
|
||||
p.Give("beans"),
|
||||
p.TakeAway("key"),
|
||||
p.Say("player", "Bab van benne. Pont, ami kell."),
|
||||
),
|
||||
},
|
||||
})
|
||||
}
|
||||
11
domain/item.mug.go
Normal file
11
domain/item.mug.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
func defineMug(g *p.Game) {
|
||||
g.ItemManager.Register(p.Item{
|
||||
Name: "mug",
|
||||
Sprite: "spr/mug",
|
||||
Description: "kedvenc bögréje",
|
||||
})
|
||||
}
|
||||
61
domain/scene.bedroom.go
Normal file
61
domain/scene.bedroom.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
func defineBedroom(g *p.Game) {
|
||||
g.SceneManager.Register(p.Scene{
|
||||
Name: "bedroom",
|
||||
Title: "Hálószoba",
|
||||
Background: "bg/bedroom",
|
||||
Music: "mus/wakeup",
|
||||
Actors: []p.SceneActor{
|
||||
{CharacterName: "player", At: p.Point{X: 160, Y: 145}},
|
||||
},
|
||||
Hotspots: []p.Hotspot{
|
||||
{
|
||||
Name: "bed",
|
||||
Area: p.Rect(20, 70, 90, 60),
|
||||
Label: "ágy",
|
||||
OnLook: p.Say("player", "A párnám még meleg."),
|
||||
OnUse: p.Say("player", "Most keltem fel. Nem alszom vissza."),
|
||||
},
|
||||
{
|
||||
Name: "nightstand",
|
||||
Area: p.Rect(115, 80, 35, 50),
|
||||
Label: "éjjeliszekrény",
|
||||
OnLook: p.If(p.Flag(FlagKeyTaken),
|
||||
p.Say("player", "Üres a tetején."),
|
||||
p.Say("player", "Egy rozsdás kulcs az éjjeliszekrényemen."),
|
||||
),
|
||||
OnTake: p.If(p.Flag(FlagKeyTaken),
|
||||
p.Say("player", "Már elvittem."),
|
||||
p.Seq(
|
||||
p.Walk("player", p.Point{X: 130, Y: 145}),
|
||||
p.Give("key"),
|
||||
p.SetFlag(FlagKeyTaken),
|
||||
p.Say("player", "Pont jól jöhet."),
|
||||
),
|
||||
),
|
||||
OnUse: p.If(p.Flag(FlagKeyTaken),
|
||||
p.Say("player", "Már elvittem a kulcsot."),
|
||||
p.Seq(
|
||||
p.Walk("player", p.Point{X: 130, Y: 145}),
|
||||
p.Give("key"),
|
||||
p.SetFlag(FlagKeyTaken),
|
||||
p.Say("player", "Megvan a kulcs."),
|
||||
),
|
||||
),
|
||||
},
|
||||
{
|
||||
Name: "door",
|
||||
Area: p.Rect(260, 50, 40, 90),
|
||||
Label: "ajtó",
|
||||
OnLook: p.Say("player", "Az ajtó a konyhába vezet."),
|
||||
OnUse: p.Seq(
|
||||
p.Walk("player", p.Point{X: 260, Y: 145}),
|
||||
p.GoTo("kitchen"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
115
domain/scene.kitchen.go
Normal file
115
domain/scene.kitchen.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
func defineKitchen(g *p.Game) {
|
||||
g.SceneManager.Register(p.Scene{
|
||||
Name: "kitchen",
|
||||
Title: "Konyha",
|
||||
Background: "bg/kitchen",
|
||||
Music: "mus/calm",
|
||||
Actors: []p.SceneActor{
|
||||
{CharacterName: "player", At: p.Point{X: 60, Y: 145}},
|
||||
{CharacterName: "cat", At: p.Point{X: 215, Y: 142}},
|
||||
},
|
||||
Hotspots: []p.Hotspot{
|
||||
{
|
||||
Name: "cupboard",
|
||||
Area: p.Rect(30, 40, 80, 80),
|
||||
Label: "szekrény",
|
||||
OnLook: p.Say("player", "Konyhaszekrény. Zárva."),
|
||||
OnUse: p.If(p.Flag(FlagCupboardOpen),
|
||||
p.Say("player", "Már nyitva van."),
|
||||
p.If(p.HasItem("key"),
|
||||
p.Seq(
|
||||
p.Walk("player", p.Point{X: 70, Y: 145}),
|
||||
p.Say("player", "Klikk."),
|
||||
p.SetFlag(FlagCupboardOpen),
|
||||
p.Give("beans"),
|
||||
p.TakeAway("key"),
|
||||
),
|
||||
p.Say("player", "Zárva. Kéne egy kulcs."),
|
||||
),
|
||||
),
|
||||
OnUseWith: map[string]p.Action{
|
||||
"key": p.Seq(
|
||||
p.Walk("player", p.Point{X: 70, Y: 145}),
|
||||
p.Say("player", "Klikk."),
|
||||
p.SetFlag(FlagCupboardOpen),
|
||||
p.Give("beans"),
|
||||
p.TakeAway("key"),
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "shelf",
|
||||
Area: p.Rect(115, 45, 35, 50),
|
||||
Label: "polc",
|
||||
OnLook: p.Say("player", "A polc tele bögrékkel."),
|
||||
OnTake: p.If(p.Flag(FlagMugTaken),
|
||||
p.Say("player", "Tiszta már mind elfogyott."),
|
||||
p.Seq(
|
||||
p.Walk("player", p.Point{X: 125, Y: 145}),
|
||||
p.Give("mug"),
|
||||
p.SetFlag(FlagMugTaken),
|
||||
p.Say("player", "Egy bögre, kérem."),
|
||||
),
|
||||
),
|
||||
OnUse: p.If(p.Flag(FlagMugTaken),
|
||||
p.Say("player", "Már elvettem egyet."),
|
||||
p.Seq(
|
||||
p.Walk("player", p.Point{X: 125, Y: 145}),
|
||||
p.Give("mug"),
|
||||
p.SetFlag(FlagMugTaken),
|
||||
p.Say("player", "Egy bögre, kérem."),
|
||||
),
|
||||
),
|
||||
},
|
||||
{
|
||||
Name: "coffee_machine",
|
||||
Area: p.Rect(160, 75, 50, 55),
|
||||
Label: "kávéfőző",
|
||||
OnLook: p.Say("player", "A jó öreg kávéfőző."),
|
||||
OnUse: p.If(p.And(p.Flag(FlagCoffeeHasBeans), p.Flag(FlagCoffeeHasMug)),
|
||||
p.RunScript("victory"),
|
||||
p.Say("player", "Még hiányzik valami. Bab? Bögre?"),
|
||||
),
|
||||
OnUseWith: map[string]p.Action{
|
||||
"beans": p.Seq(
|
||||
p.Walk("player", p.Point{X: 180, Y: 145}),
|
||||
p.SetFlag(FlagCoffeeHasBeans),
|
||||
p.TakeAway("beans"),
|
||||
p.Say("player", "Bab a helyén."),
|
||||
p.If(p.And(p.Flag(FlagCoffeeHasBeans), p.Flag(FlagCoffeeHasMug)),
|
||||
p.RunScript("victory")),
|
||||
),
|
||||
"mug": p.Seq(
|
||||
p.Walk("player", p.Point{X: 180, Y: 145}),
|
||||
p.SetFlag(FlagCoffeeHasMug),
|
||||
p.TakeAway("mug"),
|
||||
p.Say("player", "Bögre a helyén."),
|
||||
p.If(p.And(p.Flag(FlagCoffeeHasBeans), p.Flag(FlagCoffeeHasMug)),
|
||||
p.RunScript("victory")),
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "cat",
|
||||
Area: p.Rect(195, 118, 35, 22),
|
||||
Label: "Cirmos",
|
||||
OnLook: p.Say("player", "Cirmos, a házikedvencem."),
|
||||
OnTalk: p.RunDialogue("cat_morning"),
|
||||
},
|
||||
{
|
||||
Name: "door",
|
||||
Area: p.Rect(0, 40, 22, 90),
|
||||
Label: "ajtó",
|
||||
OnLook: p.Say("player", "Vissza a hálóba."),
|
||||
OnUse: p.Seq(
|
||||
p.Walk("player", p.Point{X: 20, Y: 145}),
|
||||
p.GoTo("bedroom"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
16
domain/script.intro.go
Normal file
16
domain/script.intro.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
func defineIntroScript(g *p.Game) {
|
||||
g.ScriptManager.Register(p.Script{
|
||||
Name: "intro",
|
||||
Actions: p.Seq(
|
||||
p.Wait(0.4),
|
||||
p.Say("player", "Brr, hideg van."),
|
||||
p.Say("player", "Egy kávé kéne, mielőtt szétszakad a fejem."),
|
||||
p.Walk("player", p.Point{X: 200, Y: 145}),
|
||||
p.SetVar("player.mood", "Eltökélt"),
|
||||
),
|
||||
})
|
||||
}
|
||||
20
domain/script.victory.go
Normal file
20
domain/script.victory.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package domain
|
||||
|
||||
import p "git.teletypegames.org/games/pncdsl"
|
||||
|
||||
func defineVictoryScript(g *p.Game) {
|
||||
g.ScriptManager.Register(p.Script{
|
||||
Name: "victory",
|
||||
Actions: p.Seq(
|
||||
p.Say("player", "Készen is van!"),
|
||||
p.PlaySound("snd/coffee_done"),
|
||||
p.Wait(0.6),
|
||||
p.Say("cat", "Mióóóóu. *boldog macska*"),
|
||||
p.Say("player", "Reggeli kávé: megmentve."),
|
||||
p.SetVar("score", 100),
|
||||
p.SetVar("player.mood", "Boldog"),
|
||||
p.SetVar("cat.mood", "Boldog"),
|
||||
p.ShowEnd("Vége — kösz, hogy játszottál!"),
|
||||
),
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user