This commit is contained in:
2026-05-26 07:17:05 +02:00
parent 6895b69a1f
commit e893963743
27 changed files with 412 additions and 436 deletions

View File

@@ -1,18 +0,0 @@
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,
})
}

View File

@@ -1,18 +0,0 @@
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,
})
}

View File

@@ -1,45 +0,0 @@
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()},
},
},
},
},
})
}

View File

@@ -1,31 +0,0 @@
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,
})
}
}

View File

@@ -1,11 +0,0 @@
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",
})
}

View File

@@ -1,20 +0,0 @@
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."),
),
},
})
}

View File

@@ -1,11 +0,0 @@
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",
})
}

View File

@@ -1,72 +0,0 @@
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}},
},
// Floor strip — Walk targets get clipped to this band, so clicks
// on the bed or nightstand send the player to the floor in front
// of them instead of letting them clip through furniture.
Walkboxes: []p.Polygon{
p.Poly(
p.Point{X: 10, Y: 135},
p.Point{X: 310, Y: 135},
p.Point{X: 310, Y: 160},
p.Point{X: 10, Y: 160},
),
},
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"),
),
},
},
})
}

View File

@@ -1,137 +0,0 @@
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}},
},
// Floor strip. Same shape as the bedroom — keeps movement on a
// consistent Y band and clips destinations away from the cupboard
// and coffee machine.
Walkboxes: []p.Polygon{
p.Poly(
p.Point{X: 10, Y: 135},
p.Point{X: 310, Y: 135},
p.Point{X: 310, Y: 160},
p.Point{X: 10, Y: 160},
),
},
// First time the player walks into the kitchen with the key in
// hand, drop a hint. The trigger arms on scene enter; the
// rising-edge fires once per arming because Once: true.
Triggers: []p.Trigger{
{
Name: "kitchen_with_key_hint",
Once: true,
When: p.And(p.HasItem("key"), p.Not(p.Flag(FlagCupboardOpen))),
Do: p.Say("player", "A kulcs jól jöhet a szekrényhez."),
},
},
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"),
),
},
},
})
}

View File

@@ -1,16 +0,0 @@
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"),
),
})
}

View File

@@ -1,20 +0,0 @@
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!"),
),
})
}

20
lib/assets.go Normal file
View File

@@ -0,0 +1,20 @@
package lib
import p "git.teletypegames.org/games/pncdsl"
// Assets lists every asset the game references. Files don't need to
// exist on disk — the library substitutes deterministic colored
// placeholders for anything missing.
var Assets = []p.Asset{
{Name: "bg/bedroom", Path: "assets/bg/bedroom.png", Kind: p.AssetImage},
{Name: "bg/kitchen", Path: "assets/bg/kitchen.png", Kind: p.AssetImage},
{Name: "spr/key", Path: "assets/spr/key.png", Kind: p.AssetImage},
{Name: "spr/beans", Path: "assets/spr/beans.png", Kind: p.AssetImage},
{Name: "spr/mug", Path: "assets/spr/mug.png", Kind: p.AssetImage},
{Name: "spr/player", Path: "assets/spr/player.png", Kind: p.AssetImage},
{Name: "spr/cat", Path: "assets/spr/cat.png", Kind: p.AssetImage},
{Name: "mus/wakeup", Path: "assets/mus/wakeup.ogg", Kind: p.AssetAudio},
{Name: "mus/calm", Path: "assets/mus/calm.ogg", Kind: p.AssetAudio},
{Name: "snd/coffee_done", Path: "assets/snd/coffee_done.ogg", Kind: p.AssetAudio},
}

View File

@@ -1,10 +1,10 @@
package domain
package lib
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.
// TestBuildValidates is the headless smoke test: 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 {

16
lib/character.cat.go Normal file
View File

@@ -0,0 +1,16 @@
package lib
import (
"image/color"
p "git.teletypegames.org/games/pncdsl"
)
var Cat = p.Character{
Name: "cat",
Sprite: "spr/cat",
Speed: 40,
SpeechColor: color.RGBA{200, 200, 255, 255},
W: 34,
H: 20,
}

16
lib/character.player.go Normal file
View File

@@ -0,0 +1,16 @@
package lib
import (
"image/color"
p "git.teletypegames.org/games/pncdsl"
)
var Player = p.Character{
Name: "player",
Sprite: "spr/player",
Speed: 80,
SpeechColor: color.RGBA{255, 230, 160, 255},
W: 28,
H: 62,
}

43
lib/dialog.cat_morning.go Normal file
View File

@@ -0,0 +1,43 @@
package lib
import p "git.teletypegames.org/games/pncdsl"
var CatMorning = 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()},
},
},
},
},
}

View File

@@ -1,4 +1,4 @@
package domain
package lib
const (
FlagKeyTaken = "key_taken"

9
lib/item.beans.go Normal file
View File

@@ -0,0 +1,9 @@
package lib
import p "git.teletypegames.org/games/pncdsl"
var Beans = p.Item{
Name: "beans",
Sprite: "spr/beans",
Description: "őrölt kávébab",
}

18
lib/item.key.go Normal file
View File

@@ -0,0 +1,18 @@
package lib
import p "git.teletypegames.org/games/pncdsl"
var Key = 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."),
),
},
}

9
lib/item.mug.go Normal file
View File

@@ -0,0 +1,9 @@
package lib
import p "git.teletypegames.org/games/pncdsl"
var Mug = p.Item{
Name: "mug",
Sprite: "spr/mug",
Description: "kedvenc bögréje",
}

