my picotron drive, to be shared across my devices
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
picotron/atelier2.p64

1224 lines
39 KiB

6 months ago
picotron cartridge // www.picotron.net
version 2
:: gfx/
:: map/
:: sfx/
6 months ago
:: story.txt
--[[pod_format="raw",created="2024-03-30 15:58:22",modified="2024-04-11 01:41:32",revision=208]]
ATELIER HESTER
welcome to atelier phoebe 2! this is my document for
recording story ideas! please don't read this; it is
all the spoilers! if you want to know what happens
i recommend playing the game, that is the proper
way to experience this :)
--------------
main gameplay interface, you're shown a gridd of
cubbiess which contain various ingredients
you look at the things in the cubbies and label them?
labeling could be hard with just o/x
you have twwo books, one of recipes and one of
ingredients?
drag a label from the book to the drawer/plant?
--------------
plot ddetails follow!!!
main character amnesia from alchemy gone wrong.
main character badly in debt to loan shark
everyone in town has some debt and don't talk about it
most people don't like main character
mc has to mend relationships with everyone in order
to gather everyone together to defeat loan shark
player controls a fairy assistant for alchemy
possibly fairy is new to the atelier?
early dialog esstablishes it's common knowledge that
fairies can blink white (o) to confirm things or
red (x) to be uncertain / ask a question
maybe other colors at other timess but you get it,
those are our two verbs - ask about something and
suggest something
interface is an apothecary cabinet you can open
the drawerss of and ask about. you have to suggest
ingredients to mix together for the cauldron
at the beginning MC is unsure and doesn't know about
your suggestions - "i guess i can look that up?",
"maybe i'll try this?" because the player is guiding
them. towards the end MC responds as though teaching
the player fairy, like "that's right, that'll work!"
and "good job, yeah!" to communicate that the MC
is more confident and getting their mlemory of
alchemy back
the town generally ddoesn't like the alchemisst just
because she's been kindda nasty and rude at times,
just petty disagreements that have boiled over.
she's known to be a decent alchemist though i guesss
endgame is that you rally the town together to break
free of the loan shark; it's hard too convince
townsfolk both because they don't like you at first
and also because the loans ARE legitimate. but it
turnss out that the rest of the town also has debt
to the shark and if you convince everyone you can both
1. achieve independence from the supplies he sells
(maybe he's the intermediary with the trader? or buys
and ressells everything at a markup?)
2. convince people to just reject the loanss/debt;
quesstion here of whether they do this by force,
whether cops exist, idk, this is explicitly passtoral
fantasy. maybe at the end the player will muse about
whether it's good to have mob rule, "no one in toown
liked me, what if they threatened to burn down my
shop?" "yeah, that would suck. maybe we could build
something. but right now rule by mob is better than
rule by loan shark!" idk this feels overly didactic
but you get the idea
this is really getting into the weeds of how we view
the justice system but maybe he threatens to say
"i'll send for the king's knights!" and the crowd is
like "you can do that if you want, but by the time
they get here your house will be burned down.
alternately, you can keep your house and try to
be friendly. maybe even contribute to the town. it's
up to you. burn down your storehouse or genuinely
connect with people?"
definitely overly preachy but i like that
------------------
script!!!!!!!!!!!!
------------------
title screen
new game or load?
new game ->
hester with her back to cauldrron holding a little fairy doll in pieces
fairy shakes and then comes to life
hester: "ahhh, the synthesis wworked! ... i think"
hester: "a fairy like you should be a good help around the shop."
hester: "you might noot be able to speak but you can flash white for yes and red for not sure"
the whole time there's more and more bubbling in the cauldron
hester: "you can be my hands across the atelier!"
explosion!
soot-covered hester stands up
"what just happened."
"wait a second. who am i."
"alchemy books? a cauldron?"
outside view of shop, Atelier Hester on the sign
"Hester..."
back inside
"i must be an alchemist..."
loan shark arrives
"hester! you got the latest payment for me, girlie?"
"i'm afraid i don't knwo who i am - can you help me?"
"nice try. remember you owe me 4000Z by the end of the month. have a nice day!!!"
loan shark leaves
(SAVE POINT)
"am i... in debt?"
"i don't know hwo to do alchemy... but maybe these books..."
(player opens books)
"it looks like this one has recipes... this one has infoormation about ingredients... my head..."
(when quit uot of both books, old man comes in)
"hey, hester. can i get that purified water?"
"i don't knwo who i am"
"sorry, i can't hear so good these days - purified water? my usual order?"
(moves on when you've crafted purified water)
"thank you, hester. this will help me out. here's your payment."
(old man leaves)
"i guess i'll just try to... be an alchemist and pay off my debts..."
(SAVE POINT)
at the beginning MC is unsure and doesn't know about
your suggestions - "i guess i can look that up?",
"maybe i'll try this?" because the player is guiding
them. towards the end MC responds as though teaching
the player fairy, like "that's right, that'll work!"
and "good job, yeah!" to communicate that the MC
is more confident and getting their mlemory of
alchemy back
the town generally ddoesn't like the alchemisst just
because she's been kindda nasty and rude at times,
just petty disagreements that have boiled over.
she's known to be a decent alchemist though i guesss
endgame is that you rally the town together to break
free of the loan shark; it's hard too convince
townsfolk both because they don't like you at first
and also because the loans ARE legitimate. but it
turnss out that the rest of the town also has debt
to the shark and if you convince everyone you can both
1. achieve independence from the supplies he sells
(maybe he's the intermediary with the trader? or buys
and ressells everything at a markup?)
2. convince people to just reject the loanss/debt;
quesstion here of whether they do this by force,
whether cops exist, idk, this is explicitly passtoral
fantasy. maybe at the end the player will muse about
whether it's good to have mob rule, "no one in toown
liked me, what if they threatened to burn down my
shop?" "yeah, that would suck. maybe we could build
something. but right now rule by mob is better than
rule by loan shark!" idk this feels overly didactic
but you get the idea
this is really getting into the weeds of how we view
the justice system but maybe he threatens to say
"i'll send for the king's knights!" and the crowd is
like "you can do that if you want, but by the time
they get here your house will be burned down.
alternately, you can keep your house and try to
be friendly. maybe even contribute to the town. it's
up to you. burn down your storehouse or genuinely
connect with people?"
definitely overly preachy but i like that
6 months ago
:: art.lua
6 months ago
--[[pod_format="raw",created="2024-03-31 01:52:08",modified="2024-04-17 14:41:47",revision=674]]
6 months ago
function bob(s, x, y, w, h, t)
sspr(s, 0, 0, w, h, x+t/2, y-t/2, w-t, h+t)
end
function ragged_box(x1, y1, x2, y2)
ragged_box_color(x1, y1, x2, y2, 15)
end
function ragged_box_color(x1, y1, x2, y2, bgcolor)
rectfill(x1+1, y1+1, x2, y2, bgcolor)
sspr(004, 0,0, 8,2, x1+1, y1, x2-x1, 2)
sspr(004, 0,0, 8,2, x1+1, y2, x2-x1, 2)
sspr(004, 0,0, 2,4, x1, y1, 2, y2-y1)
sspr(004, 0,0, 2,4, x2, y1+2, 2, y2-y1)
end
function easeTrig(t)
if t<0 then return 0 end
if t>1 then return 1 end
return 0.5-0.5*cos(t/2)
end
function easeAccelerate(t)
if t<0 then return 0 end
if t>1 then return 1 end
return t*t
end
function easeDecelerate(t)
if t<0 then return 0 end
if t>1 then return 1 end
return 1-(1-t)*(1-t)
end
function easeSine(t)
if t<0 then return 0 end
if t>1 then return 1 end
return sin(t/4)
end
-- add newlines to a string to fit it into lines.
function wrap(str, line_length)
-- thanks to https://stackoverflow.com/questions/17586/best-word-wrap-algorithm, i did not feel like thinking this out myself
local words = split(str, " ", false)
local output = ""
local c = 0
for w in all(words) do
while sub(w, 1, 1) == "\n" do
output = output .. "\n"
c = 0
w = sub(w, 2)
end
if c + print(w,0,-10) > line_length then
if c > 0 then
output = output .. "\n"
c = 0
end
end
output = output .. w .. " "
c += print(w,0,-10) + print(" ", 0, -10)
end
return output
end
function collides(position, object)
return position.x < object.right and position.x > object.left and position.y > object.top and position.y < object.bottom
end
:: cabinet.lua
6 months ago
--[[pod_format="raw",created="2024-04-03 19:46:51",modified="2024-04-17 14:41:47",revision=671]]
6 months ago
Cabinet = {}
function Cabinet:new(x, y, gaps)
local c = {
x=40,
y=10,
drawers = {},
shelves = {},
hover_plant = nil,
height = 4*(gaps+16)
}
-- populate the big drawers
local xoff = x
for i=0,0 do
for j=0,1 do
add(c.drawers,
Drawer:new(xoff + gaps + i*(gaps+32), y + gaps + j*(gaps+32), 009, 32))
end
end
xoff += gaps + (gaps + 32)
-- populate ssmall drawers
for i=0,3 do
for j=0,3 do
add(c.drawers,
Drawer:new(xoff + gaps + i*(gaps+16), y + gaps + j*(gaps+16), 008, 16))
end
end
xoff += gaps + 4*(gaps+16)
local s = Shelf:new(xoff+gaps, y + gaps, 76, 32)
add(s.plants, {13, 4})
add(s.plants, {14, 14})
add(c.shelves, s)
local s = Shelf:new(xoff+gaps, y + 3*gaps + 32, 76, 32)
add(s.plants, {15, 10})
add(c.shelves, s)
setmetatable(c, self)
self.__index = self
return c
end
function Cabinet:draw()
-- cabinet!
rectfill(self.x, self.y, 230, self.y + self.height, 2)
-- drawers
for a in all(self.drawers) do
a:draw()
end
-- plant shelves
for s in all(self.shelves) do s:draw(self.hover_plant) end
end
function Cabinet:update(x,y)
for d in all(self.drawers) do
if d:contains(x,y) then
d.offset = 4
else
d.offset = 0
end
end
local closest_distance = 1000
local closest_plant = nil
for s in all(self.shelves) do
for p in all(s.plants) do
local dist = abs(p[2] + s.x - x+16) + abs(s.y + 24 - y)
if dist < closest_distance then
closest_distance = dist
closest_plant = p
end
end
end
if closest_distance < 32 then self.hover_plant = closest_plant
else self.hover_plant = nil end
end
function Cabinet:drawer_at(x, y)
for d in all(self.drawers) do
if d:contains(x,y) then
return d
end
end
return nil
end
Drawer = {}
function Drawer:new(x, y, sprite, size)
local c = {x=x, y=y, sprite=sprite, size=size, offset=0}
setmetatable(c, self)
self.__index = self
return c
end
function Drawer:draw()
rectfill(self.x+2, self.y+2, self.x+self.size-3, self.y+self.size-3, 0)
spr(self.sprite, self.x, self.y+self.offset)
end
function Drawer:contains(x, y)
return x >= self.x and
x <= self.x + self.size and
y >= self.y and
y <= self.y + self.size
end
Shelf = {}
function Shelf:new(x, y, width, height)
local c = {x=x, y=y, width=width, height=height, plants={}}
setmetatable(c, self)
self.__index = self
return c
end
function Shelf:draw(highlighted)
rectfill(self.x, self.y, self.x + self.width, self.y + self.height, 0)
for p in all(self.plants) do
if highlighted ~= p then
palt(0, true)
palt(10, true)
end
spr(p[1], self.x+p[2], self.y + self.height - 32+2)
palt(10, false)
palt(0, true)
end
end
6 months ago
:: conversation.lua
--[[pod_format="raw",created="2024-04-03 02:38:22",modified="2024-04-10 14:42:28",revision=642]]
default_script = {
{"welcome to Atelier Hester!", talk_sprite}
}
Conversation = {}
function Conversation:new(script, final)
local c = {script=script or default_script, final=final or function() end, index=1}
setmetatable(c, self)
self.__index = self
return c
end
function Conversation:before()
self.behind = scene
self.before = function() end -- only ddo othis the firstt time this scene is played
end
function Conversation:update()
local now = self.script[self.index]
if now.during ~= nil then now.during() end
if btnp(4) or btnp(5) then
if now.after ~= nil then now.after() end
if self.index < #self.script then
self.index += 1
else
--self:after()
end
end
end
function Conversation:draw()
self.behind:draw()
ragged_box(30, 100, 240-30, 130)
color(0)
print(self.script[self.index][1], 34, 104)
end
function Conversation:after()
self.final()
--change_scene(self.behind)
end
6 months ago
:: fairy.lua
--[[pod_format="raw",created="2024-04-03 17:32:32",modified="2024-04-10 01:58:59",revision=384]]
Fairy = {
velocity = 1,
accel_frames = 20,
min_velocity = 0,
max_velocity = 3,
f = false
}
function Fairy:new(ff)
local f = ff or {x=120, y=68}
setmetatable(f, self)
self.__index = self
return f
end
function Fairy:draw()
if flr(30*t()) % 2 == 0 then
spr(5, self.x-8, self.y-8, self.f)
else
spr(6, self.x-8, self.y-8, self.f)
end
end
function Fairy:move()
if self.velocity < self.max_velocity then
self.velocity += (self.max_velocity - self.min_velocity) / self.accel_frames
end
if btn(0) and self.x > 0 then self.x -= self.velocity end
if btn(1) and self.x < 240 then self.x += self.velocity end
if btn(2) and self.y > 0 then self.y -= self.velocity end
if btn(3) and self.y < 135 then self.y += self.velocity end
if not (btn(0) or btn(1) or btn(2) or btn(3)) then
self.velocity = self.min_velocity
end
if btn(1) then self.f = false end
if btn(0) then self.f = true end
end
Glow = {}
function Glow:new(x,y)
local g = {x=x, y=y, t=0, length=0.7, radius=10, start_color=8, end_color=9}
setmetatable(g, self)
self.__index = self
return g
end
function Glow:draw()
for i=0,4 do
local eff_radius = self.t*self.radius / self.length
if eff_radius - i >= 0 then
local c = self.start_color
if i < (self.t/self.length)*4 then
c = self.end_color
end
circ(self.x, self.y, eff_radius-i, c)
end
end
end
function Glow:update()
self.t += 1/30.0
return self.t < self.length
end
:: gfx/0.gfx
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixtb2RpZmllZD0iMjAyNC0w
6 months ago
NC0xNyAxNDo0MTo0NyIscmV2aXNpb249MTE4N11dbHo0AOIcAAASZAAA8Rp7WzBdPXtibXA9cHh1
6 months ago
AEMgEBAE8PAsZmxhZ3M9MCxwYW5feD0wLjM3NQwA_wJ5PS0wLjEyNSx6b29tPTV9LDoAkCR6cAoP
HU8eCgcAcD8ODx4KYBoJAP8CDRpQCh8dPw4dClAKDx1fDg0IAAT-Aw8eClAKDl8ODgpQCn4KUJrw
A4sAJqUGOrAKHxMKsAoeBADwAKAaHhqQCgMOEQqQCgMPEgcAPQ4dAQYArw4KkAo_CpBa8AV9ACYQ
Jn0AER1xAP8GYDoPFy46MAo9HxweHxIKMAodbxwPCAACIF8cIAD-ARodPxwODxIaQBpeGmB68ASE
6 months ago
ACJRCAgECQACABIQCAAfGQ4AFh8J9QAmshEfHJAeED5QPhBeAgD-CSBOEE5QLBosYDwaPFAcEAog
HIAa0ArwOWIAJtQDLxwwLlAuMC5QPhA_BACRYC4QLoAeGh6QBACfCgAegB4aEB6QaAAl8DHIZATw
-7X-Dw-wG47wOPIa-hXyEv4G8iSgEv8YF-4Z-Q-_D-0dAoAC-RX_Hv0M-hr9FQJwAv0O-ib9CP4l
7T6dDgDwBAb_MP0E-juNAnACjVf_Od3_QH0LAKIH-j_9Dx-_QRdNDgBhQJ0c-kIHDQBG-kJtPAwA
VA0PFj1MDwCGB-5CG3z_QloMAC9BegsALhdqWgBHCg0KLQ8ALwdNDQACP2z_Qw0AHj9c-kQNACs-
TP5FDQAzOB1vDg8ALw2JDQAKMjz_Rg0AKHkHDgAPGwAHHJknAARPAD49SQegAA8NALcv-kMMABpH
HV8LDQ8AKA14DQAXiFkALB14DQBUXO7H-igPALQl594bXK5Hvif_JRMA8QEgV94Xbgc_G1x_N-4D
J-4iGADxBC1o-htXfieeF54bXF4n-ggn-iAYAPMGbRj_GEduZx4nfheOG1xOF-4MJ-4ergDzAxRH
XleeJ24XfhtcPhf_EDf_GhkA8wYRN15H-gIHbhduG1wuF273A65H-hUcAPQHCPcE-gcXXhdeG1we
F043-gI3rlf_EDEB8wkBZz5X-hEnThdOG0weF04Xbke_N85H-gwgAPEMTsdOV-4Hx04XPhc_G1wX
ThdeJy43vkfeN-4IIgDxEJ0uJ26n-gdXvhc_Fx4dFy4LbAc_J14XfifuN95n-gEkAPIKrY43-gmH
-ggHDj1OXA4Hzge_R85H-gD3ANcA8Ai9Pj0u-QCn-RcuHTzuFx6tPmeeR-4NbawE0FIevQ4HHv0H
V35n-ganBHD9gAc9nofOvQRA-ZiOzQcAF64FAPsDgAL9rQKQAv2rArDyq-D----hZwVVMTQuNjJo
BSE0NHYFAWkFHDHRBVD-FAHUHgIAsAS5BB4ECT8PGT0JCQAanQYAMQ8VDggAhwwOBLkEDA7UAwAf
7OQFIp8gIAT-FBH0Dh4DAALANPkGNB40CX8POX0JCQAxjRmNCAAv-QQHAAsyDxUOCQAeDAgAf-kG
NAwO9A4EABI-HvwO1gAlctQPFPAB1A4EAP8SxB7wAcQO8AK0HvACpB7wA5Qe8AR0LvAFVC7wB27w
--_rZgAl-wn5MCD6CoD5BND6APAB2fAC2fADufD---xwBy-zATrzGP4V8xL_BvMj0BP-GxVwB2Mc
A7AD-RNwB2UUE5AD-QxwB1MDkAP9BHAHQwOQA21wBwALAAZwBwIOAANwBwANAARwBwIMAAVwBwIo
AAP6Bg8NABU-gAN9DQBFA2gAAVUHDw0AHAFIBw8NACkBfwUPDQBdAUUHDw0AKQ5bAA8NAMEv-kMM
AAw-oANdDAAsA3EHAQ4AGCZwBwESAB0hbwcBFwAdHG4HARcAD20HAQEZAA9tBwEBGQAPbQcEAeQA
D20HBQImAQ9tBwcBIAAPbQcKTwOQA31tBw1PA5ADjW0HCE8DkAOdbQcDAKkEGVBtBwASABJ_bQcA
CwAwlo7NBwAQrAUA8B6qE6AD-VTzAv0U8wOtE8AD7fMmTfMK8AJTrfMD8AOj8AAjPXPwJkPwIqPw
NDOGByv-ln4FKC0zhwcWMn8FHDLPBfAK8P_iKvANCgMK8AwaAwrwCEoDAArwCAoDIAgAIwU6CABQ
CgMQAwACAGQa8AQKAAMCAB8KDgAKRAE6AAMCAPAOSsAK-xIBCsAqzirgCs4K8AEarhrwAgquCvAD
Go5VAG_OCvAFqqCVBiXg8P8AOvAMCh8TGvAIOi7BAPAiHgAuOvAFCi4AThrwAiouJD4K8AIKFA4A
6 months ago
DgQQHgAa4DoALgAEDxQzCvAACi4AHiQNPgoAUQAuEAMkCgDgICQQFBAq8AAKHhQANCOwAKBeJBAa
8AEKfhQeSgAhLkAIANIaYBQQSuAK7xgK4ArsBAChGswa8AAKzArwAQUAfxqsGvACypDZACfwDl1K
8AZaLxMK8AYKTgQeCvAGGh4TBBMq8AUKIA5DOgHwByAeBD4a8AMKLhAELgAOCvADCkMkEwCdABAw
ugBAAgoOQ7sAsAIKDgMODxQuFA4AdQEwEB0QwgDTBAogDRAUEDrwAQrGCgUAIBqmLgAQpiYAEIZh
ABCGAQIfhqABJ-1iYGAE-x4P-xUS-x4j-xUo-x4R-xU2-x4G-xU_3x7-FUZ-Hv8VSj8e-xUM8Bj_
Cg8e-gHwMP4FBT7wPD4FnhUO8EAOFZ518DZ1rvUE8Bz1BM71Qv4A9T7_BPU6-gv1MP4c9Rj_Ch3_
6 months ago
Th3_Ti3_TE3_Sl0DAE9N-kw9AwAEES05AAUDACAN-k8DNP81DREABVkABTIAAmIAQW3_SH0DAPtY
6 months ago
jf5Gnf5Grf5Ezf5C3f5C7f5A-QH_Pv0C-j79A-48-QX_Ov0H-jj9Cf42-Qv_NP0N-jL9D-4w-RH_
Lv0T-iz9Ff4q-Rj_Jv0b-iT9Hv4g-SH_Hv0k-hr9Kf4U-S7_EP00-gj9Pd79GXoBdC01LjE1ODMB
6 months ago
AASEAVcxNC44MBcAAY4BGTOOAfAnQEAE8P9aIh8Y8CZCXvAgQq7wG0L_AfAWMv4CIh7wEEL_AUJe
8ApC-gIyrvAFQv4CQv4A8AEiCADwPQbg-gFCfni_0M4yToheGL7AfkJOSO4YrsBOIn4oPvgBvrDe
mL4YDhi_oB4CnjjuSB4YzpAeAgeOCB4YrjheCO6AHgIHfhguGH4ofhgNANAPDwduCE4YTih_KP4A
HQBgDX4IThgeDwDwGgKAHgIdB24IXjhuOP4DoB4NBw1uGF4YLlj_AgcdwB4dB27I-gMHPRfAGgDy
BP4UBy03HcAuHQf_Dwc9Nw0aFw4YAHANLUcdSi6wGQCRCB8OHUctah7QGQDwCAVsFy0nDkoO8AEe
HQf_AD1cLRdOKvAEHADwBc4tNywtF37wBy4dfgc9Vy0nfvALGABgPgctBxs3DwAQDg8AQAc9B1sN
APEdEh4tJ3snfvAVHg1He37wGC4NJx1bXvAbPgcdFyte8B8uF47wIq7wJm7wKx6qBR-kQwMJFjFD
Ax80tQEdMG7wCbUBMc7wA7UBIQLgtAHyIgjA-gFC-g6wzjLOuL6QfkJ_mF5YvoBOIp44bqgOGM5w
7jgeeF4YLhjecB4CnniuKD60AQCnAVGeKE4o3g0AowheCG4YTjjOF6C1AZBuGB4oLkjOR6C1AfAD
B144Xojed6AeAh0Xjoj_ApewIQGzF-4Qx8AeHSf_C6enAUIX-ge3qAGGJ-4DJx8OZy2rAVQn3jdc
F64BRjeOZ2ytAUY3Tqd8rgEo9wGtARbHrQEXh6wBGUerAS8XLasBXvAm2W8b8Bn_CPAS-g7wDf4U
8Aj_GPAG-gx6bvAE7tr_APADfmr_DvAC-h-wAP4h4A4K-gd6-gAIAPEgAGpeCv4C0A4K-gEafhr_
A9AK-gQaTgr_BsAK-gYaHgr_CLAK-gga-gmwCg4K-iEGAPYKIqAeCv4Reo6gDgr_A_r_AaAOCq56
-hCgDiMAICDABgBAGgceB2UA8AcO9wLgCg4KTvcD-w8H0AoOCh79BvcGEwBwDvcG-QjQGhAAEAf8
BiD3HQYA8Qv9HuAKLvcbHvAAXof_Adcu4P4h8AD_AoD_BCcBP---fSkBJvAvFz8b8Cl_8CPe8B7_
A-AY-gAqXvAS-gE6jvAO-gE63vAK7kr_A-AHzjr_CfAFnjr_DfAFbir_ACru8AP_BVonAWHwAf4C
Om4JAPADDgrOKp4K-gPwAA4K7jpeCv4ECgCB-gM6Hgr_BeA4AdAG4Ar_Fip_0Ar_EUqu_wBR-gs6
-gEeAfAFBkr_BcAeCv4BSv4J0A4K3jr_CDdAAGGuKv4Gp_BNAVEM9wHwACwAIPcILwGv-gD3DuAO
Cq73FVABcSFgEEAA_wtw-xIY8Bz_MPAK-jzwAv5A8AX_NvAX-hzwaVYAJy00JAo0MS40qREfM1YA
B-8F7j8d-h3wCv4FPf4TPb7wAv4uPd5gADPwBhIPHQAeAA7gXx7wM-8SBn8enxIADgIA-x3wFk0P
Hm0OLQ4dDs0OXA79BvAKjUx9Dv0CXq0OHR4dDp3wAv1A8AX9NvAX-YQAKvEPpw8e8E8OIA7wRw4g
DhAO8EkOcA7wKD7wEg7wKF4g-wD-Fi1e-SfwCp0_rW59cv0M8AL9ATL9BXJdUv0C8AX9InK98Bf9
FlKEACkRJoQA8DUQDvBPDvBIDhAPEiAO8EgeDXAO8EMNQB0gDgANwE3wNB4dAA0gjS79DBBN8BVN
AA7NTv0X8AqdDg0ePRJdTo2SbRL9AZ0A-woi-QSSTXL9AfAFnRL9FRIeAi4SrfAX-RViowAp8Ar-
WC8e8BEW8ClO8EMPElAeBz5N8D1tbv0KjQDxGi0yHRKNTk1CLUJtHr3wCn3CXS5NMg3SHR4CDUKt
8ALNgl1CbZJNIh4ilQCPIv0HQi1yPiKVAC7wSHMfHnAe8EYO8BQm8B0u8B0m8B8O8AMO8Ew_8AkW
8CIeUC7wRh4wLxIODZAe8AMW8CINUA4tDg0OTfA9zQ4dIk1iXT4ATfAVog0ijQ6yDWItXiJtICLw
BL8A8xESLQ7yAl6CHULwAo2yLj1yDS6STQJeUr3wBZ0yXQK9csAAfz0yTVIdgm3FACmhmibwTSbw
rhbwRgUC8UtAFvAqMg8S8AkO8CkNANItAFIwIg4wQtAy8BN9ok1iHQ4CHTIAHS6AIvAAElCyDiIt
0h4iDfIDLj0QQvAB8gFOQj8TIi0SPlI_8gnwAo3yCzxiPD1yDjIdUj27AP8CEq1yLSI_Ag5SPR5N
8Bc98gq8ACrwSPovFvBNLvCtBgXwIgaABmA-HjAG8A0y8BtCQF1gMoAFBpBCwBLwBA8SANIcXfID
sFLAMvAALQzyAF1yDBIccgwyMELwAFIQoi0SDOI9EgxPEy1SK3IMYskA-x5NQjsSK_I98gjwAQwi
DBIc4jtyWyJbPbJbYvAFPPIXDPIBHDIs8BcSHPIKHLLDACjzExpPHpAe8LsuAC8W8CFeoA7wAy4w
LfA2HhAO8EQegA4ATrDdAPQHMB4ADhAOMAZe8AcywDLQXlBCYA4AHuYA8Q9CsH6iLgIOMg5CflKw
UsCyMB4HXgJe8gMOB25iDxLoAMDijgxiPxOiK44SazLkACDibuMA8RJiKyJ_8gbwAXIbUk4iW1Jb
Ijtegoti8AVSO-ICe-ICC1LnAB-y4wQp8Tk4BTAF8Es18EtF8Hs-HvAeFfAarjAG8AoG8AgfE5BN
oC4XbmAG4F6gFaAtAg2wMoAuB54gQsCOMD7AQsBCcB4HroIuAg4iXgfaAOCCLQD_A_IeB54CDTI_
EtgA8B3CzlI9Em0C3gJtMg1i8AESLXKubRItYi0CnlJNovABch0yfgJtUl0iPV6CjdkA-wE9DvIB
3bINQp3wF3JN8gRNOgUlD7UgGg86AP----------------------------------------------
-yTwI2CABPD-JL8U8ED_AvA8-gbwOT8V-gTwNz3_BfA1Tf4H8DNN-gjwMk3_CvAwTf4L8C9dBQD4
AE3_DPAuXf4N8C1N-g3wLgUAMwzwLwUAMQsPDwcAEDwmAPAMCTzwLBxN-gg88C4cPf4HLA8X8DFN
-gULHAsMCQDwrAQMCwwLDPAzTb4tLg8ZHAsc8DNdjj0uGjzwNV1ObR4qPPA2-QFKPPA3zXos8DkK
Tdoc8Dv6AwzwO5oMivA7amx68DpafHrwOVofHAxpavA4WqlaOfA0WslKOfA0SgDpKknwMyogmS8Q
KQpZ8DQKSEn4BPAw_BHwLmgPCvgM8CtoFygn_AfwKfgDNzgXqPAoJ-gMB7jwIgf4EieI8CH4FgeI
8CD4GAd48CD4GSc48B-4IfAf_CLwHfggBxgGAPEHFxjwHPghByjwG-gl8Bv4JvAaKAn4IgYA8CMO
CfgE8BoYCfgOGSgJ_ADwGRgJ_A8ZGAmYB1jwGAgZ_BAJKAmIB1jwGQn4ERkoCRgJWBkAVAn4Eik4
CwDxAhQZGBlYF1jwFwn4FRkIGWgHCwCBGBno8BYJ_Bk_AGQUGfgVGRgLAFAUCTgZ6AkAEBpyAIIT
GfgaGYgXOAkARvgA8BIIABEbiACBEQn4HAmoB0gJACQZmAkAsPgB8BAZ_BspqAc4CQCmHBm4Bzjw
Dwn4HQkAocgHGPAQCfgcKdhOACApyGUAMBOpuH0A8AEPSXgZqPAVGfgOGbgZiPAXQgDyAQggGPAa
KfgbGQjwHyn4HAkHABAZBgDwJBo5DwzwHin4GFkG8B8Z_BdpLfAdGfgUaQYJTfAcGfgReQZt8B4J
_A6ZbRXwHhn4CpmNJQgAUAapFm1VCQDyQgK5Fn2F8B4ZyMkGjcXwHgmYuc3V8B8JWKnd9QLwH8kG
zfUFAAXwHpkVjfUN8B5prfUPAAXwHQ0ZvfUV8Bvd9RjwGY0FDfUc8Bkt9STwGT0FDQIAovUc8Bgt
9SbwFy0QAEMFDfUdEgAGJACkHvAVPfUo8BQtFRIAhiDwFC31KvASJACFIvASLfUs8BASAAEUAIUQ
LfUsAAXwD14AABYAmQ8G8A899SoAFRgAA1gAiw8t9S0ABfAM7wNuLTI5LjEwFTVIMzguNyw1D49A
AAEEBPEt---DbxTwRe7wPD8Vfile8Dhdjile8Dc9DkluCW7wNj0OWe7wNT0OaW4KbvA0HT5p7vA0
DU5Z-gDwNG5JBgDwhClurxnwNN7c8DQZjvwB8DQZbvwDEB8P8DAZXvwDEBvwMRle-AILACvwMW6c
2-Axbozb8DJejJsfHyvwMl58iyg78DJebEsIGygnG-AzXlwrOEsfDgcL8DReLB8XGyhLCBsfDivw
Mx57HxcYCxcPDisYW-AzDpsPFwsnHw47GEvwMx5LHxdLFx8OSwhL8DM_Ky8XuxYA8CcNTgwLFrsI
W-AzPR4s6xgr8DM9DhwALKsoO-AzLQ5siyhLHxzwNYxrGFsGDxAfHPA0jADLBi8KAPJJMqyrFgU-
EBXwMQwAfKsGG0Ql8DCc20QVFPAvrMtEJZTwJ4xFixUkRaTwJIwFNBV7JQQF9AHwInwVRCV7JfQB
FfAgfAWEBWsl9AMF8CBsBZQFaxr0BfAgXAoA8UEG8B9cBZQVawoF9AbwHkwABZQVWw8MCgX0B-Ae
LAAldAUEFTsTGvQH8CEVBBVkBRQFSgUapAW08B8VChQlRAUUGlQKpAXE8BwVAwpEJSQFpA4A8AYa
FQQKdCUEBbQKlAXU8BgVxCXECoQKAFAFAwrEFQwA8Ark8BYFAwr0FwX0APAVBQr0GBX0APATFfQa
CABgEgX0EgqECgDzABEF9BMKdAAF9ALwDwX0FAsAcA4F9BUKZBALABANCwARdAsAQQwF9BYhADQD
8AsLAKEE8AoF9B8AFfQDCQAQEB0AMgr0IAgAUNQV9BAQGwDyAQgF5AX0CApkIBX0AvAI9AANADIl
9AENAIUJCkQQFRQl5A4AQQAVRAUOAGAV9AgKRAA6ATAI9AEbAB80DQACwRX0DQAF9AXwCPQDBQsA
MwTwCQsAUAQq1PALDACADCAaBBq08AwMAMAICiQQCjQalPAN9AJjAKAkAApUCoTwDvQCVwAADgBA
GmTwDw4AkgoKJBVUClTwEA0AYTQFVBo0BQ4A8QQEdfQBCjQFZAokBfAR5FVkBfQADwCBFAXwEvQN
BeQNAHAEBfATBfQMHACzJAVkCgXwFAX0CxUOAMHwFQX0DBrkCiQFClQNAHALOvQCevAXaQBgFFpE
6-AYCgBSZBoU6xYLAIB0CgTbBivwGaUAVIQK6xYbFwBBywYrBg0AUQkKdArbDQASFyUAAA0AMQvw
GAwAhGs-BTsGGwYLKQAxS2IrDwABUABEVBorgg8AUdS1WuIbDABiGgVkdfIOGADyEhtlbfIOOwYL
AhvwGo0CDfISKwYLQvAZLfIcC2LwGT0CDQIAEPJIBVLyJfAYLRAAgAIN8h7wFy3ySAUCEAABEgAw
FT3ySAUUEhIAAEgFEPJIBQIQADACDfJIBRDySAUnAg0UAGUQLfIu8A9cAJ8CDfIk8A498i4oBSwP
oAknD4gK-yAg-xT-NfEBfPQ--gEE-xU9BP4BBP08DgcAIDseBwBBLfQ3LggATwT_NQQKAP80BFIB
IfQ4YgExHfQ6cQFyDfQ9-gH0Pw8_Mf--6JQBH-2TAf92H1xiAxQfMuYJAfIrGN8W8EAuvw8e8D0u
7R7wOx79Ag7wOh79Ax7wOQ79Ax8RDg3wNRwezXwOHPAxHAAcDt0MDRwNXPAxTAoA9gYcDQwODPAx
DCAe-QEMPQwO8DYO-QgGAGAtTh1ObS4PALAFHg0O8DcOXQ79AAgAQE0e-QEhAFE9Hj0OzSoAUB5N
Dr0eCQBQDl0OnQotAPANHh0_LQ6NCi7wOA5NTp0KDvA5Hv0EDvA6Dk0_rQcA8YAtDm0ObR7wOw4d
Hk0eXT7wOh4dfk0eHS7wOT5Afk0e8EEezQ4NAvA-Hs0PGGLwOi6tC3Ib8DkOnRtiO-A0Cz6dC2Ib
DSvwMgILDR6dG1IbPQIL8DASC70bUhtdAgvwLA0LIhutC1IbfQIL8CodCzIbfStCG50CCwLwKB0L
Uis9G2ILvRsC8CcdC3JbYhvNCwsA8gDyBBvdG-AmLQvyAxvtAgsKALAL-QAb8CU9C-ICGwoA8AQC
CBfwED0L8gEb-QIL8AIIN-AODgDxAAv9AwvwAwg38A09C-IAGw4AQBhH8AsOAFAL-QIODR4AYAcY
N-AJTRIAMU0OvRMATBgHGCcTAEgAV-AIEgBhBAgQV-AHEgAjPR4SAHIgRwAvFfADFQAiDs0VADkw
RykTALAC8AMIMDcpDfACXZQAFS0VAHBAB0kd8AFdtwBQHR7NDhs8AEFZrSC9EQAhDt0RAEkgSf0M
EAAwKf0OEADSEg7dDgIL8Ar9DwvyBAwAOgv9DgwAEQULAFQMjSD9AQ0A9AoNbfAEG-IFzR4CC-AO
TfAFC-IGzQ4SC-AoCQBwHQ698gW9HgoA8AJeEE5tws0OIgvwIA0Abr1y3QsA8QwaZW4L-REeIgvw
FhUORU4QLgv9EQ4yC-AVhZ4KAPBN8BaFTgAeEAv9EB4i8BeFbi0L-Q8eMgAL8BXVHRD9EQ5CK-AU
tWAL-Q0uMkvwE2UQJWALEv0JLpIr8BKFgAsy-QQ_0hvwEVWwC2LdPvICG-AQVbAL8gI_8gYr8A4L
ACIdGwgAQB4b8A0IACAfCwgApvIgG-AMVaDyIgsHAGCw8iEb8AskAGcgG-ALZaAIAD8L8AwIAAEA
TAAACABhHgvwD1WgbAABCAAQHIcA8ACgC-IbG-ARRcAL8hkb8BIIAEAYG-ATCABAFxvwFAgAQRUr
8BUIAD8L8BcIAA0hNdAIAG8WReAL8hQIABQjExsIAE8LEvAVCQANHxtEAABi8ADyFPAXBwAfA-IE
FQ-ICCcPOgD---------------dQbT01fX0=
6 months ago
:: gfx/.info.pod
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixzdG9yZWQ9IjIwMjQtMDMt
MjkgMDE6MTQ6NTEiXV1sejQABAAAAAMAAAAwbmls
:: library.lua
6 months ago
--[[pod_format="raw",created="2024-04-10 00:24:20",modified="2024-04-17 14:41:47",revision=104]]
6 months ago
plant_descriptions = {
[-1]={{"i don't know what that is. where did you find this?"}},
6 months ago
[13]={{"these are chives. are we sure this is for alchemy?"}},
6 months ago
[14]={{"this is foxglove"}},
}
function get_conversation(plant)
local id = plant[1]
return plant_descriptions[id] or plant_descriptions[-1]
end
6 months ago
book_pages = {
[1]={
"hester's big book of recipes! alchemists only! dangerous recipes!",
"format: \nrecipe notes \n \ningredient 1 \ningredient 2 \ningredient 3"
},
[2]={
"\nBarthow's Encyclopaedia of Botanicals and Components",
"A comprehensive reference to help identify all ingredients an alchemist needs."
}
}
6 months ago
:: main.lua
6 months ago
--[[pod_format="raw",created="2024-04-02 02:59:37",modified="2024-04-17 14:41:47",revision=1056]]
6 months ago
-- this is atelier hester!
-- except for the one line in _init that does change_screen(shop_screen)
-- this is just a file that sets up the framework we're using:
-- change_scene to change the displayed sscene
-- _update and _draw to run the current scene
-- and some stuff for setting animations.
include("art.lua")
include("script.lua")
include("s_title.lua")
include("s_shop.lua")
include("s_conversation.lua")
include("s_drawer.lua")
6 months ago
include("s_book.lua")
6 months ago
DEBUG = true
scene = {
before=function() end,
draw=function() end,
update=function() end
}
previous_scene = scene
animations = {}
script = {}
function _init()
vid(3)
6 months ago
change_scene(shop_screen)
6 months ago
end
function _draw()
scene:draw()
for anim in all(animations) do
if anim.draw ~= nil then anim:draw() end
end
if DEBUG then
rectfill(0,0,90,10, 7)
print("animations: "..#animations, 0,0,0)
rectfill(0,10,90,20,7)
print("script nodes: "..#script, 0,10, 0)
end
end
function _update()
if #script == 0 or not script[1].blocking then
scene:update()
end
local new_animations = {}
for anim in all(animations) do
local result = anim:update()
if result then
add(new_animations, anim)
end
end
animations = new_animations
if #script > 0 then
local result = script[1]:update()
if not result then
deli(script, 1)
end
end
end
function change_scene(new_scene)
if new_scene.before ~= nil then
new_scene:before()
end
scene = new_scene
end
function play_script(s)
for action in all(s) do
add(script, action)
end
end
6 months ago
:: map/0.map
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixtb2RpZmllZD0iMjAyNC0w
NC0wNSAxMzo1NDowNiIscmV2aXNpb249NjgzXV1sejQAaAAAAFgQAADwCHt7Ym1wPXVzZXJkYXRh
KCJpMTYiLDMyAwAvIjABAP--------------------vxCCIpLGhpZGRlbj1mYWxzZSxwYW5feD0w
CADSeT0wLHRpbGVfaD0xNgoAEHcKAIB6b29tPTF9fQ==
:: map/.info.pod
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixzdG9yZWQ9IjIwMjQtMDMt
MjkgMDE6MTQ6NTEiXV1sejQABAAAAAMAAAAwbmls
:: s_book.lua
6 months ago
--[[pod_format="raw",created="2024-04-14 02:34:41",modified="2024-04-17 14:41:47",revision=92]]
6 months ago
BookScene = {
extension = 0,
behind = nil,
inset = 60,
}
6 months ago
function BookScene:new(background, pages)
c = {height=0, behind=nil, background=background, pages=pages, index=1, fairy=nil}
6 months ago
setmetatable(c, self)
self.__index = self
return c
end
function BookScene:before()
self.behind = scene
play_script({
Script.len(function(s)
self.height = 115*easeDecelerate(s.timer/s.length)
end, 0.5)
})
self.before = function() end
6 months ago
self.fairy = self.behind.fairy
6 months ago
end
function BookScene:update()
if btnp(5) then play_script({
Script.len(function(s)
self.height = 115*(1-easeAccelerate(s.timer/s.length))
end, 0.5),
Script.once(function(s) change_scene(self.behind) end)
}) end
6 months ago
self.fairy:update()
6 months ago
end
function BookScene:draw()
6 months ago
self.behind:draw(true)
6 months ago
6 months ago
if self.fairy ~= nil then self.fairy:draw() end
spr(self.background, 20, 135-self.height)
print(wrap(self.pages[self.index],80), 36, 135-self.height+10, 20)
print(wrap(self.pages[self.index+1],80), 130, 135-self.height+10, 20)
6 months ago
end
6 months ago
:: s_conversation.lua
6 months ago
--[[pod_format="raw",created="2024-04-05 14:55:45",modified="2024-04-14 02:34:19",revision=129]]
6 months ago
default_script = {
{"welcome to Atelier Hester!", talk_sprite}
}
Conversation = {}
function Conversation:new(script, final)
local c = {script=script or default_script, final=final or function() end, index=1}
setmetatable(c, self)
self.__index = self
return c
end
function Conversation:before()
self.behind = scene
self.before = function() end -- only ddo othis the firstt time this scene is played
end
function Conversation:update()
local now = self.script[self.index]
if now.during ~= nil then now.during() end
if btnp(4) or btnp(5) then
if now.after ~= nil then now.after() end
if self.index < #self.script then
self.index += 1
else
self:after()
end
end
end
function Conversation:draw()
self.behind:draw()
ragged_box(30, 100, 240-30, 130)
color(0)
print(wrap(self.script[self.index][1], 240-68), 34, 104)
end
function Conversation:after()
self:final()
change_scene(self.behind)
end
:: s_drawer.lua
6 months ago
--[[pod_format="raw",created="2024-04-05 00:59:36",modified="2024-04-14 20:06:16",revision=296]]
6 months ago
DrawerScene = {
extension = 0,
behind = nil,
inset = 60,
}
function DrawerScene:new(drawer)
c = {extension=0, behind=nil, inset=60}
if drawer.size > 16 then c.inset=30 end
setmetatable(c, self)
self.__index = self
return c
end
function DrawerScene:before()
self.behind = scene
play_script({
Script.len(function(s)
self.extension = 115*easeDecelerate(s.timer/s.length)
end, 0.5)
})
self.before = function() end
end
function DrawerScene:update()
if btnp(5) then play_script({
Script.len(function(s)
self.extension = 115*(1-easeAccelerate(s.timer/s.length))
end, 0.5),
Script.once(function(s) change_scene(self.behind) end)
}) end
end
function DrawerScene:draw()
self.behind:draw()
draw_drawer(self.extension, self.inset)
end
function draw_drawer(distance, inset)
rectfill(inset, -1, 240-inset, distance, 20)
fillp(0b1010110110110101)
rectfill(inset, -1, inset+40, distance, 20 | 21<<8)
fillp()
for i=1,4 do
rect(inset-i, -i, 240-inset+i, distance+i, 4)
end
rectfill(inset-10, distance, 240-inset+10, distance+10, 4)
rect(inset-10, distance+10, 240-inset+10, distance+10, 20)
spr(10, inset-10-32, distance, true)
spr(10, 240-inset+10, distance)
rectfill(inset+10, distance+10+1, 240-inset-10, distance+10+2, 9)
spr(11, 120-16, distance+10+1)
end
:: s_shop.lua
6 months ago
--[[pod_format="raw",created="2024-04-05 14:55:27",modified="2024-04-17 14:41:47",revision=279]]
6 months ago
-- this manages the main shop interface, where you look at the cupboard and plantss
-- and sstuff.
include("art.lua")
include("fairy.lua")
include("cabinet.lua")
include("library.lua")
cabinet = Cabinet:new(40, 10, 2)
fairy = Fairy:new()
alchemist_sprite = 192
alchemist_bob = 0
customer_sprite = 0
customer_bob = 0
customer_visible = false
door_open = 0
6 months ago
book_1 = {left=10, right=74, top=100, bottom=164}
6 months ago
book_2 = {left=70, right=134, top=100, bottom=164}
6 months ago
6 months ago
shop_screen = {}
6 months ago
function shop_screen:draw(hide_fairy)
6 months ago
cls()
cabinet:draw()
-- alchemist!
bob(alchemist_sprite, 0, 7, 96, 128, alchemist_bob)
palt(30, true)
palt(0, false)
6 months ago
spr(16, 240-100, 135-49)
6 months ago
palt(30, false)
palt(0, true)
6 months ago
spr(21+flr(2*t()%11), 240-100, 135-52)
6 months ago
-- countertop!
6 months ago
draw_counter(20)
6 months ago
6 months ago
if collides(fairy, book_1) then spr(18, book_1.left, book_1.top)
else spr(17, book_1.left, book_1.top) end
if collides(fairy, book_2) then spr(20, book_2.left, book_2.top)
else spr(19, book_2.left, book_2.top) end
6 months ago
if customer_visible then
bob(customer_sprite, 240-96, 7, 96, 128, customer_bob)
end
6 months ago
if not hides_fairy then fairy:draw() end
6 months ago
draw_door(door_open)
end
function draw_counter(height)
rectfill(0, 135-height, 240, 135, 4)
for i=1,height do
rectfill(0,135-height, 0.5*i*i, 135-i, 4+16)
rectfill(240,135-height, 240-0.5*i*i, 135-i, 4+16)
end
line(0,135-height, 240, 135-height, 4+16)
end
6 months ago
function shop_screen:update()
6 months ago
fairy:move()
cabinet:update(fairy.x, fairy.y)
if btnp(4) then
local glow = Glow:new(fairy.x, fairy.y)
glow.start_color = 7
glow.end_color = 12
add(animations, glow)
local drawer = cabinet:drawer_at(fairy.x, fairy.y)
if drawer then change_scene(DrawerScene:new(drawer)) end
6 months ago
6 months ago
if collides(fairy, book_1) then change_scene(BookScene:new(007, book_pages[1])) end
if collides(fairy, book_2) then change_scene(BookScene:new(012, book_pages[2])) end
6 months ago
end
if btnp(5) then
add(animations, Glow:new(fairy.x, fairy.y))
if cabinet.hover_plant ~= nil then
change_scene(Conversation:new(get_conversation(cabinet.hover_plant)))
end
end
end
function draw_door(open)
palt(0x00, true)
if open >=0.0 then fillp(0b1111111111111111) end
if open > 0.1 then fillp(0b1011010111100101) end
if open > 0.2 then fillp(0b1010010110100101) end
if open > 0.4 then fillp(0b1010000110100100) end
if open > 0.7 then fillp(0x0000) end
rectfill(240-(96*open), 135-128, 240, 135, 0x00)
sspr(200, 0,0,96,128, 240-(96*open), 135-128, 96*open, 128)
palt()
fillp()
end
:: s_title.lua
--[[pod_format="raw",created="2024-04-10 01:43:09",modified="2024-04-10 15:04:40",revision=101]]
title_screen = {
continue=false
}
function title_screen:update()
if btnp(2) or btnp(3) then self.continue = not self.continue end
if btnp(4) and not self.continue then
change_scene(shop_screen)
play_script(the_script)
end
end
function title_screen:draw()
cls()
print("Atelier Hester ", 120-(68/2), 50, 7)
print("Start", 120-25/2, 70, 7)
print("Continue", 120-39/2, 90, 7)
local y = 70
if self.continue then y=90 end
rect(120-50/2, y-5, 120+50/2-1, y+7+5, 7)
end
6 months ago
:: screen_drawer.lua
--[[pod_format="raw",created="2024-04-05 00:59:25",modified="2024-04-05 00:59:26",revision=1]]
6 months ago
:: script.lua
6 months ago
--[[pod_format="raw",created="2024-04-04 01:01:55",modified="2024-04-14 03:09:34",revision=554]]
6 months ago
Script = {}
-- sscriptanim generates animation functions and adds the boilerplate we want
-- can track time, but generally the ssystem we're working with is that
-- animations are objects which repeatedly get :update() called on them
-- they run at least once, every frame, *until they return false*.
-- so keep returning true to keep playing, rerturn false to end
-- the blocking argument determines whether update() is called on the underlying
-- scene, i think.
-- the ScriptAnim.len variant will take nil returnss as carte blanche to keep
-- running, checking for exactly the value false to cancel out.
function Script.len(func, len, blocking)
local b = blocking
if b == nil then b = true end
return {
timer = 0,
length=len,
blocking=b,
update=function(self)
-- we wrap the function we got passsed so that it'll update the timer
-- and end appropriately
self.timer += 1/60.0
if func(self) == false then return false end
return self.timer < self.length
end
}
end
-- ScriptAnim.once is cnofusingly named, and will call func(self) every frame
-- until it returns false.
function Script.once(func, blocking)
local b = blocking
if b == nil then b = true end
return {
timer=0,
blocking=b,
update=function(self)
self.timer += 1/60.0
return func(self)
end
}
end
-- stay in this script node until func(self) sets self.done to true
function Script.waitTilAfter(func, blocking)
local b = blocking
if b == nil then b = true end
return {
first=true,
done=false,
timer=0,
blocking=b,
update=function(self)
if self.first then
func(self)
self.first = not self.first
end
return not self.done
end
}
end
-- functions for making a cnoversation script line that bobs the alchemist or the
-- custmoer respectively
function A(arg)
arg.during=function() alchemist_bob=abs(5*sin(3*t())) end
arg.after=function() alchemist_bob=0 end
return arg
end
function B(arg)
arg.during=function() customer_bob=abs(5*sin(3*t())) end
arg.after=function() customer_bob=0 end
return arg
end
-- here's a sample script for a guy walking in and asking for flibbertygibbets
the_script = {
Script.len(function(s) -- open door
door_open = easeTrig(s.timer/s.length)
6 months ago
end, 0.5),
6 months ago
Script.once(function() -- person appearss
alchemist_sprite = 193
customer_visible = true
customer_sprite = 201
return false
6 months ago
end),
6 months ago
Script.len(function(s) -- door closes
door_open = easeTrig(1-(s.timer/s.length))
6 months ago
end, 0.5),
6 months ago
Script.waitTilAfter(function(s) -- cnoversation starts
change_scene(Conversation:new({
A{"Welcome to Atelier Hester!"},
B{"hey do yuo have flibbertygibbetss"},
A{"Fresh out, sorry."}
}, function() s.done = true end))
end, false),
Script.len(function(s) -- open door
door_open = easeTrig(s.timer/s.length)
end, 0.5),
Script.once(function() -- person appearss
alchemist_sprite = 192
customer_visible = false
return false
end),
Script.len(function(s) -- door closes
door_open = easeTrig(1-(s.timer/s.length))
end, 0.5),
}
:: sfx/0.sfx
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixtb2RpZmllZD0iMjAyNC0w
NC0wNSAxMzo1NDowNiIscmV2aXNpb249NjY4XV1sejQAEAEAAFEHAADwJ3B4dQADKAAAAwAED0AQ
Ag4AAaABIAKgDgAPEAAN8MoBAgMEBQYHAA--kAgJCgsPDA8NDw4PDxAA8AANDxEPEg8TDxQPFQ8W
DxcTAPEBDxgPGQ8aDxsPHA8dDx4PHxQA8QAgDyEPIg8jDyQPJQ8mDycUAPEAKA8pDyoPKw8sDy0P
Lg8vFADxADAPMQ8yDzMPNA81DzYPNxQA-wU4DzkPOg87DzwPPQ8_Dz8AD--w-wEA6-8nWgEQBg8g
EAEgASAB8AACEAIMEAEgDyEgATAPQPDDDygP--DGD-gKD-8PgA-3Dw0B8AkBEAYMMAD-OR--AQDc
v-gPQAANQP--sPBwCgD--2Qf-wEAl1D-----Hw==
:: sfx/.info.pod
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixzdG9yZWQ9IjIwMjQtMDMt
MjkgMDE6MTQ6NTEiXV1sejQABAAAAAMAAAAwbmls
6 months ago
:: shop.lua
--[[pod_format="raw",created="2024-03-29 01:14:51",modified="2024-04-05 14:54:05",revision=1117]]
-- this manages the main shop interface, where you look at the cupboard and plantss
-- and sstuff.
include("art.lua")
include("fairy.lua")
include("cabinet.lua")
cabinet = Cabinet:new(40, 10, 2)
fairy = Fairy:new()
alchemist_sprite = 192
alchemist_bob = 0
customer_sprite = 0
customer_bob = 0
customer_visible = false
door_open = 0
shop_screen = {}
function shop_screen.draw()
cls()
cabinet:draw()
-- alchemist!
bob(alchemist_sprite, 0, 7, 96, 128, alchemist_bob)
fairy:draw()
-- countertop!
draw_counter(14)
if customer_visible then
bob(customer_sprite, 240-96, 7, 96, 128, customer_bob)
end
draw_door(door_open)
end
function draw_counter(height)
rectfill(0, 135-height, 240, 135, 4)
for i=1,height do
rectfill(0,135-height, 0.5*i*i, 135-i, 4+16)
rectfill(240,135-height, 240-0.5*i*i, 135-i, 4+16)
end
line(0,135-height, 240, 135-height, 4+16)
end
function shop_screen.update()
fairy:move()
cabinet:update(fairy.x, fairy.y)
if btnp(4) then
local drawer = cabinet:drawer_at(fairy.x, fairy.y)
if drawer then change_scene(DrawerScene:new(drawer)) end
end
end
function draw_door(open)
palt(0x00, true)
if open >=0.0 then fillp(0b1111111111111111) end
if open > 0.1 then fillp(0b1011010111100101) end
if open > 0.2 then fillp(0b1010010110100101) end
if open > 0.4 then fillp(0b1010000110100100) end
if open > 0.7 then fillp(0x0000) end
rectfill(240-(96*open), 135-128, 240, 135, 0x00)
sspr(200, 0,0,96,128, 240-(96*open), 135-128, 96*open, 128)
palt()
fillp()
end
6 months ago
:: [eoc]