Skip to content

Commit 669acc5

Browse files
authored
Add Clue language (#6356)
1 parent c727264 commit 669acc5

File tree

13 files changed

+987
-0
lines changed

13 files changed

+987
-0
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
[submodule "vendor/grammars/CUE-Sheet_sublime"]
2323
path = vendor/grammars/CUE-Sheet_sublime
2424
url = https://github.com/relikd/CUE-Sheet_sublime
25+
[submodule "vendor/grammars/Clue-for-VSCode"]
26+
path = vendor/grammars/Clue-for-VSCode
27+
url = https://github.com/ClueLang/Clue-for-VSCode.git
2528
[submodule "vendor/grammars/CoDT7-Sublime"]
2629
path = vendor/grammars/CoDT7-Sublime
2730
url = https://github.com/Jake-NotTheMuss/CoDT7-Sublime.git

grammars.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ vendor/grammars/AutoHotkey:
1515
- source.ahk
1616
vendor/grammars/CUE-Sheet_sublime:
1717
- source.cuesheet
18+
vendor/grammars/Clue-for-VSCode:
19+
- source.clue
1820
vendor/grammars/CoDT7-Sublime:
1921
- source.gsc
2022
vendor/grammars/ColdFusion:

lib/linguist/languages.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,14 @@ Cloud Firestore Security Rules:
12351235
filenames:
12361236
- firestore.rules
12371237
language_id: 407996372
1238+
Clue:
1239+
type: programming
1240+
color: "#0009b5"
1241+
extensions:
1242+
- ".clue"
1243+
tm_scope: source.clue
1244+
ace_mode: text
1245+
language_id: 163763508
12381246
CoNLL-U:
12391247
type: data
12401248
extensions:

samples/Clue/game.clue

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
static score, mistakes = 0, 1
2+
static hackamount, hacked = 0.5
3+
4+
local terminal = import("terminal")
5+
6+
local names = {}
7+
8+
local i = 1
9+
for name with love.filesystem.lines("assets/names.txt") {
10+
names[i] = name
11+
i += 1
12+
}
13+
14+
local commands
15+
local seed2 = love.math.random(10, 10000)
16+
17+
local fn EntryCode(seed) {
18+
local rng = love.math.newRandomGenerator((seed2 + math.floor(leveltime / 30)) * 10 + seed)
19+
local code = ""
20+
for _ = 1, 20 {
21+
code ..= string.char(rng::random(33, 122))
22+
}
23+
return code
24+
}
25+
26+
local fn GenerateIP(hacker) {
27+
return math.ceil(math.abs(love.math.randomNormal(75, 128)) % (hacker ? 256 : 1000))
28+
}
29+
30+
local user = {
31+
new = fn(self) {
32+
local hacker = love.math.random() > 0.8
33+
self.ip1 = GenerateIP(hacker)
34+
self.ip2 = GenerateIP(hacker)
35+
self.ip3 = GenerateIP(hacker)
36+
self.ip4 = GenerateIP(hacker)
37+
self.glitch = self.ip1 > 255 || self.ip2 > 255 || self.ip3 > 255 || self.ip4 > 255
38+
self.name = names[love.math.random(6000)]
39+
self.age = math.floor((hacker || self.glitch) ? love.math.random(14, 79) : love.math.random(9, 145))
40+
self.code = hacker ? love.math.random(-20, -1) : love.math.random(0, 9)
41+
self.time = leveltime
42+
self.hacker = hacker
43+
}
44+
next = fn(self) {
45+
commands.score.code()
46+
terminal::write("Reading next user's information...", 15)
47+
self::new()
48+
commands.user.code(4)
49+
}
50+
}
51+
52+
user::new()
53+
54+
local fn AwardScore(amount) {
55+
if amount < 0 {
56+
amount = math.ceil($ * mistakes)
57+
terminal::write(string.format("(%d points)", amount), 60, 1, 0, 0)
58+
mistakes += 0.5
59+
} else {
60+
terminal::write(string.format("(+%d points)", amount), 60, 1, 1, 0)
61+
}
62+
score += amount
63+
}
64+
65+
commands = {
66+
score = {
67+
desc = "Display current score."
68+
code = fn {
69+
terminal::write("Score: " .. score, nil, 1, 0, 1)
70+
local mistakes = (mistakes - 1) * 2
71+
if mistakes == 0 {
72+
terminal::write("You never messed up so far.", nil, 1, 0, 1)
73+
} else {
74+
terminal::write("You messed up " .. mistakes .. " times.", nil, 1, 0, 1)
75+
}
76+
}
77+
}
78+
user = {
79+
desc = "Display the info of the user trying to connect."
80+
code = fn(s = 0) {
81+
terminal::write("Name: " .. user.name, 60, 1, 1, 0)
82+
terminal::write("Age: " .. user.age, 60, 1, 1, 0)
83+
terminal::write(string.format("IP: %d.%d.%d.%d", user.ip1, user.ip2, user.ip3, user.ip4), 60, 1, 1, 0)
84+
terminal::write(string.format(
85+
"Entry Code: %s (changes in %d seconds)",
86+
EntryCode(user.code),
87+
math.max(29 - math.floor(leveltime % 30) - s, 0)
88+
), 60, 1, 1, 0)
89+
}
90+
}
91+
codes = {
92+
desc = "Display the 10 currently valid codes."
93+
code = fn {
94+
terminal::write("Currently valid codes:")
95+
for i = 0, 9 {
96+
terminal::write(EntryCode(i), 60, 1, 1, 0)
97+
}
98+
terminal::write(string.format(
99+
"The codes will change in %d seconds.",
100+
29 - math.floor(leveltime % 30)
101+
))
102+
}
103+
}
104+
allow = {
105+
desc = "Allow the current user."
106+
code = fn {
107+
terminal::write(user.name .. " was allowed connection...", 10)
108+
if user.hacker {
109+
terminal::write("But they were an hacker!", 60, 1, 0, 0)
110+
hacked = leveltime + 0.5
111+
mistakes += 0.5
112+
errors = 2
113+
user::new()
114+
return
115+
} elseif user.glitch {
116+
terminal::write("But they were a glitch!", 60, 1, 0, 0)
117+
AwardScore(math.min(score / -2.5, -500))
118+
errors = 1
119+
} elseif user.age < 14 {
120+
terminal::write("But they were too young to join.", 60, 1, 0, 0)
121+
AwardScore(-300)
122+
} elseif user.age >= 80 {
123+
terminal::write("But they were a troll.", 60, 1, 0, 0)
124+
AwardScore(-200)
125+
} else {
126+
terminal::write("And that was the correct choice!", 60, 1, 1, 0)
127+
AwardScore(math.max(500 + math.floor((user.time - leveltime) * 20), 10))
128+
}
129+
user::next()
130+
}
131+
}
132+
deny = {
133+
desc = "Deny the current user."
134+
code = fn {
135+
terminal::write(user.name .. " was denied connection...", 10)
136+
if !user.hacker && !user.glitch && user.age >= 14 && user.age < 80 {
137+
terminal::write("But they had no bad intentions.", 60, 1, 0, 0)
138+
AwardScore(-500)
139+
} else {
140+
terminal::write("And that was the correct choice!", 60, 1, 1, 0)
141+
AwardScore(math.max(300 + math.floor((user.time - leveltime) * 20), 10))
142+
}
143+
user::next()
144+
}
145+
}
146+
}
147+
148+
return commands

samples/Clue/graph.clue

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
io.stdout::setvbuf("no");
2+
3+
import("line");
4+
5+
method love.draw() {
6+
love.graphics.print(formula, 0, 0, 0, 2);
7+
love.graphics.translate(150, 450);
8+
love.graphics.setColor(0.3, 0.3, 0.3);
9+
for x = -150, 650, 10 {
10+
if x == 0 {continue}
11+
love.graphics.line(x, 150, x, -450);
12+
}
13+
for y = -450, 150, 10 {
14+
if y == 0 {continue}
15+
love.graphics.line(-150, y, 650, y);
16+
}
17+
love.graphics.setColor(1, 1, 1);
18+
love.graphics.line(0, 150, 0, -450);
19+
love.graphics.line(-150, 0, 650, 0);
20+
if dots {
21+
love.graphics.line(dots);
22+
} else {
23+
love.graphics.origin()
24+
love.graphics.setColor(1, 0, 0);
25+
love.graphics.printf(errormsg, 0, 300, 400, "center", 0, 2);
26+
}
27+
}

samples/Clue/line.clue

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
static dots, formula, errormsg;
2+
dots = {0, 0, 0, 0};
3+
formula = "y=";
4+
errormsg = "";
5+
6+
local utf8 = require("utf8");
7+
local env = {x = 0, y = 0};
8+
9+
for k, v of math {
10+
env[k] = v;
11+
}
12+
13+
method love.textinput(key) {
14+
formula ..= key;
15+
dots = {};
16+
try {
17+
local formula, errormsg = loadstring(formula);
18+
if !formula {error(errormsg);}
19+
setfenv(formula, env);
20+
for x = -150, 650 {
21+
env.x = x;
22+
formula();
23+
table.insert(dots, env.x || 0);
24+
table.insert(dots, -(env.y || 0));
25+
}
26+
} catch error {
27+
dots = nil;
28+
errormsg = error;
29+
}
30+
}
31+
32+
method love.keypressed(key) {
33+
if key == "backspace" && utf8.len(formula) > 0 {
34+
formula = ($)::sub(1, utf8.len($)-1);
35+
}
36+
}

samples/Clue/main.clue

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
static font = love.graphics.newFont("assets/clacon2.ttf", 24, "mono")
2+
static fontheight = 23 //force it to 23 cause windows and linux use different sizes...
3+
static screenheight = love.graphics.getHeight() - 10
4+
static leveltime = 0
5+
6+
io.stdout::setvbuf("no")
7+
8+
local utf8 = require("utf8")
9+
local terminal = import("terminal")
10+
import("player")
11+
12+
local screen = love.graphics.newCanvas()
13+
local hum = love.audio.newSource("assets/hum.ogg", "stream")
14+
local win = love.audio.newSource("assets/win.ogg", "static")
15+
local wrong = love.audio.newSource("assets/wrong.ogg", "static")
16+
17+
love.graphics.setFont(font)
18+
love.keyboard.setKeyRepeat(true)
19+
love.graphics.setShader(love.graphics.newShader("assets/shader.glsl"))
20+
21+
local start_command = commands.start
22+
23+
method love.load() {
24+
terminal::write("╔═╗ ╔═════╗ ╔═════╗ ╔═╗ ╔═════╗ ╔═════╗ ╔═════╗ ╔═════╗", 400)
25+
terminal::write("║ ║ ║ ╔═╗ ║ ║ ╔═╗ ║ ║ ║ ║ ╔═══╝ ║ ╔═╗ ║ ║ ╔═══╝ ║ ╔═══╝", 400)
26+
terminal::write("║ ║ ║ ╚═╝ ║ ║ ╚═╝ ║ ║ ║ ║ ╚═══╗ ║ ╚═╝ ║ ║ ╚═══╗ ║ ╚═══╗", 400)
27+
terminal::write("║ ║ ║ ╔═══╝ ║ ╔═══╝ ║ ║ ║ ╔═══╝ ║ ╔═╗ ║ ╚═══╗ ║ ║ ╔═══╝", 400)
28+
terminal::write("║ ║ ║ ║ ║ ║ ║ ╚═══╗ ║ ╚═══╗ ║ ║ ║ ║ ╔═══╝ ║ ║ ╚═══╗", 400)
29+
terminal::write("╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝", 400)
30+
terminal::write("A game for the LÖVE Jam 2023 - Created by Maiori")
31+
terminal::write("(Type 'guide' for instructions)")
32+
hum::setLooping(true)
33+
hum::setVolume(0.10)
34+
hum::play()
35+
}
36+
37+
method love.update(dt) {
38+
leveltime += dt
39+
local unfinished = terminal.unfinished[pointer]
40+
if unfinished {
41+
unfinished.progress += dt * unfinished.speed * 2
42+
if unfinished.progress >= #unfinished.text {
43+
unfinished.progress = nil
44+
table.remove(terminal.unfinished, 1)
45+
love.wheelmoved(0, -fontheight)
46+
match unfinished.text::sub(-7) { //this is a hacky way to do this...
47+
"glitch!" => {
48+
terminal::corrupt()
49+
}
50+
"choice!" => {
51+
win::play()
52+
}
53+
"o join." || " troll." || "ntions." => {
54+
wrong::play()
55+
}
56+
}
57+
}
58+
} elseif hacked && leveltime > hacked {
59+
terminal::corrupt()
60+
hacked = leveltime + hackamount
61+
hackamount /= 1.22
62+
if hackamount < 0.00000000000001 {
63+
hacked = nil
64+
hackamount = 0.5
65+
commands.clear.code()
66+
setmetatable(commands, {})
67+
commands.restart = start_command
68+
terminal::write("GAME OVER", 1, 1, 0, 0)
69+
terminal::write("Your server was destroyed...will you try again?", 15, 1, 0, 0)
70+
terminal::write("Final Score: " .. score, nil, 1, 0, 0)
71+
terminal::write("You messed up " .. ((mistakes - 1) * 2) .. " times.", nil, 1, 0, 0)
72+
terminal::write("(Type 'restart' to try again)", nil, 1, 0, 0)
73+
score = 0
74+
mistakes = 1
75+
}
76+
}
77+
}
78+
79+
global fn UpdateCanvas() {
80+
love.graphics.clear()
81+
local y = terminal::draw()
82+
if terminal::finished() && !hacked {
83+
love.graphics.setColor(0.125490196, 0.760784314, 0.054901961)
84+
local text = "$ " .. terminal.input[1]
85+
love.graphics.print(text, 5, y)
86+
if math.floor(leveltime) % 2 == 0 {
87+
love.graphics.print("_", 5 + font::getWidth(text), y)
88+
}
89+
}
90+
}
91+
92+
method love.draw() {
93+
screen::renderTo(UpdateCanvas)
94+
love.graphics.setColor(1, 1, 1)
95+
love.graphics.draw(screen)
96+
}
97+
98+
method love.resize(_, height) {
99+
screenheight = height - 10
100+
screen = love.graphics.newCanvas()
101+
love.wheelmoved(0, 0)
102+
}

0 commit comments

Comments
 (0)