70
lib/scene.bedroom.go Normal file
View File

@@ -0,0 +1,70 @@
package lib
import p "git.teletypegames.org/games/pncdsl"
var Bedroom = 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}},
},
// Floor strip — Walk targets get clipped to this band, so clicks
// on the bed or nightstand send the player to the floor in front
// of them instead of letting them clip through furniture.
Walkboxes: []p.Polygon{
p.Poly(
p.Point{X: 10, Y: 135},
p.Point{X: 310, Y: 135},
p.Point{X: 310, Y: 160},
p.Point{X: 10, Y: 160},
),
},
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"),
),
},
},
}

135
lib/scene.kitchen.go Normal file
View File

@@ -0,0 +1,135 @@
package lib
import p "git.teletypegames.org/games/pncdsl"
var Kitchen = 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}},
},
// Floor strip. Same shape as the bedroom — keeps movement on a
// consistent Y band and clips destinations away from the cupboard
// and coffee machine.
Walkboxes: []p.Polygon{
p.Poly(
p.Point{X: 10, Y: 135},
p.Point{X: 310, Y: 135},
p.Point{X: 310, Y: 160},
p.Point{X: 10, Y: 160},
),
},
// First time the player walks into the kitchen with the key in
// hand, drop a hint. The trigger arms on scene enter; the
// rising-edge fires once per arming because Once: true.
Triggers: []p.Trigger{
{
Name: "kitchen_with_key_hint",
Once: true,
When: p.And(p.HasItem("key"), p.Not(p.Flag(FlagCupboardOpen))),
Do: p.Say("player", "A kulcs jól jöhet a szekrényhez."),
},
},
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"),
),
},
},
}

14
lib/script.intro.go Normal file
View File

@@ -0,0 +1,14 @@
package lib
import p "git.teletypegames.org/games/pncdsl"
var IntroScript = 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"),
),
}

18
lib/script.victory.go Normal file
View File

@@ -0,0 +1,18 @@
package lib
import p "git.teletypegames.org/games/pncdsl"
var VictoryScript = 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!"),
),
}

View File

@@ -1,29 +1,43 @@
package domain
package lib
import p "git.teletypegames.org/games/pncdsl"
import (
"log"
// 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.
p "git.teletypegames.org/games/pncdsl"
)
// Run builds the game and hands it to the pncdsl engine. It is the
// single entry point referenced from main.go.
func Run() {
if err := p.Run(Build()); err != nil {
log.Fatal(err)
}
}
// Build wires every entity declared in the sibling files into a fresh
// *Game. Validate() runs from p.Run() to cross-check name references
// between managers.
func Build() *p.Game {
g := p.NewGame("Reggeli Kávé", 320, 200)
registerAssets(g)
for _, a := range Assets {
g.AssetManager.Register(a)
}
definePlayer(g)
defineCat(g)
g.CharacterManager.Register(Player)
g.CharacterManager.Register(Cat)
defineKey(g)
defineBeans(g)
defineMug(g)
g.ItemManager.Register(Key)
g.ItemManager.Register(Beans)
g.ItemManager.Register(Mug)
defineCatMorning(g)
g.DialogueManager.Register(CatMorning)
defineIntroScript(g)
defineVictoryScript(g)
g.ScriptManager.Register(IntroScript)
g.ScriptManager.Register(VictoryScript)
defineBedroom(g)
defineKitchen(g)
g.SceneManager.Register(Bedroom)
g.SceneManager.Register(Kitchen)
// Story-rich HUD: top bar + NPC character panel + chat log + permanent
// verb wheel + small inventory. The player panel is skipped — the
@@ -52,7 +66,7 @@ func Build() *p.Game {
},
})
g.UIManager.Register(&p.Cursor{Name: "cursor"})
g.UIManager.Register(&saveKeys{})
g.UIManager.Register(&SaveKeys{})
g.MaxLogLines = 64
// initial HUD vars

View File

@@ -1,4 +1,4 @@
package domain
package lib
import (
"github.com/hajimehoshi/ebiten/v2"
@@ -7,14 +7,14 @@ import (
p "git.teletypegames.org/games/pncdsl"
)
// saveKeys is a no-draw widget that binds F5 → Save(slot 0) and
// SaveKeys is a no-draw widget that binds F5 → Save(slot 0) and
// F9 → Load(slot 0). Errors are surfaced via FlashLine so the player
// sees them in the status strip.
type saveKeys struct{}
type SaveKeys struct{}
func (s *saveKeys) GetName() string { return "save_keys" }
func (s *SaveKeys) GetName() string { return "save_keys" }
func (s *saveKeys) Tick(ctx *p.UICtx) {
func (s *SaveKeys) Tick(ctx *p.UICtx) {
g := ctx.Game
if inpututil.IsKeyJustPressed(ebiten.KeyF5) {
if err := g.Save(0); err != nil {
@@ -32,4 +32,4 @@ func (s *saveKeys) Tick(ctx *p.UICtx) {
}
}
func (s *saveKeys) Draw(_ *ebiten.Image, _ *p.UICtx) {}
func (s *SaveKeys) Draw(_ *ebiten.Image, _ *p.UICtx) {}

11
main.go
View File

@@ -1,14 +1,7 @@
package main
import (
"log"
"git.teletypegames.org/games/pncdsl-demo/domain"
"git.teletypegames.org/games/pncdsl"
)
import "git.teletypegames.org/games/pncdsl-demo/lib"
func main() {
if err := pncdsl.Run(domain.Build()); err != nil {
log.Fatal(err)
}
lib.Run()
}