Compare commits
5 Commits
feature/ta
...
47e5e0ca17
| Author | SHA1 | Date | |
|---|---|---|---|
| 47e5e0ca17 | |||
| 98fd6981cc | |||
| 3ed06353b8 | |||
| 0b8e2368ec | |||
| ff96ca963d |
@@ -38,6 +38,10 @@ globals = {
|
|||||||
"MysteriousManScreen",
|
"MysteriousManScreen",
|
||||||
"DiscussionWindow",
|
"DiscussionWindow",
|
||||||
"EndWindow",
|
"EndWindow",
|
||||||
|
"PlayerNameWindow",
|
||||||
|
"TextInput",
|
||||||
|
"CodeGenerator",
|
||||||
|
"CreditsWindow",
|
||||||
"mset",
|
"mset",
|
||||||
"mget",
|
"mget",
|
||||||
"btnp",
|
"btnp",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ init/init.context.lua
|
|||||||
system/system.util.lua
|
system/system.util.lua
|
||||||
system/system.print.lua
|
system/system.print.lua
|
||||||
system/system.input.lua
|
system/system.input.lua
|
||||||
|
system/system.textinput.lua
|
||||||
system/system.mouse.lua
|
system/system.mouse.lua
|
||||||
system/system.asciiart.lua
|
system/system.asciiart.lua
|
||||||
system/system.rle.lua
|
system/system.rle.lua
|
||||||
@@ -16,6 +17,7 @@ logic/logic.timer.lua
|
|||||||
logic/logic.trigger.lua
|
logic/logic.trigger.lua
|
||||||
logic/logic.minigame.lua
|
logic/logic.minigame.lua
|
||||||
logic/logic.glitch.lua
|
logic/logic.glitch.lua
|
||||||
|
logic/logic.codegenerator.lua
|
||||||
logic/logic.discussion.lua
|
logic/logic.discussion.lua
|
||||||
system/system.ui.lua
|
system/system.ui.lua
|
||||||
audio/audio.manager.lua
|
audio/audio.manager.lua
|
||||||
@@ -79,6 +81,8 @@ window/window.minigame.rhythm.lua
|
|||||||
window/window.minigame.ddr.lua
|
window/window.minigame.ddr.lua
|
||||||
window/window.discussion.lua
|
window/window.discussion.lua
|
||||||
window/window.continued.lua
|
window/window.continued.lua
|
||||||
|
window/window.credits.lua
|
||||||
|
window/window.player_name.lua
|
||||||
window/window.game.lua
|
window/window.game.lua
|
||||||
system/system.main.lua
|
system/system.main.lua
|
||||||
meta/meta.assets.lua
|
meta/meta.assets.lua
|
||||||
|
|||||||
60
inc/logic/logic.codegenerator.lua
Normal file
60
inc/logic/logic.codegenerator.lua
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
--- @section CodeGenerator
|
||||||
|
|
||||||
|
CodeGenerator = {}
|
||||||
|
|
||||||
|
local SALT = 27471
|
||||||
|
local BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
local NAME_LEN = 3
|
||||||
|
|
||||||
|
-- Per-position offsets derived from SALT so each character slot
|
||||||
|
-- maps to a different region of the 2-char base-36 space.
|
||||||
|
local SALTS = {
|
||||||
|
SALT % 36,
|
||||||
|
math.floor(SALT / 36) % 36,
|
||||||
|
math.floor(SALT / 1296) % 36,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Encodes a number (0–935) as exactly 2 base-36 characters.
|
||||||
|
--- @within CodeGenerator
|
||||||
|
function CodeGenerator.encode_pair(n)
|
||||||
|
return BASE36:sub(math.floor(n / 36) + 1, math.floor(n / 36) + 1)
|
||||||
|
.. BASE36:sub(n % 36 + 1, n % 36 + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Decodes 2 base-36 characters back to a number.
|
||||||
|
--- @within CodeGenerator
|
||||||
|
function CodeGenerator.decode_pair(s)
|
||||||
|
local d1 = BASE36:find(s:sub(1, 1), 1, true) - 1
|
||||||
|
local d2 = BASE36:find(s:sub(2, 2), 1, true) - 1
|
||||||
|
return d1 * 36 + d2
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Encrypts a player name into a code twice its length.
|
||||||
|
--- Each input character (A-Z, value 0-25) is encoded as
|
||||||
|
--- c + SALTS[i] * 26, producing 2 base-36 output characters.
|
||||||
|
--- @within CodeGenerator
|
||||||
|
--- @param text string NAME_LEN-character uppercase player name.
|
||||||
|
--- @return string Encrypted code (2 * NAME_LEN base-36 characters).
|
||||||
|
function CodeGenerator.encrypt(text)
|
||||||
|
local result = ""
|
||||||
|
for i = 1, NAME_LEN do
|
||||||
|
local c = math.max(0, (string.byte(text, i) or 65) - 65)
|
||||||
|
result = result .. CodeGenerator.encode_pair(c + SALTS[i] * 26)
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Decrypts a personal code back to the original player name.
|
||||||
|
--- @within CodeGenerator
|
||||||
|
--- @param encrypted_text string The code to decrypt (2 * NAME_LEN chars).
|
||||||
|
--- @return string Original player name, or "???" if the code is invalid.
|
||||||
|
function CodeGenerator.decrypt(encrypted_text)
|
||||||
|
local t = encrypted_text:upper()
|
||||||
|
if #t ~= NAME_LEN * 2 then return "???" end
|
||||||
|
local result = ""
|
||||||
|
for i = 1, NAME_LEN do
|
||||||
|
local pair = CodeGenerator.decode_pair(t:sub((i - 1) * 2 + 1, i * 2))
|
||||||
|
result = result .. string.char(pair % 26 + 65)
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
@@ -509,23 +509,23 @@
|
|||||||
-- 255:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
-- 255:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
|
||||||
-- </SPRITES>
|
-- </SPRITES>
|
||||||
-- <MAP>
|
-- <MAP>
|
||||||
-- 000:ffffffffff0010201020102010201020102010201020102000ffffffffff40404040404087f3f3f3f397a7b7c7d7a7e7f70818a7b7c7d7a7b7c7d7a70b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 000:20102010200010201020102010201020102010201020102000102010201040404040404087f3f3f3f397a7b7c7d7a7e7f70818a7b7c7d7a7b7c7d7a70b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 001:ffffffffff0040404040404040404040404040404040404000ffffffffff40404040404087f3f3f3f328a7384858a76878f388a7384858a7384858a70b40403b4b4040404040404040404040404040404040404040404040400b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 001:40404040400040404040404040404040404040404040404000404040404040404040404087f3f3f3f328a7384858a76878f388a7384858a7384858a70b40403b4b4040404040404040404040404040404040404040404040400b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 002:ffffffffff00406070408090a040b0c0d0e0f001f001112100ffffffffff984098409840a8f3f3f3f3b8a7a7a7a7a7c8d8e8f8a7a7a7a7a7a7a7a7a70b405b6b7b4040404040404040404040404040d0e0f001f001f00111210b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 002:408090a04000406070408090a040b0c0d0e0f001f001112100408090a040984098409840a8f3f3f3f3b8a7a7a7a7a7c8d8e8f8a7a7a7a7a7a7a7a7a70b405b6b7b4040404040404040404040404040d0e0f001f001f00111210b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 003:ffffffffff004031414051617140814091a1b1b1b1b1c1d100ffffffffff984098409840a8f3f3f3f3091919191919293949591919191919191919190b8b9babbb4040cbdbebfb0c401c2c2c2c3c4091a14c5c6c6c6c6cc1d10b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 003:4051617140004031414051617140814091a1b1b1b1b1c1d1004051617140984098409840a8f3f3f3f3091919191919293949591919191919191919190b8b9babbb4040cbdbebfb0c401c2c2c2c3c4091a14c5c6c6c6c6cc1d10b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 004:ffffffffffe140f1024012223240814042a15262728292a2e1ffffffffff984098409840a8f3f3f3f369f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f37c8c9cacbc7282ccdcecfc0d401d3030302d4042a13d4d7282728292a27c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 004:4012223240e140f1024012223240814042a15262728292a2e14012223240984098409840a8f3f3f3f369f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f37c8c9cacbc7282ccdcecfc0d401d3030302d4042a13d4d7282728292a27c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 005:ffffffffffb240c2d240e2f203132333435363738393a3b3b2ffffffffff984098409840a8f3f3f3f369f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f35d406d7d40e3958d9dadbdcd40ddedfded0e404353839383938393a3b35d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 005:4040404040b240c2d240e2f203132333435363738393a3b3b24040404040984098409840a8f3f3f3f369f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f35d406d7d40e3958d9dadbdcd40ddedfded0e404353839383938393a3b35d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 006:ffffffffffe1c3d3c3d3e3f30414c3d32434445410201020e1ffffffffff404040404040798989898999a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a97c1e1e1e1e44542e1e1e1e3e1e444e4e4e541e243444544454445444547c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 006:d3c3d3c3d3e1c3d3c3d3e3f30414c3d32434445410201020e1c3d3c3d3c3404040404040798989898999a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a97c1e1e1e1e44542e1e1e1e3e1e444e4e4e541e243444544454445444547c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 007:ffffffffffb264748494a4b4c4d46494649464940040e4f4b2ffffffffff4040404040404040404040404040404040404040404040404040404040405d1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 007:9464354594b264748494a4b4c4d46494649464940040e4f4b264354594644040404040404040404040404040404040404040404040404040404040405d1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 008:ffffffffffe1c30515d325d33545c3d355d3c3d365b17585e1ffffffffff4040404040404098989898404040404040404040404040404040404040407c1e7e8e1e1e1e9eae1ebe1e1e1e1e1e1e1e1e72821ebe1e72821ebe1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 008:d3c3e395d3e1c30515d325d33545c3d355d3c3d365b17585e1c3e395d3254040404040404098989898404040404040404040404040404040404040407c1e7e8e1e1e1e9eae1ebe1e1e1e1e1e1e1e1e72821ebe1e72821ebe1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 009:ffffffffffb264e395a5b594e39564c5d5946494e5b1b1f5b2ffffffffff4040404040404040404040404040404040404040404040404040404040405d1e05151ebe1ecedeeefe1e1e1e1e1e1e1e1ee395eefe1ee395eefe1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 009:9464465694b264e395a5b594e39564c5d5946494e5b1b1f5b264e395a5b54040404040404040404040404040404040404040404040404040404040405d1e05151ebe1ecedeeefe1e1e1e1e1e1e1e1ee395eefe1ee395eefe1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 010:ffffffffffe1c306162636d34656c3e3d5d3c3d376b1b1b1e1ffffffffff404040404040409898989840b9c9c9d9e9f90a0a0a0a4040400a0a0a0a407c1ee395eefe1e0f1f2f3f1e1e1e1e1e1e1e1ee3952f3f1ee3952f3f1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 010:d3c3d3c3d3e1c306162636d34656c3e3d5d3c3d376b1b1b1e1c3e3952636404040404040409898989840b9c9c9d9e9f90a0a0a0a4040400a0a0a0a407c1ee395eefe1e0f1f2f3f1e1e1e1e1e1e1e1ee3952f3f1ee3952f3f1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 011:ffffffffffb264946494649464948696a694649410201020b2ffffffffff4040404040404040404040401a2a3a4a5a6a7a40404040404040404040405d1ee3952f3f1e4f5f1ebe1e1e1e1e1e1e1e1ee3951ebe1ee3951ebe1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 011:9464946494b264946494649464948696a694649410201020b264e395d3254040404040404040404040401a2a3a4a5a6a7a40404040404040404040405d1ee3952f3f1e4f5f1ebe1e1e1e1e1e1e1e1ee3951ebe1ee3951ebe1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 012:ffffffffffe1c37282d3c3d3c3d3b6c6d6d3c3d300e6f607e1ffffffffff4040404040404098989898408a9aaabaca9ada40404040404040404040407c1e4f5f1ebe1e0515eefe1e1e1e1e1e1e1e1ee395eefe1ee395eefe1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 012:d3c37282d3e1c37282d3c3d3c3d3b6c6d6d3c3d300e6f607e1c3e395a5b54040404040404098989898408a9aaabaca9ada40404040404040404040407c1e4f5f1ebe1e0515eefe1e1e1e1e1e1e1e1ee395eefe1ee395eefe1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 013:ffffffffffb264e395946494649464946494649465172737b2ffffffffffeaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea5d1e0515eefe1e6f7f2f3f1e1e1e1e1e1e1e1e6f7f2f3f1e6f7f2f3f1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 013:9464e39594b264e395946494649464946494649465172737b26406162636eaeaeaeaeaeaeafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaea5d1e0515eefe1e6f7f2f3f1e1e1e1e1e1e1e1e6f7f2f3f1e6f7f2f3f1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 014:ffffffffffe1c34454d3c3d3c3d3c3d3c3d3c3d3e5b14757e1fffffffffff3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f37c1e6f7f2f3f1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 014:d3c34454d3e1c34454d3c3d3c3d3c3d3c3d3c3d3e5b14757e1c3d3c3d3c3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f37c1e6f7f2f3f1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 015:ffffffffffb2649464946494649464946494649476b1b1b1b2fffffffffff3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f35d1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 015:9464946494b2649464946494649464946494649476b1b1b1b26494649464f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f35d1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e5d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- 016:ffffffffff0010201020766777001020102010201020102000fffffffffff3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f30b1b2b1b2b7667776777761b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
-- 016:201020102000102010207667770010201020102010201020001020102010f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f30b1b2b1b2b7667776777761b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b1b2b0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
-- </MAP>
|
-- </MAP>
|
||||||
-- <SFX>
|
-- <SFX>
|
||||||
-- 016:00000000000000400040004000700070007000400040004000700070007000c000c000c000c000c000c000c000c000c000c000c000c000c000c000c0470000000000
|
-- 016:00000000000000400040004000700070007000400040004000700070007000c000c000c000c000c000c000c000c000c000c000c000c000c000c000c0470000000000
|
||||||
|
|||||||
@@ -4,5 +4,5 @@
|
|||||||
-- desc: Life of a programmer
|
-- desc: Life of a programmer
|
||||||
-- site: https://git.teletype.hu/games/impostor
|
-- site: https://git.teletype.hu/games/impostor
|
||||||
-- license: MIT License
|
-- license: MIT License
|
||||||
-- version: 1.0-beta2
|
-- version: 1.0-beta3
|
||||||
-- script: lua
|
-- script: lua
|
||||||
|
|||||||
@@ -30,3 +30,9 @@ function Input.back() return btnp(INPUT_KEY_B) or keyp(INPUT_KEY_BACKSPACE) end
|
|||||||
--- Checks if Enter is pressed.
|
--- Checks if Enter is pressed.
|
||||||
--- @within Input
|
--- @within Input
|
||||||
function Input.enter() return keyp(INPUT_KEY_ENTER) end
|
function Input.enter() return keyp(INPUT_KEY_ENTER) end
|
||||||
|
--- Checks if Up is pressed or held (with repeat).
|
||||||
|
--- @within Input
|
||||||
|
function Input.up_repeat() return btnp(INPUT_KEY_UP, 20, 4) end
|
||||||
|
--- Checks if Down is pressed or held (with repeat).
|
||||||
|
--- @within Input
|
||||||
|
function Input.down_repeat() return btnp(INPUT_KEY_DOWN, 20, 4) end
|
||||||
|
|||||||
81
inc/system/system.textinput.lua
Normal file
81
inc/system/system.textinput.lua
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
--- @section TextInput
|
||||||
|
|
||||||
|
TextInput = {}
|
||||||
|
|
||||||
|
local LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
local _pos = {}
|
||||||
|
local _cursor = 1
|
||||||
|
local _max_len = 3
|
||||||
|
|
||||||
|
--- Initialises a new text input session.
|
||||||
|
--- @within TextInput
|
||||||
|
--- @param max_len number Maximum character count (default 3).
|
||||||
|
function TextInput.init(max_len)
|
||||||
|
_max_len = max_len or 3
|
||||||
|
_pos = {}
|
||||||
|
for i = 1, _max_len do _pos[i] = 1 end
|
||||||
|
_cursor = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Advances to the next letter at the cursor position (wraps Z→A).
|
||||||
|
--- @within TextInput
|
||||||
|
function TextInput.next_letter()
|
||||||
|
_pos[_cursor] = (_pos[_cursor] % #LETTERS) + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Goes back to the previous letter at the cursor position (wraps A→Z).
|
||||||
|
--- @within TextInput
|
||||||
|
function TextInput.prev_letter()
|
||||||
|
_pos[_cursor] = ((_pos[_cursor] - 2) % #LETTERS) + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Confirms the current letter and advances the cursor to the next position.
|
||||||
|
--- When called on the last position the cursor moves into the done state.
|
||||||
|
--- @within TextInput
|
||||||
|
function TextInput.select_letter()
|
||||||
|
if _cursor <= _max_len then _cursor = _cursor + 1 end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Moves the cursor one position to the right (stops at last position).
|
||||||
|
--- @within TextInput
|
||||||
|
function TextInput.next_position()
|
||||||
|
if _cursor < _max_len then _cursor = _cursor + 1 end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Moves the cursor one position to the left (stops at first position).
|
||||||
|
--- Also steps back out of the done state.
|
||||||
|
--- @within TextInput
|
||||||
|
function TextInput.prev_position()
|
||||||
|
if _cursor > 1 then _cursor = _cursor - 1 end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns the assembled name string.
|
||||||
|
--- @within TextInput
|
||||||
|
--- @return string
|
||||||
|
function TextInput.get_name()
|
||||||
|
local s = ""
|
||||||
|
for i = 1, _max_len do s = s .. LETTERS:sub(_pos[i], _pos[i]) end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns the current 1-based cursor position.
|
||||||
|
--- @within TextInput
|
||||||
|
--- @return number
|
||||||
|
function TextInput.get_position()
|
||||||
|
return _cursor
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns the letter at the given 1-based position.
|
||||||
|
--- @within TextInput
|
||||||
|
--- @param i number
|
||||||
|
--- @return string
|
||||||
|
function TextInput.get_letter(i)
|
||||||
|
return LETTERS:sub(_pos[i], _pos[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns true when all positions have been confirmed.
|
||||||
|
--- @within TextInput
|
||||||
|
--- @return boolean
|
||||||
|
function TextInput.is_done()
|
||||||
|
return _cursor > _max_len
|
||||||
|
end
|
||||||
@@ -30,9 +30,15 @@ function EndWindow.draw()
|
|||||||
Print.text(yes_text, centerX - 40, y, yes_color)
|
Print.text(yes_text, centerX - 40, y, yes_color)
|
||||||
Print.text(no_text, centerX + 10, y, no_color)
|
Print.text(no_text, centerX + 10, y, no_color)
|
||||||
elseif Context._end.state == "ending" then
|
elseif Context._end.state == "ending" then
|
||||||
Print.text_center("Game over -- good ending.", Config.screen.width / 2, 50, Config.colors.light_blue)
|
local cx = Config.screen.width / 2
|
||||||
Print.text_center("Congratulations!", Config.screen.width / 2, 70, Config.colors.white)
|
local name = Context.player_name or "AAA"
|
||||||
Print.text_center("Press Z to return to menu", Config.screen.width / 2, 110, Config.colors.light_grey)
|
local code = CodeGenerator.encrypt(name)
|
||||||
|
Print.text_center("Game over -- good ending.", cx, 40, Config.colors.light_blue)
|
||||||
|
Print.text_center("Congrats " .. name .. "!", cx, 54, Config.colors.white)
|
||||||
|
Print.text_center("Your personal code:", cx, 72, Config.colors.light_grey)
|
||||||
|
Print.text_center(code, cx, 84, Config.colors.white, false, 3)
|
||||||
|
Print.text_center("Write it down!", cx, 112, Config.colors.item)
|
||||||
|
Print.text_center("Press Z to return to menu", cx, 126, Config.colors.dark_grey)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -102,17 +102,13 @@ function MenuWindow.update()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Starts a new game from the menu.
|
--- Opens player name entry then starts a new game.
|
||||||
--- @within MenuWindow
|
--- @within MenuWindow
|
||||||
function MenuWindow.new_game()
|
function MenuWindow.new_game()
|
||||||
Context.new_game()
|
PlayerNameWindow.init(function()
|
||||||
end
|
Context.new_game()
|
||||||
|
end)
|
||||||
--- Loads a game from the menu.
|
Window.set_current("player_name")
|
||||||
--- @within MenuWindow
|
|
||||||
function MenuWindow.load_game()
|
|
||||||
Context.load_game()
|
|
||||||
GameWindow.set_state("game")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Saves the current game from the menu.
|
--- Saves the current game from the menu.
|
||||||
@@ -139,6 +135,21 @@ function MenuWindow.controls()
|
|||||||
Window.set_current("controls")
|
Window.set_current("controls")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Opens the player name entry screen (test mode shortcut).
|
||||||
|
--- @within MenuWindow
|
||||||
|
function MenuWindow.player_name()
|
||||||
|
PlayerNameWindow.init()
|
||||||
|
Window.set_current("player_name")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Opens the credits screen.
|
||||||
|
--- @within MenuWindow
|
||||||
|
function MenuWindow.credits()
|
||||||
|
CreditsWindow.init()
|
||||||
|
Window.set_current("credits")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Opens the audio test menu.
|
--- Opens the audio test menu.
|
||||||
--- @within MenuWindow
|
--- @within MenuWindow
|
||||||
function MenuWindow.audio_test()
|
function MenuWindow.audio_test()
|
||||||
@@ -153,6 +164,14 @@ function MenuWindow.continued()
|
|||||||
GameWindow.set_state("continued")
|
GameWindow.set_state("continued")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Opens the end screen for testing.
|
||||||
|
--- @within MenuWindow
|
||||||
|
function MenuWindow.end_screen()
|
||||||
|
Context._end.state = "ending"
|
||||||
|
Context._end.selection = 1
|
||||||
|
GameWindow.set_state("end")
|
||||||
|
end
|
||||||
|
|
||||||
--- Opens the DDR minigame test.
|
--- Opens the DDR minigame test.
|
||||||
--- @within MenuWindow
|
--- @within MenuWindow
|
||||||
function MenuWindow.ddr_test()
|
function MenuWindow.ddr_test()
|
||||||
@@ -171,13 +190,15 @@ function MenuWindow.refresh_menu_items()
|
|||||||
end
|
end
|
||||||
|
|
||||||
table.insert(_menu_items, {label = "New Game", decision = MenuWindow.new_game})
|
table.insert(_menu_items, {label = "New Game", decision = MenuWindow.new_game})
|
||||||
table.insert(_menu_items, {label = "Load Game", decision = MenuWindow.load_game})
|
|
||||||
table.insert(_menu_items, {label = "Controls", decision = MenuWindow.controls})
|
table.insert(_menu_items, {label = "Controls", decision = MenuWindow.controls})
|
||||||
|
table.insert(_menu_items, {label = "Credits", decision = MenuWindow.credits})
|
||||||
|
|
||||||
if Context.test_mode then
|
if Context.test_mode then
|
||||||
table.insert(_menu_items, {label = "Audio Test", decision = MenuWindow.audio_test})
|
table.insert(_menu_items, {label = "Audio Test", decision = MenuWindow.audio_test})
|
||||||
table.insert(_menu_items, {label = "To Be Continued...", decision = MenuWindow.continued})
|
table.insert(_menu_items, {label = "To Be Continued...", decision = MenuWindow.continued})
|
||||||
table.insert(_menu_items, {label = "DDR Test", decision = MenuWindow.ddr_test})
|
table.insert(_menu_items, {label = "DDR Test", decision = MenuWindow.ddr_test})
|
||||||
|
table.insert(_menu_items, {label = "End Screen", decision = MenuWindow.end_screen})
|
||||||
|
table.insert(_menu_items, {label = "Player Name", decision = MenuWindow.player_name})
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(_menu_items, {label = "Exit", decision = MenuWindow.exit})
|
table.insert(_menu_items, {label = "Exit", decision = MenuWindow.exit})
|
||||||
|
|||||||
115
inc/window/window.player_name.lua
Normal file
115
inc/window/window.player_name.lua
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
--- @section PlayerNameWindow
|
||||||
|
|
||||||
|
local _frame = 0
|
||||||
|
local _on_confirm = nil
|
||||||
|
local MAX_LEN = 3
|
||||||
|
local BOX_W = 24
|
||||||
|
local BOX_H = 24
|
||||||
|
local BOX_GAP = 12
|
||||||
|
local BOX_Y = 50
|
||||||
|
local WARN_Y = 104
|
||||||
|
|
||||||
|
local function box_start_x()
|
||||||
|
return math.floor((Config.screen.width - (MAX_LEN * BOX_W + (MAX_LEN - 1) * BOX_GAP)) / 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function box_x(i)
|
||||||
|
return box_start_x() + (i - 1) * (BOX_W + BOX_GAP)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Initialises the player name window.
|
||||||
|
--- @within PlayerNameWindow
|
||||||
|
--- @param on_confirm function Called with the entered name when the player saves.
|
||||||
|
function PlayerNameWindow.init(on_confirm)
|
||||||
|
_frame = 0
|
||||||
|
_on_confirm = on_confirm
|
||||||
|
TextInput.init(MAX_LEN)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function draw_boxes()
|
||||||
|
local cursor = TextInput.get_position()
|
||||||
|
local blink = math.floor(_frame / 18) % 2 == 0
|
||||||
|
|
||||||
|
for i = 1, MAX_LEN do
|
||||||
|
local x = box_x(i)
|
||||||
|
local is_cur = (i == cursor)
|
||||||
|
local done = TextInput.is_done()
|
||||||
|
|
||||||
|
local fill = (is_cur and not done) and Config.colors.blue or Config.colors.black
|
||||||
|
local border = (is_cur and not done) and Config.colors.white
|
||||||
|
or done and Config.colors.light_blue
|
||||||
|
or Config.colors.dark_grey
|
||||||
|
|
||||||
|
rect (x, BOX_Y, BOX_W, BOX_H, fill)
|
||||||
|
rectb(x, BOX_Y, BOX_W, BOX_H, border)
|
||||||
|
|
||||||
|
local show = not (is_cur and blink and not done)
|
||||||
|
if show then
|
||||||
|
local ch = TextInput.get_letter(i)
|
||||||
|
local cw = print(ch, 0, -100, 0, false, 2)
|
||||||
|
local cx = x + math.floor((BOX_W - cw) / 2)
|
||||||
|
local cy = BOX_Y + math.floor((BOX_H - 11) / 2)
|
||||||
|
local col = (is_cur and not done) and Config.colors.white or Config.colors.light_grey
|
||||||
|
print(ch, cx, cy, col, false, 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- caret arrow below active box
|
||||||
|
if not TextInput.is_done() then
|
||||||
|
local cx = box_x(cursor) + math.floor(BOX_W / 2)
|
||||||
|
local ay = BOX_Y + BOX_H + 4
|
||||||
|
line(cx - 4, ay, cx, ay + 4, Config.colors.white)
|
||||||
|
line(cx + 4, ay, cx, ay + 4, Config.colors.white)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Draws the player name window.
|
||||||
|
--- @within PlayerNameWindow
|
||||||
|
function PlayerNameWindow.draw()
|
||||||
|
cls(Config.colors.black)
|
||||||
|
|
||||||
|
Print.text_center("Player Name", Config.screen.width / 2, 14, Config.colors.white, false, 2)
|
||||||
|
|
||||||
|
draw_boxes()
|
||||||
|
|
||||||
|
if TextInput.is_done() then
|
||||||
|
Print.text_center("Z: save name B: edit", Config.screen.width / 2, BOX_Y + BOX_H + 12, Config.colors.light_blue)
|
||||||
|
else
|
||||||
|
Print.text_center("Up/Dn: letter Lft/Rgt: move Z: ok", Config.screen.width / 2, BOX_Y + BOX_H + 12, Config.colors.dark_grey)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Warning section
|
||||||
|
rect(0, WARN_Y, Config.screen.width, Config.screen.height - WARN_Y, Config.colors.blue)
|
||||||
|
rectb(0, WARN_Y, Config.screen.width, Config.screen.height - WARN_Y, Config.colors.light_blue)
|
||||||
|
Print.text_center("Remember your name!", Config.screen.width / 2, WARN_Y + 8, Config.colors.white)
|
||||||
|
Print.text_center("You will need it to load the game.", Config.screen.width / 2, WARN_Y + 20, Config.colors.light_grey)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Updates player name window logic.
|
||||||
|
--- @within PlayerNameWindow
|
||||||
|
function PlayerNameWindow.update()
|
||||||
|
_frame = _frame + 1
|
||||||
|
|
||||||
|
if TextInput.is_done() then
|
||||||
|
if Input.select() then
|
||||||
|
Context.player_name = TextInput.get_name()
|
||||||
|
if _on_confirm then _on_confirm() else Window.set_current("menu") end
|
||||||
|
elseif Input.back() then
|
||||||
|
TextInput.prev_position()
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if Input.up_repeat() then TextInput.next_letter() end
|
||||||
|
if Input.down_repeat() then TextInput.prev_letter() end
|
||||||
|
if Input.right() then TextInput.next_position() end
|
||||||
|
if Input.select() then TextInput.select_letter() end
|
||||||
|
|
||||||
|
if Input.left() or Input.back() then
|
||||||
|
if TextInput.get_position() > 1 then
|
||||||
|
TextInput.prev_position()
|
||||||
|
else
|
||||||
|
Window.set_current("menu")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -39,3 +39,9 @@ Window.register("discussion", DiscussionWindow)
|
|||||||
|
|
||||||
ContinuedWindow = {}
|
ContinuedWindow = {}
|
||||||
Window.register("continued", ContinuedWindow)
|
Window.register("continued", ContinuedWindow)
|
||||||
|
|
||||||
|
CreditsWindow = {}
|
||||||
|
Window.register("credits", CreditsWindow)
|
||||||
|
|
||||||
|
PlayerNameWindow = {}
|
||||||
|
Window.register("player_name", PlayerNameWindow)
|
||||||
|
|||||||
Reference in New Issue
Block a user