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.
1331 lines
42 KiB
1331 lines
42 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-29 15:31:52",revision=710]]
|
|
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)
|
|
add(collider_renders, 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-23 02:36:18",revision=694]]
|
|
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-23 03:08:39",revision=432]]
|
|
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(10*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:update()
|
|
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
|
|
|
|
if btnp(4) then
|
|
local glow = Glow:new(self.x, self.y)
|
|
glow.start_color = 7
|
|
glow.end_color = 12
|
|
add(animations, glow)
|
|
end
|
|
|
|
if btnp(5) then
|
|
local glow = Glow:new(self.x, self.y)
|
|
add(animations, glow)
|
|
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
|
|
NC0yOSAxNzo1MDoyMSIscmV2aXNpb249MTI4Nl1dbHo0AGAeAAAZZwAA8Rp7WzBdPXtibXA9cHh1
|
|
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
|
|
Go5VAGyOCvAFqqDHAGQ1LjE1ODMBAATQAFcxNC44MBcAAdoAHjPaAMAAOvAMCh8TGvAIOi7VAPAi
|
|
HgAuOvAFCi4AThrwAiouJD4K8AIKFA4ADgQQHgAa4DoALgAEDxQzCvAACi4AHiQNPgoAUQAuEAMk
|
|
CgDgICQQFBAq8AAKHhQANCPEAKBeJBAa8AEKfhQeSgAhLkAIANIaYBQQSuAK7xgK4ArsBAChGswa
|
|
8AAKzArwAQUAfxqsGvACypDtADvwDl1K8AZaLxMK8AYKTgQeCvAGGh4TBBMq8AUKIA5DYgHwByAe
|
|
BD4a8AMKLhAELgAOCvADCkMkEwCxABAwzgBAAgoOQ88AsAIKDgMODxQuFA4AnQEwEB0Q1gDTBAog
|
|
DRAUEDrwAQrGCgUAIBqmLgAQpiYAEIZhABCGKQIfhsgBQD----NRADbwJ0BABPD-WiIfGPAmQl7w
|
|
IEKu8BtC-gHwFjL_AiIe8BBC-gFCXvAKQv4CMq7wBUL_AkL_APABIggA8D0G4P4BQn54vtDOMk6I
|
|
Xhi_wH5CTkjuGK7ATiJ_KD74Ab6w3pi_GA4YvqAeAp447kgeGM6QHgIHjggeGK44XgjugB4CB34Y
|
|
Lhh_KH4YDQDQDw8HbghOGE4ofij_AB0AYA1_CE4YHg8A8BoCgB4CHQduCF44bjj_A6AeDQcNbhhe
|
|
GC5Y-gIHHcAeHQduyP4DBz0XwBoA8gT_FActNx3ALh0H-g8HPTcNGhcOGABwDS1HHUousBkAkQgf
|
|
Dh1HLWoe0BkA8AgFbBctJw5KDvABHh0H-gA9XC0XTirwBBwA8AXOLTcsLRd_8AcuHX4HPVctJ37w
|
|
CxgAYD4HLQcbNw8AEA4PAEAHPQdbDQDxHRIeLSd7J37wFR4NR3t_8BguDScdW17wGz4HHRcrXvAf
|
|
LheO8CKu8CZu8CseqQQf5CcKCRYxqAQfNLUBHTBu8Am1ATHO8AO1ASEC4LQB8iIIwP4BQv4OsM4y
|
|
zri_kH5CfpheWL6ATiKeOG6oDhjOcO44HnheGC4Y3nAeAp54rig_tAEApwFRnihOKN4NAKMIXghu
|
|
GE44zhegtQGQbhgeKC5IzkegtQHwAwdeOF6I3negHgIdF46I-gKXsCEBsxf_EMfAHh0n-gunpwFC
|
|
F-4Ht6gBhif_AycfDmctqwFUJ943XBeuAUY3jmdsrQFGN06nfK4BKPcBrQEWx60BF4esARlHqwEv
|
|
Fy2rAV7wJtlvG-AZ-gjwEv4O8A3_FPAI-hjwBv4Mem7wBO7a-gDwA35q-g7wAv4f8AD_IeAOCv4H
|
|
ev4ACADxIABqXgr_AtAOCv4BGn4a-gPQCv4EGk4K-gbACv4GGh4K-giwCv4IGv4JsAoOCv4hBgD2
|
|
CiKgHgr_EXqOoA4K-gPq-gGgDgquev4QoA4jACAgwAYAQBoHHgdlAPAHDvcC4AoOCk73A-8PB9AK
|
|
Dgoe-Qb3BhMAcA73Bv0I0BoQABAH5wUg9x0GAPEK-R7gCi73Gx7wAF6H-gHXLuD_IfAA-gKA-poE
|
|
T----30pASbwLxc-G-ApfvAj3vAe-gPwGP4AKl7wEv4BOo7wDv4BOt7wCu5K-gPwB846-gnwBZ46
|
|
-g3wBW4q-gAq7vAD-gVaJwFh8AH_AjpuCQDwAw4KziqeCv4D8AAOCu46Xgr_BAoAgf4DOh4K-gXg
|
|
OAHQBuAK-hYqftAK-hFKrvsAUf4LOv4BHgHwBQZK-gXAHgr_AUr_CdAOCt46-gg3QABhrir_Bqfg
|
|
TQFRDPcB8AAsACD3CC8Br-4A9w7gDgqu9xVQAXEjYBBAABv1PwAnLTQMCTQxLjSREB8zPwB4DucG
|
|
Dz0ACh81uwAsDz8A-3UPbxsaDzoA---------wf9YmBgBP8eD-8VEv8eI-8VKP8eEf8VNv8eBv8V
|
|
Pt8e-xVGfx7-FUo-Hv8VDPAY-goPHv4B8DD_BQU_8Dw_BZ4VDvBADhWedfA2da71BPAc9QTO9UL_
|
|
APU_-gT1Ov4L9TD_HPUY-god-k4d-k4t-kxN-kpdAwBPTf5MPQMABBEtOQAFAwAhDf4pCCQ1DREA
|
|
BVkABTIAAmIAQW3_SH0DAP9Yjf5Gnf5Grf5Ezf5C3f5C7f5A-QH_Pv0C-j79A-48-QX_Ov0H-jj9
|
|
Cf42-Qv_NP0N-jL9D-4w-RH_Lv0T-iz9Ff4q-Rj_Jv0b-iT9Hv4g-SH_Hv0k-hr9Kf4U-S7_EP00
|
|
-gj9Pd79GXoBIw75CA8-AP9VDi4DD3kAHP8LcP8SGPAc-jDwCv488AL_QPAF-jbwF-4c8GlWAC--
|
|
Be4-Hf4d8Ar_BT3_Ez2_8AL_Lj3eYAAz8AYSDx0AHgAO4F8e8DP-EgZ-Hp8SAA4CAP8d8BZNDx5t
|
|
Di0OHQ7NDlwO-QbwCo1MfQ79Al6tDh0eHQ6d8AL9QPAF-TbwF-2EACrxD6cPHvBPDiAO8EcOIA4Q
|
|
DvBJDnAO8Cg_8BIO8CheIP8A-xYtXv0n8AqdPq1ufXL9DPAC-QEy-QVyXVL9AvAF-SJyvfAX-RZS
|
|
hAApESaEAPA1EA7wTw7wSA4QDxIgDvBIHg1wDvBDDUAdIA4ADcBN8DQeHQANII0u-QwQTfAVTQAO
|
|
zU79F-AKnQ4NHj0SXU6Nkm0S-QGdAP8KIv0Ekk1y-QHwBZ0S-RUSHgIuEq3wF-0VYqMAKfAK-1gv
|
|
HvARFvApTvBDDxJQHgc_TfA9bW79Co0A8RotMh0SjU5NQi1CbR698Ap9wl0uTTIN0h0eAg1CrfAC
|
|
zYJdQm2STSIeIpUAjyL9B0Itcj4ilQAu8EhzHx5wHvBGDvAUJvAdLvAdJvAfDvADDvBMPvAJFvAi
|
|
HlAu8EYeMC8SDg2QHvADFvAiDVAOLQ4NDk3wPc0OHSJNYl0_AE3wFaINIo0Osg1iLV4ibSAi8AS-
|
|
APMREi0O8gJegh1C8AKNsi49cg0ukk0CXlK98AWdMl0CvXLAAH89Mk1SHYJtxQApoZom8E0m8K4W
|
|
8EYFAvFLQBbwKjIPEvAJDvApDQDSLQBSMCIOMELQMvATfaJNYh0OAh0yAB0ugCLwABJQsg4iLdIe
|
|
Ig3yAy49EELwAfIBTkI-EyItEj5SPvIJ8AKN8gs8Yjw9cg4yHVI9uwD-AhKtci0iPgIOUj0eTfAX
|
|
PfIKvAAq8Ej6LxbwTS7wrQYF8CIGgAZgPx4wBvANMvAbQkBdYDKABQaQQsAS8AQPEgDSHF3yA7BS
|
|
wDLwAC0M8gBdcgwSHHIMMjBC8ABSEKItEgziPRIMTxMtUityDGLJAP8eTUI7EiviPfII8AEMIgwS
|
|
HOI7clsiWz2yW2LwBTzyFwzyARwyLPAXEhzyChyywwAo8xMaTx6QHvC7LgAvFvAhXqAO8AMuMC3w
|
|
Nh4QDvBEHoAOAE6w3QD0BzAeAA4QDjAGXvAHMsAy0F5QQmAOAB7mAPEPQrB_oi4CDjIOQn5SsFLA
|
|
sjAeB14CXvIDDgduYg8S6ADA4o4MYj8ToiuOEmsy5AAg4m7jAPESYisifvIG8AFyG1JOIltSWyI7
|
|
XoKLYvAFUjvyAnvyAgtS5wAf8uMEKfE5OAUwBfBLNfBLRfB7Px7wHhXwGq4wBvAKBvAIHxOQTaAu
|
|
F25gBuBeoBWgLQINsDKALgeeIELAjjA_wELAQnAeB66CLgIOIl4H2gDggi0A-gPiHgeeAg0yPhLY
|
|
APAdws5SPRJtAt4CbTINYvABEi1yrm0SLWItAp5STaLwAXIdMn4CbVJdIj1ego3ZAP4BPQ7yAd2y
|
|
DUKd8BdyTfIETToFDzIHGA86AP------------8kAY4d-wAeFzbwCgcwBvALBhAG8AwFAA-wFwsG
|
|
MAbwCBZQFvAFBx8ccAbwAwcvGi8cED4G8AEHbxoeTQbwAAfdBQBzHQutBvAABgcA-wgtC50G8AEG
|
|
vQbwAwadBvAFFl0W8AhWwBIVJQAuEfF6--r2BvA6Bv8aBAbwORb_BAbwOBb_BQbwNxb_BhbwNRb_
|
|
CAbwNBb_CQbwMxb_CwbwMRb_DBbwLib_DhbwLBb_EhbwKCb_FBbwJhb_FxbwJBb_GRbwISb_Gxbw
|
|
Hxb_HxbwHBb_ISbwGRb_JBbwFxb_JhbwFRb_KQbwFAb_KhbwEhb_KxbwEQb_LQYGAHYW8A8G-i8G
|
|
BgBPMAbwDgYAmVEwnxjwAAkAUw0GUAYNDAASnQgAEGD8ARkDCgASthAAE5AYAE_gBvACCAAII2ZA
|
|
EAA-UAYwCgAdUFbwA-Yw8gEfYy8CFB8yXQMnDzoA-----------------9nwI2CABPD-JL8U8ED_
|
|
AvA8-gbwOT8V-gTwNz3_BfA1Tf4H8DNN-gjwMk3_CvAwTf4L8C9dBQD4AE3_DPAuXf4N8C1N-g3w
|
|
LgUAMwzwLwUAMQsPDwcAEDwmAPAMCTzwLBxN-gg88C4cPf4HLA8X8DFN-gULHAsMCQDwrAQMCwwL
|
|
DPAzTb4tLg8ZHAsc8DNdjj0uGjzwNV1ObR4qPPA2-QFKPPA3zXos8DkKTdoc8Dv6AwzwO5oMivA7
|
|
amx68DpafHrwOVofHAxpavA4WqlaOfA0WslKOfA0SgDpKknwMyogmS8QKQpZ8DQKSEn4BPAw_BHw
|
|
LmgPCvgM8CtoFygn_AfwKfgDNzgXqPAoJ-gMB7jwIgf4EieI8CH4FgeI8CD4GAd48CD4GSc48B-4
|
|
IfAf_CLwHfggBxgGAPEHFxjwHPghByjwG-gl8Bv4JvAaKAn4IgYA8CMOCfgE8BoYCfgOGSgJ_ADw
|
|
GRgJ_A8ZGAmYB1jwGAgZ_BAJKAmIB1jwGQn4ERkoCRgJWBkAVAn4Eik4CwDxAhQZGBlYF1jwFwn4
|
|
FRkIGWgHCwCBGBno8BYJ_Bk_AGQUGfgVGRgLAFAUCTgZ6AkAEBpyAIITGfgaGYgXOAkARvgA8BII
|
|
ABEbiACBEQn4HAmoB0gJACQZmAkAsPgB8BAZ_BspqAc4CQCmHBm4BzjwDwn4HQkAocgHGPAQCfgc
|
|
KdhOACApyGUAMBOpuH0A8AEPSXgZqPAVGfgOGbgZiPAXQgDyAQggGPAaKfgbGQjwHyn4HAkHABAZ
|
|
BgDwJBo5DwzwHin4GFkG8B8Z_BdpLfAdGfgUaQYJTfAcGfgReQZt8B4J_A6ZbRXwHhn4CpmNJQgA
|
|
UAapFm1VCQDyQgK5Fn2F8B4ZyMkGjcXwHgmYuc3V8B8JWKnd9QLwH8kGzfUFAAXwHpkVjfUN8B5p
|
|
rfUPAAXwHQ0ZvfUV8Bvd9RjwGY0FDfUc8Bkt9STwGT0FDQIAovUc8Bgt9SbwFy0QAEMFDfUdEgAG
|
|
JACkHvAVPfUo8BQtFRIAhiDwFC31KvASJACFIvASLfUs8BASAAEUAIUQLfUsAAXwD14AABYAmQ8G
|
|
8A899SoAFRgAA1gAiw8t9S0ABfAM7wNuLTI5LjEwHTlIMzguNzQ5D5ZDAAEEBPEt---DbxTwRe7w
|
|
PD8Vfile8Dhdjile8Dc9DkluCW7wNj0OWe7wNT0OaW4KbvA0HT5p7vA0DU5Z-gDwNG5JBgDwhClu
|
|
rxnwNN7c8DQZjvwB8DQZbvwDEB8P8DAZXvwDEBvwMRle-AILACvwMW6c2-Axbozb8DJejJsfHyvw
|
|
Ml58iyg78DJebEsIGygnG-AzXlwrOEsfDgcL8DReLB8XGyhLCBsfDivwMx57HxcYCxcPDisYW-Az
|
|
DpsPFwsnHw47GEvwMx5LHxdLFx8OSwhL8DM_Ky8XuxYA8CcNTgwLFrsIW-AzPR4s6xgr8DM9DhwA
|
|
LKsoO-AzLQ5siyhLHxzwNYxrGFsGDxAfHPA0jADLBi8KAPJJMqyrFgU-EBXwMQwAfKsGG0Ql8DCc
|
|
20QVFPAvrMtEJZTwJ4xFixUkRaTwJIwFNBV7JQQF9AHwInwVRCV7JfQBFfAgfAWEBWsl9AMF8CBs
|
|
BZQFaxr0BfAgXAoA8UEG8B9cBZQVawoF9AbwHkwABZQVWw8MCgX0B-AeLAAldAUEFTsTGvQH8CEV
|
|
BBVkBRQFSgUapAW08B8VChQlRAUUGlQKpAXE8BwVAwpEJSQFpA4A8AYaFQQKdCUEBbQKlAXU8BgV
|
|
xCXECoQKAFAFAwrEFQwA8Ark8BYFAwr0FwX0APAVBQr0GBX0APATFfQaCABgEgX0EgqECgDzABEF
|
|
9BMKdAAF9ALwDwX0FAsAcA4F9BUKZBALABANCwARdAsAQQwF9BYhADQD8AsLAKEE8AoF9B8AFfQD
|
|
CQAQEB0AMgr0IAgAUNQV9BAQGwDyAQgF5AX0CApkIBX0AvAI9AANADIl9AENAIUJCkQQFRQl5A4A
|
|
QQAVRAUOAGAV9AgKRAA6ATAI9AEbAB80DQACwRX0DQAF9AXwCPQDBQsAMwTwCQsAUAQq1PALDACA
|
|
DCAaBBq08AwMAMAICiQQCjQalPAN9AJjAKAkAApUCoTwDvQCVwAADgBAGmTwDw4AkgoKJBVUClTw
|
|
EA0AYTQFVBo0BQ4A8QQEdfQBCjQFZAokBfAR5FVkBfQADwCBFAXwEvQNBeQNAHAEBfATBfQMHACz
|
|
JAVkCgXwFAX0CxUOAMHwFQX0DBrkCiQFClQNAHALOvQCevAXaQBgFFpE6-AYCgBSZBoU6xYLAIB0
|
|
CgTbBivwGaUAVIQK6xYbFwBBywYrBg0AUQkKdArbDQASFyUAAA0AMQvwGAwAhGs-BTsGGwYLKQAx
|
|
S2IrDwABUABEVBorgg8AUdS1WuIbDABiGgVkdfIOGADyEhtlbfIOOwYLAhvwGo0CDfISKwYLQvAZ
|
|
LfIcC2LwGT0CDQIAEPJIBVLyJfAYLRAAgAIN8h7wFy3ySAUCEAABEgAwFT3ySAUUEhIAAEgFEPJI
|
|
BQIQADACDfJIBRDySAUnAg0UAGUQLfIu8A9cAJ8CDfIk8A498i4oBSwPoAknD4gK-yAg-xTEGvEB
|
|
fPQ--gEE-xU9BP4BBP08DgcAIDseBwBBLfQ3LggATwT_NQQKAP80BFIBIfQ4YgExHfQ6cQFyDfQ9
|
|
-gH0P70wMf--6JQBH-2TAf92H1z2GyID5gnyKxjfFvBALr8PHvA9Lu0e8Dse-QIO8Doe-QMe8DkO
|
|
-QMfEQ4N8DUcHs18DhzwMRwAHA7dDA0cDVzwMUwKAPYGHA0MDgzwMQwgHv0BDD0MDvA2Dv0IBgBg
|
|
LU4dTm0uDwCwBR4NDvA3Dl0O-QAIAEBNHv0BIQBRPR49Ds0qAFAeTQ69HgkAUA5dDp0KLQDwDR4d
|
|
Pi0OjQou8DgOTU6dCg7wOR79BA7wOg5NPq0HAPGALQ5tDm0e8DsOHR5NHl0_8DoeHX5NHh0u8Dk_
|
|
QH5NHvBBHs0ODQLwPx7NDxhi8DourQtyG-A5Dp0bYjvwNAs_nQtiGw0r8DICCw0enRtSGz0CC-Aw
|
|
Egu9G1IbXQIL8CwNCyIbrQtSG30CC-AqHQsyG30rQhudAgsC8CgdC1IrPRtiC70bAvAnHQtyW2Ib
|
|
zQsLAPIA8gQb3RvwJi0L8gMb7QILCgCwC-0AG-AlPQvyAhsKAPAEAggX8BA9C-IBG-0CC-ACCDfw
|
|
Dg4A8QAL-QML8AMIN-ANPQvyABsOAEAYR-ALDgBQC-0CDg0eAGAHGDfwCU0SADFNDr0TAEwYBxgn
|
|
EwBIAFfwCBIAYQQIEFfwBxIAIz0eEgByIEcALxXwAxUAIg7NFQA5MEcpEwCwAvADCDA3KQ3wAl2U
|
|
ABUtFQBwQAdJHfABXbcAUB0ezQ4bPABBWa0gvREAIQ7dEQBJIEn9DBAAMCn9DhAA0hIO3Q4CC-AK
|
|
-Q8L8gQMADoL-Q4MABEFCwBUDI0g-QENAPQKDW3wBBvyBc0eAgvwDk3wBQvyBs0OEgvwKAkAcB0O
|
|
vfIFvR4KAPACXhBObcLNDiIL8CANAG69ct0LAPEMGmVuC-0RHiIL8BYVDkVOEC4L-REOMgvwFYWe
|
|
CgDwTfAWhU4AHhAL-RAeIvAXhW4tC-0PHjIAC-AV1R0Q-REOQivwFLVgC-0NLjJL8BNlECVgCxL9
|
|
CS6SK-AShYALMv0EPtIb8BFVsAti3T7yAhvwEFWwC-ICPvIGK-AOCwAiHRsIAEAeG-ANCAAgHwsI
|
|
AKbyIBvwDFWg8iILBwBgsPIhG-ALJABnIBvwC2WgCAA-C-AMCAABAEwAAAgAYR4L8A9VoGwAAQgA
|
|
EByHAPAAoAvyGxvwEUXAC-IZG-ASCABAGBvwEwgAQBcb8BQIAEEVK-AVCAA-C-AXCAANITXQCABv
|
|
FkXgC-IUCAAUIxMbCABPCxLwFQkADR8bRAAAYvAA8hTwFwcAHwPyBBUPyAgnDzoA------------
|
|
---3UG09NX19
|
|
:: gfx/.info.pod
|
|
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixzdG9yZWQ9IjIwMjQtMDMt
|
|
MjkgMDE6MTQ6NTEiXV1sejQABAAAAAMAAAAwbmls
|
|
:: library.lua
|
|
--[[pod_format="raw",created="2024-04-10 00:24:20",modified="2024-04-29 16:05:11",revision=200]]
|
|
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"}},
|
|
}
|
|
ingredient_descriptions = {
|
|
["reagent green"]={{"blah blah reagent green blah blah"}}
|
|
}
|
|
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-29 15:34:08",revision=1153]]
|
|
-- 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 = {}
|
|
|
|
collider_renders = {}
|
|
|
|
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)
|
|
|
|
for r in all(collider_renders) do
|
|
rect(r.left, r.top, r.right, r.bottom, 9)
|
|
end
|
|
while #collider_renders > 0 do
|
|
deli(collider_renders)
|
|
end
|
|
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-23 02:42:38",revision=126]]
|
|
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)
|
|
|
|
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)
|
|
|
|
if self.fairy ~= nil then self.fairy:draw() end
|
|
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-29 15:59:50",revision=379]]
|
|
DrawerScene = {
|
|
extension = 0,
|
|
behind = nil,
|
|
inset = 60,
|
|
contents = {
|
|
title = "reagent green",
|
|
small_graphic = 128,
|
|
large_graphic = 129,
|
|
|
|
},
|
|
fairy = nil,
|
|
interior_collider = {},
|
|
contents_collider = {}
|
|
}
|
|
|
|
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
|
|
|
|
c.interior_collider = {left=c.inset, top=0, right=240-c.inset, bottom=c.extension}
|
|
c.contents_collider = {
|
|
left=120-96/2,
|
|
top=10,
|
|
right=120+96/2,
|
|
bottom=10+96,
|
|
}
|
|
|
|
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
|
|
self.fairy = self.behind.fairy
|
|
end
|
|
|
|
function DrawerScene:update()
|
|
self.interior_collider.bottom = self.extension
|
|
|
|
if (btnp(5) or btnp(4)) and not collides(self.fairy, self.interior_collider) 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
|
|
|
|
if collides(self.fairy, self.contents_collider) then
|
|
if btnp(4) then
|
|
add(self.behind.tray, {self.contents.small_graphic})
|
|
end
|
|
if btnp(5) then
|
|
change_scene(Conversation:new(ingredient_descriptions[self.contents.title]))
|
|
end
|
|
end
|
|
|
|
self.fairy:update()
|
|
end
|
|
|
|
function DrawerScene:draw()
|
|
self.behind:draw()
|
|
draw_drawer(self.extension, self.inset)
|
|
|
|
spr(self.contents.large_graphic,
|
|
self.contents_collider.left,
|
|
self.extension - 115 + self.contents_collider.top)
|
|
self.fairy:draw()
|
|
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-29 17:50:21",revision=430]]
|
|
-- 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 = {
|
|
fairy = Fairy:new(),
|
|
tray = {}, -- list of selected ingredients, up to 3?
|
|
tray_slots = {}
|
|
}
|
|
|
|
for i=1,3 do
|
|
shop_screen.tray_slots[i] = {
|
|
left=108+i*32,
|
|
right=108+i*32+32,
|
|
top=135-4-32,
|
|
bottom=135-4
|
|
}
|
|
end
|
|
|
|
function shop_screen:draw()
|
|
cls()
|
|
|
|
cabinet:draw()
|
|
|
|
-- alchemist!
|
|
bob(alchemist_sprite, 0, 7, 96, 128, alchemist_bob)
|
|
|
|
palt(30, true)
|
|
palt(0, false)
|
|
spr(64, 240-100, 135-49)
|
|
palt(30, false)
|
|
palt(0, true)
|
|
spr(72+flr(2*t()%11), 240-100, 135-52)
|
|
|
|
-- countertop!
|
|
draw_counter(20)
|
|
|
|
if collides(self.fairy, book_1) then spr(18, book_1.left, book_1.top)
|
|
else spr(17, book_1.left, book_1.top) end
|
|
|
|
if collides(self.fairy, book_2) then spr(20, book_2.left, book_2.top)
|
|
else spr(19, book_2.left, book_2.top) end
|
|
|
|
for idx, box in ipairs(self.tray_slots) do
|
|
local ingredient = self.tray[idx]
|
|
if ingredient ~= nil then
|
|
spr(ingredient[1], box.left, box.top)
|
|
end
|
|
end
|
|
|
|
if customer_visible then
|
|
bob(customer_sprite, 240-96, 7, 96, 128, customer_bob)
|
|
end
|
|
|
|
self.fairy:draw()
|
|
|
|
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()
|
|
self.fairy:update()
|
|
cabinet:update(self.fairy.x, self.fairy.y)
|
|
if btnp(4) then
|
|
local drawer = cabinet:drawer_at(self.fairy.x, self.fairy.y)
|
|
if drawer then change_scene(DrawerScene:new(drawer)) end
|
|
|
|
if collides(self.fairy, book_1) then change_scene(BookScene:new(007, book_pages[1])) end
|
|
if collides(self.fairy, book_2) then change_scene(BookScene:new(012, book_pages[2])) end
|
|
|
|
if cabinet.hover_plant ~= nil and #self.tray < #self.tray_slots then
|
|
add(self.tray, cabinet.hover_plant)
|
|
end
|
|
end
|
|
|
|
if btnp(5) then
|
|
add(animations, Glow:new(self.fairy.x, self.fairy.y))
|
|
if cabinet.hover_plant ~= nil then
|
|
change_scene(Conversation:new(get_conversation(cabinet.hover_plant)))
|
|
end
|
|
|
|
for idx, box in ipairs(self.tray_slots) do
|
|
if collides(self.fairy, box) then
|
|
deli(self.tray, idx)
|
|
end
|
|
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-04-23 01:22:37",modified="2024-04-23 01:22:37",revision=0]]
|
|
-- 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)
|
|
|
|
spr(64, 240-96, 135-96)
|
|
|
|
-- countertop!
|
|
draw_counter(14)
|
|
|
|
if customer_visible then
|
|
bob(customer_sprite, 240-96, 7, 96, 128, customer_bob)
|
|
end
|
|
|
|
draw_door(door_open)
|
|
|
|
fairy:draw()
|
|
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$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTA0LTIzIDAxOjEzOjI4IixydW50aW1lPTUsc3RvcmVk
|
|
PSIyMDI0LTA0LTI5IDE3OjUwOjIxIix3b3Jrc3BhY2VzPXt7bG9jYXRpb249InNfc2hvcC5sdWEj
|
|
MSIsd29ya3NwYWNlX2luZGV4PTF9LHtsb2NhdGlvbj0iZ2Z4LzAuZ2Z4Iix3b3Jrc3BhY2VfaW5k
|
|
ZXg9Mn19XV1sejQABAAAAAMAAAAwbmls
|
|
:: [eoc]
|
|
|