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.
1232 lines
39 KiB
1232 lines
39 KiB
picotron cartridge // www.picotron.net
|
|
version 2
|
|
|
|
:: gfx/
|
|
:: map/
|
|
:: sfx/
|
|
:: art.lua
|
|
--[[pod_format="raw",created="2024-03-31 01:52:08",modified="2024-04-14 22:07:40",revision=671]]
|
|
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
|
|
--[[pod_format="raw",created="2024-04-03 19:46:51",modified="2024-04-14 22:07:40",revision=668]]
|
|
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
|
|
:: 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
|
|
:: 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
|
|
NC0xNCAyMjowNzo0MCIscmV2aXNpb249MTE4NV1dbHo0AOIcAAASZAAA8Rp7WzBdPXtibXA9cHh1
|
|
AEMgEBAE8PAsZmxhZ3M9MCxwYW5feD0wLjM3NQwA_wJ5PS0wLjEyNSx6b29tPTV9LDoAkCR6cAoP
|
|
HU8eCgcAcD8ODx4KYBoJAP8CDRpQCh8dPw4dClAKDx1fDg0IAAT-Aw8eClAKDl8ODgpQCn4KUJrw
|
|
A4sAJqUGOrAKHxMKsAoeBADwAKAaHhqQCgMOEQqQCgMPEgcAPQ4dAQYArw4KkAo_CpBa8AV9ACYQ
|
|
Jn0AER1xAP8GYDoPFy46MAo9HxweHxIKMAodbxwPCAACIF8cIAD-ARodPxwODxIaQBpeGmB68ASE
|
|
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
|
|
DgQQHgAa4DoALgAEDxQzCvAACi4AHiQNPgoAUQAuEAMkCgDgICQQFBAq8AAKHhQANCOwAKBeJBAa
|
|
8AEKfhQeSgAhLkAIANIaYBQQSuAK7xgK4ArsBAChGswa8AAKzArwAQUAfxqsGvACypDZACfwDl1K
|
|
8AZaLxMK8AYKTgQeCvAGGh4TBBMq8AUKIA5DOgHwByAeBD4a8AMKLhAELgAOCvADCkMkEwCdABAw
|
|
ugBAAgoOQ7sAsAIKDgMODxQuFA4AdQEwEB0QwgDTBAogDRAUEDrwAQrGCgUAIBqmLgAQpiYAEIZh
|
|
ABCGAQIfhqABJ-1iYGAE-x4P-xUS-x4j-xUo-x4R-xU2-x4G-xU_3x7-FUZ-Hv8VSj8e-xUM8Bj_
|
|
Cg8e-gHwMP4FBT7wPD4FnhUO8EAOFZ518DZ1rvUE8Bz1BM71Qv4A9T7_BPU6-gv1MP4c9Rj_Ch3_
|
|
Th3_Ti3_TE3_Sl0DAE9N-kw9AwAEES05AAUDACAN-k8DNP81DREABVkABTIAAmIAQW3_SH0DAPtY
|
|
jf5Gnf5Grf5Ezf5C3f5C7f5A-QH_Pv0C-j79A-48-QX_Ov0H-jj9Cf42-Qv_NP0N-jL9D-4w-RH_
|
|
Lv0T-iz9Ff4q-Rj_Jv0b-iT9Hv4g-SH_Hv0k-hr9Kf4U-S7_EP00-gj9Pd79GXoBdC01LjE1ODMB
|
|
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=
|
|
:: gfx/.info.pod
|
|
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixzdG9yZWQ9IjIwMjQtMDMt
|
|
MjkgMDE6MTQ6NTEiXV1sejQABAAAAAMAAAAwbmls
|
|
:: library.lua
|
|
--[[pod_format="raw",created="2024-04-10 00:24:20",modified="2024-04-14 22:07:40",revision=101]]
|
|
plant_descriptions = {
|
|
[-1]={{"i don't know what that is. where did you find this?"}},
|
|
[13]={{"these are chives. are we sure this is for alchemy?"}},
|
|
[14]={{"this is foxglove"}},
|
|
}
|
|
function get_conversation(plant)
|
|
local id = plant[1]
|
|
return plant_descriptions[id] or plant_descriptions[-1]
|
|
end
|
|
|
|
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."
|
|
}
|
|
}
|
|
|
|
:: main.lua
|
|
--[[pod_format="raw",created="2024-04-02 02:59:37",modified="2024-04-14 22:07:40",revision=1053]]
|
|
-- 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")
|
|
include("s_book.lua")
|
|
|
|
DEBUG = true
|
|
|
|
scene = {
|
|
before=function() end,
|
|
draw=function() end,
|
|
update=function() end
|
|
}
|
|
previous_scene = scene
|
|
|
|
animations = {}
|
|
|
|
script = {}
|
|
|
|
function _init()
|
|
vid(3)
|
|
change_scene(shop_screen)
|
|
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
|
|
:: map/0.map
|
|
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixtb2RpZmllZD0iMjAyNC0w
|
|
NC0wNSAxMzo1NDowNiIscmV2aXNpb249NjgzXV1sejQAaAAAAFgQAADwCHt7Ym1wPXVzZXJkYXRh
|
|
KCJpMTYiLDMyAwAvIjABAP--------------------vxCCIpLGhpZGRlbj1mYWxzZSxwYW5feD0w
|
|
CADSeT0wLHRpbGVfaD0xNgoAEHcKAIB6b29tPTF9fQ==
|
|
:: map/.info.pod
|
|
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixzdG9yZWQ9IjIwMjQtMDMt
|
|
MjkgMDE6MTQ6NTEiXV1sejQABAAAAAMAAAAwbmls
|
|
:: s_book.lua
|
|
--[[pod_format="raw",created="2024-04-14 02:34:41",modified="2024-04-14 22:07:40",revision=89]]
|
|
BookScene = {
|
|
extension = 0,
|
|
behind = nil,
|
|
inset = 60,
|
|
}
|
|
|
|
function BookScene:new(background, pages)
|
|
c = {height=0, behind=nil, background=background, pages=pages, index=1, fairy=nil}
|
|
|
|
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
|
|
|
|
self.fairy = self.behind.fairy
|
|
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
|
|
|
|
self.fairy:update()
|
|
end
|
|
|
|
function BookScene:draw()
|
|
self.behind:draw(true)
|
|
|
|
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)
|
|
end
|
|
:: s_conversation.lua
|
|
--[[pod_format="raw",created="2024-04-05 14:55:45",modified="2024-04-14 02:34:19",revision=129]]
|
|
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
|
|
--[[pod_format="raw",created="2024-04-05 00:59:36",modified="2024-04-14 20:06:16",revision=296]]
|
|
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
|
|
--[[pod_format="raw",created="2024-04-05 14:55:27",modified="2024-04-14 22:07:40",revision=276]]
|
|
-- 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
|
|
|
|
book_1 = {left=10, right=74, top=100, bottom=164}
|
|
book_2 = {left=70, right=134, top=100, bottom=164}
|
|
|
|
shop_screen = {}
|
|
function shop_screen:draw(hide_fairy)
|
|
cls()
|
|
|
|
cabinet:draw()
|
|
|
|
-- alchemist!
|
|
bob(alchemist_sprite, 0, 7, 96, 128, alchemist_bob)
|
|
|
|
palt(30, true)
|
|
palt(0, false)
|
|
spr(16, 240-100, 135-49)
|
|
palt(30, false)
|
|
palt(0, true)
|
|
spr(21+flr(2*t()%11), 240-100, 135-52)
|
|
|
|
-- countertop!
|
|
draw_counter(20)
|
|
|
|
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
|
|
|
|
if customer_visible then
|
|
bob(customer_sprite, 240-96, 7, 96, 128, customer_bob)
|
|
end
|
|
|
|
if not hides_fairy then fairy:draw() 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 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
|
|
|
|
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
|
|
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
|
|
:: screen_drawer.lua
|
|
--[[pod_format="raw",created="2024-04-05 00:59:25",modified="2024-04-05 00:59:26",revision=1]]
|
|
|
|
:: script.lua
|
|
--[[pod_format="raw",created="2024-04-04 01:01:55",modified="2024-04-14 03:09:34",revision=554]]
|
|
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)
|
|
end, 0.5),
|
|
Script.once(function() -- person appearss
|
|
alchemist_sprite = 193
|
|
customer_visible = true
|
|
customer_sprite = 201
|
|
return false
|
|
end),
|
|
Script.len(function(s) -- door closes
|
|
door_open = easeTrig(1-(s.timer/s.length))
|
|
end, 0.5),
|
|
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
|
|
:: 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
|
|
:: 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
|
|
:: .info.pod
|
|
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTA0LTEyIDE2OjM3OjU3IixydW50aW1lPTUsc3RvcmVk
|
|
PSIyMDI0LTA0LTE0IDIyOjA3OjQxIix3b3Jrc3BhY2VzPXt7bG9jYXRpb249Im1haW4ubHVhIzIx
|
|
Iix3b3Jrc3BhY2VfaW5kZXg9MX0se2xvY2F0aW9uPSJzX3Nob3AubHVhIzQ5Iix3b3Jrc3BhY2Vf
|
|
aW5kZXg9MX0se2xvY2F0aW9uPSJzX2Jvb2subHVhIzQzIix3b3Jrc3BhY2VfaW5kZXg9MX0se2xv
|
|
Y2F0aW9uPSJsaWJyYXJ5Lmx1YSMzIix3b3Jrc3BhY2VfaW5kZXg9MX0se2xvY2F0aW9uPSJhcnQu
|
|
bHVhIzEiLHdvcmtzcGFjZV9pbmRleD0xfSx7bG9jYXRpb249ImNhYmluZXQubHVhIzEiLHdvcmtz
|
|
cGFjZV9pbmRleD0xfSx7bG9jYXRpb249ImdmeC8wLmdmeCIsd29ya3NwYWNlX2luZGV4PTJ9fV1d
|
|
bHo0AAQAAAADAAAAMG5pbA==
|
|
:: [eoc]
|
|
|