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.
1195 lines
37 KiB
1195 lines
37 KiB
picotron cartridge // www.picotron.net
|
|
version 2
|
|
|
|
:: gfx/
|
|
:: map/
|
|
:: sfx/
|
|
:: 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
|
|
:: screen_drawer.lua
|
|
--[[pod_format="raw",created="2024-04-05 00:59:25",modified="2024-04-05 00:59:26",revision=1]]
|
|
|
|
:: 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
|
|
:: art.lua
|
|
--[[pod_format="raw",created="2024-03-31 01:52:08",modified="2024-04-12 14:41:51",revision=629]]
|
|
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 02:34:28",revision=631]]
|
|
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
|
|
:: 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
|
|
NC0xNCAwMzoyMjo1NiIscmV2aXNpb249MTEyMF1dbHo0AJgZAABjXQAA8Rp7WzBdPXtibXA9cHh1
|
|
AEMgEBAE8PAsZmxhZ3M9MCxwYW5feD0wLjM3NQwA_wJ5PS0wLjEyNSx6b29tPTV9LDoAkCR6cAoP
|
|
HU8eCgcAcD8ODx4KYBoJAP8CDRpQCh8dPw4dClAKDx1fDg0IAAT-Aw8eClAKDl8ODgpQCn4KUJrw
|
|
A4sAJqUGOrAKHxMKsAoeBADwAKAaHhqQCgMOEQqQCgMPEgcAPQ4dAQYArw4KkAo_CpBa8AV9ACYQ
|
|
Jn0AER1xAP8GYDoPFy46MAo9HxweHxIKMAodbxwPCAACIF8cIAD-ARodPxwODxIaQBpeGmB68ASE
|
|
ACJRCAgECQACABIQCAAfGQ4AFh8J9QAm-yAQLxyQPgAuUC4AHiAuEC4gLjAOEA4wHgBeEF5ALBos
|
|
YDwaPFAcEAogHIAa0ArwOWgAJccgLDAsUAwADDAMAAwIADAcEBwIABEQAgD-EVAcAAwQDAAcYCwQ
|
|
LIAcGhyQHxwaHpAeCgAegB4aEB6QfwAl8EnIZATw-7X-Dw-wG47wNf8YHf4V-RL_Bv0mcP0a-hn9
|
|
D-4P-R9w-Rb_Hv0M-hr9FnD9D-4m-Qj_Je0_rXD9B-4w-QT_O51wnVf_Od3_QI1wnQf_P73_Qhdd
|
|
CgDyAECd-kQHXXCd-kJtDx-_RQsAYg0PFj0vHxkAaAf_Qh8WXw0ARW8f-kMNAE9-H-5CDQBeCYIA
|
|
Dw0AFAnDAA8NACETTx8BDw0AWk8-H-5GDQAqDlsADw0AwC-_QwwAT2FfH_7H-igOADAm594QAGGu
|
|
R74n-iUSAHAhV94Xbgc_FgBxfjf_Ayf_IhcAcBxXfieeF54XAHFeJ-4IJ-4gFwCQGEduZx4nfheO
|
|
GQBxThf_DCf_HhkAkBRHXleeJ24XfhkAcT4X-hA3-hoZAKARN15H-gIHbhduGgCRLhdu9wOuR-4V
|
|
HACQCPcE-gcXXhdeGwCyHhdON-4CN65X-hAmAaABZz5X-hEnThdOzwDBHhdOF25HvjfOR-4MIACx
|
|
TsdOV-4Hx04XPhe_APA_F04XXicuN75H3jf_CAddcK0uJ26n-gdXvhc_Fx4dFy4PFm8fBz4nXhd_
|
|
J_433mf_AQddcL2ON-4Jh-4IBw49TlwOB84HvkfOR-4A9wDVAPspzT49Lv0Ap-0XLh087hcerT5n
|
|
nkf_DX1w-VMevQ4HHv0HV35n-gaNcP2BBz2eh86dcP2Zjt1w-bADAF-w----3z0FFBwxvAVQ-xQB
|
|
1B4CALAEuQQeBAk-Dxk9CQkAGp0GADEPFQ4IAIcMDgS5BAwO1AMAH_y4BSKfICAE-xQR9A4eAwAC
|
|
wDT5BjQeNAl-Dzl9CQkAMY0ZjQgAL-0EBwALMg8VDgkAHgwIAH-5BjQMDvQOBAASPx78DtYAJXLU
|
|
DxTwAdQOBAD-EsQe8AHEDvACtB7wAqQe8AOUHvAEdC7wBVQu8Adu8P--q2YAJf8J_TAg_gqA_QTQ
|
|
_gDwAdnwAtnwA7nw---8UAAlAEQCH-M9ACfwCKIq8A0KAwrwDBoDCvAISgMACvAICgMgCAAjBToI
|
|
AFAKAxADAAIAZBrwBAoAAwIAHwoOAApEAToAAwIA8A5KwAr-EgEKwCrOKuAKzgrwARquGvACCq4K
|
|
8AMajlUAb44K8AWqoMYAJ8AAOvAMCh8TGvAIOi7BAPAiHgAuOvAFCi4AThrwAiouJD4K8AIKFA4A
|
|
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-kw9AwAEES05AAUDADAN-v8BACQ1DREABVkABTIAAmIAQW3_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
|
|
AASEAVcxNC44MBcAAY4BGTOOAfB0QEAE8P9bPxjwJq7wIe7wHf4E8Bj_BCge8BL_BEhe8Ar_Bziu
|
|
8AX_B0j_APAB-gVI-gbg-gFIfni_0M44ToheGL7AfkhOSO4YrsBOKH4oPvgBvrDemL4YDhi_oM44
|
|
7kgeGM6QLgeOCB4YrjheCO6ALgd_GC4Yfih_GO6ALg8PB24IThg5ALD_AIAuBw1_CE4YHg4A8BkC
|
|
gC4dB24IXjhuOP4DoB4NBw1uGF4YLlj_AgcdwB4dB27I-gMHPRfAGgDyBP4UBy03HcAuHQf_Dwc9
|
|
Nw0aFw4YAHANLUcdSi6wGQCRCB8OHUctah7QGQDwCAVsFy0nDkoO8AEeHQf_AD1cLRdOKvAEHADw
|
|
Bc4tNywtF37wBy4dfgc9Vy0nfvALGABgPgctBxs3DwAQDg8AQAc9B1sNAPAdEh4tJ3snfvAVHg1H
|
|
e37wGC4NJx1bXvAbPgcdFyte8B8uF47wIq7wJm7wKx6YBS--5DMDCRYxMwMfNKUBF5Bu8An_BzjO
|
|
8AOlASAC4KQB8SAIwP4BSP4OsM44zri_kH5IfpheWL6ATiieOG6oDhjOcO44HnheGC4Y3nDOeK4o
|
|
PqQBAJgBUJ4oTijeDACiCF4IbhhOOM4XoKUB8A5uGB4oLkjOR6AuBw0HXjheiN53oC4dF46I-gKX
|
|
sBEBsxf_EMfAHh0n-gunlwFCF-4Ht5gBhif_AycfDmctmwFUJ943XBeeAUY3jmdsnQFGN06nfJ4B
|
|
KPcBnQEWx50BF4ecARlHmwEvFy2bAV7wJtlvG-AZ-gjwEv4O8A3_FPAI-hjwBv4Mem7wBO7a-gDw
|
|
A35q-g7wAv4f8AD_IeAOCv4Hev4ACADxIABqXgr_AtAOCv4BGn4a-gPQCv4EGk4K-gbACv4GGh4K
|
|
-giwCv4IGv4JsAoOCv4hBgD2CiKgHgr_EXqOoA4K-gPq-gGgDgquev4QoA4jACAgwAYAQBoHHgdl
|
|
APAHDvcC4AoOCk73A-8PB9AKDgoe-Qb3BhMAcA73Bv0I0BoQABAH3AYg9x0GAPEK-R7gCi73Gx7w
|
|
AF6H-gHXLuD_IfAA-gKA-loIT----30pASbwLxc-G-ApfvAj3vAe-gPwGP4AKl7wEv4BOo7wDv4B
|
|
Ot7wCu5K-gPwB846-gnwBZ46-g3wBW4q-gAq7vAD-gVaJwFh8AH_AjpuCQDwAw4KziqeCv4D8AAO
|
|
Cu46Xgr_BAoAgf4DOh4K-gXgOAHQBuAK-hYqftAK-hFKrvsAUf4LOv4BHgHwBQZK-gXAHgr_AUr_
|
|
CdAOCt46-gg3QABhrir_BqfgTQFRDPcB8AAsACD3CC8Br-4A9w7gDgqu9xVQAXEhYBBAAPsLcP8S
|
|
GPAc-jDwCv488AL_QPAF-jbwF-4c8GlWAHYtMC4wMjUwAQAUNGMANDIuM2MAHzNjAAf-Be4-Hf4d
|
|
8Ar_BT3_Ez2_8AL_Lj3ebQBA8AYSDx0AHgAO4F8e8DP-EgZ-Hp8SAA4CAP8d8BZNDx5tDi0OHQ7N
|
|
DlwO-QbwCo1MfQ79Al6tDh0eHQ6d8AL9QPAF-TbwF-2RADfxD6cPHvBPDiAO8EcOIA4QDvBJDnAO
|
|
8Cg_8BIO8CheIBkB-xYtXv0n8AqdPq1ufXL9DPAC-QEy-QVyXVL9AvAF-SJyvfAX-RZSkQA2ESaR
|
|
APA1EA7wTw7wSA4QDxIgDvBIHg1wDvBDDUAdIA4ADcBN8DQeHQANII0u-QwQTfAVTQAOzU79F-AK
|
|
nQ4NHj0SXU6Nkm0S-QGqAP8KIv0Ekk1y-QHwBZ0S-RUSHgIuEq3wF-0VYrAANvAK-1gvHvARFvAp
|
|
TvBDDxJQHgc_TfA9bW79CpoA8RotMh0SjU5NQi1CbR698Ap9wl0uTTIN0h0eAg1CrfACzYJdQm2S
|
|
TSIeIqIAjyL9B0Itcj4iogA78EhzHx5wHvBGDvAUJvAdLvAdJvAfDvADDvBMPvAJFvAiHlAu8EYe
|
|
MC8SDg2QHvADFvAiDVAOLQ4NDk3wPc0OHSJNYl0_AE3wFaINIo0Osg1iLV4ibSAi8ATMAPMREi0O
|
|
8gJegh1C8AKNsi49cg0ukk0CXlK98AWdMl0CvXLNAH89Mk1SHYJt0gA2oZom8E0m8K4W8EYsAvFL
|
|
QBbwKjIPEvAJDvApDQDSLQBSMCIOMELQMvATfaJNYh0OAh0yAB0ugCLwABJQsg4iLdIeIg3yAy49
|
|
EELwAfIBTkI-EyItEj5SPvIJ8AKN8gs8Yjw9cg4yHVI9yAD-AhKtci0iPgIOUj0eTfAXPfIKyQAz
|
|
DysZK-8KPg8e4A6gDiAOsA7wBP8SEC59Qq1C-RDwAFIAeB-wOgD-------------------------
|
|
----------------------9M8CNggATw-yS-FPBA-gLwPP4G8Dk-Ff4E8Dc9-gXwNU3_B-AzTf4I
|
|
8DJN-grwME3_C-AvXQUA_ABN-gzwLl3_DfAtTf4N8C4FADMM8C8FADELDw8HABA8JgDwDAk88Cwc
|
|
Tf4IPPAuHD3_BywPF-AxTf4FCxwLDAkA8KwEDAsMCwzwM02_LS4PGRwLHPAzXY49Lho88DVdTm0e
|
|
KjzwNv0BSjzwN816LPA5Ck3aHPA7_gMM8DuaDIrwO2psevA6Wnx68DlaHxwMaWrwOFqpWjnwNFrJ
|
|
SjnwNEoA6SpJ8DMqIJkvDCkKWfA0CkhJ_ATwMPgR8C5oDwr4DPAraBcoJ-gH8Cn4Azc4F6jwKCf4
|
|
DAe48CIH_BIniPAh_BYHiPAg_BgHePAg_BknOPAf_CHwH-gi8B34IAcYBgDxBxcY8Bz4IQco8Bv4
|
|
JfAb_CbwGigJ_CIGAPAjDgn4BPAaGAn4DhkoCfgA8BkYCfgPGRgJmAdY8BgIGfgQCSgJiAdY8BkJ
|
|
_BEZKAkYCVgZAFQJ_BIpOAsA8QIUGRgZWBdY8BcJ_BUZCBloBwsAgRgZ6PAWCfgZPgBkFBn4FRkY
|
|
CwBQFAk4GegJABAacgCCExn4GhmIFzgJAEb4APASCAARG4gAgREJ_BwJqAdICQAkGZgJALD4AfAQ
|
|
GfgbKagHOAkAphwZuAc48A8J_B0JAKHIBxjwEAn4HCnYTgAgKchlADATqbh9APABD0l4GajwFRn4
|
|
Dhm4GYjwF0IA8gEIIBjwGin4GxkI8B8p_BwJBwAQGQYA8CMaOQjwHin4GFkI8B8Z_BdpLfAdGfgU
|
|
aQgJTfAcGfgReQht8B4J_A6ZbRXwHhn4CpmNJQgAUAapGG1VCQDyQgK5GH2F8B4ZyMkIjcXwHgmY
|
|
uc3V8B8JWKnd9QLwH8kIzfUFAAXwHpkVjfUN8B5prfUPAAXwHQ0ZvfUV8Bvd9RjwGY0FDfUc8Bkt
|
|
9STwGT0FDQIAovUc8Bgt9SbwFy0QAEMFDfUdEgAGJACkHvAVPfUo8BQtFRIAhiDwFC31KvASJACF
|
|
IvASLfUs8BASAAEUAIUQLfUsAAXwD14AABYAiQbwDz31KgAVFwADVwCLDy31LQAF8AztA24tMjku
|
|
MTC4M0gzOC43zzMP8DkAAQIE8S3--8NvFPBF7vA8PxV_KV7wOF2OKV7wNz0OSW4JbvA2PQ5Z7vA1
|
|
PQ5pbgpu8DQdPmnu8DQNTln_APA0bkkGAPCEKW6vGfA03tzwNBmO-AHwNBlu-AMQHw-wMBle-AMQ
|
|
G-AxGV78AgsAK-Axbpzb8DFujNvwMl6Mmx8fK-AyXnyLKDvwMl5sSwgbKCcb8DNeXCs4Sx8OBwvw
|
|
NF4sHxcbKEsIGx8OK-AzHnsfFxgLFw8OKxhb8DMOmw8XCycfDjsYS-AzHksfF0sXHw5LCEvwMz4r
|
|
Lxe7FgDwJw1ODAsWuwhb8DM9HizrGCvwMz0OHAAsqyg78DMtDmyLKEsfHPA1jGsYWwYPDB8c8DSM
|
|
AMsGLwoA8kkyrKsWBT8MFfAxDAB8qwYbRCXwMJzbRBUU8C_sy0QllPAnjEWLFSRFpPAkjAU0FXsl
|
|
BAX0AfAifBVEJXsl9AEV8CB8BYQFayX0AwXwIGwFlAVrGvQF8CBcCgDxQAbwH1wFlBVrCgX0BvAe
|
|
TAAFlBVbBAoF9AfwHiwAJXQFBBU7FBr0B-AhFQQVZAUUBUoFGqQFtPAfFQoUJUQFFBpUCqQFxPAc
|
|
FQQKRCUkBaQOAPAGGhUECnQlBAW0CpQF1PAYFcQlxAqECgBQBQQKxBUMAPAK5PAWBQQK9BcF9ADw
|
|
FQUK9BgV9ADwExX0GggAYBIF9BIKhAoA8wARBfQTCnQABfQC8A8F9BQLAHAOBfQVCmQQCwAQDQsA
|
|
EXQLAEEMBfQWIQA0A-ALCwChBPAKBfQfABX0AwkAEBAdADIK9CAIAFDUFfQQEBsA8gEIBeQF9AgK
|
|
ZCAV9ALwCPQADQAyJfQBDQCFCQpEEBUUJeQOAEEAFUQFDgBgFfQICkQAOQEwCPQBGwAfNA0AAsEV
|
|
9A0ABfQF8Aj0AwULADME8AkLAFAEKtTwCwwAgAwgGgQatPAMDADACAokEAo0GpTwDfQCYwCgJAAK
|
|
VAqE8A70AlcAAA4AQBpk8A8OAJIKCiQVVApU8BANAGE0BVQaNAUOAPEEBHX0AQo0BWQKJAXwEeRV
|
|
ZAX0AA8AgRQF8BL0DQXkDQBwBAXwEwX0DBwAsyQFZAoF8BQF9AsVDgDB8BUF9Awa5AokBQpUDQBw
|
|
Czr0AnrwF2kAYBRaROvwGAoAUmQaFOsWCwCAdAoE2wYr8BmlAFSECusWGxcAQcsGKwYNAFEJCnQK
|
|
2w0AEhclAAANADEL8BgMAIRrPwU7BhsGCykAMUtjKw8AAVAARFQaK4MPAFHUtVrjGwwAYhoFZHXz
|
|
DhgA8hIbZW3zDjsGCwMb8BqNAw3zEisGC0PwGS3zHAtj8Bk9Aw0CABDzRgVS8yXwGC0QAIADDfMe
|
|
8Bct80YFAhAAARIAMBU980YFFBMSAABGBRDzRgUCEAAwAw3zRgUQ80YFJwMNFABlEC3zLvAPXACf
|
|
Aw3zJPAOPfMuJwUsD50JJw_FCv8gIP8UwTTxAXz0P-4BBP8VPQT_AQT9PA4HACA7HgcAQS30Ny4I
|
|
AE8E-jUECgD-NARSASH0OGIBMR30OnEBcg30Pf4B9D_xPDH--_iUAR-9kwH-dh9cYgMUHzLlCQHy
|
|
KxjfFvBALr8PHvA9Lu0e8Dse-QIO8Doe-QMe8DkO-QMfEQ4N8DUcHs18DhzwMRwAHA7dDA0cDVzw
|
|
MUwKAPYGHA0MDgzwMQwgHv0BDD0MDvA2Dv0IBgBgLU4dTm0uDwCwBR4NDvA3Dl0O-QAIAEBNHv0B
|
|
IQBRPR49Ds0qAFAeTQ69HgkAUA5dDp0KLQDwDR4dPi0OjQou8DgOTU6dCg7wOR79BA7wOg5NPq0H
|
|
APGALQ5tDm0e8DsOHR5NHl0_8DoeHX5NHh0u8Dk_QH5NHvBBHs0ODQLwPx7NDxhi8DourQtyG-A5
|
|
Dp0bYjvwNAs_nQtiGw0r8DICCw0enRtSGz0CC-AwEgu9G1IbXQIL8CwNCyIbrQtSG30CC-AqHQsy
|
|
G30rQhudAgsC8CgdC1IrPRtiC70bAvAnHQtyW2IbzQsLAPIA8gQb3RvwJi0L8gMb7QILCgCwC-0A
|
|
G-AlPQvyAhsKAPAEAggX8BA9C-IBG-0CC-ACCDfwDg4A8QAL-QML8AMIN-ANPQvyABsOAEAYR-AL
|
|
DgBQC-0CDg0eAGAHGDfwCU0SADFNDr0TAEwYBxgnEwBIAFfwCBIAYQQIEFfwBxIAIz0eEgByIEcA
|
|
LxXwAxUAIg7NFQA5MEcpEwCwAvADCDA3KQ3wAl2UABUtFQBwQAdJHfABXbcAUB0ezQ4bPABBWa0g
|
|
vREAIQ7dEQBJIEn9DBAAMCn9DhAA0hIO3Q4CC-AK-Q8L8gQMADoL-Q4MABEFCwBUDI0g-QENAPQK
|
|
DW3wBBvyBc0eAgvwDk3wBQvyBs0OEgvwKAkAcB0OvfIFvR4KAPACXhBObcLNDiIL8CANAG69ct0L
|
|
APEMGmVuC-0RHiIL8BYVDkVOEC4L-REOMgvwFYWeCgDwTfAWhU4AHhAL-RAeIvAXhW4tC-0PHjIA
|
|
C-AV1R0Q-REOQivwFLVgC-0NLjJL8BNlECVgCxL9CS6SK-AShYALMv0EPtIb8BFVsAti3T7yAhvw
|
|
EFWwC-ICPvIGK-AOCwAiHRsIAEAeG-ANCAAgHwsIAKbyIBvwDFWg8iILBwBgsPIhG-ALJABnIBvw
|
|
C2WgCAA-C-AMCAABAEwAAAgAYR4L8A9VoGwAAQgAEByHAPAAoAvyGxvwEUXAC-IZG-ASCABAGBvw
|
|
EwgAQBcb8BQIAEEVK-AVCAA-C-AXCAANITXQCABvFkXgC-IUCAAUIxMbCABPCxLwFQkADR8bRAAA
|
|
YvAA8hTwFwcAHwPyBBUPyAgnDzoA---------------3UG09NX19
|
|
:: gfx/.info.pod
|
|
b64$LS1bW3BvZCxjcmVhdGVkPSIyMDI0LTAzLTI5IDAxOjE0OjUxIixzdG9yZWQ9IjIwMjQtMDMt
|
|
MjkgMDE6MTQ6NTEiXV1sejQABAAAAAMAAAAwbmls
|
|
:: library.lua
|
|
--[[pod_format="raw",created="2024-04-10 00:24:20",modified="2024-04-10 01:58:59",revision=35]]
|
|
plant_descriptions = {
|
|
[-1]={{"i don't know what that is. where did you find this?"}},
|
|
[14]={{"this is foxglove"}},
|
|
}
|
|
function get_conversation(plant)
|
|
local id = plant[1]
|
|
return plant_descriptions[id] or plant_descriptions[-1]
|
|
end
|
|
|
|
:: main.lua
|
|
--[[pod_format="raw",created="2024-04-02 02:59:37",modified="2024-04-14 03:22:56",revision=1000]]
|
|
-- 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(title_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 03:22:56",revision=27]]
|
|
BookScene = {
|
|
extension = 0,
|
|
behind = nil,
|
|
inset = 60,
|
|
}
|
|
|
|
function BookScene:new(background)
|
|
c = {height=0, behind=nil, background=background}
|
|
|
|
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
|
|
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
|
|
end
|
|
|
|
function BookScene:draw()
|
|
self.behind:draw()
|
|
|
|
spr(007, 20, 135-self.height)
|
|
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 03:22:56",revision=281]]
|
|
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 03:22:56",revision=205]]
|
|
-- 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=80, right=144, top=100, bottom=164}
|
|
|
|
shop_screen = {}
|
|
function shop_screen:draw()
|
|
cls()
|
|
|
|
cabinet:draw()
|
|
|
|
-- alchemist!
|
|
bob(alchemist_sprite, 0, 7, 96, 128, alchemist_bob)
|
|
|
|
palt(30, true)
|
|
palt(0, false)
|
|
spr(16, 240-110, 135-36)
|
|
palt(30, false)
|
|
palt(0, true)
|
|
spr(21+flr(2*t()%8), 240-110, 135-39)
|
|
|
|
-- countertop!
|
|
draw_counter(14)
|
|
|
|
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
|
|
|
|
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()
|
|
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)) end
|
|
if collides(fairy, book_2) then change_scene(BookScene:new(007)) 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
|
|
:: 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
|
|
:: 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
|
|
PSIyMDI0LTA0LTE0IDAzOjIyOjU3Iix3b3Jrc3BhY2VzPXt7bG9jYXRpb249Im1haW4ubHVhIzE1
|
|
Iix3b3Jrc3BhY2VfaW5kZXg9MX0se2xvY2F0aW9uPSJzX3Nob3AubHVhIzM4Iix3b3Jrc3BhY2Vf
|
|
aW5kZXg9MX0se2xvY2F0aW9uPSJzX2RyYXdlci5sdWEjMSIsd29ya3NwYWNlX2luZGV4PTF9LHts
|
|
b2NhdGlvbj0ic19ib29rLmx1YSMzOSIsd29ya3NwYWNlX2luZGV4PTF9LHtsb2NhdGlvbj0iZ2Z4
|
|
LzAuZ2Z4Iix3b3Jrc3BhY2VfaW5kZXg9Mn19XV1sejQABAAAAAMAAAAwbmls
|
|
:: [eoc]
|
|
|