Compare commits
3237 Commits
v0.12.4
...
test-new-m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
707bcca368 | ||
|
|
f8f115de10 | ||
|
|
b07c4dc53a | ||
|
|
6eeddba773 | ||
|
|
0cfe4df468 | ||
|
|
eb5c3c3be5 | ||
|
|
a5b9206694 | ||
|
|
375e67bdc4 | ||
|
|
724a576aa3 | ||
|
|
ed47dcb90c | ||
|
|
64b08a5a4d | ||
|
|
baed0153a2 | ||
|
|
46d95b33e4 | ||
|
|
200d270fee | ||
|
|
a8628275a0 | ||
|
|
20a1d2bcc1 | ||
|
|
b887a1f096 | ||
|
|
9bf0e9f28d | ||
|
|
dfc724767b | ||
|
|
f0e66e9dc5 | ||
|
|
0932335f0b | ||
|
|
a9b39e396a | ||
|
|
2e0ceaae72 | ||
|
|
04f38d2eb6 | ||
|
|
fc1ed4dff6 | ||
|
|
f8935d3dd7 | ||
|
|
a86228677f | ||
|
|
79df9f7876 | ||
|
|
12ea2d76be | ||
|
|
485bd72241 | ||
|
|
7240275075 | ||
|
|
29ef9b8d15 | ||
|
|
97f4795d4e | ||
|
|
226e45b24d | ||
|
|
d6ab7e72b2 | ||
|
|
168f44b8b3 | ||
|
|
b73f646a4c | ||
|
|
36cefcc000 | ||
|
|
f901c25c87 | ||
|
|
6d8478b029 | ||
|
|
9bcb040019 | ||
|
|
d977087fc0 | ||
|
|
1a330771d7 | ||
|
|
9c8c9f2106 | ||
|
|
0498beecdf | ||
|
|
8e075adf8f | ||
|
|
60f2a0e647 | ||
|
|
b642f2b5c4 | ||
|
|
2b80f72c6b | ||
|
|
462720881a | ||
|
|
3dda0254a8 | ||
|
|
054a52a445 | ||
|
|
85242d808b | ||
|
|
57241677a9 | ||
|
|
6ccdee2a53 | ||
|
|
a3d2b7b7f3 | ||
|
|
b7b28b4ae3 | ||
|
|
30748200dd | ||
|
|
c9f8240234 | ||
|
|
5c7082e886 | ||
|
|
9a3c889a9d | ||
|
|
f41f58e13f | ||
|
|
e81f25c216 | ||
|
|
36fc681fbf | ||
|
|
87e5e29129 | ||
|
|
b432fdf90a | ||
|
|
6e78a3fedd | ||
|
|
24760801af | ||
|
|
f5e8e0f7a5 | ||
|
|
df089a2f04 | ||
|
|
6600713f4b | ||
|
|
96dad762b2 | ||
|
|
5470387685 | ||
|
|
fa64c868b9 | ||
|
|
2f4a416353 | ||
|
|
3dbafb042c | ||
|
|
97e7b019dd | ||
|
|
28103ad952 | ||
|
|
1826ca6f2f | ||
|
|
db490a6c6c | ||
|
|
421fdef4f9 | ||
|
|
d717ce842d | ||
|
|
f13c9792af | ||
|
|
41e7b8e0f4 | ||
|
|
4bd723a7ee | ||
|
|
66d5bd5490 | ||
|
|
351d0258b2 | ||
|
|
26fb9a7052 | ||
|
|
307fd637fa | ||
|
|
93fb716f89 | ||
|
|
7b41551e2d | ||
|
|
4806af5f7d | ||
|
|
85cb55cdd0 | ||
|
|
27a9697e47 | ||
|
|
7d230cc3b0 | ||
|
|
0db2fffad1 | ||
|
|
2a3296a0e8 | ||
|
|
941b875afa | ||
|
|
99155bb9cf | ||
|
|
0701dd2ad3 | ||
|
|
5570c19e1f | ||
|
|
a728c91476 | ||
|
|
6a43481067 | ||
|
|
29a049fe4e | ||
|
|
b5a9c8e1bb | ||
|
|
bb9a35c161 | ||
|
|
b25a345b42 | ||
|
|
b22b0e0194 | ||
|
|
55cf95f218 | ||
|
|
225ddbcfac | ||
|
|
9377090c7c | ||
|
|
ed002ec2e1 | ||
|
|
e33036d9ec | ||
|
|
ef03e7c009 | ||
|
|
aef4220ac0 | ||
|
|
46223e38cd | ||
|
|
4bafa4bffe | ||
|
|
2b3dd877dd | ||
|
|
0553e5c45e | ||
|
|
4d93374cf6 | ||
|
|
4e421bf9ba | ||
|
|
8b2a9d7c01 | ||
|
|
5a3244d345 | ||
|
|
f1b9d0c5e4 | ||
|
|
6493e0e623 | ||
|
|
e71ba17f9f | ||
|
|
e656363e20 | ||
|
|
0826a748ae | ||
|
|
a595fe99ef | ||
|
|
9dbc7942e3 | ||
|
|
845d8ae32e | ||
|
|
5c524e138c | ||
|
|
86d9265ff9 | ||
|
|
6994a5d6d3 | ||
|
|
e6213b00c1 | ||
|
|
43e2caa30e | ||
|
|
97ca245dfc | ||
|
|
36de1c0751 | ||
|
|
704341fd15 | ||
|
|
22b61bc9c3 | ||
|
|
f4cbbc0a2a | ||
|
|
dc99187b9d | ||
|
|
915598dec4 | ||
|
|
e7b4518d73 | ||
|
|
9603a78e87 | ||
|
|
bd90e051d4 | ||
|
|
26e66b313f | ||
|
|
c534bbd12a | ||
|
|
83b5e217e5 | ||
|
|
c0adf5bf0b | ||
|
|
4ff737a4ac | ||
|
|
5af0706c09 | ||
|
|
4ccee0f1de | ||
|
|
9b752d540e | ||
|
|
e860c7b7ec | ||
|
|
8a1fd9531f | ||
|
|
5fd6e0ee99 | ||
|
|
53b2b81fe0 | ||
|
|
6ccc811b46 | ||
|
|
962a61567a | ||
|
|
58f05e1cec | ||
|
|
6b426790c7 | ||
|
|
d4fc578673 | ||
|
|
51b567b8db | ||
|
|
07b47dee3f | ||
|
|
4431a906b9 | ||
|
|
2bb6852e3e | ||
|
|
1948ed3e16 | ||
|
|
81b5ccae30 | ||
|
|
5543ff0d29 | ||
|
|
cd567e9e98 | ||
|
|
5d86925a8a | ||
|
|
e3db564a4b | ||
|
|
a4293624ab | ||
|
|
367e2dc81a | ||
|
|
9ec33c6eef | ||
|
|
9c9b8d36f2 | ||
|
|
4fc6f335c7 | ||
|
|
d2f4123d08 | ||
|
|
b29d352a1b | ||
|
|
cd5a71cd12 | ||
|
|
cdd68e985d | ||
|
|
8cf4d4280c | ||
|
|
cd29bf8702 | ||
|
|
13d98be051 | ||
|
|
a350ff3182 | ||
|
|
e0360cc7eb | ||
|
|
4249a29b63 | ||
|
|
43b2a0a8c8 | ||
|
|
6d6584f99e | ||
|
|
077c651226 | ||
|
|
3fc872aa76 | ||
|
|
cb0b347a38 | ||
|
|
d08967c688 | ||
|
|
3666c0caa9 | ||
|
|
4ef179fccb | ||
|
|
861f9b3caa | ||
|
|
05292df456 | ||
|
|
9fed692223 | ||
|
|
b1c04c1fea | ||
|
|
bc9adc2cd3 | ||
|
|
cdf149afca | ||
|
|
73145b4e5e | ||
|
|
f8b9f30fd6 | ||
|
|
e6bc567b12 | ||
|
|
fe004a72f0 | ||
|
|
0433fd3d9d | ||
|
|
1c18060570 | ||
|
|
be54c0e641 | ||
|
|
0be2eb9107 | ||
|
|
4859faf1e7 | ||
|
|
c25d40c67d | ||
|
|
b6c37a5c9f | ||
|
|
f6b4c1b109 | ||
|
|
841faeede4 | ||
|
|
e61b9b23a0 | ||
|
|
72a826ef0a | ||
|
|
f070b8f295 | ||
|
|
1646b75520 | ||
|
|
241617e31a | ||
|
|
5de2893e07 | ||
|
|
030e894040 | ||
|
|
e7b9a4ba87 | ||
|
|
617bae67c6 | ||
|
|
64d2d08820 | ||
|
|
037b33c99a | ||
|
|
afa69ce9a4 | ||
|
|
3226c0c831 | ||
|
|
4e759cad4c | ||
|
|
291795928d | ||
|
|
a1315e7f7f | ||
|
|
657bc2b4e0 | ||
|
|
d8b12fc55d | ||
|
|
6d11367ea4 | ||
|
|
eb9e741b4f | ||
|
|
c47546d501 | ||
|
|
11aa178fc1 | ||
|
|
f3a88ef269 | ||
|
|
720dc2131f | ||
|
|
701ef17ae1 | ||
|
|
1a689a5f07 | ||
|
|
ef12ab0cee | ||
|
|
3d26db7a01 | ||
|
|
dd3df9981b | ||
|
|
5d04e83529 | ||
|
|
7ed4626d71 | ||
|
|
ecf5a29a71 | ||
|
|
1a24b346a0 | ||
|
|
72d06c7a02 | ||
|
|
26fde8c694 | ||
|
|
8adeb99be7 | ||
|
|
c92f15156b | ||
|
|
63f69d712b | ||
|
|
55a1bd06f3 | ||
|
|
6a29abf7f0 | ||
|
|
83bdd9f2c4 | ||
|
|
95879827c8 | ||
|
|
2ade518207 | ||
|
|
36c8449e4d | ||
|
|
3c04df69f3 | ||
|
|
1224ee9a67 | ||
|
|
fdd1d4463a | ||
|
|
940ac3736c | ||
|
|
d38897b54d | ||
|
|
90848c6654 | ||
|
|
0220d5aefc | ||
|
|
f42032df07 | ||
|
|
05d7eb60bc | ||
|
|
942416317c | ||
|
|
576de945fb | ||
|
|
8b02084428 | ||
|
|
9f666d69db | ||
|
|
a4c52d9162 | ||
|
|
592b11366e | ||
|
|
07f50b9243 | ||
|
|
ec74d55686 | ||
|
|
4518513e87 | ||
|
|
7df4e2144f | ||
|
|
7f9c9248ce | ||
|
|
9c1db48804 | ||
|
|
0628830f0c | ||
|
|
9436f2f5fb | ||
|
|
c5e1b5617f | ||
|
|
298c417aa3 | ||
|
|
fc74831700 | ||
|
|
d9db55de44 | ||
|
|
3fd205e8c2 | ||
|
|
5cb828fb92 | ||
|
|
5f7a3fd53f | ||
|
|
8e3e598753 | ||
|
|
2a0a0f60f8 | ||
|
|
6b7d1fdf9f | ||
|
|
65199a40f7 | ||
|
|
f9082a8800 | ||
|
|
1670c6e7d6 | ||
|
|
ff2073ed4d | ||
|
|
f14aaac635 | ||
|
|
c709fa622f | ||
|
|
c752556bf3 | ||
|
|
e7d9703fcc | ||
|
|
1ed52a84b0 | ||
|
|
4fdb278751 | ||
|
|
8318803923 | ||
|
|
42de7e3676 | ||
|
|
3efa646ee3 | ||
|
|
b414c2ab42 | ||
|
|
205dea3db7 | ||
|
|
6cac688555 | ||
|
|
09b1b08c1e | ||
|
|
b61a1270e9 | ||
|
|
b85cee7e1f | ||
|
|
8e674e3e29 | ||
|
|
aa2812c874 | ||
|
|
6f282431c4 | ||
|
|
470e54cdd0 | ||
|
|
da3ef1c2a6 | ||
|
|
9efe0e62d5 | ||
|
|
7038f81b46 | ||
|
|
de972a60df | ||
|
|
6a87787d6f | ||
|
|
6dc9a4b507 | ||
|
|
5b7c888d57 | ||
|
|
a1f761b83e | ||
|
|
c40a6bfaa0 | ||
|
|
441c6f7667 | ||
|
|
a07d57cf71 | ||
|
|
a467f972f9 | ||
|
|
3f455ee360 | ||
|
|
7a0b913768 | ||
|
|
a7b240ade8 | ||
|
|
bb64404821 | ||
|
|
caf92eb3c8 | ||
|
|
6a117a0fab | ||
|
|
26682509f7 | ||
|
|
d85d92fb43 | ||
|
|
c412003cb3 | ||
|
|
e39b5dbd51 | ||
|
|
db162ea66f | ||
|
|
f9f9fde368 | ||
|
|
4b221c2eb5 | ||
|
|
ed45bebfa0 | ||
|
|
fa0bc3805f | ||
|
|
7710f0b70f | ||
|
|
0277ddadb5 | ||
|
|
88e23e32f5 | ||
|
|
8ab5b4a17a | ||
|
|
503dfd69ef | ||
|
|
ae61ec26c0 | ||
|
|
00bc24bd50 | ||
|
|
abd15d6307 | ||
|
|
c01ac546d1 | ||
|
|
af77221ba2 | ||
|
|
204f0938d3 | ||
|
|
ad39d1408c | ||
|
|
ed011173f6 | ||
|
|
491fcb5860 | ||
|
|
c2d5537d8d | ||
|
|
7d5037ae87 | ||
|
|
07d7714317 | ||
|
|
2cab97f37d | ||
|
|
d184778c9a | ||
|
|
9fd3b3008d | ||
|
|
71aa35b214 | ||
|
|
4443dc9d3e | ||
|
|
839e357301 | ||
|
|
ac56c5a415 | ||
|
|
36e3343341 | ||
|
|
510f7d7513 | ||
|
|
3128eb38c0 | ||
|
|
14ef654612 | ||
|
|
bc5193f95e | ||
|
|
8cbb4a38bc | ||
|
|
fce08c83ef | ||
|
|
018e99f9e6 | ||
|
|
7fe390b34b | ||
|
|
8c7202c569 | ||
|
|
ab386bb53c | ||
|
|
87c791b8c7 | ||
|
|
00e3e2d19d | ||
|
|
8d7d5c7b04 | ||
|
|
849a18e159 | ||
|
|
a4357d0843 | ||
|
|
e2b4a78b59 | ||
|
|
01387b5488 | ||
|
|
168e2f80b8 | ||
|
|
4f79ef8708 | ||
|
|
16497833df | ||
|
|
cd6a50d5a0 | ||
|
|
4c5a61f2d8 | ||
|
|
1fd8d39970 | ||
|
|
d133d64890 | ||
|
|
b27aa8b60d | ||
|
|
230d67492e | ||
|
|
4f9d5b282c | ||
|
|
a2955e8722 | ||
|
|
df892671d5 | ||
|
|
7fa96eee1a | ||
|
|
a1030906c7 | ||
|
|
e6a9a4f4be | ||
|
|
efa1247596 | ||
|
|
069fcee721 | ||
|
|
66621404f1 | ||
|
|
e09609ea21 | ||
|
|
d02ae67bc0 | ||
|
|
27327d57c4 | ||
|
|
cce93b6df9 | ||
|
|
546104ba5b | ||
|
|
ca5816ba14 | ||
|
|
e5bd16476e | ||
|
|
94431d4c2e | ||
|
|
f98d6892f1 | ||
|
|
1fe436cbe3 | ||
|
|
c5a37a9920 | ||
|
|
eed7e96096 | ||
|
|
a7f36a4162 | ||
|
|
8ba872d45d | ||
|
|
7a55451faa | ||
|
|
372571bd80 | ||
|
|
77120c0b90 | ||
|
|
01d1e44644 | ||
|
|
0ad8cddefe | ||
|
|
ce67253502 | ||
|
|
cb9f2c0617 | ||
|
|
635d9407ed | ||
|
|
0f9f6565f1 | ||
|
|
a45b6ad57e | ||
|
|
a5de06dedb | ||
|
|
fbfbd1ed98 | ||
|
|
8f06b3bd1a | ||
|
|
7e0dbceefc | ||
|
|
7e3db1de17 | ||
|
|
111790fdab | ||
|
|
bec03de7b8 | ||
|
|
f5dfae3a6c | ||
|
|
d3dec2b5f1 | ||
|
|
f083136998 | ||
|
|
cd3d0b370c | ||
|
|
f4c6632941 | ||
|
|
750cb9a669 | ||
|
|
62a198a017 | ||
|
|
5780ba0f3e | ||
|
|
86edeb1e0c | ||
|
|
53b1852f28 | ||
|
|
e3c385693b | ||
|
|
572c0fbfa1 | ||
|
|
bbdf71167a | ||
|
|
2136ccd9a2 | ||
|
|
2131aea575 | ||
|
|
32b21c7d29 | ||
|
|
8f6f6f316f | ||
|
|
66f9ac2791 | ||
|
|
ac0ba90438 | ||
|
|
990659ce91 | ||
|
|
00c602c844 | ||
|
|
9db62ffc39 | ||
|
|
e7c777e502 | ||
|
|
4991e8cea2 | ||
|
|
111d4e991f | ||
|
|
bedfa74a32 | ||
|
|
f6944dc223 | ||
|
|
a34a3051a3 | ||
|
|
0e13883faf | ||
|
|
e8860eda1b | ||
|
|
33ba4820b3 | ||
|
|
5ed0dda8ab | ||
|
|
bd260b2c6f | ||
|
|
aa01ab07f7 | ||
|
|
684cb90a7d | ||
|
|
172101ed55 | ||
|
|
98b5914726 | ||
|
|
d1518e7ba4 | ||
|
|
72d4faa52a | ||
|
|
862dcbf806 | ||
|
|
3db28f5136 | ||
|
|
f9e37f3c6a | ||
|
|
457681e6ec | ||
|
|
904bcf6852 | ||
|
|
e21e57ff84 | ||
|
|
562a69831a | ||
|
|
706a683540 | ||
|
|
8e2aee5e84 | ||
|
|
c009893377 | ||
|
|
3ae128d4c3 | ||
|
|
cb2164c21d | ||
|
|
951b7407fc | ||
|
|
f68facbe0e | ||
|
|
5535366bb1 | ||
|
|
d75b709f23 | ||
|
|
5a1fd0ca4d | ||
|
|
f4b85e0dbb | ||
|
|
c38bceb87e | ||
|
|
2569e8844e | ||
|
|
e42fa8351e | ||
|
|
9582a625ff | ||
|
|
81abb06f7b | ||
|
|
7cfea0eebe | ||
|
|
01c2bfe955 | ||
|
|
70242e6a07 | ||
|
|
c1edba974f | ||
|
|
546b3f230d | ||
|
|
14593eb487 | ||
|
|
838621a3ae | ||
|
|
283d4a5fce | ||
|
|
490cf44132 | ||
|
|
9dcbd86fc3 | ||
|
|
0a15011ec7 | ||
|
|
f7dfe1d869 | ||
|
|
5e9c9cb5fa | ||
|
|
c485c26c93 | ||
|
|
137d9296cd | ||
|
|
11b144da74 | ||
|
|
25ef9d9886 | ||
|
|
0e1e279209 | ||
|
|
a960897a83 | ||
|
|
69ab7849c5 | ||
|
|
bc55c3d892 | ||
|
|
cee1c41c35 | ||
|
|
6c5fe2463e | ||
|
|
880ce376b3 | ||
|
|
5a8b573bb7 | ||
|
|
ab1e750fa4 | ||
|
|
f6f4e1cd1a | ||
|
|
2a9549b106 | ||
|
|
1ed7ee3952 | ||
|
|
a69fc35f5a | ||
|
|
28e83dcf02 | ||
|
|
8c6df74237 | ||
|
|
d86cd6a8c6 | ||
|
|
c40d411d63 | ||
|
|
aca63abf49 | ||
|
|
4733615c4b | ||
|
|
80e5469653 | ||
|
|
4ea2cb18c7 | ||
|
|
840be65198 | ||
|
|
5a568df6cd | ||
|
|
cf57161174 | ||
|
|
7847e72f63 | ||
|
|
00999426b9 | ||
|
|
188da8b6ff | ||
|
|
59182b0ec8 | ||
|
|
6ced935c22 | ||
|
|
ad50475bb6 | ||
|
|
9c40f4918c | ||
|
|
62c802d2c3 | ||
|
|
3294760f6d | ||
|
|
85d72a1ee5 | ||
|
|
e02bb0f23c | ||
|
|
b0465775dc | ||
|
|
bd4b28e052 | ||
|
|
c6c5c849b4 | ||
|
|
cc5c3db1c1 | ||
|
|
f60236f06e | ||
|
|
bd63584207 | ||
|
|
e5fd3f6c9f | ||
|
|
423173413f | ||
|
|
a136d01da5 | ||
|
|
8ab675baf0 | ||
|
|
8d8e537cd4 | ||
|
|
d3b117a23f | ||
|
|
007982c481 | ||
|
|
ff9b0abfc7 | ||
|
|
275e983f55 | ||
|
|
bccb0b9976 | ||
|
|
d5f01537f8 | ||
|
|
6029363af8 | ||
|
|
cde61a57b8 | ||
|
|
2fc1768a7a | ||
|
|
50d73bcc1e | ||
|
|
0f570be7e5 | ||
|
|
658e6f7fdd | ||
|
|
d651932d9a | ||
|
|
6167c9f317 | ||
|
|
33acf06a71 | ||
|
|
9833e759cc | ||
|
|
918bb09d54 | ||
|
|
9a0a396872 | ||
|
|
6c6dc654e6 | ||
|
|
00c0cc3d9e | ||
|
|
0eb0fd3311 | ||
|
|
4e3823616d | ||
|
|
7450bae6d2 | ||
|
|
a2ddaf5341 | ||
|
|
b266a0ae57 | ||
|
|
ac9e649e02 | ||
|
|
506e1a4c1d | ||
|
|
c9d74a4cdf | ||
|
|
0ff2e6e273 | ||
|
|
c4c6ab3130 | ||
|
|
bc5b7638db | ||
|
|
2db147461c | ||
|
|
716c44746b | ||
|
|
0278a3ad47 | ||
|
|
3601047ffb | ||
|
|
8013319c14 | ||
|
|
b4f14bcb5b | ||
|
|
406beab9d6 | ||
|
|
58a8828503 | ||
|
|
fd563b732c | ||
|
|
30093f9db5 | ||
|
|
2f16c54cde | ||
|
|
bca7f2e19b | ||
|
|
2696106f96 | ||
|
|
9f7692f91c | ||
|
|
48b2ff5416 | ||
|
|
81104d7004 | ||
|
|
b56103f247 | ||
|
|
0923cf3acf | ||
|
|
fffb7d0188 | ||
|
|
f02124de0c | ||
|
|
a1a77f291b | ||
|
|
31bb7f62c6 | ||
|
|
bfb5fc3f5e | ||
|
|
ac2e53adc7 | ||
|
|
46e8e161d0 | ||
|
|
68e2255e1b | ||
|
|
222c1b5bba | ||
|
|
59c63da36f | ||
|
|
89fb7a7659 | ||
|
|
ea02bc470a | ||
|
|
361dc576f3 | ||
|
|
395ad907b8 | ||
|
|
bf5cdb1b99 | ||
|
|
45f9c80888 | ||
|
|
b80a72785b | ||
|
|
20ab916f9c | ||
|
|
76bfaa870e | ||
|
|
10ed702c2e | ||
|
|
e236be7a62 | ||
|
|
2fbd183322 | ||
|
|
14df29ce21 | ||
|
|
cb3d9e4862 | ||
|
|
d9a82878bf | ||
|
|
e484bef6df | ||
|
|
c8d358cc64 | ||
|
|
013765d5d2 | ||
|
|
ed2b07d5cf | ||
|
|
8d0780cef4 | ||
|
|
2ba25014c6 | ||
|
|
033a770759 | ||
|
|
b7832c133a | ||
|
|
93af618fa0 | ||
|
|
d4539c3a23 | ||
|
|
3d70a5ac79 | ||
|
|
f40b2f75bd | ||
|
|
46a49050b9 | ||
|
|
fb4fd15687 | ||
|
|
f3e18de45f | ||
|
|
fd3b187d32 | ||
|
|
820b555924 | ||
|
|
f8a0e67a2e | ||
|
|
99e77969ad | ||
|
|
fdb6276869 | ||
|
|
221e252acb | ||
|
|
dea01ffed6 | ||
|
|
166769e7e1 | ||
|
|
86d3314cb2 | ||
|
|
13a08298b7 | ||
|
|
66d2323626 | ||
|
|
cd432e3b3f | ||
|
|
cbf73f5194 | ||
|
|
5cd03f40f6 | ||
|
|
25b5f53f34 | ||
|
|
f9902a6ea5 | ||
|
|
0099bf53cb | ||
|
|
e6a8cf7a10 | ||
|
|
9b6855b424 | ||
|
|
6df8383580 | ||
|
|
b12663f404 | ||
|
|
66d3df0c10 | ||
|
|
a61e74c004 | ||
|
|
3d0a39dd34 | ||
|
|
6f643b8a1b | ||
|
|
d39cc71240 | ||
|
|
501fab147d | ||
|
|
6ee6cd7a1e | ||
|
|
7d5586d9a1 | ||
|
|
db78d713e7 | ||
|
|
ece5dfb799 | ||
|
|
1cb6b82f25 | ||
|
|
b0728650df | ||
|
|
48b4049d90 | ||
|
|
7f8efcdf41 | ||
|
|
dfa356e9d9 | ||
|
|
964537219a | ||
|
|
07eecc860f | ||
|
|
faf25008f9 | ||
|
|
116a3563bb | ||
|
|
6880c88301 | ||
|
|
8590f4c383 | ||
|
|
ff1e034a87 | ||
|
|
b36948cf30 | ||
|
|
c01df71fd4 | ||
|
|
7d90571d50 | ||
|
|
0cc7e121c8 | ||
|
|
060cdbbf51 | ||
|
|
769a654ed6 | ||
|
|
469899e8eb | ||
|
|
024e0df8e1 | ||
|
|
7603829942 | ||
|
|
ad91ac9c93 | ||
|
|
7a22dead81 | ||
|
|
73bc5dd30e | ||
|
|
154157b976 | ||
|
|
c5551a1b64 | ||
|
|
0d292446a2 | ||
|
|
7ba0d0d3a0 | ||
|
|
88bd9216d0 | ||
|
|
d8b728a6b3 | ||
|
|
26acecb8e4 | ||
|
|
b64234a7a3 | ||
|
|
1ca5fd7204 | ||
|
|
6868d53224 | ||
|
|
993866ab5b | ||
|
|
3eddb524d0 | ||
|
|
956316c327 | ||
|
|
88ff734ec7 | ||
|
|
3fb6b34a1e | ||
|
|
81a4429767 | ||
|
|
73bf974b1c | ||
|
|
693fb9f43f | ||
|
|
b3e65aea9f | ||
|
|
bb149f9890 | ||
|
|
26d2c8188d | ||
|
|
051d45edce | ||
|
|
6e35d7683c | ||
|
|
da405793da | ||
|
|
ef9aa8e195 | ||
|
|
7899c3a49f | ||
|
|
3394409183 | ||
|
|
300cf10413 | ||
|
|
8203f75cc9 | ||
|
|
10e0453a54 | ||
|
|
b131c34717 | ||
|
|
94a0f44fc5 | ||
|
|
8a47d7dc0f | ||
|
|
7a18c86927 | ||
|
|
958a296662 | ||
|
|
d932a0a990 | ||
|
|
3060d89ed4 | ||
|
|
54447e187a | ||
|
|
e4d62cc4af | ||
|
|
83a1770bac | ||
|
|
fd9793a42f | ||
|
|
47ba8fe0af | ||
|
|
639df50a31 | ||
|
|
bded1eab15 | ||
|
|
4a06c7b0bb | ||
|
|
08775dcca9 | ||
|
|
011fd8d175 | ||
|
|
f2ef3644aa | ||
|
|
b3a319b336 | ||
|
|
667a39dfd3 | ||
|
|
8f9b9952ea | ||
|
|
444e39ce33 | ||
|
|
74ad038f21 | ||
|
|
00401befca | ||
|
|
f5bffd6f74 | ||
|
|
63ac23a999 | ||
|
|
41e4cacdd8 | ||
|
|
a61e0086e0 | ||
|
|
6f7ebb4cbf | ||
|
|
43db02f97d | ||
|
|
3d4c51c532 | ||
|
|
45718eb41a | ||
|
|
90d51b979a | ||
|
|
6261256dea | ||
|
|
b1a508f209 | ||
|
|
17eedeaf38 | ||
|
|
733919e1df | ||
|
|
7f7eec18bc | ||
|
|
7c70f8c9bc | ||
|
|
9473364fde | ||
|
|
f8fc909fe6 | ||
|
|
d5a42f2316 | ||
|
|
9837330be0 | ||
|
|
c99bc2c38d | ||
|
|
9896918c35 | ||
|
|
0e605c66c4 | ||
|
|
4bf7ef0e25 | ||
|
|
438fef9f26 | ||
|
|
489a00e2d2 | ||
|
|
a1dd5b4188 | ||
|
|
3b5c66d192 | ||
|
|
10df10abfd | ||
|
|
4e0607b09c | ||
|
|
96f8f2cb28 | ||
|
|
4d91b92a33 | ||
|
|
9ad96608cf | ||
|
|
73f4dcd828 | ||
|
|
95cff8b986 | ||
|
|
f2ffdc9e58 | ||
|
|
702abbf7b1 | ||
|
|
cc0076a204 | ||
|
|
3f64d1044b | ||
|
|
28a0dd8b97 | ||
|
|
1787dbde4d | ||
|
|
6c10bff565 | ||
|
|
479fec4c59 | ||
|
|
1533e0fe74 | ||
|
|
242416a25d | ||
|
|
03689c6a0b | ||
|
|
2e9f1c18e5 | ||
|
|
c405cd93be | ||
|
|
99bbff0d34 | ||
|
|
653debbbc2 | ||
|
|
2279eb8e31 | ||
|
|
f475fafbf1 | ||
|
|
52bb86ad78 | ||
|
|
535a590ffd | ||
|
|
b2143557bd | ||
|
|
a6c47f5122 | ||
|
|
fddb2db8c7 | ||
|
|
da58578d33 | ||
|
|
391821bf16 | ||
|
|
7ae314fb2c | ||
|
|
7b141a5eaa | ||
|
|
0b1357c2ee | ||
|
|
417072bf00 | ||
|
|
ff0fa1802d | ||
|
|
07e07e61ee | ||
|
|
4f939d7ea4 | ||
|
|
9fa4b97e5e | ||
|
|
b890813732 | ||
|
|
f9650c565c | ||
|
|
6eca35759f | ||
|
|
c927e58ce4 | ||
|
|
4c7ba04274 | ||
|
|
bb60813323 | ||
|
|
4fc7dd447e | ||
|
|
dc0b39d6b5 | ||
|
|
84058f9833 | ||
|
|
d78fc5bf9c | ||
|
|
d839037c09 | ||
|
|
cfe0ef8864 | ||
|
|
e2d12d766f | ||
|
|
e73647780c | ||
|
|
1de11365c1 | ||
|
|
7ebf8aca5b | ||
|
|
58b8f354e0 | ||
|
|
2bfcc7e0f2 | ||
|
|
a7ddc69679 | ||
|
|
86d1f9470e | ||
|
|
57a233d51b | ||
|
|
a021fcd951 | ||
|
|
3bfa49236e | ||
|
|
0e52416a9b | ||
|
|
a0f8258cad | ||
|
|
a2da057581 | ||
|
|
56cbe4c5b6 | ||
|
|
48c9bd6dfd | ||
|
|
a30b69db4c | ||
|
|
e57ddbb6eb | ||
|
|
f1068eacd8 | ||
|
|
b762741a6e | ||
|
|
1f59aaca43 | ||
|
|
53d4fd8547 | ||
|
|
0eea1ae0c6 | ||
|
|
43a2ca9407 | ||
|
|
30ed4179d6 | ||
|
|
6f715a663a | ||
|
|
1d30623222 | ||
|
|
4db71b4b0d | ||
|
|
fe6d698b74 | ||
|
|
7393b3c716 | ||
|
|
493fcb2f05 | ||
|
|
47c509c0a7 | ||
|
|
c98783d33f | ||
|
|
b71c9d7bf3 | ||
|
|
25ed49f1a6 | ||
|
|
cb0a3314b6 | ||
|
|
3880197d02 | ||
|
|
ec04da06d7 | ||
|
|
4654e9f7c7 | ||
|
|
fc3517584d | ||
|
|
8677e98a24 | ||
|
|
152dc13ded | ||
|
|
76ab6282a9 | ||
|
|
61b264cd70 | ||
|
|
3714fea994 | ||
|
|
e1a820d1f9 | ||
|
|
3f94dadcef | ||
|
|
e67d6ce53c | ||
|
|
13cf53e885 | ||
|
|
f95be0996d | ||
|
|
dbc5a1e45c | ||
|
|
dd30e4b3ec | ||
|
|
9468c0435a | ||
|
|
4be5933dc8 | ||
|
|
fe5ba06328 | ||
|
|
a2f5db8d3c | ||
|
|
b48e65a9d8 | ||
|
|
18471a201f | ||
|
|
1d61a3af8b | ||
|
|
e4f5b8f95c | ||
|
|
d31ab133f4 | ||
|
|
dcc15dd42b | ||
|
|
280f2c0af5 | ||
|
|
890264ef7d | ||
|
|
e9d58a4f74 | ||
|
|
9020798f90 | ||
|
|
7167df10e6 | ||
|
|
8bedd7aa2a | ||
|
|
357e747391 | ||
|
|
8c11721c75 | ||
|
|
da13235c88 | ||
|
|
aababce74c | ||
|
|
a395004027 | ||
|
|
0489394d67 | ||
|
|
4cde774cc2 | ||
|
|
baa2b105d3 | ||
|
|
9667d9ffa8 | ||
|
|
b8b85b569c | ||
|
|
27f2d05c56 | ||
|
|
49e1c0758d | ||
|
|
2299eb0e33 | ||
|
|
b6e17594c6 | ||
|
|
19c2724e8b | ||
|
|
7f4591bcec | ||
|
|
4de7ee4ce0 | ||
|
|
eb6f1718a8 | ||
|
|
36ce09c4f1 | ||
|
|
1994a615c2 | ||
|
|
82b75a5aa9 | ||
|
|
2ec91f58ae | ||
|
|
e9cd7ef5ca | ||
|
|
29aff06b1d | ||
|
|
18f3414f34 | ||
|
|
a7b236d528 | ||
|
|
46fdf03925 | ||
|
|
f67f31baa2 | ||
|
|
1fcbb8ea7d | ||
|
|
60ef682c80 | ||
|
|
c668a22345 | ||
|
|
cb69f011e5 | ||
|
|
176e96fd1f | ||
|
|
43e550b9b2 | ||
|
|
ee139d5ff0 | ||
|
|
5c5ec3e16c | ||
|
|
da82d679ce | ||
|
|
834a08d58d | ||
|
|
395485527e | ||
|
|
8c9fd45fcc | ||
|
|
59356b9f28 | ||
|
|
bb3cc84ca4 | ||
|
|
ac2c708d01 | ||
|
|
57497dbd74 | ||
|
|
827d0cdf5a | ||
|
|
e3539f17bd | ||
|
|
b88580ad9a | ||
|
|
8d8cceaeea | ||
|
|
290c7988b2 | ||
|
|
f97767aff4 | ||
|
|
fae14d4f9b | ||
|
|
699247266e | ||
|
|
5c8b80741f | ||
|
|
e5287d876b | ||
|
|
b3e6e42790 | ||
|
|
fce5b9696f | ||
|
|
f252ed63d5 | ||
|
|
3114d3a27d | ||
|
|
e186bfe80d | ||
|
|
3db2a4b30d | ||
|
|
1c25138eaf | ||
|
|
1807c95c53 | ||
|
|
7ea78ee48a | ||
|
|
5d57feaea5 | ||
|
|
f4583e46bf | ||
|
|
5ed00a67c4 | ||
|
|
0148c539be | ||
|
|
51cdf864be | ||
|
|
bd9ee49255 | ||
|
|
16c377427a | ||
|
|
66dcfa40b0 | ||
|
|
e726ef505f | ||
|
|
a686a2e9d1 | ||
|
|
720ee71f8b | ||
|
|
557cdf6cfb | ||
|
|
6b93675ec1 | ||
|
|
9419c4c639 | ||
|
|
7eb243a18f | ||
|
|
3a2b531d4c | ||
|
|
05068f8df5 | ||
|
|
a6d80667c1 | ||
|
|
a0dccadfd7 | ||
|
|
7992eab16c | ||
|
|
a1c6f720a2 | ||
|
|
a1162f1b0f | ||
|
|
80f21ae2f0 | ||
|
|
fce8623595 | ||
|
|
e82a5c8026 | ||
|
|
517d4cfc82 | ||
|
|
7f7f7e752e | ||
|
|
5963db479e | ||
|
|
96266ab310 | ||
|
|
c7f6b396e0 | ||
|
|
b7ca91f9e2 | ||
|
|
9ec7cdb070 | ||
|
|
3e1220fa0e | ||
|
|
660946215e | ||
|
|
a7b38335c9 | ||
|
|
e4803cc89d | ||
|
|
b104298c7d | ||
|
|
e049375bbc | ||
|
|
f48bd550b7 | ||
|
|
00ec064dc3 | ||
|
|
4c5409aa01 | ||
|
|
6166c87e16 | ||
|
|
159cd74c28 | ||
|
|
60ef83dd34 | ||
|
|
3c02c5957e | ||
|
|
bbef071931 | ||
|
|
726928aadc | ||
|
|
7ad386d28f | ||
|
|
a4c9bdef4a | ||
|
|
a64edc70ed | ||
|
|
f6826432d0 | ||
|
|
f29efa8f60 | ||
|
|
e7bcf489eb | ||
|
|
15d43f6313 | ||
|
|
a7f7374f96 | ||
|
|
de1a1cbe9a | ||
|
|
27a0e8ee3a | ||
|
|
db4f193046 | ||
|
|
118182a6cc | ||
|
|
442b3bd233 | ||
|
|
12c96f321b | ||
|
|
f77d8d5219 | ||
|
|
b7d5a3f9c6 | ||
|
|
b887ca01d0 | ||
|
|
179ff9b10a | ||
|
|
4c18629cd7 | ||
|
|
295e79984f | ||
|
|
8f910f95f4 | ||
|
|
ee55055385 | ||
|
|
674edfc330 | ||
|
|
c33e5029df | ||
|
|
a2f205362a | ||
|
|
3d6771b3d2 | ||
|
|
fe9ff0c337 | ||
|
|
754545cc40 | ||
|
|
aab45b1b14 | ||
|
|
9eaa00e878 | ||
|
|
8520ca44ee | ||
|
|
6b8ac5e939 | ||
|
|
5767acb5bf | ||
|
|
9e3fc97727 | ||
|
|
7817499da7 | ||
|
|
1c43e92577 | ||
|
|
3e4f945d56 | ||
|
|
491c4d25d7 | ||
|
|
2432d57d70 | ||
|
|
9408b592fd | ||
|
|
743f192d85 | ||
|
|
4e47b0acb7 | ||
|
|
43ab4e1e42 | ||
|
|
9b28cdbcd2 | ||
|
|
acb29c33d3 | ||
|
|
e3eee3dc02 | ||
|
|
e3eae25caa | ||
|
|
cc23869128 | ||
|
|
36c11961b6 | ||
|
|
f21dc94979 | ||
|
|
d4ab850e7b | ||
|
|
edf6e075f2 | ||
|
|
92c3b8314d | ||
|
|
33260fc820 | ||
|
|
5b5afec84d | ||
|
|
d818e697e9 | ||
|
|
03edb20265 | ||
|
|
4157062442 | ||
|
|
2f46645149 | ||
|
|
31f4576acd | ||
|
|
e1d85b0a04 | ||
|
|
961cf347da | ||
|
|
02c4655f0d | ||
|
|
b7b94ca900 | ||
|
|
8671b52cbb | ||
|
|
9fe045b916 | ||
|
|
4d2a914719 | ||
|
|
1cfcf03ede | ||
|
|
a81d2e9ccc | ||
|
|
d7cf2c19ab | ||
|
|
42c72349dd | ||
|
|
027a228734 | ||
|
|
543aed0350 | ||
|
|
fa704c5d66 | ||
|
|
ad6adb221c | ||
|
|
5978a80b46 | ||
|
|
8c4f380d73 | ||
|
|
273de18ae3 | ||
|
|
44082fe78e | ||
|
|
9e6295e008 | ||
|
|
eaf4e3d71e | ||
|
|
bd52f1bb3c | ||
|
|
6682355c1b | ||
|
|
f76b08ab27 | ||
|
|
1943a55bcc | ||
|
|
9ec822a095 | ||
|
|
04f67d4052 | ||
|
|
d9251f16db | ||
|
|
f268ed8427 | ||
|
|
58881f8ef5 | ||
|
|
addc68b5f1 | ||
|
|
79368af6ee | ||
|
|
9f64d84c5a | ||
|
|
bafc8abfc0 | ||
|
|
abaa962531 | ||
|
|
8049792dc4 | ||
|
|
7dbd5de980 | ||
|
|
36a965a1c3 | ||
|
|
d382bad8e1 | ||
|
|
186f18f4d2 | ||
|
|
c777fc969a | ||
|
|
1b176ed5ad | ||
|
|
2654c8a614 | ||
|
|
23e3dc465d | ||
|
|
132cb89b90 | ||
|
|
39ca55fd84 | ||
|
|
d457fb0011 | ||
|
|
42620bf739 | ||
|
|
fc8d19756d | ||
|
|
45dce3210a | ||
|
|
9dbb32c982 | ||
|
|
cf84ab5921 | ||
|
|
05d01bbcc5 | ||
|
|
64b8058dc6 | ||
|
|
ba09d9440f | ||
|
|
21fc6505ff | ||
|
|
5a27de7550 | ||
|
|
9c9324e7d9 | ||
|
|
e938621996 | ||
|
|
4cf1f4ba15 | ||
|
|
ce937bd0bb | ||
|
|
3e4963e56c | ||
|
|
adb205d8fa | ||
|
|
c4f6a6823d | ||
|
|
f53a37c496 | ||
|
|
fbc1c6b60a | ||
|
|
6559a405e1 | ||
|
|
45ec45c206 | ||
|
|
a0ff754464 | ||
|
|
a7f0f30af2 | ||
|
|
c48d8f9a45 | ||
|
|
276cbd6aa1 | ||
|
|
6f1ba85869 | ||
|
|
9bba05f26c | ||
|
|
5d75e11679 | ||
|
|
d58a67012d | ||
|
|
7e41b747dd | ||
|
|
4dd23b8e76 | ||
|
|
19403e0ae5 | ||
|
|
2ff87a0655 | ||
|
|
f0b12799b8 | ||
|
|
c81850cb36 | ||
|
|
d7fe8bfeee | ||
|
|
06c5beae7d | ||
|
|
c929ddbe97 | ||
|
|
77b557fb13 | ||
|
|
dbc58e0bc9 | ||
|
|
1bb5e0c056 | ||
|
|
31c03681fa | ||
|
|
742dc43c5d | ||
|
|
a9a241cc41 | ||
|
|
3ffaeed317 | ||
|
|
8950cf9533 | ||
|
|
21bdb374d0 | ||
|
|
3b2ce1e85a | ||
|
|
ffc84334bf | ||
|
|
c37370a50a | ||
|
|
43c8218a14 | ||
|
|
625c859e0d | ||
|
|
2ee2eb4274 | ||
|
|
6262ad637d | ||
|
|
df78225114 | ||
|
|
130de57d1a | ||
|
|
d7aba9bb64 | ||
|
|
77bf9c6f16 | ||
|
|
b44d144b26 | ||
|
|
376a528fac | ||
|
|
6dec156d4d | ||
|
|
372f27b6ac | ||
|
|
d6d2d394bc | ||
|
|
7c326ce0d7 | ||
|
|
1ae26d39c2 | ||
|
|
702d427183 | ||
|
|
432ba338b7 | ||
|
|
c1ce09ac52 | ||
|
|
57982d3c43 | ||
|
|
c168a6c685 | ||
|
|
17479ac08b | ||
|
|
a73819214b | ||
|
|
c5730b31f7 | ||
|
|
4bfebdea13 | ||
|
|
d040754d8c | ||
|
|
7943ebc8f8 | ||
|
|
5ce0b90d9f | ||
|
|
e97d892926 | ||
|
|
3b026ce204 | ||
|
|
d269828924 | ||
|
|
1e1560651a | ||
|
|
782e1ef506 | ||
|
|
3a3c805792 | ||
|
|
51235a61ad | ||
|
|
f493de998c | ||
|
|
72b5acfece | ||
|
|
176ddf6abb | ||
|
|
44c52300e4 | ||
|
|
2eae6cdfda | ||
|
|
0f896d0a4f | ||
|
|
02189c4262 | ||
| d649a0caa1 | |||
| e28894549c | |||
| b3ef90237f | |||
| ebc4e08986 | |||
| 8d74a35f29 | |||
| a37e164c0b | |||
| a71b504589 | |||
|
|
20cd27d7f6 | ||
|
|
ac889dcba9 | ||
|
|
70bbb12285 | ||
|
|
e7e568f67a | ||
|
|
3452ae1d66 | ||
|
|
2ad336b13a | ||
|
|
78b15b78fa | ||
|
|
eb7b637703 | ||
|
|
b083a0801f | ||
|
|
471f1076c4 | ||
|
|
e50fe63e02 | ||
|
|
7682054dea | ||
|
|
1e3c2f039b | ||
|
|
a832e56b42 | ||
|
|
3858cfd9ba | ||
|
|
5b4fd892ff | ||
|
|
4ffa88805c | ||
|
|
2a0b26f2fd | ||
|
|
30308eb308 | ||
|
|
5f8cbe524e | ||
|
|
a2f0142712 | ||
|
|
d2c6529d2a | ||
|
|
b23e32df7f | ||
|
|
a94a0a2f87 | ||
|
|
6fe40e9438 | ||
|
|
d4523e8e1d | ||
|
|
9fadef2a6e | ||
|
|
1970a1b47d | ||
|
|
19d090859c | ||
|
|
7fda77bd1e | ||
|
|
34c14c922c | ||
|
|
0f8a1057dc | ||
|
|
a74faca9cb | ||
|
|
336aa85cf8 | ||
|
|
43710a4c4d | ||
|
|
451cf90939 | ||
|
|
6713f48361 | ||
|
|
f6e3b35482 | ||
|
|
1d7e58d3bf | ||
|
|
b501cd374b | ||
|
|
e6f5723ecc | ||
|
|
998c79d331 | ||
|
|
a21d6e834d | ||
|
|
a4541dd764 | ||
|
|
e788dd543e | ||
|
|
f24fa81d87 | ||
|
|
20fb2a3e92 | ||
|
|
e7f77291e4 | ||
|
|
fa0848c8b2 | ||
|
|
8a740091b3 | ||
|
|
5fa3be5886 | ||
|
|
a9d2f097d8 | ||
|
|
450483acc7 | ||
|
|
43019185a8 | ||
|
|
f537b36662 | ||
|
|
98385b8b56 | ||
|
|
8d44046a90 | ||
|
|
9b1ab459a0 | ||
|
|
f4c0d19734 | ||
|
|
f088bdcf8b | ||
|
|
60600dbe2f | ||
|
|
eb95cc4b47 | ||
|
|
57dfdacffa | ||
|
|
0c839790fe | ||
|
|
1f29916e09 | ||
|
|
310023dc94 | ||
|
|
9448dcefb4 | ||
|
|
167e77ddf2 | ||
|
|
dc586ad82e | ||
|
|
6d331f882f | ||
|
|
b945760c72 | ||
|
|
98aa49c2c3 | ||
|
|
78feab88bf | ||
|
|
6f005d467d | ||
|
|
324011f01b | ||
|
|
0d97d2a02d | ||
|
|
37bec38524 | ||
|
|
847795c0ef | ||
|
|
aa1a5a1550 | ||
|
|
997b3cbecd | ||
|
|
652aced790 | ||
|
|
47af067c03 | ||
|
|
5b31e3eb87 | ||
|
|
0bb4b069e7 | ||
|
|
eded658d38 | ||
|
|
1caeb0ed6b | ||
|
|
611a1f0a04 | ||
|
|
13e58e6f80 | ||
|
|
d6853d381f | ||
|
|
b6cc14fe2f | ||
|
|
9b1f9fa9dd | ||
|
|
cca53b6376 | ||
|
|
1aa991f89f | ||
|
|
7407bbefdf | ||
|
|
40fb835d9c | ||
|
|
e4df92fb54 | ||
|
|
7b9760e376 | ||
|
|
52607545fa | ||
|
|
849756531d | ||
|
|
2e16240fb8 | ||
|
|
181beda455 | ||
|
|
d0f77f4b78 | ||
|
|
dea2f6c8d7 | ||
|
|
615fd414ec | ||
|
|
7296498410 | ||
|
|
554970c036 | ||
|
|
057abe6ba5 | ||
|
|
3b215eb7af | ||
|
|
1abaa0e5c5 | ||
|
|
0c5cb1686e | ||
|
|
21f0aabae0 | ||
|
|
e5458c1ab9 | ||
|
|
a30c0395aa | ||
|
|
0b9006faf3 | ||
|
|
adefb776fe | ||
|
|
ee089b0f31 | ||
|
|
44200458c5 | ||
|
|
5d2d4eae17 | ||
|
|
25f87cae53 | ||
|
|
1e4f11a6ce | ||
|
|
36b9dcaf43 | ||
|
|
ad3aff6a50 | ||
|
|
3bd6da6276 | ||
|
|
3ccc8cdd7b | ||
|
|
501f3a4eec | ||
|
|
cfc6f65da5 | ||
|
|
5853ac1823 | ||
|
|
3057b2a12f | ||
|
|
9ce90b76a4 | ||
|
|
e016a20c21 | ||
|
|
8fb8352c8d | ||
|
|
ed7ecd98c4 | ||
|
|
512c78e192 | ||
|
|
81b3082087 | ||
|
|
6fff929856 | ||
|
|
e636deb08e | ||
|
|
464d5bedda | ||
|
|
9cc70d4212 | ||
|
|
737cdb74bd | ||
|
|
a833139e13 | ||
|
|
4ec9377f78 | ||
|
|
e9e96f287f | ||
|
|
57745f5d0a | ||
|
|
515c2d1f60 | ||
|
|
decbde8d63 | ||
|
|
08c892d4ff | ||
|
|
850a31d172 | ||
|
|
6ae419eeee | ||
|
|
40bae13411 | ||
|
|
61946fe52e | ||
|
|
27cede0fad | ||
|
|
adae63eabb | ||
|
|
3ff5f74af7 | ||
|
|
c3c151b375 | ||
|
|
2163d09c08 | ||
|
|
ea70c2ef9e | ||
|
|
53f949571e | ||
|
|
1d64a6b799 | ||
|
|
84b5790ab2 | ||
|
|
6aa8de3506 | ||
|
|
c1b55139b6 | ||
|
|
670417dc6a | ||
|
|
bd1d1f8ae4 | ||
|
|
29a922e41f | ||
|
|
ac9fd5e618 | ||
|
|
9d6a74680a | ||
|
|
9d52cf27d8 | ||
|
|
35c38387e1 | ||
|
|
908997ddef | ||
|
|
cf0b95e955 | ||
|
|
5bf5d44c96 | ||
|
|
854776dac0 | ||
|
|
6e1ba35ca3 | ||
|
|
a5a41e3b0c | ||
|
|
e78114dd53 | ||
|
|
6174f3709c | ||
|
|
7f1f9b0221 | ||
|
|
0af4e2adb9 | ||
|
|
d5ab596749 | ||
|
|
3d128d4850 | ||
|
|
46aa6fcc48 | ||
|
|
60d1eb4e3c | ||
|
|
4b2c55d90e | ||
|
|
0023c0a4c6 | ||
|
|
0265793a3f | ||
|
|
b99d247ba5 | ||
|
|
bdc1e592a7 | ||
|
|
d3ef7e7f81 | ||
|
|
78dfec15d6 | ||
|
|
7a824e09a3 | ||
|
|
7c58355048 | ||
|
|
89662e7e2c | ||
|
|
718fc750d9 | ||
|
|
9e143fbb73 | ||
|
|
c561181bdf | ||
|
|
b45920109f | ||
|
|
07290fe7ce | ||
|
|
944f57b04a | ||
|
|
4079c6596e | ||
|
|
defe6c4f26 | ||
|
|
ed2a46e059 | ||
|
|
498a0ef7e8 | ||
|
|
06d34d8c55 | ||
|
|
cd670212a2 | ||
|
|
41e58e0bd6 | ||
|
|
b0af47a422 | ||
|
|
ccfb0c72dd | ||
|
|
be1b87a1af | ||
|
|
33ffb80241 | ||
|
|
42b61af93d | ||
|
|
cfdba225e0 | ||
|
|
8c0b3fd31d | ||
|
|
ef88d3e437 | ||
|
|
cbbb04655b | ||
|
|
956b768475 | ||
|
|
51768a5a27 | ||
|
|
4a58967590 | ||
|
|
bc879ee8e2 | ||
|
|
d3046fa588 | ||
|
|
ce8fefe9f8 | ||
|
|
f7369ef4ae | ||
|
|
c0cfb97034 | ||
|
|
c742e9fd31 | ||
|
|
1d1522a9c4 | ||
|
|
a9925b3f15 | ||
|
|
2ea9a58a41 | ||
|
|
9abf7bb45b | ||
|
|
6afaf462f8 | ||
|
|
b1ac913dd8 | ||
|
|
4e5b16c0e2 | ||
|
|
56b2a41eee | ||
|
|
8b32f29c2a | ||
|
|
52ad2e2ddc | ||
|
|
2edd5542f8 | ||
|
|
cb27f145a3 | ||
|
|
44cbe58486 | ||
|
|
1c8844c3c4 | ||
|
|
6c864ea59a | ||
|
|
9818685856 | ||
|
|
51e709acf6 | ||
|
|
f826899f45 | ||
|
|
b3f9aa3d28 | ||
|
|
d9c31f6661 | ||
|
|
2af3f15997 | ||
|
|
701e4bbdbb | ||
|
|
ce8e2597fe | ||
|
|
b185852271 | ||
|
|
7a2ac914df | ||
|
|
a0e3eb21c5 | ||
|
|
c9132b02a4 | ||
|
|
0e81b0f8c8 | ||
|
|
de3bd91d4d | ||
|
|
ad35dab32b | ||
|
|
b650999f96 | ||
|
|
9c2974e4f0 | ||
|
|
00859ee26b | ||
|
|
89218c7529 | ||
|
|
53d94f1f51 | ||
|
|
332700fd64 | ||
|
|
8e1dd048b5 | ||
|
|
e9e6b25276 | ||
|
|
ab6080767b | ||
|
|
87e27e8a4b | ||
|
|
3b56679a32 | ||
|
|
bbf46a0d6d | ||
|
|
8622268445 | ||
|
|
201c20b56f | ||
|
|
835430bf84 | ||
|
|
4db12c500e | ||
|
|
77b9809eaa | ||
|
|
e2f84ee25a | ||
|
|
15f414f43d | ||
|
|
e060d99b02 | ||
|
|
97ca282f8a | ||
|
|
a1980cf766 | ||
|
|
82dc468868 | ||
|
|
5eb162718c | ||
|
|
04b4ac00fc | ||
|
|
345223c159 | ||
|
|
44adb2a018 | ||
|
|
f4ef9a1612 | ||
|
|
9066c6428a | ||
|
|
6c45388172 | ||
|
|
c9265c640a | ||
|
|
5deb724f7d | ||
|
|
fd21edd024 | ||
|
|
b1d5490e1b | ||
|
|
7248af35de | ||
|
|
601049ffe1 | ||
|
|
7ae418c597 | ||
|
|
e29c3af8bb | ||
|
|
23f587165a | ||
|
|
0e0b6db4a5 | ||
|
|
7295179f5d | ||
|
|
03dad89787 | ||
|
|
7b227181f2 | ||
|
|
f3994316e3 | ||
|
|
57792bd230 | ||
|
|
09bdb4e52b | ||
|
|
5ceb59daae | ||
|
|
f3d8c6b98a | ||
|
|
82749e9e19 | ||
|
|
6859d70ca7 | ||
|
|
34cfca88d7 | ||
|
|
5ccda32d63 | ||
|
|
5dfdfb8151 | ||
|
|
23b1692702 | ||
|
|
706fa901e2 | ||
|
|
1c553df53a | ||
|
|
f1416f46fc | ||
|
|
b988de13bb | ||
|
|
f74f7b3814 | ||
|
|
c406059177 | ||
|
|
1dcce5f3b2 | ||
|
|
cb2f011b19 | ||
|
|
70871ee4fd | ||
|
|
2f7647c5ba | ||
|
|
f536173dea | ||
|
|
9488dc61f9 | ||
|
|
6f74595305 | ||
|
|
a1f32ca333 | ||
|
|
45ab91267f | ||
|
|
3472ccc73d | ||
|
|
a9789b1c21 | ||
|
|
20095c01d1 | ||
|
|
653b256253 | ||
|
|
a9a66bf21e | ||
|
|
2fd310baed | ||
|
|
ef94e1bf3a | ||
|
|
fe91265f62 | ||
|
|
b8a9c42a3b | ||
|
|
b0ecb28b48 | ||
|
|
6cb81b461b | ||
|
|
9b44971de8 | ||
|
|
c8908f38fb | ||
|
|
d7c721ae5b | ||
|
|
4d3d00bc58 | ||
|
|
5eaeaaa79f | ||
|
|
d77af59521 | ||
|
|
b5093d19f4 | ||
|
|
ef14e8b38c | ||
|
|
0f3c234ca0 | ||
|
|
563d820fbe | ||
|
|
d15757dcc2 | ||
|
|
9d28505140 | ||
|
|
ce91e75cd2 | ||
|
|
4809d4193e | ||
|
|
9ee310e73f | ||
|
|
1380fa768c | ||
|
|
0ea58e0858 | ||
|
|
d1c1631bae | ||
|
|
ef2b845837 | ||
|
|
e252364c59 | ||
|
|
bc14c6f625 | ||
|
|
bcc1b25023 | ||
|
|
5f609f41a5 | ||
|
|
38589fbebe | ||
|
|
356316aaa3 | ||
|
|
b554409b32 | ||
|
|
076d854f11 | ||
|
|
14852fa3e9 | ||
|
|
42e2823e28 | ||
|
|
535e78a8b3 | ||
|
|
c8480a17e9 | ||
|
|
6989158216 | ||
|
|
7fc3d13c99 | ||
|
|
7ce56b8913 | ||
|
|
a0980138f9 | ||
|
|
16e01e510e | ||
|
|
ee628778cf | ||
|
|
36a30a6318 | ||
|
|
096f162ea6 | ||
|
|
22c213b10f | ||
|
|
ba66610a01 | ||
|
|
ab4a055194 | ||
|
|
2ce2f91414 | ||
|
|
0f1c8c7b2f | ||
|
|
8adcd4b8a9 | ||
|
|
db5a8594fd | ||
|
|
5238d855b4 | ||
|
|
6c2cbe5f20 | ||
|
|
27ce516dd9 | ||
|
|
981479ca5f | ||
|
|
70a41855d1 | ||
|
|
3571ef404c | ||
|
|
86ee26381c | ||
|
|
198b18ec89 | ||
|
|
18ff09befa | ||
|
|
bd48c266b8 | ||
|
|
cf410dfbdd | ||
|
|
4afac2a2fb | ||
|
|
d96f45c3b3 | ||
|
|
e381f66767 | ||
|
|
d0b9cdc503 | ||
|
|
e846222ace | ||
|
|
b3e9b128b6 | ||
|
|
0708d05ec9 | ||
|
|
f4eda19684 | ||
|
|
b0c71e0f6c | ||
|
|
3b675ad8ed | ||
|
|
4c95f6bfbc | ||
|
|
98715e4579 | ||
|
|
89af52b14b | ||
|
|
1b4c1b8d7f | ||
|
|
aea6840263 | ||
|
|
cc33d04f32 | ||
|
|
e75ab93838 | ||
|
|
85f3cb4d19 | ||
|
|
dab880bc82 | ||
|
|
004bb0cfca | ||
|
|
ca0ca8fd98 | ||
|
|
660f027c01 | ||
|
|
a69648274c | ||
|
|
eee820bc73 | ||
|
|
4e9fbf6764 | ||
|
|
f78856c58e | ||
|
|
e5a3b6c6ac | ||
|
|
37a3e36bd5 | ||
|
|
99eeeb915a | ||
|
|
00f6d46f71 | ||
|
|
41660e4074 | ||
|
|
88367fc7a6 | ||
|
|
5361235234 | ||
|
|
82634a32a5 | ||
|
|
cc89c937dc | ||
|
|
e0997f0ecb | ||
|
|
8127a999b3 | ||
|
|
490bebf632 | ||
|
|
82040d0525 | ||
|
|
eee6160565 | ||
|
|
8daae21a76 | ||
|
|
bb722d4a2b | ||
|
|
160be9048c | ||
|
|
46c2ed8332 | ||
|
|
101c8a2994 | ||
|
|
e7bfc8335e | ||
|
|
c17865d777 | ||
|
|
28cf3d878f | ||
|
|
67d6d4a3ee | ||
|
|
369891ba54 | ||
|
|
18ccd00083 | ||
|
|
ce36d5d43c | ||
|
|
0ee460b679 | ||
|
|
e77f415f38 | ||
|
|
6d78bd2b42 | ||
|
|
39d91a513b | ||
|
|
7075d7d5b2 | ||
|
|
17e67c674b | ||
|
|
e90a12418d | ||
|
|
ec4697c45e | ||
|
|
11862e6fba | ||
|
|
0e50c54754 | ||
|
|
90943f207a | ||
|
|
a6c62fb6ed | ||
|
|
cde97fdd3f | ||
|
|
3cfa230d2b | ||
|
|
5b57c84034 | ||
|
|
6bd4895255 | ||
|
|
21834a357d | ||
|
|
a51a95339b | ||
|
|
67f5ed49ec | ||
|
|
4d6bf2fb4b | ||
|
|
80e95f3e27 | ||
|
|
7e68ea5fb6 | ||
|
|
fecfeefb5b | ||
|
|
bca0410e28 | ||
|
|
67aea3b5ce | ||
|
|
94e3f15ee7 | ||
|
|
6519e8445e | ||
|
|
4ae14b6c73 | ||
|
|
4752c5ad2d | ||
|
|
b3f6e29a36 | ||
|
|
e5ea8098df | ||
|
|
83f037b704 | ||
|
|
6428cb39a5 | ||
|
|
1bc19d6cf7 | ||
|
|
0af32f12e3 | ||
|
|
24bd08a1b2 | ||
|
|
53fb02b4db | ||
|
|
a49d71f097 | ||
|
|
c78e2c0fbf | ||
|
|
66c9968932 | ||
|
|
39a5a1e637 | ||
|
|
0b83fd839a | ||
|
|
30399cecaf | ||
|
|
d3170ab219 | ||
|
|
2e5f943b79 | ||
|
|
a9ab373f0b | ||
|
|
bef232376b | ||
|
|
628365cb49 | ||
|
|
f9ed93641c | ||
|
|
0a63bea195 | ||
|
|
ef8bf5fc3e | ||
|
|
b7b630fc81 | ||
|
|
d784c33fe8 | ||
|
|
ec9f8ba46f | ||
|
|
97a351cd92 | ||
|
|
15de6ad437 | ||
|
|
5ef18545f8 | ||
|
|
2cdc62f4a2 | ||
|
|
1757ba149c | ||
|
|
4ae816e9a6 | ||
|
|
918acf2b58 | ||
|
|
77a5774965 | ||
|
|
8185e36839 | ||
|
|
6d937d91d2 | ||
|
|
d2b171427a | ||
|
|
acd3684ad4 | ||
|
|
18170b1793 | ||
|
|
6644e62887 | ||
|
|
94d769c01c | ||
|
|
228f7723e1 | ||
|
|
69b47c66b4 | ||
|
|
77b6e14e7f | ||
|
|
6bae8f1fa4 | ||
|
|
967b56db58 | ||
|
|
330cb313e7 | ||
|
|
83aac737c7 | ||
|
|
cb3ad51357 | ||
|
|
1bb945e9c7 | ||
|
|
e4ff198b27 | ||
|
|
762a2a907e | ||
|
|
cd00b2f1cd | ||
|
|
ec62da93a4 | ||
|
|
6518e581b6 | ||
|
|
1c2c16e50d | ||
|
|
68f105141a | ||
|
|
197dd0f724 | ||
|
|
996a7d5ef4 | ||
|
|
2197af2799 | ||
|
|
2b05efb0ff | ||
|
|
57f67749dc | ||
|
|
25ad789e61 | ||
|
|
59ef90e120 | ||
|
|
8ee2e89cc5 | ||
|
|
d5736a5b08 | ||
|
|
32a7035a90 | ||
|
|
9e61505205 | ||
|
|
51d2f43229 | ||
|
|
454755083c | ||
|
|
0b43a01976 | ||
|
|
4fda9d8ef3 | ||
|
|
34fc38961c | ||
|
|
c55f4d3d62 | ||
|
|
aec53318bf | ||
|
|
7a74b9bbf7 | ||
|
|
94597a7474 | ||
|
|
8996ae40d7 | ||
|
|
00a3320b72 | ||
|
|
e65932b806 | ||
|
|
d981a2ae4d | ||
|
|
855d2164c5 | ||
|
|
16f85bf2ab | ||
|
|
489e6f3027 | ||
|
|
42b7b1c9e4 | ||
|
|
ae03346bb7 | ||
|
|
cf49685406 | ||
|
|
8f92fb5ea5 | ||
|
|
6950be53a0 | ||
|
|
f3ec154cb1 | ||
|
|
c25f2f7cb6 | ||
|
|
6ef7db7ddf | ||
|
|
7f563df71c | ||
|
|
1f1d69d484 | ||
|
|
7079061f22 | ||
|
|
6a30651cc5 | ||
|
|
f183686463 | ||
|
|
d4fd2cd22f | ||
|
|
5adda6adaa | ||
|
|
dc2abfe043 | ||
|
|
4f865374c5 | ||
|
|
a5a7cc6a9b | ||
|
|
9f3550adbc | ||
|
|
fecb292e9b | ||
|
|
a0a959e901 | ||
|
|
23c250d44a | ||
|
|
cd7156d65b | ||
|
|
5c198ab916 | ||
|
|
b07f97097f | ||
|
|
34886ca643 | ||
|
|
276a37361e | ||
|
|
8d37948cec | ||
|
|
e3f312252b | ||
|
|
0f3dd61249 | ||
|
|
58e5118d45 | ||
|
|
6fa4cf17c7 | ||
|
|
3d13c8ff2a | ||
|
|
543e2ba093 | ||
|
|
30297385af | ||
|
|
37fb89bae0 | ||
|
|
798b3acb89 | ||
|
|
57868b700b | ||
|
|
3100f31a62 | ||
|
|
9c4ab537be | ||
|
|
0590de3f14 | ||
|
|
d3bcb19c16 | ||
|
|
ed42ea0b57 | ||
|
|
1133d256ee | ||
|
|
9df16b2999 | ||
|
|
0f6d8ace1c | ||
|
|
60e0222146 | ||
|
|
591fa94632 | ||
|
|
152aa0406e | ||
|
|
fa0dc1f946 | ||
|
|
8f860b21a8 | ||
|
|
2a5105a49e | ||
|
|
0fa9f85a8d | ||
|
|
202117a60e | ||
|
|
35c7935f9c | ||
|
|
d953d623a2 | ||
|
|
4ddccd7211 | ||
|
|
4a2d13c6d7 | ||
|
|
c92b4c1863 | ||
|
|
fb736c5a7a | ||
|
|
9046a0a7c8 | ||
|
|
4173441d3c | ||
|
|
b5c3af05d8 | ||
|
|
6fa9aa30fa | ||
|
|
41ce44fc0e | ||
|
|
59848cd559 | ||
|
|
092c944d27 | ||
|
|
8ec051f523 | ||
|
|
22cc708a65 | ||
|
|
4e577a01ae | ||
|
|
5b43ff8c45 | ||
|
|
d07075ca9c | ||
|
|
cd49507a2b | ||
|
|
00464f1e80 | ||
|
|
6ec902e618 | ||
|
|
30e276b132 | ||
|
|
b8597d1518 | ||
|
|
5543f29e4f | ||
|
|
dc67239382 | ||
|
|
2a571bbb97 | ||
|
|
2824bef04a | ||
|
|
8fc7ebdab7 | ||
|
|
793d6780f3 | ||
|
|
605561148b | ||
|
|
54daef0cd9 | ||
|
|
ac0ff16537 | ||
|
|
e44053446a | ||
|
|
d4fb606c72 | ||
|
|
4cfdd4e58b | ||
|
|
3b82a144ea | ||
|
|
2f06c1b476 | ||
|
|
25b6b2c5ba | ||
|
|
9948505145 | ||
|
|
9d8feab2cc | ||
|
|
bcb5d3eba4 | ||
|
|
d7a10c00ed | ||
|
|
d2593cfb81 | ||
|
|
8101cf89f8 | ||
|
|
8636c6dcd5 | ||
|
|
b9c5599f95 | ||
|
|
93f854e6e4 | ||
|
|
ffc09b0801 | ||
|
|
d246064ded | ||
|
|
468f264545 | ||
|
|
9bec223b09 | ||
|
|
4606bb4d01 | ||
|
|
c8405c8924 | ||
|
|
95a33c0e6c | ||
|
|
ed2ad35dde | ||
|
|
234ae08c76 | ||
|
|
d21506b8d7 | ||
|
|
1fa7bf9c27 | ||
|
|
b50e01e4cf | ||
|
|
7abf9b0d0c | ||
|
|
504c6f46c3 | ||
|
|
78b1dcc949 | ||
|
|
9b0c859593 | ||
|
|
c9a3075d0a | ||
|
|
953b17ee88 | ||
|
|
95bc979da7 | ||
|
|
622b1a5e25 | ||
|
|
0c66ca1bdc | ||
|
|
67323c4d93 | ||
|
|
e2b0069947 | ||
|
|
5697a201ef | ||
|
|
c6115e3417 | ||
|
|
0ad122ce01 | ||
|
|
121e1421d3 | ||
|
|
e674457e6f | ||
|
|
45948b9d94 | ||
|
|
8d0bfce39f | ||
|
|
5eeab94368 | ||
|
|
d415d68762 | ||
|
|
0d4760f819 | ||
|
|
a0e6bda26e | ||
|
|
85e6810f99 | ||
|
|
38326bc3b6 | ||
|
|
3e89edefdb | ||
|
|
554e63925d | ||
|
|
57701c6041 | ||
|
|
57e1213370 | ||
|
|
d1ed97e5b4 | ||
|
|
f293f043d5 | ||
|
|
70408e4a2e | ||
|
|
a04438dbf8 | ||
|
|
0f30a35ae3 | ||
|
|
e56391c347 | ||
|
|
9612085a6a | ||
|
|
5bac3002f8 | ||
|
|
c50d1af806 | ||
|
|
96a07c96ee | ||
|
|
cc1261c285 | ||
|
|
adbb888fe4 | ||
|
|
64122b61fc | ||
|
|
bd4c7880e9 | ||
|
|
53433b33d6 | ||
|
|
ef2346efa0 | ||
|
|
0f61c8db8b | ||
|
|
b67c0b8232 | ||
|
|
e365daba93 | ||
|
|
71a2bfe284 | ||
|
|
dd767aa088 | ||
|
|
2ff66b32fd | ||
|
|
fe2d34b057 | ||
|
|
e3b36c8ad1 | ||
|
|
99ba68fce8 | ||
|
|
91e33495da | ||
|
|
d6699fbaa1 | ||
|
|
08666e8bd2 | ||
|
|
b2b397f3e4 | ||
|
|
8336a6c7a6 | ||
|
|
506989580f | ||
|
|
cd258057fb | ||
|
|
044247dccf | ||
|
|
b3f7c2cb4a | ||
|
|
02508c71a0 | ||
|
|
20f77fe26b | ||
|
|
cd889da4bd | ||
|
|
83c64785ec | ||
|
|
ae260f4908 | ||
|
|
fefa5433fd | ||
|
|
f3eb95df93 | ||
|
|
8571b020b9 | ||
|
|
297ccf4496 | ||
|
|
5e617375e1 | ||
|
|
7307a071ab | ||
|
|
ee4ca51aff | ||
|
|
dd682a4e6a | ||
|
|
8893c7da3e | ||
|
|
364024ca0f | ||
|
|
4bf8eb4c1a | ||
|
|
4cc77e0068 | ||
|
|
bd99556e1e | ||
|
|
93e422e1cc | ||
|
|
cba9464b6f | ||
|
|
d09240944b | ||
|
|
16e7dd71f1 | ||
|
|
ac546e4f8d | ||
|
|
2663e4d629 | ||
|
|
7ff13b286e | ||
|
|
e44964696a | ||
|
|
db53da509d | ||
|
|
de7f1b92f6 | ||
|
|
0886bfe8f9 | ||
|
|
46b3ad8a70 | ||
|
|
b4be31361e | ||
|
|
b11e5e12d3 | ||
|
|
177edbf7d6 | ||
|
|
6a335d9c31 | ||
|
|
152e248a15 | ||
|
|
ed6c6dc793 | ||
|
|
192607f874 | ||
|
|
a2c610e877 | ||
|
|
fa745cca61 | ||
|
|
65a4bd3665 | ||
|
|
29a5556c33 | ||
|
|
5afba67c1d | ||
|
|
9af190529c | ||
|
|
1d36d50fca | ||
|
|
871e042044 | ||
|
|
9a99f5d851 | ||
|
|
c0d97939fa | ||
|
|
58305a9690 | ||
|
|
2e7df49c4f | ||
|
|
e984ce39c3 | ||
|
|
2ce1ca6bf8 | ||
|
|
1c342d0327 | ||
|
|
f68aa26278 | ||
|
|
175d9bd7d7 | ||
|
|
9836bda502 | ||
|
|
a21e7a5e8d | ||
|
|
42f3cd8e31 | ||
|
|
1038e75a64 | ||
|
|
d90f0f3e86 | ||
|
|
18b5efcc0e | ||
|
|
2627e55229 | ||
|
|
d605e5fbb8 | ||
|
|
445b0167fa | ||
|
|
0012788eb1 | ||
|
|
32403078bc | ||
|
|
992e28a036 | ||
|
|
e14307045d | ||
|
|
53b0d1fda3 | ||
|
|
97cfbdb982 | ||
|
|
7369c22401 | ||
|
|
e662ad1dfc | ||
|
|
45ecff616c | ||
|
|
b05a19f036 | ||
|
|
3bca0336fa | ||
|
|
216bb4ea87 | ||
|
|
7017901594 | ||
|
|
72524ab50f | ||
|
|
9adaa3c3d6 | ||
|
|
653628f0b3 | ||
|
|
a4186dbf84 | ||
|
|
74de4c14d3 | ||
|
|
11bb084d70 | ||
|
|
1fae1c9ba6 | ||
|
|
5aa483b445 | ||
|
|
ea4b5ed297 | ||
|
|
a557925a63 | ||
|
|
ac64dd0b67 | ||
|
|
b74cca772b | ||
|
|
f6da1a525c | ||
|
|
5049262846 | ||
|
|
c53e55d703 | ||
|
|
d6801d5be5 | ||
|
|
bd8e55b977 | ||
|
|
f8de8d4f16 | ||
|
|
2eb4818398 | ||
|
|
eda6c0d746 | ||
|
|
7676f32cf2 | ||
|
|
a4f920ae86 | ||
|
|
c21e010159 | ||
|
|
89b87be143 | ||
|
|
5607930540 | ||
|
|
957eb64753 | ||
|
|
d05c38ac58 | ||
|
|
bb30a8e9d1 | ||
|
|
19a3181ffb | ||
|
|
ac411c6dd4 | ||
|
|
c770fc4528 | ||
|
|
29e664ece4 | ||
|
|
d378e1479d | ||
|
|
b58c525a6d | ||
|
|
2de7fb9956 | ||
|
|
6d3ec2a8d2 | ||
|
|
4ac3fea028 | ||
|
|
602c321067 | ||
|
|
e50f1d9f50 | ||
|
|
f48a9c6a33 | ||
|
|
c8db07a8c8 | ||
|
|
1fc4dae61b | ||
|
|
d5ca3113e2 | ||
|
|
66c70eb292 | ||
|
|
fcae6c61e4 | ||
|
|
28576c2c9a | ||
|
|
385d376037 | ||
|
|
1d796c624d | ||
|
|
8b8ec2c175 | ||
|
|
293258b606 | ||
|
|
ef9f9ae04f | ||
|
|
de7922181b | ||
|
|
637d3ee670 | ||
|
|
be769a3617 | ||
|
|
c21a5afb61 | ||
|
|
3f5c9eb9b4 | ||
|
|
74d493199f | ||
|
|
c341cecdbc | ||
|
|
c99a715f30 | ||
|
|
530c87b81e | ||
|
|
3d7584b015 | ||
|
|
87a1424df0 | ||
|
|
355c2cd8a1 | ||
|
|
bc9aaff19a | ||
|
|
cb040a5669 | ||
|
|
4a31485359 | ||
|
|
ad1cffe113 | ||
|
|
e758b03e07 | ||
|
|
e31caaeb65 | ||
|
|
0b885d83af | ||
|
|
7f11ea594e | ||
|
|
76278cf11f | ||
|
|
65eb109cb9 | ||
|
|
3d02bc87ea | ||
|
|
4f278925f4 | ||
|
|
cb16482a61 | ||
|
|
46f118bbb9 | ||
|
|
3a5bff36b2 | ||
|
|
18f2e4ce04 | ||
|
|
1cc5eea3a4 | ||
|
|
20a8470b3c | ||
|
|
e242a89a4b | ||
|
|
9de9048a78 | ||
|
|
311dc3b644 | ||
|
|
e49e4a05bc | ||
|
|
79a7c53581 | ||
|
|
3cdc0d34f3 | ||
|
|
291e458745 | ||
|
|
080efec9e0 | ||
|
|
83444fbe00 | ||
|
|
737fc24e16 | ||
|
|
b9d2a8b283 | ||
|
|
e999a9cb1e | ||
|
|
d111f7fc66 | ||
|
|
fb1970ffc2 | ||
|
|
a96b308c28 | ||
|
|
5af3021d08 | ||
|
|
2e477bdab6 | ||
|
|
05b697debf | ||
|
|
b0064d179c | ||
|
|
48dbed2571 | ||
|
|
7643f19815 | ||
|
|
deca828207 | ||
|
|
754a8f611f | ||
|
|
f12356beb4 | ||
|
|
c9c5092055 | ||
|
|
a541317801 | ||
|
|
c7d15fbd3d | ||
|
|
420abe8240 | ||
|
|
95c9a1d638 | ||
|
|
7971eba517 | ||
|
|
c27e99aa6c | ||
|
|
5b22712058 | ||
|
|
c9109986d1 | ||
|
|
570508beba | ||
|
|
f890f9fdf1 | ||
|
|
94412b9c83 | ||
|
|
fca81dee71 | ||
|
|
9f956f965a | ||
|
|
2400325b22 | ||
|
|
ae3c8e8548 | ||
|
|
0007b2ab07 | ||
|
|
2594d43a53 | ||
|
|
39e6504bb5 | ||
|
|
402f777a90 | ||
|
|
7b0717c392 | ||
|
|
e303a8a300 | ||
|
|
31cb4b1ad9 | ||
|
|
ca746075db | ||
|
|
1676f36b5b | ||
|
|
0a2763e769 | ||
|
|
09d0612aeb | ||
|
|
9b3b0e2086 | ||
|
|
f28ab22ef9 | ||
|
|
935cb44639 | ||
|
|
5579c85bf4 | ||
|
|
ca856cbb35 | ||
|
|
6cee129a68 | ||
|
|
9fa420d6e3 | ||
|
|
ad7130b0d5 | ||
|
|
9f04510c9b | ||
|
|
5058fdf892 | ||
|
|
47043cf105 | ||
|
|
e5b726aa4a | ||
|
|
ae1dd6dfaa | ||
|
|
546d3f9b18 | ||
|
|
81cf35322e | ||
|
|
12afb565c7 | ||
|
|
5826231326 | ||
|
|
b0ac27ad23 | ||
|
|
5d1e286645 | ||
|
|
0baf5dba9f | ||
|
|
9019350f0c | ||
|
|
306154572e | ||
|
|
65da7fdfbd | ||
|
|
f12e4128e6 | ||
|
|
635be949f0 | ||
|
|
129e9d5417 | ||
|
|
f389fa4eb2 | ||
|
|
cb78009e64 | ||
|
|
b79b6ab846 | ||
|
|
026fbc910f | ||
|
|
63d3f02abe | ||
|
|
59a612c6fc | ||
|
|
b382b8b264 | ||
|
|
af0e14daff | ||
|
|
9cdb382d0d | ||
|
|
833d0723f2 | ||
|
|
064fca3b0a | ||
|
|
34a7ab3bf3 | ||
|
|
8aa8e431a7 | ||
|
|
fb838d198a | ||
|
|
532b1f370a | ||
|
|
c26f50d359 | ||
|
|
b723469b43 | ||
|
|
91c240c463 | ||
|
|
6bb589325b | ||
|
|
fbd3f05c63 | ||
|
|
07b3606d42 | ||
|
|
287d5a805d | ||
|
|
444c5e571e | ||
|
|
1bf20a3217 | ||
|
|
214e317804 | ||
|
|
8d0e89faf9 | ||
|
|
ae41e5f2e6 | ||
|
|
798a6c0eb6 | ||
|
|
7ebda3b9ae | ||
|
|
30c5493486 | ||
|
|
b4d27f3d0d | ||
|
|
e44a10de2c | ||
|
|
1baa59162e | ||
|
|
aacb11a22b | ||
|
|
d041b0e993 | ||
|
|
6c44808c19 | ||
|
|
ee28bacf0c | ||
|
|
199d05b910 | ||
|
|
138e59d74f | ||
|
|
dd26376b3b | ||
|
|
9e07ee862c | ||
|
|
9b11399d48 | ||
|
|
baf97a90a1 | ||
|
|
41d85e1f36 | ||
|
|
ce0a46dc2b | ||
|
|
3c39c8a788 | ||
|
|
321d6554e7 | ||
|
|
cc9cf92b27 | ||
|
|
02b4f66b12 | ||
|
|
8889323476 | ||
|
|
df1633f011 | ||
|
|
4e840f3025 | ||
|
|
e44bae66d5 | ||
|
|
4e073d1bb6 | ||
|
|
2fbb295490 | ||
|
|
b72631cd82 | ||
|
|
832c09980a | ||
|
|
ca68a8ef87 | ||
|
|
0645cec207 | ||
|
|
53dde3ec9e | ||
|
|
df5c16e05f | ||
|
|
bb3bb938e8 | ||
|
|
c196a2104e | ||
|
|
c78c596095 | ||
|
|
8d2d0f0b22 | ||
|
|
26d06e8f3a | ||
|
|
59eb8ae7f1 | ||
|
|
7d932016b8 | ||
|
|
998eb56348 | ||
|
|
7837064e80 | ||
|
|
53745c61e5 | ||
|
|
14adcff9dc | ||
|
|
7d67288766 | ||
|
|
d904b126df | ||
|
|
649df9be49 | ||
|
|
4e49c1f80d | ||
|
|
41eda72394 | ||
|
|
8a49398740 | ||
|
|
6fbec2b298 | ||
|
|
15d8bbead9 | ||
|
|
f2d72d70f1 | ||
|
|
0bcfd10a9d | ||
|
|
324b4f1b38 | ||
|
|
27f11db7f4 | ||
|
|
0c734c5351 | ||
|
|
48da6a84a6 | ||
|
|
21cb2657ca | ||
|
|
b7ee5e771e | ||
|
|
4967782464 | ||
|
|
29582469d2 | ||
|
|
18c1c9c69a | ||
|
|
ed3521cc53 | ||
|
|
4795d77e84 | ||
|
|
e0c594c402 | ||
|
|
5f02042124 | ||
|
|
4b09023b21 | ||
|
|
320197198b | ||
|
|
d31423d91e | ||
|
|
23bb6ac486 | ||
|
|
7da178c5ec | ||
|
|
1fe9d2598b | ||
|
|
9f56948f47 | ||
|
|
4e2822eb0a | ||
|
|
54697c44de | ||
|
|
b757055525 | ||
|
|
906211f0f5 | ||
|
|
05808e4587 | ||
|
|
0b685cc9a2 | ||
|
|
a9985fec2c | ||
|
|
315237d0fc | ||
|
|
3015db94be | ||
|
|
6ac3943043 | ||
|
|
c9a7f825de | ||
|
|
27c1925021 | ||
|
|
2332d85434 | ||
|
|
e8650525b2 | ||
|
|
ea882e9611 | ||
|
|
e46a28681d | ||
|
|
48ce3a3d8f | ||
|
|
f7fa8d0758 | ||
|
|
2d1094a8aa | ||
|
|
ff6b7d982b | ||
|
|
4c3219688b | ||
|
|
2b723bd094 | ||
|
|
de53ee09e3 | ||
|
|
745dd5ede0 | ||
|
|
ca267fd565 | ||
|
|
2bdbc4d792 | ||
|
|
bdf1ce640c | ||
|
|
8a1a3b971f | ||
|
|
8a9adb5c98 | ||
|
|
23d6444a54 | ||
|
|
2a098a9445 | ||
|
|
1e22364429 | ||
|
|
c65eff0de8 | ||
|
|
4ea26cfa32 | ||
|
|
f3f63454d3 | ||
|
|
194bd8085f | ||
|
|
52e9dac9ee | ||
|
|
9eafdbf741 | ||
|
|
3901b079d7 | ||
|
|
5529f7588c | ||
|
|
0271b0501b | ||
|
|
32ec6d6be7 | ||
|
|
110c68f1e0 | ||
|
|
e42a0102c2 | ||
|
|
ae8e8825b7 | ||
|
|
c287008fc6 | ||
|
|
c245c076f9 | ||
|
|
c6db6834e9 | ||
|
|
9fdb50d12a | ||
|
|
65faa84351 | ||
|
|
c2cfb709bb | ||
|
|
202559211c | ||
|
|
24e97e10c8 | ||
|
|
677456456d | ||
|
|
708de33603 | ||
|
|
5405244e4b | ||
|
|
9c12048964 | ||
|
|
3b5d21fcd4 | ||
|
|
eb15bec707 | ||
|
|
e9fd74ef5d | ||
|
|
d4a29db051 | ||
|
|
27075d1596 | ||
|
|
56bbd269c9 | ||
|
|
046a41177f | ||
|
|
14302d0106 | ||
|
|
68366bf9a3 | ||
|
|
7e65a81d31 | ||
|
|
5268ad041f | ||
|
|
7d325bd0db | ||
|
|
f6d0dd2d0f | ||
|
|
5fc3dff2d5 | ||
|
|
18461e1e47 | ||
|
|
7add4d358e | ||
|
|
c1dbc494ae | ||
|
|
409b5b8577 | ||
|
|
4548730df2 | ||
|
|
4170965c64 | ||
|
|
1f8895257d | ||
|
|
7286d4ffe0 | ||
|
|
2f2e4f389f | ||
|
|
ad47797467 | ||
|
|
ed66e69e7c | ||
|
|
81fa257915 | ||
|
|
0bd6006d70 | ||
|
|
81a0dd4a5c | ||
|
|
78b7dfcc36 | ||
|
|
5d728573cd | ||
|
|
881769b433 | ||
|
|
dfae6a686c | ||
|
|
5e0d640c2f | ||
|
|
a7133e92d8 | ||
|
|
027e16f676 | ||
|
|
53607f6fe7 | ||
|
|
4a9066b1cb | ||
|
|
23c0c63c6a | ||
|
|
20f031fcb4 | ||
|
|
a1c44bab40 | ||
|
|
38a91ce351 | ||
|
|
0e4f04d091 | ||
|
|
ef64e0f6ef | ||
|
|
1af58efad5 | ||
|
|
e741ac0a98 | ||
|
|
ec63618bea | ||
|
|
0efdb7dc33 | ||
|
|
101636a60a | ||
|
|
306b627ef8 | ||
|
|
d601aad274 | ||
|
|
6b0f60d859 | ||
|
|
7c2ab421e9 | ||
|
|
d37802185b | ||
|
|
d1e074c1ca | ||
|
|
a439d55bf8 | ||
|
|
1ad3acb5a5 | ||
|
|
3001a60ee0 | ||
|
|
aad6dcb269 | ||
|
|
ee02013fa5 | ||
|
|
c0736132b1 | ||
|
|
fa8493fd3e | ||
|
|
209038adb2 | ||
|
|
4dad8500bc | ||
|
|
6cffe74f36 | ||
|
|
0233adc184 | ||
|
|
ccbe7646da | ||
|
|
5d456dda67 | ||
|
|
42f251de21 | ||
|
|
f25c4e1423 | ||
|
|
4222fff2e3 | ||
|
|
35ac6eacbc | ||
|
|
e6becff209 | ||
|
|
d0b797d6bd | ||
|
|
014ae84983 | ||
|
|
2aeb8b5dea | ||
|
|
ad7feed5bf | ||
|
|
411d4dc1b3 | ||
|
|
467eee308f | ||
|
|
b740072209 | ||
|
|
d34627fab6 | ||
|
|
0cc6840506 | ||
|
|
d2d9781cfa | ||
|
|
af710acf9e | ||
|
|
62f3a834dc | ||
|
|
53b68c6e0b | ||
|
|
a195b89a71 | ||
|
|
00d00880ed | ||
|
|
2f8f272894 | ||
|
|
4207d1b03f | ||
|
|
73c5dc56d3 | ||
|
|
8891367791 | ||
|
|
8ca05bbb43 | ||
|
|
0e14db9f0b | ||
|
|
fa7bbd86b9 | ||
|
|
86a696ad15 | ||
|
|
783defbbed | ||
|
|
01f779ef37 | ||
|
|
29af52c72e | ||
|
|
a3ff9dacc8 | ||
|
|
c0155ad275 | ||
|
|
ad20c62c73 | ||
|
|
88281c57cd | ||
|
|
cb82489f33 | ||
|
|
66c16329ac | ||
|
|
c092c099be | ||
|
|
307c2ded5a | ||
|
|
00718b4293 | ||
|
|
7222ddd591 | ||
|
|
85db878943 | ||
|
|
3d33b0938b | ||
|
|
e7d2897582 | ||
|
|
4193c1358b | ||
|
|
9cf3f58dcb | ||
|
|
abb98f88af | ||
|
|
f17c597d7d | ||
|
|
ea78673811 | ||
|
|
9d8478a9c0 | ||
|
|
0113cfb78e | ||
|
|
612850efb6 | ||
|
|
b0eac8af63 | ||
|
|
b4c781b7fd | ||
|
|
b647b44c95 | ||
|
|
6f9a72557d | ||
|
|
86c8a45e01 | ||
|
|
d9dd692fa9 | ||
|
|
d735bcdc8b | ||
|
|
00234fa52a | ||
|
|
1878558392 | ||
|
|
86c45e39f6 | ||
|
|
7cb3797624 | ||
|
|
2473a59858 | ||
|
|
8de29b0a90 | ||
|
|
1f115e6836 | ||
|
|
347729a26e | ||
|
|
fac14772f5 | ||
|
|
1f2652cc5e | ||
|
|
f7ece80bec | ||
|
|
7d5059c6ca | ||
|
|
742e9419be | ||
|
|
053a5a55e6 | ||
|
|
390d2a42b8 | ||
|
|
ea0d699e1b | ||
|
|
d83122731b | ||
|
|
3399c51d25 | ||
|
|
6663915149 | ||
|
|
2fa968a923 | ||
|
|
862e6c3e7b | ||
|
|
65db835cb5 | ||
|
|
9f8b8d2596 | ||
|
|
08d69bf1e7 | ||
|
|
a20fc4d9d1 | ||
|
|
7ff6bdbaf6 | ||
|
|
374f2ab779 | ||
|
|
ac8a41004b | ||
|
|
b3418e8d90 | ||
|
|
078d8bd4e5 | ||
|
|
67912e18d0 | ||
|
|
38c4405c16 | ||
|
|
2cb5b54d33 | ||
|
|
13f1ae7c6f | ||
|
|
55bba313fe | ||
|
|
d168304a6d | ||
|
|
d018b9fba0 | ||
|
|
cf81177ed2 | ||
|
|
1b66ce9aa3 | ||
|
|
0d45d88dbd | ||
|
|
7692556d09 | ||
|
|
c08a13b2d1 | ||
|
|
706e8ef130 | ||
|
|
b326ccaaee | ||
|
|
3c14351a5b | ||
|
|
a59362b687 | ||
|
|
fab019a34c | ||
|
|
36712e5486 | ||
|
|
0e5c519363 | ||
|
|
f1ed03b77a | ||
|
|
76b44307ca | ||
|
|
563b9eeb8c | ||
|
|
90621a1dd9 | ||
|
|
2fb181d391 | ||
|
|
2753fc3505 | ||
|
|
c1765423a6 | ||
|
|
deb104c341 | ||
|
|
e0d844d35e | ||
|
|
eb8f2c4eba | ||
|
|
92afc9d8f0 | ||
|
|
5fd0bb034e | ||
|
|
bea124c33e | ||
|
|
0ffef5a767 | ||
|
|
5000be3263 | ||
|
|
edd903c0df | ||
|
|
90b3dd2c19 | ||
|
|
20cab9001b | ||
|
|
0e0d88d755 | ||
|
|
6aed6a0926 | ||
|
|
e67929857f | ||
|
|
e82c6322a0 | ||
|
|
73a1b860d5 | ||
|
|
d301b99738 | ||
|
|
37a659ab30 | ||
|
|
7bcbb4c5b9 | ||
|
|
f74a421f64 | ||
|
|
5f633efa59 | ||
|
|
d9a9747901 | ||
|
|
756ca31319 | ||
|
|
601591c7db | ||
|
|
0cca8f2c83 | ||
|
|
d5043446d9 | ||
|
|
49dc6f90bc | ||
|
|
d803802b43 | ||
|
|
8e382f104b | ||
|
|
b7f8162f5f | ||
|
|
6230510b2e | ||
|
|
f50c9a6b2d | ||
|
|
4cdafcccd2 | ||
|
|
42015f846f | ||
|
|
17ed24de8a | ||
|
|
03c6cf01de | ||
|
|
7ec1688825 | ||
|
|
210e602057 | ||
|
|
136341feef | ||
|
|
a71ceefc3f | ||
|
|
2cfd373463 | ||
|
|
416534b99c | ||
|
|
78ada2809e | ||
|
|
03a1b5ccd4 | ||
|
|
15a24b40de | ||
|
|
b4111d5ec5 | ||
|
|
5c1807c5f5 | ||
|
|
88f249e301 | ||
|
|
77e9283b95 | ||
|
|
6829ed9308 | ||
|
|
9265026e1e | ||
|
|
68d8ed9df0 | ||
|
|
20da98f597 | ||
|
|
3917bbc61b | ||
|
|
87f8c283d2 | ||
|
|
5beec7ea38 | ||
|
|
782732278e | ||
|
|
a728d4427e | ||
|
|
00c99eb41e | ||
|
|
a3ecfca30b | ||
|
|
4ca9d6979e | ||
|
|
bbeeb40d6a | ||
|
|
e1d52de410 | ||
|
|
459bd9ad31 | ||
|
|
7fd8a23f55 | ||
|
|
d84ec529f8 | ||
|
|
04faf21764 | ||
|
|
9d4aa9187c | ||
|
|
344f76b705 | ||
|
|
ea64b9e987 | ||
|
|
ed8a6c1607 | ||
|
|
0899560086 | ||
|
|
32b75cbec3 | ||
|
|
3e25f9c1d7 | ||
|
|
c46fd84767 | ||
|
|
a2ccff5959 | ||
|
|
c064b8d0f3 | ||
|
|
3484d35b77 | ||
|
|
d8a3e1c97a | ||
|
|
7020bbc55d | ||
|
|
56803fa83b | ||
|
|
030956bdb8 | ||
|
|
835690c609 | ||
|
|
1d8e2094e0 | ||
|
|
a6389ce4be | ||
|
|
a22cc09675 | ||
|
|
17c301c775 | ||
|
|
4ad28a324a | ||
|
|
12254b5849 | ||
|
|
d178140d7d | ||
|
|
2dfbee784d | ||
|
|
29844c5716 | ||
|
|
392798d7f5 | ||
|
|
666a3bd6ef | ||
|
|
159d1e4e57 | ||
|
|
e90515453a | ||
|
|
7aa38225fe | ||
|
|
cfa6b8cd90 | ||
|
|
2f6d53a88f | ||
|
|
832d222f5d | ||
|
|
00b4a206ab | ||
|
|
dd07df9ac0 | ||
|
|
974f2b823c | ||
|
|
2ebf8f5941 | ||
|
|
0fc8d864ea | ||
|
|
28fd42fdd3 | ||
|
|
e8c471c059 | ||
|
|
d9da71723d | ||
|
|
3ca0f6f9af | ||
|
|
f45331d019 | ||
|
|
39e18df6e7 | ||
|
|
6cb5c1a179 | ||
|
|
db51b68058 | ||
|
|
f128527039 | ||
|
|
5694316eac | ||
|
|
7fdc5729d2 | ||
|
|
fc1f363a8b | ||
|
|
1545cb2154 | ||
|
|
1e58ef93a4 | ||
|
|
d9dd56f6e2 | ||
|
|
11d7caa6f6 | ||
|
|
36c5432c65 | ||
|
|
940e08ea54 | ||
|
|
0de1317d2f | ||
|
|
d2e6fd2dcc | ||
|
|
9527d7c0c2 | ||
|
|
c73e07ecaf | ||
|
|
8058a9385a | ||
|
|
44a859296a | ||
|
|
057b36bf5b | ||
|
|
3ce669442d | ||
|
|
bb3de2c396 | ||
|
|
796bd649c2 | ||
|
|
30a8444840 | ||
|
|
fc7695a9f3 | ||
|
|
d1d2def4b0 | ||
|
|
f17a776c14 | ||
|
|
f9b2929a64 | ||
|
|
22b4924b63 | ||
|
|
dfba194108 | ||
|
|
a5f3315037 | ||
|
|
02051b5413 | ||
|
|
74622c377f | ||
|
|
d034be1aff | ||
|
|
df0be2468e | ||
|
|
ce2bf43eab | ||
|
|
f418a22c42 | ||
|
|
bcf1c9c7d4 | ||
|
|
ca6d3ba9e2 | ||
|
|
0aca743e0c | ||
|
|
c75edd9af8 | ||
|
|
e3f3c87c30 | ||
|
|
ccdfce9f88 | ||
|
|
9cd4bd55a1 | ||
|
|
311a11e1df | ||
|
|
db99ed87a0 | ||
|
|
40f9bb28f5 | ||
|
|
c1e36b0669 | ||
|
|
cdfe748f08 | ||
|
|
1c53d0bea5 | ||
|
|
8b445a49b9 | ||
|
|
c68df20847 | ||
|
|
7509420d72 | ||
|
|
db539dafd1 | ||
|
|
b842293563 | ||
|
|
3818c32d33 | ||
|
|
3bf447cb86 | ||
|
|
5f14acf1f2 | ||
|
|
ab7e0e31f6 | ||
|
|
6dee6e5481 | ||
|
|
1fba135b4d | ||
|
|
c7e7198dc6 | ||
|
|
4aae83c7ad | ||
|
|
cf61df2acb | ||
|
|
f866ac1778 | ||
|
|
ae3338dc20 | ||
|
|
4567f19885 | ||
|
|
b667b1e19f | ||
|
|
53d28c1346 | ||
|
|
1b34a13321 | ||
|
|
b370807de1 | ||
|
|
37fa39b5b8 | ||
|
|
d824b87b17 | ||
|
|
0bf4642f10 | ||
|
|
49f79068ae | ||
|
|
34351cb6d4 | ||
|
|
37520a9634 | ||
|
|
9714ba1113 | ||
|
|
b6cf044441 | ||
|
|
bf7fbb1218 | ||
|
|
ed66f5b467 | ||
|
|
38f5ec6393 | ||
|
|
15ecee6767 | ||
|
|
640403866f | ||
|
|
25efce87dc | ||
|
|
79bc8f9527 | ||
|
|
0043052057 | ||
|
|
75f1651042 | ||
|
|
b1ca2c8dda | ||
|
|
069b547e58 | ||
|
|
e5136dd2e5 | ||
|
|
d58b7a9ff1 | ||
|
|
f192e8c993 | ||
|
|
2e9260ace5 | ||
|
|
880b48dc5d | ||
|
|
a3c7a8af26 | ||
|
|
088800c769 | ||
|
|
ecf899f610 | ||
|
|
6cbd7d19da | ||
|
|
a2f7c5e5ee | ||
|
|
e236884eeb | ||
|
|
ec6436a43f | ||
|
|
c8eba1338e | ||
|
|
8ce481c427 | ||
|
|
96346ee454 | ||
|
|
d3b22b0447 | ||
|
|
e9d6778cde | ||
|
|
7587d8cafd | ||
|
|
b94eed6df8 | ||
|
|
32b9221b35 | ||
|
|
1ab9f31e3c | ||
|
|
3572bea87c | ||
|
|
c0868feb6b | ||
|
|
8cd40cc99a | ||
|
|
de24bcbc16 | ||
|
|
9eee7778a4 | ||
|
|
2bb85c63d7 | ||
|
|
fa1cebca2d | ||
|
|
ea2db5da95 | ||
|
|
85e5464bf3 | ||
|
|
a2ab4167f1 | ||
|
|
1ba10e18e8 | ||
|
|
e71bf616f2 | ||
|
|
a9c892e6c7 | ||
|
|
33101665e3 | ||
|
|
a330d29a28 | ||
|
|
2bddffd538 | ||
|
|
0ad262bf64 | ||
|
|
8b75ff7335 | ||
|
|
35179f49ad | ||
|
|
d3cc3b16bb | ||
|
|
04e39265ca | ||
|
|
27df62c80b | ||
|
|
1e92029b3c | ||
|
|
1e88d8ba46 | ||
|
|
c42bb942f1 | ||
|
|
57003e3e8a | ||
|
|
ae03ad29c1 | ||
|
|
31e8ad6e0a | ||
|
|
d62b91659c | ||
|
|
3a250447b0 | ||
|
|
678e254b68 | ||
|
|
b86d085519 | ||
|
|
d060f15e83 | ||
|
|
1ac4016235 | ||
|
|
db4b597be8 | ||
|
|
133d54597c | ||
|
|
9083109ff1 | ||
|
|
c6f408ff82 | ||
|
|
898a6cf567 | ||
|
|
dd6659ce3d | ||
|
|
a8119bc9dd | ||
|
|
7d90a4dcfc | ||
|
|
23524e5827 | ||
|
|
337a776fbb | ||
|
|
0c2bab42e8 | ||
|
|
f70099352a | ||
|
|
eb79aad6cd | ||
|
|
4a0f6398eb | ||
|
|
a792190d44 | ||
|
|
3e6a24d9c3 | ||
|
|
fd63fe73cd | ||
|
|
23ccfecad4 | ||
|
|
e0690e0816 | ||
|
|
8708daaa60 | ||
|
|
a883c8a6cf | ||
|
|
cdc57dda38 | ||
|
|
82459a583f | ||
|
|
ec35f8d2f7 | ||
|
|
76070d195e | ||
|
|
8421d2e03c | ||
|
|
82170df927 | ||
|
|
3581905462 | ||
|
|
2a4ca8c5af | ||
|
|
eda1b18bc6 | ||
|
|
8fdef2b7f5 | ||
|
|
063de09d3f | ||
|
|
5f96e8450e | ||
|
|
25b3617196 | ||
|
|
55ae9a0999 | ||
|
|
5943970312 | ||
|
|
35f62f1636 | ||
|
|
9946048b00 | ||
|
|
5fd2dd5b95 | ||
|
|
f01ed4059a | ||
|
|
6a43f029c3 | ||
|
|
8c094a6d03 | ||
|
|
711fce8305 | ||
|
|
efaa279e24 | ||
|
|
f053b99ce3 | ||
|
|
8464a93106 | ||
|
|
d824f987b8 | ||
|
|
8b87ca4d63 | ||
|
|
6a648ae4d5 | ||
|
|
3cddabafb7 | ||
|
|
7f00b46125 | ||
|
|
74759e3e0d | ||
|
|
2df8fa14e8 | ||
|
|
9e63c89166 | ||
|
|
946a1504f8 | ||
|
|
1ca55f777f | ||
|
|
54ee86340c | ||
|
|
834daec255 | ||
|
|
80f2f08283 | ||
|
|
b06d07bd47 | ||
|
|
fd5455e71f | ||
|
|
cdf50ffb8d | ||
|
|
ab5d6878de | ||
|
|
d6037ad15b | ||
|
|
31844006d7 | ||
|
|
ba29da4f48 | ||
|
|
9f285d21ef | ||
|
|
bdb8b91e1f | ||
|
|
723255dfa6 | ||
|
|
b35ad7303c | ||
|
|
973784ca0f | ||
|
|
e911f4b9c5 | ||
|
|
74ba833b47 | ||
|
|
e28132c291 | ||
|
|
afcef53669 | ||
|
|
7a20524fc9 | ||
|
|
066fa92a24 | ||
|
|
d6f17198a7 | ||
|
|
3751292833 | ||
|
|
c433d77362 | ||
|
|
3bf02da791 | ||
|
|
4ca5624e3b | ||
|
|
6d6ee45830 | ||
|
|
ececb31307 | ||
|
|
33ec4897f6 | ||
|
|
a28e25c4fb | ||
|
|
67c8ee3c94 | ||
|
|
b41136047c | ||
|
|
e6cea306c1 | ||
|
|
950a6b42c2 | ||
|
|
6c70a8c041 | ||
|
|
bfee3e4634 | ||
|
|
c50d343f31 | ||
|
|
0a7ea944c9 | ||
|
|
7222f4d079 | ||
|
|
1c77c88b12 | ||
|
|
2d2bf64799 | ||
|
|
160d852cd2 | ||
|
|
1b5401bf7f | ||
|
|
d2a524b26e | ||
|
|
fbd435a018 | ||
|
|
28c38e84da | ||
|
|
38fe77804e | ||
|
|
2a658dc371 | ||
|
|
d301a1c12b | ||
|
|
58db840200 | ||
|
|
01753100f1 | ||
|
|
5073fe5363 | ||
|
|
cab826ba34 | ||
|
|
5fea32203a | ||
|
|
b85ac13c49 | ||
|
|
d7c45dbe08 | ||
|
|
39da050c74 | ||
|
|
443fd1513a | ||
|
|
93058057ec | ||
|
|
7c446872cb | ||
|
|
5eaea39e74 | ||
|
|
db8ee5fc35 | ||
|
|
5190157454 | ||
|
|
2bc03d43bc | ||
|
|
d3ad6ff7bf | ||
|
|
a8387de735 | ||
|
|
38fd971d5c | ||
|
|
15e4f332ed | ||
|
|
33924b2c4a | ||
|
|
5b718e3f8c | ||
|
|
d86eb59963 | ||
|
|
eec05e7eb6 | ||
|
|
38d3e4477c | ||
|
|
bc71d1dd7f | ||
|
|
d4b32a14b8 | ||
|
|
9991c782d4 | ||
|
|
58b6129f7c | ||
|
|
e170c16d02 | ||
|
|
7c4b69753a | ||
|
|
3f72f258a1 | ||
|
|
dc0318092a | ||
|
|
769ed65d61 | ||
|
|
91e27ad4d8 | ||
|
|
70cd39a55f | ||
|
|
facb64c0a7 | ||
|
|
2cc74ea946 | ||
|
|
c8f4faaa95 | ||
|
|
8d3910b7a0 | ||
|
|
c9056fe2dc | ||
|
|
e593c724c4 | ||
|
|
c11be9f82f | ||
|
|
1e28535ed4 | ||
|
|
9354cb5c59 | ||
|
|
5427e564de | ||
|
|
9d4ef9f7ef | ||
|
|
aaa9ca607f | ||
|
|
14bd90bf75 | ||
|
|
625d457517 | ||
|
|
b7575ddc4e | ||
|
|
7217df1829 | ||
|
|
55e76a52be | ||
|
|
4af660666b | ||
|
|
91ee6b9f56 | ||
|
|
28e31472fe | ||
|
|
2fd81413d1 | ||
|
|
c50b61ffc5 | ||
|
|
fa6f945eb2 | ||
|
|
d812b74f36 | ||
|
|
bfac711663 | ||
|
|
3446220895 | ||
|
|
54421a0a6e | ||
|
|
3751ec2c34 | ||
|
|
18988e690b | ||
|
|
a858ddbe67 | ||
|
|
94705970be | ||
|
|
4c29ed4634 | ||
|
|
ea9858d41d | ||
|
|
c9d147c528 | ||
|
|
5ff8d96054 | ||
|
|
6413111615 | ||
|
|
d4cbfc82a6 | ||
|
|
aad36f44c1 | ||
|
|
515c6f93a8 | ||
|
|
665fdbf53e | ||
|
|
3df8b55d65 | ||
|
|
99e63b749a | ||
|
|
eb370ba88f | ||
|
|
4643ef6179 | ||
|
|
d1aad2a921 | ||
|
|
709486f8d9 | ||
|
|
768c608a02 | ||
|
|
4fd21ba834 | ||
|
|
765fbaf247 | ||
|
|
112c6dc020 | ||
|
|
b4aac1d129 | ||
|
|
55ad0d3ab0 | ||
|
|
4d6b3cc3da | ||
|
|
f405ce9660 | ||
|
|
209829d42f | ||
|
|
cc4bde1265 | ||
|
|
bbe6614ddc | ||
|
|
9a619734ae | ||
|
|
28380815e7 | ||
|
|
6a6cf1e3ab | ||
|
|
851469b6a5 | ||
|
|
017e190e4a | ||
|
|
4c351cd1e1 | ||
|
|
045adaaa43 | ||
|
|
48e9e5e2c5 | ||
|
|
674a48133a | ||
|
|
44cfddf601 | ||
|
|
667c3c240b | ||
|
|
ba8a39465f | ||
|
|
562f7c4f2d | ||
|
|
c6c24b8f05 | ||
|
|
261caf3544 | ||
|
|
1957370b5c | ||
|
|
32f9c82ffc | ||
|
|
1a212fb64b | ||
|
|
ecd8354d8f | ||
|
|
dcf0d6649d | ||
|
|
c2087cef25 | ||
|
|
b5021a1121 | ||
|
|
387e272763 | ||
|
|
96e1253030 | ||
|
|
783c3eced4 | ||
|
|
a46dec04eb | ||
|
|
bc0d22e54c | ||
|
|
15cedd71b6 | ||
|
|
3efda7ce74 | ||
|
|
5a884f45ca | ||
|
|
c57c9a972f | ||
|
|
3ef57cde27 | ||
|
|
4dc6512898 | ||
|
|
6485e9cec5 | ||
|
|
f1bc85b5bc | ||
|
|
1c710c95cc | ||
|
|
223ce05fad | ||
|
|
59f0d190cb | ||
|
|
cf57caea70 | ||
|
|
c0e44b324b | ||
|
|
20c177c653 | ||
|
|
16f3ad09dd | ||
|
|
3c40dc0fdb | ||
|
|
d329f665b1 | ||
|
|
19b2f268a8 | ||
|
|
c18ce9abf2 | ||
|
|
44af9ede48 | ||
|
|
ccc40411ea | ||
|
|
51cc1a44d9 | ||
|
|
b565eb7b37 | ||
|
|
861f6f7127 | ||
|
|
fd7574e7fd | ||
|
|
a372a86668 | ||
|
|
e213ca8daf | ||
|
|
10ac82cd41 | ||
|
|
6201271e22 | ||
|
|
17cc178c11 | ||
|
|
ee99cd9786 | ||
|
|
24afafceba | ||
|
|
152482b225 | ||
|
|
fc15e2fe3d | ||
|
|
caf99c2605 | ||
|
|
afa0a529cd | ||
|
|
40d88a1838 | ||
|
|
0ae960834d | ||
|
|
0b59842908 | ||
|
|
eac6800a17 | ||
|
|
04bdf2e5ee | ||
|
|
ba4dec552f | ||
|
|
6f60c4c1a5 | ||
|
|
58b182c46f | ||
|
|
b56cc96ffb | ||
|
|
f6b613ee17 | ||
|
|
1d24a4ccd1 | ||
|
|
00c511b4e9 | ||
|
|
47201098c8 | ||
|
|
a99014b64b | ||
|
|
1ec9b6417a | ||
|
|
46a081e056 | ||
|
|
c7dc7088c4 | ||
|
|
87e23f3e88 | ||
|
|
cb23837684 | ||
|
|
27baab2f57 | ||
|
|
cbd013d2f5 | ||
|
|
dcc05aff08 | ||
|
|
4800afa0db | ||
|
|
b769d1b1d5 | ||
|
|
e6221b5f42 | ||
|
|
11635ec959 | ||
|
|
773f15c563 | ||
|
|
e9b4e4450c | ||
|
|
30042a363e | ||
|
|
315de60e79 | ||
|
|
33e71dbfa9 | ||
|
|
fec1da8818 | ||
|
|
c2c0deaeb7 | ||
|
|
0a95db4035 | ||
|
|
0c60dcb264 | ||
|
|
5ae8f2c5a7 | ||
|
|
86bc261042 | ||
|
|
8680a8175f | ||
|
|
c2d5fd7a90 | ||
|
|
5c382e63b0 | ||
|
|
e3e36d943e | ||
|
|
d15ca6e6d1 | ||
|
|
412248b6d9 | ||
|
|
f89da92b52 | ||
|
|
8a57bdf774 | ||
|
|
cad86487c1 | ||
|
|
1729e1f36d | ||
|
|
4850cdb292 | ||
|
|
f89655e5fa | ||
|
|
6c86a4e48b | ||
|
|
c7bd0e0e03 | ||
|
|
5a355a1d11 | ||
|
|
3bf44819e4 | ||
|
|
27257a40d2 | ||
|
|
4987120713 | ||
|
|
0ca43c0945 | ||
|
|
3eb3dde089 | ||
|
|
a495610f29 | ||
|
|
2506eee0fb | ||
|
|
b13d164ccf | ||
|
|
01bf8bc4a8 | ||
|
|
fe2abf6903 | ||
|
|
f611199fab | ||
|
|
8fffeaca94 | ||
|
|
aa4992469d | ||
|
|
7dd7aec10c | ||
|
|
bfac67fa87 | ||
|
|
06b9dc86d6 | ||
|
|
83253c76e8 | ||
|
|
66f5c30f5a | ||
|
|
da46057666 | ||
|
|
10343559a6 | ||
|
|
e3dd55a102 | ||
|
|
f6154ba46f | ||
|
|
a38e1f201d | ||
|
|
a97fc8b53a | ||
|
|
d0ec3f4139 | ||
|
|
ecc1ae826f | ||
|
|
408377e51b | ||
|
|
1f5698ce15 | ||
|
|
d4a23ee68c | ||
|
|
b76b82d6ee | ||
|
|
2a0154dfa0 | ||
|
|
622177e0df | ||
|
|
b04131b408 | ||
|
|
e93ef851ac | ||
|
|
4d7f2e6698 | ||
|
|
abf827bc2b | ||
|
|
ee25d35220 | ||
|
|
eef8e594a2 | ||
|
|
5edeffbda4 | ||
|
|
af4df9c2e2 | ||
|
|
ac18ad2fcd | ||
|
|
1d293bb186 | ||
|
|
99611910de | ||
|
|
632c88c5f8 | ||
|
|
a3d6155096 | ||
|
|
af3fc34098 | ||
|
|
dbd261fbf1 | ||
|
|
19a7a322c5 | ||
|
|
36cf0aaf8e | ||
|
|
32b0937ad9 | ||
|
|
13b176d515 | ||
|
|
81aab6bdb3 | ||
|
|
23abf14888 | ||
|
|
79f49fab4d | ||
|
|
e732aae87b | ||
|
|
cf3ca2e9e0 | ||
|
|
1030330add | ||
|
|
b82e3b873b | ||
|
|
b0f885ab2c | ||
|
|
2758a2eb03 | ||
|
|
6c012aa0ad | ||
|
|
52a3c01829 | ||
|
|
33b0d15bb3 | ||
|
|
9565a4f36a | ||
|
|
07d1252fb0 | ||
|
|
f0ef22f730 | ||
|
|
1f070f78e6 | ||
|
|
e2c29aabf8 | ||
|
|
f0fb37c9fc | ||
|
|
b4a4831ef9 | ||
|
|
3680ff4b6a | ||
|
|
d899954912 | ||
|
|
fdf01e1d1e | ||
|
|
d49a08626f | ||
|
|
2512bace19 | ||
|
|
6e3961fe0f | ||
|
|
020c87158c | ||
|
|
a12df840a4 | ||
|
|
ca9565bb60 | ||
|
|
4d39924059 | ||
|
|
a409557019 | ||
|
|
54abfee660 | ||
|
|
42f02bb9fc | ||
|
|
a4348f9646 | ||
|
|
7a33814886 | ||
|
|
1e7ee927c4 | ||
|
|
b423d0346b | ||
|
|
3b3af9056a | ||
|
|
7d62f00274 | ||
|
|
d5dcc78acd | ||
|
|
fdbbdfea05 | ||
|
|
2d974543ff | ||
|
|
44bf90e830 | ||
|
|
ca8cf27371 | ||
|
|
4d7da801a7 | ||
|
|
dfebbecb87 | ||
|
|
5805edef0a | ||
|
|
6eed2fff0e | ||
|
|
25b76e3b86 | ||
|
|
e976fbb623 | ||
|
|
11a93c8470 | ||
|
|
5b0f9f1f4d | ||
|
|
eaaaeada51 | ||
|
|
b440a900c4 | ||
|
|
0de8fa1934 | ||
|
|
bb95c9e3a3 | ||
|
|
937eed1ee6 | ||
|
|
0cd9d11d4e | ||
|
|
4809afe287 | ||
|
|
681802d030 | ||
|
|
ddbe1d9c97 | ||
|
|
aa3826ed8d | ||
|
|
c2333982fa | ||
|
|
5d963ce7ae | ||
|
|
8e1c53b1e7 | ||
|
|
5c073257b7 | ||
|
|
35e09b3acd | ||
|
|
7ed0248032 | ||
|
|
c7a813e8d5 | ||
|
|
b97b87bfb0 | ||
|
|
106a22eb27 | ||
|
|
0439a3e73d | ||
|
|
3fb6cfb1be | ||
|
|
4eba28fa96 | ||
|
|
0443d5baf7 | ||
|
|
19c393a8d9 | ||
|
|
f63db4dd19 | ||
|
|
106b2a7a98 | ||
|
|
876461e8d2 | ||
|
|
2f359025f2 | ||
|
|
d5fd82e8d6 | ||
|
|
123e453bd2 | ||
|
|
d4075c6fa9 | ||
|
|
dd1189c5ff | ||
|
|
e5af9f53e6 | ||
|
|
80eb2e8371 | ||
|
|
284d02d172 | ||
|
|
2124b24f61 | ||
|
|
fc39239be1 | ||
|
|
d018265175 | ||
|
|
62a039b672 | ||
|
|
9e1df8b804 | ||
|
|
fcac817f11 | ||
|
|
7d89676df6 | ||
|
|
96987add7b | ||
|
|
88a5e50256 | ||
|
|
7bc3f83e7b | ||
|
|
6bb6fb64d8 | ||
|
|
e7b737cba2 |
8
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_1.md
vendored
Normal file
8
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_1.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
name: Bug report (bluescreen crash) Bug报告 (蓝屏报错)
|
||||
about: Create a report of problems which made the crash with a bluescreen
|
||||
---
|
||||
Screenshot with crash information (*Image(s) Here*):
|
||||
|
||||
|
||||
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button (*Details Here*)
|
||||
8
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_2.md
vendored
Normal file
8
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_2.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
name: Bug report (unintended behaviors) Bug报告 (奇怪的现象)
|
||||
about: Create a report of unintended behaviors
|
||||
---
|
||||
Screenshot with unintended behaviors (*Image(s) Here*):
|
||||
|
||||
|
||||
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button (*Details Here*):
|
||||
4
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_3.md
vendored
Normal file
4
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_3.md
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
name: Feature Request 添加新功能
|
||||
about: Suggest an idea that may improve Techmino 提一些有意思的新想法,让Techmino越来越好!
|
||||
---
|
||||
24
.github/actions/automatic-test/action.yml
vendored
Normal file
24
.github/actions/automatic-test/action.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: 'Automatic Test'
|
||||
description: 'Check for obvious errors.'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/build-love
|
||||
with:
|
||||
file-path: Techmino.love
|
||||
- name: Download love
|
||||
shell: bash
|
||||
run: |
|
||||
curl -L https://github.com/love2d/love/releases/download/11.3/love-11.3-linux-x86_64.tar.gz | tar xz
|
||||
- name: Prepare PulseAudio
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install pulseaudio pulseaudio-utils pavucontrol alsa-oss alsa-utils -y
|
||||
- name: Run automated test
|
||||
uses: GabrielBB/xvfb-action@v1
|
||||
with:
|
||||
run: |
|
||||
./dest/love Techmino.love --test
|
||||
102
.github/actions/build-android/action.yml
vendored
Normal file
102
.github/actions/build-android/action.yml
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
name: 'build Android'
|
||||
description: 'build Android package'
|
||||
inputs:
|
||||
type:
|
||||
required: true
|
||||
apkCode:
|
||||
required: true
|
||||
name:
|
||||
required: true
|
||||
file-path:
|
||||
required: true
|
||||
SIGNING_KEY:
|
||||
required: true
|
||||
KEY_STORE_PASSWORD:
|
||||
required: true
|
||||
ALIAS:
|
||||
required: true
|
||||
KEY_PASSWORD:
|
||||
required: true
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '8'
|
||||
- name: Clone love-android
|
||||
shell: bash
|
||||
run: |
|
||||
git clone --recurse-submodules https://github.com/26F-Studio/love-android -b CI --depth 1 --shallow-submodules
|
||||
- uses: ./.github/actions/build-love
|
||||
with:
|
||||
file-path: love-android/app/src/main/assets/game.love
|
||||
- name: Download ColdClear arm64-v8a
|
||||
uses: ./.github/actions/get-cc
|
||||
with:
|
||||
arch: android_aarch64
|
||||
dir: ColdClear/arm64-v8a
|
||||
- name: Process ColdClear arm64-v8a
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p love-android/app/libs/arm64-v8a
|
||||
mv ColdClear/arm64-v8a/love-11.3-android/lib/arm64-v8a/libcold_clear.so love-android/app/libs/arm64-v8a
|
||||
mkdir -p libAndroid/arm64-v8a
|
||||
mv ColdClear/arm64-v8a/libs/arm64-v8a/libCCloader.so libAndroid/arm64-v8a
|
||||
- name: Download ColdClear armeabi-v7a
|
||||
uses: ./.github/actions/get-cc
|
||||
with:
|
||||
arch: android_armv7
|
||||
dir: ColdClear/armeabi-v7a
|
||||
- name: Process ColdClear armeabi-v7a
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p love-android/app/libs/armeabi-v7a
|
||||
mv ColdClear/armeabi-v7a/love-11.3-android/lib/armeabi-v7a/libcold_clear.so love-android/app/libs/armeabi-v7a
|
||||
mkdir -p libAndroid/armeabi-v7a
|
||||
mv ColdClear/armeabi-v7a/libs/armeabi-v7a/libCCloader.so libAndroid/armeabi-v7a
|
||||
- name: Pack ColdClear
|
||||
shell: bash
|
||||
run: |
|
||||
7z a -tzip love-android/app/src/main/assets/game.love libAndroid
|
||||
- name: update Android information
|
||||
shell: python
|
||||
run: |
|
||||
if '${{ inputs.type }}' == 'Release':
|
||||
appName = 'Techmino'
|
||||
packageName = 'org.love2d.MrZ.Techmino'
|
||||
edition = 'release'
|
||||
elif '${{ inputs.type }}' == 'Snapshot':
|
||||
appName = 'Techmino_Snapshot'
|
||||
packageName = 'org.love2d.MrZ.Techmino.Snapshot'
|
||||
edition = 'snapshot'
|
||||
with open('./love-android/app/src/main/AndroidManifest.xml', "r+", encoding='utf-8') as file:
|
||||
data = file.read()
|
||||
data = data\
|
||||
.replace('@appName', appName)\
|
||||
.replace('@edition', edition)
|
||||
file.seek(0)
|
||||
file.truncate()
|
||||
file.write(data)
|
||||
with open("./love-android/app/build.gradle", "r+", encoding='utf-8') as file:
|
||||
data = file.read()
|
||||
data = data\
|
||||
.replace('@packageName', packageName)\
|
||||
.replace('@versionCode', '${{ inputs.apkCode }}')\
|
||||
.replace('@versionName', '${{ inputs.name }}')\
|
||||
.replace('@storePassword', '${{ inputs.KEY_STORE_PASSWORD }}')\
|
||||
.replace('@keyAlias', '${{ inputs.ALIAS }}')\
|
||||
.replace('@keyPassword', '${{ inputs.KEY_PASSWORD }}')
|
||||
file.seek(0)
|
||||
file.truncate()
|
||||
file.write(data)
|
||||
- name: Build Techmino
|
||||
shell: bash
|
||||
run: |
|
||||
echo "${{ inputs.SIGNING_KEY }}" | base64 -d > love-android/app/android.keystore
|
||||
chmod 777 love-android/gradlew
|
||||
cd love-android/
|
||||
./gradlew assembleRelease
|
||||
- name: rename apk
|
||||
shell: bash
|
||||
run: mv love-android/app/build/outputs/apk/release/app-release.apk ${{ inputs.file-path }}
|
||||
96
.github/actions/build-ios/action.yml
vendored
Normal file
96
.github/actions/build-ios/action.yml
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
name: 'build iOS'
|
||||
description: 'build iOS package'
|
||||
inputs:
|
||||
name:
|
||||
required: true
|
||||
description: "Version name"
|
||||
type:
|
||||
required: true
|
||||
description: "Build type"
|
||||
APPLE_API_ID:
|
||||
required: true
|
||||
description: "API key ID"
|
||||
APPLE_API_ISSUER:
|
||||
required: true
|
||||
description: "API issuer ID"
|
||||
APPLE_API_KEY:
|
||||
required: true
|
||||
description: "API key content"
|
||||
APPLE_APP_BUILD:
|
||||
required: true
|
||||
description: "Build number"
|
||||
APPLE_APP_CHANGELOG:
|
||||
required: true
|
||||
description: "Changelog"
|
||||
APPLE_APP_ID:
|
||||
required: true
|
||||
description: "AppStore Apple ID"
|
||||
APPLE_APP_IDENTIFIER:
|
||||
required: true
|
||||
description: "Bundle ID"
|
||||
APPLE_APP_PROFILE:
|
||||
required: true
|
||||
description: "Provisioning Profile specifer"
|
||||
APPLE_KEYCHAIN_NAME:
|
||||
required: true
|
||||
description: "Temporary keychain name"
|
||||
APPLE_KEYCHAIN_PWD:
|
||||
required: true
|
||||
description: "Temporary keychain password"
|
||||
FASTLANE_DISCORD_WEBHOOK:
|
||||
required: true
|
||||
description: "Fastlane Discord webhook"
|
||||
FASTLANE_ACTION_ID:
|
||||
required: true
|
||||
description: "Fastlane Action ID"
|
||||
FASTLANE_MATCH_PWD:
|
||||
required: true
|
||||
description: "Fastlane Match description password"
|
||||
FASTLANE_MATCH_TOKEN:
|
||||
required: true
|
||||
description: "Fastlane Match Github token"
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- uses: ./.github/actions/build-love
|
||||
- name: Checkout source codes
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: '26F-Studio/Techmino-iOS'
|
||||
path: 'Techmino-iOS'
|
||||
- name: Download CCloader
|
||||
uses: ./.github/actions/get-cc
|
||||
with:
|
||||
arch: iOS
|
||||
- name: Update source codes
|
||||
shell: bash
|
||||
run: |
|
||||
mv Techmino.love Techmino-iOS/platform/xcode
|
||||
mv libcold_clear.a Techmino-iOS/platform/xcode
|
||||
mv libCCloader.a Techmino-iOS/platform/xcode
|
||||
- name: Run fastlane
|
||||
uses: maierj/fastlane-action@v2.0.1
|
||||
with:
|
||||
lane: '${{ inputs.type }}'
|
||||
subdirectory: 'Techmino-iOS/platform/xcode'
|
||||
env:
|
||||
ACTION_ID: '${{ inputs.FASTLANE_ACTION_ID }}'
|
||||
API_ID: '${{ inputs.APPLE_API_ID }}'
|
||||
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
||||
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
||||
APP_BUILD: '${{ inputs.APPLE_APP_BUILD }}'
|
||||
APP_CHANGELOG: '${{ inputs.APPLE_APP_CHANGELOG }}'
|
||||
APP_ID: '${{ inputs.APPLE_APP_ID }}'
|
||||
APP_IDENTIFIER: '${{ inputs.APPLE_APP_IDENTIFIER }}'
|
||||
APP_PROFILE: '${{ inputs.APPLE_APP_PROFILE }}'
|
||||
APP_VERSION: '${{ inputs.name }}'
|
||||
DISCORD_WEBHOOK: '${{ inputs.FASTLANE_DISCORD_WEBHOOK }}'
|
||||
KEYCHAIN_NAME: '${{ inputs.APPLE_KEYCHAIN_NAME }}'
|
||||
KEYCHAIN_PWD: '${{ inputs.APPLE_KEYCHAIN_PWD }}'
|
||||
MATCH_PASSWORD: '${{ inputs.FASTLANE_MATCH_PWD }}'
|
||||
MATCH_TOKEN: '${{ inputs.FASTLANE_MATCH_TOKEN }}'
|
||||
- name: Move ipa
|
||||
shell: bash
|
||||
run: |
|
||||
mv Techmino-iOS/platform/xcode/Techmino.ipa Techmino.ipa
|
||||
|
||||
40
.github/actions/build-linux/action.yml
vendored
Normal file
40
.github/actions/build-linux/action.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: 'build Linux'
|
||||
description: 'build Linux package'
|
||||
inputs:
|
||||
file-path:
|
||||
required: false
|
||||
default: Techmino.AppImage
|
||||
icon:
|
||||
required: true
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Download AppImageKit
|
||||
shell: bash
|
||||
run: |
|
||||
curl -OL https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage
|
||||
- name: Download love
|
||||
shell: bash
|
||||
run: |
|
||||
curl -OL https://github.com/love2d/love/releases/download/11.3/love-11.3-x86_64.AppImage
|
||||
chmod 777 love-11.3-x86_64.AppImage
|
||||
./love-11.3-x86_64.AppImage --appimage-extract
|
||||
- name: Download ColdClear
|
||||
uses: ./.github/actions/get-cc
|
||||
with:
|
||||
arch: linux
|
||||
- name: Pack Techmino
|
||||
shell: bash
|
||||
run: |
|
||||
rm -rf squashfs-root/love squashfs-root/love.desktop squashfs-root/love.svg squashfs-root/.DirIcon
|
||||
mv .github/build/Linux/love.template squashfs-root/love
|
||||
mv .github/build/Linux/Techmino.desktop.template squashfs-root/Techmino.desktop
|
||||
mv ${{ inputs.icon }} squashfs-root/icon.png
|
||||
cp squashfs-root/icon.png squashfs-root/.DirIcon
|
||||
chmod 777 squashfs-root/love
|
||||
mkdir -p squashfs-root/usr/share/Techmino
|
||||
mv media parts Zframework conf.lua main.lua version.lua legals.md license.txt squashfs-root/usr/share/Techmino
|
||||
mv CCloader.so squashfs-root/usr/share/Techmino
|
||||
mv libcold_clear.so squashfs-root/usr/lib
|
||||
chmod 777 appimagetool-x86_64.AppImage
|
||||
./appimagetool-x86_64.AppImage squashfs-root ${{ inputs.file-path }}
|
||||
11
.github/actions/build-love/action.yml
vendored
Normal file
11
.github/actions/build-love/action.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
name: 'build love'
|
||||
description: 'build love file'
|
||||
inputs:
|
||||
file-path:
|
||||
required: true
|
||||
default: Techmino.love
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- run: 7z a -tzip ${{ inputs.file-path }} media parts Zframework conf.lua main.lua version.lua legals.md license.txt
|
||||
shell: bash
|
||||
152
.github/actions/build-macos/action.yml
vendored
Normal file
152
.github/actions/build-macos/action.yml
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
name: 'build Mac OS'
|
||||
description: 'build Mac OS package'
|
||||
inputs:
|
||||
name:
|
||||
required: true
|
||||
description: "Version name"
|
||||
icon:
|
||||
required: true
|
||||
description: "App icons (.icns)"
|
||||
APPLE_API_ID:
|
||||
required: true
|
||||
description: "API key ID"
|
||||
APPLE_API_ISSUER:
|
||||
required: true
|
||||
description: "API issuer ID"
|
||||
APPLE_API_KEY:
|
||||
required: true
|
||||
description: "API key content"
|
||||
APPLE_APP_IDENTIFIER:
|
||||
required: true
|
||||
description: "Bundle ID"
|
||||
APPLE_KEYCHAIN_NAME:
|
||||
required: true
|
||||
description: "Temporary keychain name"
|
||||
APPLE_KEYCHAIN_PWD:
|
||||
required: true
|
||||
description: "Temporary keychain password"
|
||||
FASTLANE_MATCH_PWD:
|
||||
required: true
|
||||
description: "Fastlane Match description password"
|
||||
FASTLANE_MATCH_TOKEN:
|
||||
required: true
|
||||
description: "Fastlane Match Github token"
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- uses: ./.github/actions/build-love
|
||||
- name: Checkout template
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: '26F-Studio/Techmino-macOS'
|
||||
path: 'Techmino-macOS'
|
||||
- name: Download ColdClear
|
||||
uses: ./.github/actions/get-cc
|
||||
with:
|
||||
arch: macOS
|
||||
- name: Fastlane match
|
||||
uses: maierj/fastlane-action@v2.0.1
|
||||
with:
|
||||
lane: 'get_cert'
|
||||
subdirectory: 'Techmino-macOS'
|
||||
env:
|
||||
API_ID: '${{ inputs.APPLE_API_ID }}'
|
||||
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
||||
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
||||
APP_IDENTIFIER: '${{ inputs.APPLE_APP_IDENTIFIER }}'
|
||||
KEYCHAIN_NAME: '${{ inputs.APPLE_KEYCHAIN_NAME }}'
|
||||
KEYCHAIN_PWD: '${{ inputs.APPLE_KEYCHAIN_PWD }}'
|
||||
MATCH_PASSWORD: '${{ inputs.FASTLANE_MATCH_PWD }}'
|
||||
MATCH_TOKEN: '${{ inputs.FASTLANE_MATCH_TOKEN }}'
|
||||
- name: Modify template
|
||||
shell: python
|
||||
run: |
|
||||
import datetime
|
||||
from io import open
|
||||
thisYear = str(datetime.datetime.today().year)
|
||||
with open('./.github/build/macOS/info.plist.template', 'r', encoding='utf-8') as file:
|
||||
data = file.read()
|
||||
data = data\
|
||||
.replace('@versionName', '${{ inputs.name }}'[1:])\
|
||||
.replace('@thisYear', thisYear)\
|
||||
.replace('@bundleId', '${{ inputs.APPLE_APP_IDENTIFIER }}')
|
||||
with open('./Techmino-macOS/Techmino.app/Contents/info.plist', 'w+', encoding='utf-8') as file:
|
||||
file.write(data)
|
||||
- name: Pack
|
||||
shell: bash
|
||||
run: |
|
||||
mv Techmino.love Techmino-macOS/Techmino.app/Contents/Resources
|
||||
mv CCloader.dylib Techmino-macOS/Techmino.app/Contents/Frameworks
|
||||
mv ${{ inputs.icon }} Techmino-macOS/Techmino.app/Contents/Resources/iconfile.icns
|
||||
|
||||
chmod +x Techmino-macOS/Techmino.app/Contents/Frameworks/CCloader.dylib
|
||||
chmod +x Techmino-macOS/Techmino.app/Contents/MacOS/love
|
||||
- name: Codesign executable
|
||||
shell: bash
|
||||
run: |
|
||||
security unlock-keychain -p ${{ inputs.TEMP_KEYCHAIN_PASSWORD }} \
|
||||
~/Library/Keychains/${{ inputs.TEMP_KEYCHAIN_USER }}-db
|
||||
|
||||
[[ $(security find-identity) =~ ([0-9A-F]{40}) ]]
|
||||
|
||||
codesign --timestamp --force --strict --deep -v \
|
||||
--options runtime \
|
||||
-s ${BASH_REMATCH[1]} \
|
||||
--entitlements Techmino-macOS/love.entitlements \
|
||||
Techmino-macOS/Techmino.app
|
||||
- name: Fastlane notarize
|
||||
uses: maierj/fastlane-action@v2.0.1
|
||||
with:
|
||||
lane: 'make_safe'
|
||||
subdirectory: 'Techmino-macOS'
|
||||
env:
|
||||
API_ID: '${{ inputs.APPLE_API_ID }}'
|
||||
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
||||
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
||||
APP_IDENTIFIER: '${{ inputs.APPLE_APP_IDENTIFIER }}'
|
||||
NOTARIZE_OBJECT: 'Techmino.app'
|
||||
- name: Create DMG file
|
||||
shell: bash
|
||||
run: |
|
||||
brew install create-dmg
|
||||
create-dmg \
|
||||
--volname "Techmino for MacOS" \
|
||||
--volicon "./.github/build/macOS/Techminodisk.icns" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 800 500 \
|
||||
--icon-size 100 \
|
||||
--icon "Techmino.app" 239 203 \
|
||||
--background ".github/build/macOS/backgroundImage.tiff" \
|
||||
--hide-extension "Techmino.app" \
|
||||
--app-drop-link 565 203 \
|
||||
"Techmino-macOS/Techmino-macOS.dmg" \
|
||||
"Techmino-macOS/Techmino.app/"
|
||||
- name: Codesign DMG
|
||||
shell: bash
|
||||
run: |
|
||||
security unlock-keychain -p ${{ inputs.TEMP_KEYCHAIN_PASSWORD }} \
|
||||
~/Library/Keychains/${{ inputs.TEMP_KEYCHAIN_USER }}-db
|
||||
|
||||
[[ $(security find-identity) =~ ([0-9A-F]{40}) ]]
|
||||
|
||||
codesign --timestamp --force --strict --deep -v \
|
||||
--options runtime \
|
||||
-s ${BASH_REMATCH[1]} \
|
||||
--entitlements Techmino-macOS/love.entitlements \
|
||||
Techmino-macOS/Techmino-macOS.dmg
|
||||
- name: Fastlane notarize
|
||||
uses: maierj/fastlane-action@v2.0.1
|
||||
with:
|
||||
lane: 'make_safe'
|
||||
subdirectory: 'Techmino-macOS'
|
||||
env:
|
||||
API_ID: '${{ inputs.APPLE_API_ID }}'
|
||||
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
||||
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
||||
APP_IDENTIFIER: '${{ inputs.APPLE_APP_IDENTIFIER }}'
|
||||
NOTARIZE_OBJECT: 'Techmino-macOS.dmg'
|
||||
- name: Finalize
|
||||
shell: bash
|
||||
run: |
|
||||
mv Techmino-macOS/Techmino-macOS.dmg Techmino.dmg
|
||||
spctl -a -t open --context context:primary-signature -vv Techmino.dmg
|
||||
60
.github/actions/build-windows/action.yml
vendored
Normal file
60
.github/actions/build-windows/action.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
name: 'build Windows'
|
||||
description: 'build Windows package'
|
||||
inputs:
|
||||
love-url:
|
||||
required: true
|
||||
love-dir:
|
||||
required: true
|
||||
arch:
|
||||
required: true
|
||||
version:
|
||||
required: true
|
||||
icon:
|
||||
required: true
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Download love
|
||||
uses: ./.github/actions/get-unzip
|
||||
with:
|
||||
url: ${{ inputs.love-url }}
|
||||
- name: move love
|
||||
shell: bash
|
||||
run: mv ${{ inputs.love-dir }} love
|
||||
- name: Download ColdClear
|
||||
uses: ./.github/actions/get-cc
|
||||
with:
|
||||
arch: ${{ inputs.arch }}
|
||||
- name: Download ResourceHacker
|
||||
uses: ./.github/actions/get-unzip
|
||||
with:
|
||||
url: http://www.angusj.com/resourcehacker/resource_hacker.zip
|
||||
- uses: ./.github/actions/build-love
|
||||
- name: update Windows template
|
||||
shell: python
|
||||
run: |
|
||||
Version = '${{ inputs.version }}'.replace('V', '')
|
||||
FileVersion = (f"{Version.replace('.', ',')},0")
|
||||
with open('./.github/build/Windows/Techmino.rc.template', 'r', encoding='utf8') as file:
|
||||
data = file.read()
|
||||
data = data\
|
||||
.replace('@FileVersion', FileVersion)\
|
||||
.replace('@Version', Version)
|
||||
with open('Techmino.rc', 'w+', encoding='utf8') as file:
|
||||
file.write(data)
|
||||
- name: Pack Techmino
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmd /c copy /b .\love\love.exe + .\Techmino.love .\love\Techmino.exe
|
||||
del .\love\love.exe
|
||||
del .\love\lovec.exe
|
||||
del .\love\game.ico
|
||||
del .\love\love.ico
|
||||
del .\love\changes.txt
|
||||
del .\love\readme.txt
|
||||
move .\cold_clear.dll .\love
|
||||
move .\CCloader.dll .\love
|
||||
cmd /c '.\ResourceHacker.exe -open .\love\Techmino.exe -save .\love\Techmino.exe -action delete -mask ICONGROUP,,'
|
||||
cmd /c '.\ResourceHacker.exe -open .\Techmino.rc -save .\Techmino.res -action compile'
|
||||
cmd /c '.\ResourceHacker.exe -open .\love\Techmino.exe -save .\love\Techmino.exe -action addoverwrite -res "${{ inputs.icon }}" -mask ICONGROUP,1,'
|
||||
cmd /c '.\ResourceHacker.exe -open .\love\Techmino.exe -save .\love\Techmino.exe -action addoverwrite -res ".\Techmino.res" -mask VERSIONINFO,1,'
|
||||
32
.github/actions/get-cc/action.yml
vendored
Normal file
32
.github/actions/get-cc/action.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: 'get cc'
|
||||
description: 'download cc into specific dir'
|
||||
inputs:
|
||||
tag:
|
||||
required: false
|
||||
default:
|
||||
arch:
|
||||
required: true
|
||||
dir:
|
||||
required: false
|
||||
default: '.'
|
||||
repo:
|
||||
required: false
|
||||
default: 26F-Studio/cold_clear_ai_love2d_wrapper
|
||||
temp-file:
|
||||
required: false
|
||||
default: temp.zip
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- run: |
|
||||
echo "::set-output name=tag::"$(if [ -z "${{ inputs.tag }}" ]
|
||||
then curl -w '%{url_effective}' -I -L -s -S https://github.com/${{ inputs.repo }}/releases/latest -o /dev/null | grep -o '\<[^/]*$'
|
||||
else echo ${{ inputs.tag }}
|
||||
fi)
|
||||
id: get-tag
|
||||
shell: bash
|
||||
- uses: ./.github/actions/get-unzip
|
||||
with:
|
||||
url: https://github.com/${{ inputs.repo }}/releases/download/${{ steps.get-tag.outputs.tag }}/${{ inputs.arch }}.zip
|
||||
dir: ${{ inputs.dir }}
|
||||
temp-file: ${{ inputs.temp-file }}
|
||||
18
.github/actions/get-unzip/action.yml
vendored
Normal file
18
.github/actions/get-unzip/action.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: 'get and unzip'
|
||||
description: 'cURL and then 7-zip x'
|
||||
inputs:
|
||||
url:
|
||||
required: true
|
||||
dir:
|
||||
required: false
|
||||
default: '.'
|
||||
temp-file:
|
||||
required: false
|
||||
default: temp.zip
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- run: curl -L ${{ inputs.url }} -o ${{ inputs.temp-file }}
|
||||
shell: bash
|
||||
- run: 7z x ${{ inputs.temp-file }} -o${{ inputs.dir }}
|
||||
shell: bash
|
||||
37
.github/actions/update-version/action.yml
vendored
Normal file
37
.github/actions/update-version/action.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: 'update version'
|
||||
description: 'common update logic for snapshot and release'
|
||||
inputs:
|
||||
commit:
|
||||
required: false
|
||||
type:
|
||||
required: true
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- shell: python
|
||||
name: update snapshot saving folder
|
||||
run: |
|
||||
from io import open
|
||||
if '${{ inputs.type }}'.lower() != 'snapshot':
|
||||
exit(0)
|
||||
with open('conf.lua', 'r+', encoding='utf-8') as file:
|
||||
data = file.read()
|
||||
data = data.replace("t.identity='Techmino'--Saving folder", "t.identity='Techmino_Snapshot'--Saving folder")
|
||||
file.seek(0)
|
||||
file.truncate()
|
||||
file.flush()
|
||||
file.write(data)
|
||||
- shell: python
|
||||
run: |
|
||||
from io import open
|
||||
import re
|
||||
with open('version.lua', 'r+', encoding='utf-8') as file:
|
||||
commitHash = '${{ inputs.commit }}'
|
||||
if commitHash != '':
|
||||
commitHash = '@' + commitHash[0:4]
|
||||
data = file.read()
|
||||
data = re.sub('(\d)"', r'\1' + commitHash + '"', data, 1)
|
||||
file.seek(0)
|
||||
file.truncate()
|
||||
file.flush()
|
||||
file.write(data)
|
||||
8
.github/build/Linux/Techmino.desktop.template
vendored
Normal file
8
.github/build/Linux/Techmino.desktop.template
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Name=Techmino Alpha
|
||||
Comment=Techmino is fun!
|
||||
Exec=wrapper-love %f
|
||||
Type=Application
|
||||
Categories=Game;
|
||||
Terminal=false
|
||||
Icon=icon
|
||||
BIN
.github/build/Linux/icon.png
vendored
Normal file
BIN
.github/build/Linux/icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
.github/build/Linux/icon_snapshot.png
vendored
Normal file
BIN
.github/build/Linux/icon_snapshot.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
5
.github/build/Linux/love.template
vendored
Normal file
5
.github/build/Linux/love.template
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
export LOVE_LAUNCHER_LOCATION="$(dirname "$(which "$0")")"
|
||||
export LD_LIBRARY_PATH="${LOVE_LAUNCHER_LOCATION}/lib/x86_64-linux-gnu:${LOVE_LAUNCHER_LOCATION}/usr/bin:${LOVE_LAUNCHER_LOCATION}/usr/lib:${LOVE_LAUNCHER_LOCATION}/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
|
||||
/sbin/ldconfig -p | grep -q libstdc++ || export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${LOVE_LAUNCHER_LOCATION}/libstdc++/"
|
||||
exec ${LOVE_BIN_WRAPPER} "${LOVE_LAUNCHER_LOCATION}/usr/bin/love" "${LOVE_LAUNCHER_LOCATION}/usr/share/Techmino"
|
||||
23
.github/build/Windows/Techmino.rc.template
vendored
Normal file
23
.github/build/Windows/Techmino.rc.template
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
1 VERSIONINFO
|
||||
FILEVERSION @FileVersion
|
||||
PRODUCTVERSION @FileVersion
|
||||
FILEOS 0x40004
|
||||
FILETYPE 0x1
|
||||
{
|
||||
BLOCK "StringFileInfo"
|
||||
{
|
||||
BLOCK "040904B0"
|
||||
{
|
||||
VALUE "FileDescription", "Techmino Alpha"
|
||||
VALUE "CompanyName", "26F Studio"
|
||||
VALUE "LegalCopyright", "Copyright @ 26F Studio"
|
||||
VALUE "ProductName", "Techmino"
|
||||
VALUE "ProductVersion", "@Version"
|
||||
}
|
||||
}
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
{
|
||||
VALUE "Translation", 0x0409 0x04E4
|
||||
}
|
||||
}
|
||||
BIN
.github/build/Windows/icon.ico
vendored
Normal file
BIN
.github/build/Windows/icon.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
BIN
.github/build/Windows/icon.png
vendored
Normal file
BIN
.github/build/Windows/icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
BIN
.github/build/Windows/icon_snapshot.ico
vendored
Normal file
BIN
.github/build/Windows/icon_snapshot.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
.github/build/macOS/Techminodisk.icns
vendored
Normal file
BIN
.github/build/macOS/Techminodisk.icns
vendored
Normal file
Binary file not shown.
BIN
.github/build/macOS/backgroundImage.tiff
vendored
Normal file
BIN
.github/build/macOS/backgroundImage.tiff
vendored
Normal file
Binary file not shown.
BIN
.github/build/macOS/icon.icns
vendored
Normal file
BIN
.github/build/macOS/icon.icns
vendored
Normal file
Binary file not shown.
BIN
.github/build/macOS/icon_snapshot.icns
vendored
Normal file
BIN
.github/build/macOS/icon_snapshot.icns
vendored
Normal file
Binary file not shown.
56
.github/build/macOS/info.plist.template
vendored
Normal file
56
.github/build/macOS/info.plist.template
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>19B88</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>love</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>iconfile</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@bundleId</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Techmino</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>@versionName</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>LoVe</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>11C504</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>19B90</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.15</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1130</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>11C504</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.7</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>©2020-@thisYear 26F Studio, GNU LGPLv3.0</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
38
.github/workflows/build.yml
vendored
38
.github/workflows/build.yml
vendored
@@ -1,38 +0,0 @@
|
||||
name: Techmino CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ ci ]
|
||||
pull_request:
|
||||
branches: [ ci ]
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
lfs: true
|
||||
- name: Download love
|
||||
run: |
|
||||
curl -LO https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||
7z x love-11.3-win64.zip
|
||||
- name: Download ColdClear
|
||||
run: |
|
||||
curl -LO https://github.com/26F-Studio/Techmino/releases/download/coldclear/coldclear.zip
|
||||
7z x coldclear.zip -ocoldclear
|
||||
move coldclear\win64\cold_clear.dll love-11.3-win64
|
||||
move coldclear\win64\CCloader.dll love-11.3-win64
|
||||
- name: Pack Techmino
|
||||
shell: cmd
|
||||
run: |
|
||||
7z a game.zip BGM document image modes parts SFX VOICE Zframework conf.lua font.ttf main.lua
|
||||
move game.zip game.love
|
||||
copy /b love-11.3-win64\love.exe + game.love love-11.3-win64\Techmino.exe
|
||||
del love-11.3-win64\love.exe
|
||||
del love-11.3-win64\lovec.exe
|
||||
- name: Artifact
|
||||
uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: Techmino_win64
|
||||
path: love-11.3-win64
|
||||
203
.github/workflows/dev.yml
vendored
Normal file
203
.github/workflows/dev.yml
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
name: Techmino Develop CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, ci* ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
get-info:
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
name: ${{ steps.actual-get-info.outputs.name }}
|
||||
apkCode: ${{ steps.actual-get-info.outputs.apkCode }}
|
||||
code: ${{ steps.actual-get-info.outputs.code }}
|
||||
commit: ${{ steps.actual-get-info.outputs.commit }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install lua
|
||||
run: |
|
||||
sudo apt-get install lua5.3 -y
|
||||
- name: Get Version
|
||||
id: actual-get-info
|
||||
run: |
|
||||
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
||||
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
|
||||
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
||||
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
||||
|
||||
automatic-test:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/automatic-test
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-windows
|
||||
with:
|
||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||
love-dir: love-11.3-win64
|
||||
arch: win64
|
||||
version: ${{ needs.get-info.outputs.name }}
|
||||
icon: .\.github\build\Windows\icon_snapshot.ico
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Windows
|
||||
path: love
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-linux
|
||||
with:
|
||||
icon: .github/build/Linux/icon_snapshot.png
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Linux
|
||||
path: Techmino.AppImage
|
||||
|
||||
build-android:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-android
|
||||
with:
|
||||
type: Snapshot
|
||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
file-path: Techmino_Snapshot.apk
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android
|
||||
path: Techmino_Snapshot.apk
|
||||
|
||||
build-android-mini:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- name: remove media
|
||||
run: |
|
||||
rm -rf media/music media/effect media/vocal
|
||||
- uses: ./.github/actions/build-android
|
||||
with:
|
||||
type: Snapshot
|
||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
file-path: Techmino_Snapshot_Mini.apk
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android_Mini
|
||||
path: Techmino_Snapshot_Mini.apk
|
||||
|
||||
build-macOS:
|
||||
runs-on: macos-10.15
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-macos
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
icon: .github/build/macOS/icon_snapshot.icns
|
||||
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_macOS
|
||||
path: Techmino.dmg
|
||||
|
||||
build-iOS:
|
||||
runs-on: macos-latest
|
||||
if: (!startsWith( github.ref , 'refs/heads/ci-')) || startsWith( github.ref , 'refs/heads/ci-ios-')
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-ios
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
type: 'dev'
|
||||
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||
APPLE_APP_BUILD: '${{ needs.get-info.outputs.code }}.2.${{ github.run_number }}.${{ github.run_attempt }}'
|
||||
APPLE_APP_CHANGELOG: '${{ github.event.commits[0].message }}'
|
||||
APPLE_APP_ID: '${{ secrets.APPLE_APP_ID }}'
|
||||
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||
FASTLANE_ACTION_ID: '${{ github.run_id }}'
|
||||
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_iOS
|
||||
path: Techmino.ipa
|
||||
|
||||
build-love:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-love
|
||||
with:
|
||||
file-path: Techmino.love
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Love
|
||||
path: Techmino.love
|
||||
28
.github/workflows/getVersion.lua
vendored
Normal file
28
.github/workflows/getVersion.lua
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
local arg=arg[1]
|
||||
if arg=="-apkCode"then
|
||||
local code=require"version".apkCode
|
||||
print(code)
|
||||
elseif arg=="-code"then
|
||||
local str=require"version".code
|
||||
print(str)
|
||||
elseif arg=="-name"then
|
||||
local str=require"version".string
|
||||
print(str)
|
||||
elseif arg=="-release"then
|
||||
local str=require"version".string:gsub("V","",1)
|
||||
print(str)
|
||||
elseif arg=="-updateTitle"then
|
||||
local note=require"parts.updateLog"
|
||||
local p1=note:find("\n%d")+1
|
||||
local p2=note:find("\n",p1)-1
|
||||
note=note:sub(p1,p2)
|
||||
print(note)
|
||||
elseif arg=="-updateNote"then
|
||||
local note=require"parts.updateLog"
|
||||
local p1=note:find("\n",note:find("\n%d")+1)+1
|
||||
local p2=note:find("\n%d",p1+1)
|
||||
note=note:sub(p1,p2-2)
|
||||
:gsub(" ","- ")
|
||||
:gsub(" ","# ")
|
||||
print(note)
|
||||
end
|
||||
189
.github/workflows/release.yml
vendored
Normal file
189
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
name: Techmino Release CI
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
get-info:
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
name: ${{ steps.actual-get-info.outputs.name }}
|
||||
apkCode: ${{ steps.actual-get-info.outputs.apkCode }}
|
||||
code: ${{ steps.actual-get-info.outputs.code }}
|
||||
release: ${{ steps.actual-get-info.outputs.release }}
|
||||
updateTitle: ${{ steps.actual-get-info.outputs.updateTitle }}
|
||||
updateNote: ${{ steps.actual-get-info.outputs.updateNote }}
|
||||
commit: ${{ steps.actual-get-info.outputs.commit }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install lua
|
||||
run: |
|
||||
sudo apt-get install lua5.3 -y
|
||||
- name: Get Version
|
||||
id: actual-get-info
|
||||
run: |
|
||||
UPDATE_NOTE=$(lua .github/workflows/getVersion.lua -updateNote)
|
||||
UPDATE_NOTE="${UPDATE_NOTE//'%'/'%25'}"
|
||||
UPDATE_NOTE="${UPDATE_NOTE//$'\n'/'%0A'}"
|
||||
UPDATE_NOTE="${UPDATE_NOTE//$'\r'/'%0D'}"
|
||||
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
||||
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
|
||||
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
||||
echo "::set-output name=release::$(lua .github/workflows/getVersion.lua -release)"
|
||||
echo "::set-output name=updateTitle::$(lua .github/workflows/getVersion.lua -updateTitle)"
|
||||
echo "::set-output name=updateNote::$UPDATE_NOTE"
|
||||
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
||||
|
||||
build-windows-x64:
|
||||
runs-on: windows-latest
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-windows
|
||||
with:
|
||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||
love-dir: love-11.3-win64
|
||||
arch: win64
|
||||
version: ${{ needs.get-info.outputs.release }}
|
||||
icon: .\.github\build\Windows\icon.ico
|
||||
- name: Pack Techmino
|
||||
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip .\love
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip
|
||||
|
||||
build-windows-x86:
|
||||
runs-on: windows-latest
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-windows
|
||||
with:
|
||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win32.zip
|
||||
love-dir: love-11.3-win32
|
||||
arch: win32
|
||||
version: ${{ needs.get-info.outputs.release }}
|
||||
icon: .\.github\build\Windows\icon.ico
|
||||
- name: Pack Techmino
|
||||
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip .\love
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-linux
|
||||
with:
|
||||
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
|
||||
icon: .github/build/Linux/icon.png
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
|
||||
|
||||
build-android:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-android
|
||||
with:
|
||||
type: Release
|
||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
|
||||
|
||||
build-macOS:
|
||||
runs-on: macos-10.15
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-macos
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
icon: .github/build/macOS/icon.icns
|
||||
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
|
||||
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
|
||||
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
|
||||
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
|
||||
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
|
||||
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
|
||||
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
|
||||
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
|
||||
- name: Pack Techmino
|
||||
run: |
|
||||
mv Techmino.dmg Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
|
||||
|
||||
build-iOS:
|
||||
runs-on: macos-latest
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-ios
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
type: "release"
|
||||
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
|
||||
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
|
||||
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
|
||||
APPLE_APP_BUILD: "${{ needs.get-info.outputs.code }}.0.${{ github.run_number }}.${{ github.run_attempt }}"
|
||||
APPLE_APP_CHANGELOG: "${{ needs.get-info.outputs.updateNote }}"
|
||||
APPLE_APP_ID: "${{ secrets.APPLE_APP_ID }}"
|
||||
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
|
||||
APPLE_APP_PROFILE: "${{ secrets.APPLE_APP_PROFILE }}"
|
||||
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
|
||||
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
|
||||
FASTLANE_ACTION_ID: "${{ github.run_id }}"
|
||||
FASTLANE_DISCORD_WEBHOOK: "${{ secrets.FASTLANE_DISCORD_WEBHOOK }}"
|
||||
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
|
||||
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
|
||||
- name: Rename ipa
|
||||
shell: bash
|
||||
run: |
|
||||
mv Techmino.ipa Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
|
||||
|
||||
Add-Release-note:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
body: ${{ needs.get-info.outputs.updateNote }}
|
||||
154
.github/workflows/test.yml
vendored
Normal file
154
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
name: Techmino Test CI
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'pre*'
|
||||
|
||||
jobs:
|
||||
get-info:
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
name: ${{ steps.actual-get-info.outputs.name }}
|
||||
apkCode: ${{ steps.actual-get-info.outputs.apkCode }}
|
||||
code: ${{ steps.actual-get-info.outputs.code }}
|
||||
release: ${{ steps.actual-get-info.outputs.release }}
|
||||
commit: ${{ steps.actual-get-info.outputs.commit }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install lua
|
||||
run: |
|
||||
sudo apt-get install lua5.3 -y
|
||||
- name: Get Version
|
||||
id: actual-get-info
|
||||
run: |
|
||||
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
||||
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
|
||||
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
||||
echo "::set-output name=release::$(lua .github/workflows/getVersion.lua -release)"
|
||||
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-windows
|
||||
with:
|
||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||
love-dir: love-11.3-win64
|
||||
arch: win64
|
||||
version: ${{ needs.get-info.outputs.name }}
|
||||
icon: .\.github\build\Windows\icon_snapshot.ico
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Windows
|
||||
path: love
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-linux
|
||||
with:
|
||||
icon: .github/build/Linux/icon_snapshot.png
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Linux
|
||||
path: Techmino.AppImage
|
||||
|
||||
build-android:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-android
|
||||
with:
|
||||
type: Snapshot
|
||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
file-path: Techmino_Snapshot.apk
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Android
|
||||
path: Techmino_Snapshot.apk
|
||||
|
||||
build-macOS:
|
||||
runs-on: macos-10.15
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-macos
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
icon: .github/build/macOS/icon_snapshot.icns
|
||||
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_MacOS
|
||||
path: Techmino.dmg
|
||||
|
||||
build-iOS:
|
||||
runs-on: macos-latest
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- uses: ./.github/actions/build-ios
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
type: 'test'
|
||||
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||
APPLE_APP_BUILD: '${{ needs.get-info.outputs.code }}.1.${{ github.run_number }}.${{ github.run_attempt }}'
|
||||
APPLE_APP_CHANGELOG: '${{ github.event.commits[0].message }}'
|
||||
APPLE_APP_ID: '${{ secrets.APPLE_APP_ID }}'
|
||||
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||
FASTLANE_ACTION_ID: '${{ github.run_id }}'
|
||||
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_iOS
|
||||
path: Techmino.ipa
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,4 +1,8 @@
|
||||
.vscode
|
||||
libAndroid
|
||||
font.ttf
|
||||
note.lua
|
||||
*.ini
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
Icon?
|
||||
.Trash
|
||||
.file
|
||||
|
||||
165
LICENSE
165
LICENSE
@@ -1,165 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
@@ -1,44 +1,56 @@
|
||||
local BGlist={
|
||||
none={
|
||||
draw=function()
|
||||
love.graphics.clear(.15,.15,.15)
|
||||
end
|
||||
}
|
||||
local gc_clear=love.graphics.clear
|
||||
local BGs={
|
||||
none={draw=function()gc_clear(.08,.08,.084)end}
|
||||
}
|
||||
local BGlist={'none'}
|
||||
local BG={
|
||||
cur="none",
|
||||
init=nil,
|
||||
resize=nil,
|
||||
update=NULL,
|
||||
draw=BGlist.none.draw,
|
||||
event=nil,
|
||||
discard=NULL,
|
||||
default='none',
|
||||
locked=false,
|
||||
cur='none',
|
||||
init=false,
|
||||
resize=false,
|
||||
update=NULL,
|
||||
draw=BGs.none.draw,
|
||||
event=false,
|
||||
discard=NULL,
|
||||
}
|
||||
|
||||
function BG.lock()BG.locked=true end
|
||||
function BG.unlock()BG.locked=false end
|
||||
function BG.add(name,bg)
|
||||
BGlist[name]=bg
|
||||
BGs[name]=bg
|
||||
BGlist[#BGlist+1]=name
|
||||
end
|
||||
function BG.getList()
|
||||
return BGlist
|
||||
end
|
||||
function BG.remList(name)
|
||||
table.remove(BGlist,TABLE.find(BGlist,name))
|
||||
end
|
||||
function BG.send(...)
|
||||
if BG.event then
|
||||
BG.event(...)
|
||||
end
|
||||
if BG.event then
|
||||
BG.event(...)
|
||||
end
|
||||
end
|
||||
function BG.set(background)
|
||||
if background==BG.cur or not SETTING.bg then return end
|
||||
BG.discard()
|
||||
BG.cur=background
|
||||
background=BGlist[background]
|
||||
if not background then
|
||||
LOG.print("No BG called"..background,"warn")
|
||||
return
|
||||
end
|
||||
function BG.setDefault(bg)
|
||||
BG.default=bg
|
||||
end
|
||||
function BG.set(name)
|
||||
name=name or BG.default
|
||||
if not BGs[name]or BG.locked then return end
|
||||
if name~=BG.cur then
|
||||
BG.discard()
|
||||
BG.cur=name
|
||||
local bg=BGs[name]
|
||||
|
||||
BG.init= background.init or NULL
|
||||
BG.resize= background.resize or NULL
|
||||
BG.update= background.update or NULL
|
||||
BG.draw= background.draw or NULL
|
||||
BG.event= background.event or NULL
|
||||
BG.discard= background.discard or NULL
|
||||
BG.init()
|
||||
BG.init= bg.init or NULL
|
||||
BG.resize= bg.resize or NULL
|
||||
BG.update= bg.update or NULL
|
||||
BG.draw= bg.draw or NULL
|
||||
BG.event= bg.event or NULL
|
||||
BG.discard=bg.discard or NULL
|
||||
BG.init()
|
||||
end
|
||||
return true
|
||||
end
|
||||
return BG
|
||||
return BG
|
||||
|
||||
@@ -1,86 +1,182 @@
|
||||
local min=math.min
|
||||
|
||||
local function fadeOut(src)
|
||||
while true do
|
||||
coroutine.yield()
|
||||
local v=src:getVolume()-.025*SETTING.bgm
|
||||
src:setVolume(v>0 and v or 0)
|
||||
if v<=0 then
|
||||
src:stop()
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
local function fadeIn(src)
|
||||
while true do
|
||||
coroutine.yield()
|
||||
local v=SETTING.bgm
|
||||
v=min(v,src:getVolume()+.025*v)
|
||||
src:setVolume(v)
|
||||
if v>=SETTING.bgm then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
local function removeCurFadeOut(task,code,src)
|
||||
return task.code==code and task.args[1]==src
|
||||
end
|
||||
local lastLoaded={}
|
||||
local maxLoadedCount=3
|
||||
local nameList={}
|
||||
local SourceObjList={}
|
||||
local volume=1
|
||||
|
||||
local BGM={
|
||||
--nowPlay=[str:playing ID]
|
||||
--playing=[src:playing SRC]
|
||||
default=false,
|
||||
onChange=NULL,
|
||||
--nowPlay=[str:playing ID]
|
||||
--playing=[src:playing SRC]
|
||||
--lastPlayed=[str:lastPlayed ID]
|
||||
}
|
||||
function BGM.set(L)
|
||||
BGM.list=L
|
||||
BGM.len=#L
|
||||
end
|
||||
function BGM.loadOne(N)
|
||||
N=BGM.list[N]
|
||||
local file="media/BGM/"..N..".ogg"
|
||||
if love.filesystem.getInfo(file)then
|
||||
BGM.list[N]=love.audio.newSource(file,"stream")
|
||||
BGM.list[N]:setLooping(true)
|
||||
BGM.list[N]:setVolume(0)
|
||||
else
|
||||
LOG.print("No BGM file: "..N,5,COLOR.orange)
|
||||
end
|
||||
end
|
||||
function BGM.loadAll()
|
||||
for i=1,#BGM.list do
|
||||
BGM.loadOne(i)
|
||||
end
|
||||
end
|
||||
function BGM.play(s)
|
||||
if SETTING.bgm==0 then
|
||||
BGM.nowPlay=s
|
||||
BGM.playing=BGM.list[s]
|
||||
return
|
||||
end
|
||||
if s and BGM.list[s]and BGM.nowPlay~=s then
|
||||
if BGM.nowPlay then TASK.new(fadeOut,BGM.playing)end
|
||||
TASK.removeTask_iterate(removeCurFadeOut,fadeOut,BGM.list[s])
|
||||
TASK.removeTask_code(fadeIn)
|
||||
|
||||
TASK.new(fadeIn,BGM.list[s])
|
||||
BGM.nowPlay=s
|
||||
BGM.playing=BGM.list[s]
|
||||
BGM.playing:play()
|
||||
end
|
||||
function BGM.getList()return nameList end
|
||||
function BGM.getCount()return #nameList end
|
||||
local function _addFile(name,path)
|
||||
if not SourceObjList[name]then
|
||||
table.insert(nameList,name)
|
||||
SourceObjList[name]={path=path,source=false}
|
||||
end
|
||||
end
|
||||
function BGM.freshVolume()
|
||||
if BGM.playing then
|
||||
local v=SETTING.bgm
|
||||
if v>0 then
|
||||
BGM.playing:setVolume(v)
|
||||
BGM.playing:play()
|
||||
elseif BGM.nowPlay then
|
||||
BGM.playing:pause()
|
||||
end
|
||||
end
|
||||
function BGM.load(name,path)
|
||||
if type(name)=='table'then
|
||||
for k,v in next,name do
|
||||
_addFile(k,v)
|
||||
end
|
||||
else
|
||||
_addFile(name,path)
|
||||
end
|
||||
table.sort(nameList)
|
||||
LOG(BGM.getCount().." BGM files added")
|
||||
end
|
||||
function BGM.stop()
|
||||
TASK.removeTask_code(fadeIn)
|
||||
if BGM.nowPlay then TASK.new(fadeOut,BGM.playing)end
|
||||
BGM.nowPlay,BGM.playing=nil
|
||||
|
||||
local function _tryReleaseSources()
|
||||
local n=#lastLoaded
|
||||
while #lastLoaded>maxLoadedCount do
|
||||
local name=lastLoaded[n]
|
||||
if SourceObjList[name].source:isPlaying()then
|
||||
n=n-1
|
||||
if n<=0 then return end
|
||||
else
|
||||
SourceObjList[name].source=SourceObjList[name].source:release()and nil
|
||||
table.remove(lastLoaded,n)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
return BGM
|
||||
function BGM.setDefault(bgm)
|
||||
BGM.default=bgm
|
||||
end
|
||||
function BGM.setMaxSources(count)
|
||||
maxLoadedCount=count
|
||||
_tryReleaseSources()
|
||||
end
|
||||
function BGM.setChange(func)
|
||||
BGM.onChange=func
|
||||
end
|
||||
function BGM.setVol(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||
volume=v
|
||||
if BGM.playing then
|
||||
if volume>0 then
|
||||
BGM.playing:setVolume(volume)
|
||||
BGM.playing:play()
|
||||
elseif BGM.nowPlay then
|
||||
BGM.playing:pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function task_fadeOut(src)
|
||||
while true do
|
||||
coroutine.yield()
|
||||
local v=src:getVolume()-.025*volume
|
||||
src:setVolume(v>0 and v or 0)
|
||||
if v<=0 then
|
||||
src:pause()
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
local function task_fadeIn(src)
|
||||
while true do
|
||||
coroutine.yield()
|
||||
local v=volume
|
||||
v=math.min(v,src:getVolume()+.025*v)
|
||||
src:setVolume(v)
|
||||
if v>=volume then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
local function check_curFadeOut(task,code,src)
|
||||
return task.code==code and task.args[1]==src
|
||||
end
|
||||
local function _tryLoad(name)
|
||||
if SourceObjList[name]then
|
||||
if SourceObjList[name].source then
|
||||
return true
|
||||
elseif love.filesystem.getInfo(SourceObjList[name].path)then
|
||||
SourceObjList[name].source=love.audio.newSource(SourceObjList[name].path,'stream')
|
||||
SourceObjList[name].source:setVolume(0)
|
||||
table.insert(lastLoaded,1,name)
|
||||
_tryReleaseSources()
|
||||
return true
|
||||
else
|
||||
LOG("No BGM: "..SourceObjList[name],5)
|
||||
end
|
||||
elseif name then
|
||||
LOG("No BGM: "..name,5)
|
||||
end
|
||||
end
|
||||
function BGM.play(name,args)
|
||||
name=name or BGM.default
|
||||
args=args or""
|
||||
if not _tryLoad(name)or args:sArg('-preLoad')then return end
|
||||
if volume==0 then
|
||||
BGM.nowPlay=name
|
||||
BGM.playing=SourceObjList[name].source
|
||||
return true
|
||||
end
|
||||
if name and SourceObjList[name].source then
|
||||
if BGM.nowPlay~=name then
|
||||
if BGM.nowPlay then
|
||||
if not args:sArg('-sdout')then
|
||||
TASK.new(task_fadeOut,BGM.playing)
|
||||
else
|
||||
BGM.playing:pause()
|
||||
end
|
||||
end
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[name].source)
|
||||
TASK.removeTask_code(task_fadeIn)
|
||||
|
||||
BGM.nowPlay=name
|
||||
BGM.playing=SourceObjList[name].source
|
||||
if not args:sArg('-sdin')then
|
||||
BGM.playing:setVolume(0)
|
||||
TASK.new(task_fadeIn,BGM.playing)
|
||||
else
|
||||
BGM.playing:setVolume(volume)
|
||||
BGM.playing:play()
|
||||
end
|
||||
SourceObjList[name].source:setLooping(not args:sArg('-noloop'))
|
||||
BGM.lastPlayed=BGM.nowPlay
|
||||
BGM.playing:seek(0)
|
||||
BGM.playing:play()
|
||||
BGM.onChange(name)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
function BGM.seek(t)
|
||||
if BGM.playing then
|
||||
BGM.playing:seek(t)
|
||||
end
|
||||
end
|
||||
function BGM.isPlaying()
|
||||
return BGM.playing and BGM.playing:isPlaying()
|
||||
end
|
||||
function BGM.continue()
|
||||
if BGM.lastPlayed then
|
||||
BGM.nowPlay,BGM.playing=BGM.lastPlayed,SourceObjList[BGM.lastPlayed].source
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[BGM.nowPlay].source)
|
||||
TASK.removeTask_code(task_fadeIn)
|
||||
TASK.new(task_fadeIn,BGM.playing)
|
||||
BGM.playing:play()
|
||||
end
|
||||
end
|
||||
function BGM.stop(args)
|
||||
args=args or""
|
||||
TASK.removeTask_code(task_fadeIn)
|
||||
if not args:sArg('-s')then
|
||||
if BGM.nowPlay then
|
||||
TASK.new(task_fadeOut,BGM.playing)
|
||||
end
|
||||
elseif BGM.playing then
|
||||
BGM.playing:pause()
|
||||
end
|
||||
BGM.nowPlay,BGM.playing=nil
|
||||
end
|
||||
return BGM
|
||||
|
||||
@@ -1,93 +1,148 @@
|
||||
local abs=math.abs
|
||||
local function hsv(h,s,v,a)--Color type, Color amount, Light
|
||||
if s<=0 then return v,v,v,a end
|
||||
h=h*6
|
||||
local c=v*s
|
||||
local x=abs((h-1)%2-1)*c
|
||||
if h<1 then return v,x+v-c,v-c,a
|
||||
elseif h<2 then return x+v-c,v,v-c,a
|
||||
elseif h<3 then return v-c,v,x+v-c,a
|
||||
elseif h<4 then return v-c,x+v-c,v,a
|
||||
elseif h<5 then return x+v-c,v-c,v,a
|
||||
else return v,v-c,x+v-c,a
|
||||
end
|
||||
end
|
||||
|
||||
local COLOR={
|
||||
red= {1.0, 0.0, 0.0},
|
||||
fire= {1.0, 0.4, 0.0},
|
||||
orange= {1.0, 0.6, 0.0},
|
||||
yellow= {1.0, 1.0, 0.0},
|
||||
lame= {0.7, 1.0, 0.0},
|
||||
grass= {0.5, 1.0, 0.0},
|
||||
green= {0.0, 1.0, 0.0},
|
||||
water= {0.0, 1.0, 0.6},
|
||||
cyan= {0.0, 1.0, 1.0},
|
||||
sky= {0.0, 0.7, 1.0},
|
||||
sea= {0.0, 0.4, 1.0},
|
||||
blue= {0.2, 0.2, 1.0},
|
||||
purple= {0.4, 0.0, 1.0},
|
||||
grape= {0.7, 0.0, 1.0},
|
||||
magenta= {1.0, 0.0, 1.0},
|
||||
pink= {1.0, 0.0, 0.5},
|
||||
hsv=hsv,
|
||||
|
||||
lRed= {1.0, 0.5, 0.5},
|
||||
lFire= {1.0, 0.7, 0.5},
|
||||
lOrange= {1.0, 0.8, 0.3},
|
||||
lYellow= {1.0, 1.0, 0.5},
|
||||
lLame= {0.8, 1.0, 0.4},
|
||||
lGrass= {0.6, 1.0, 0.4},
|
||||
lGreen= {0.5, 1.0, 0.5},
|
||||
lWater= {0.4, 1.0, 0.7},
|
||||
lCyan= {0.5, 1.0, 1.0},
|
||||
lSky= {0.5, 0.8, 1.0},
|
||||
lSea= {0.4, 0.7, 1.0},
|
||||
lBlue= {0.7, 0.7, 1.0},
|
||||
lPurple= {0.7, 0.4, 1.0},
|
||||
lGrape= {0.8, 0.4, 1.0},
|
||||
lMagenta= {1.0, 0.5, 1.0},
|
||||
lPink= {1.0, 0.4, 0.7},
|
||||
red= {hsv(0.00, 0.89, 0.91)},
|
||||
fire= {hsv(0.04, 0.93, 0.94)},
|
||||
orange= {hsv(0.09, 0.99, 0.96)},
|
||||
yellow= {hsv(0.15, 0.82, 0.90)},
|
||||
lime= {hsv(0.20, 0.89, 0.88)},
|
||||
jade= {hsv(0.25, 1.00, 0.82)},
|
||||
green= {hsv(0.33, 1.00, 0.81)},
|
||||
aqua= {hsv(0.47, 1.00, 0.76)},
|
||||
cyan= {hsv(0.53, 1.00, 0.88)},
|
||||
navy= {hsv(0.56, 1.00, 1.00)},
|
||||
sea= {hsv(0.61, 1.00, 1.00)},
|
||||
blue= {hsv(0.64, 1.00, 0.95)},
|
||||
violet= {hsv(0.74, 1.00, 0.91)},
|
||||
purple= {hsv(0.80, 1.00, 0.81)},
|
||||
magenta= {hsv(0.86, 1.00, 0.78)},
|
||||
wine= {hsv(0.92, 0.98, 0.91)},
|
||||
|
||||
dRed= {0.6, 0.0, 0.0},
|
||||
dFire= {0.6, 0.3, 0.0},
|
||||
dOrange= {0.6, 0.4, 0.0},
|
||||
dYellow= {0.6, 0.6, 0.0},
|
||||
dLame= {0.5, 0.6, 0.0},
|
||||
dGrass= {0.3, 0.6, 0.0},
|
||||
dGreen= {0.0, 0.6, 0.0},
|
||||
dWater= {0.0, 0.6, 0.4},
|
||||
dCyan= {0.0, 0.6, 0.6},
|
||||
dSky= {0.0, 0.4, 0.6},
|
||||
dSea= {0.0, 0.2, 0.6},
|
||||
dBlue= {0.1, 0.1, 0.6},
|
||||
dPurple= {0.2, 0.0, 0.6},
|
||||
dGrape= {0.4, 0.0, 0.6},
|
||||
dMagenta= {0.6, 0.0, 0.6},
|
||||
dPink= {0.6, 0.0, 0.3},
|
||||
lRed= {hsv(0.00, 0.38, 0.93)},
|
||||
lFire= {hsv(0.04, 0.45, 0.91)},
|
||||
lOrange= {hsv(0.10, 0.53, 0.92)},
|
||||
lYellow= {hsv(0.14, 0.61, 0.95)},
|
||||
lLime= {hsv(0.20, 0.66, 0.92)},
|
||||
lJade= {hsv(0.26, 0.56, 0.90)},
|
||||
lGreen= {hsv(0.34, 0.49, 0.89)},
|
||||
lAqua= {hsv(0.47, 0.59, 0.86)},
|
||||
lCyan= {hsv(0.51, 0.77, 0.88)},
|
||||
lNavy= {hsv(0.54, 0.80, 0.95)},
|
||||
lSea= {hsv(0.57, 0.72, 0.97)},
|
||||
lBlue= {hsv(0.64, 0.44, 0.96)},
|
||||
lViolet= {hsv(0.72, 0.47, 0.95)},
|
||||
lPurple= {hsv(0.80, 0.62, 0.89)},
|
||||
lMagenta= {hsv(0.86, 0.61, 0.89)},
|
||||
lWine= {hsv(0.93, 0.57, 0.92)},
|
||||
|
||||
black= {0.0, 0.0, 0.0},
|
||||
dGrey= {0.3, 0.3, 0.3},
|
||||
grey= {0.6, 0.6, 0.6},
|
||||
lGrey= {0.8, 0.8, 0.8},
|
||||
white= {1.0, 1.0, 1.0},
|
||||
dRed= {hsv(0.00, 0.80, 0.48)},
|
||||
dFire= {hsv(0.04, 0.80, 0.34)},
|
||||
dOrange= {hsv(0.07, 0.80, 0.39)},
|
||||
dYellow= {hsv(0.12, 0.80, 0.37)},
|
||||
dLime= {hsv(0.20, 0.80, 0.26)},
|
||||
dJade= {hsv(0.29, 0.80, 0.27)},
|
||||
dGreen= {hsv(0.33, 0.80, 0.26)},
|
||||
dAqua= {hsv(0.46, 0.80, 0.24)},
|
||||
dCyan= {hsv(0.50, 0.80, 0.30)},
|
||||
dNavy= {hsv(0.58, 0.80, 0.42)},
|
||||
dSea= {hsv(0.64, 0.80, 0.40)},
|
||||
dBlue= {hsv(0.67, 0.80, 0.34)},
|
||||
dViolet= {hsv(0.71, 0.80, 0.35)},
|
||||
dPurple= {hsv(0.76, 0.80, 0.32)},
|
||||
dMagenta= {hsv(0.87, 0.80, 0.28)},
|
||||
dWine= {hsv(0.92, 0.80, 0.28)},
|
||||
|
||||
black= {hsv(0.04, 0.04, 0.14)},
|
||||
dGray= {hsv(0.02, 0.05, 0.44)},
|
||||
gray= {hsv(0.02, 0.05, 0.65)},
|
||||
lGray= {hsv(0.02, 0.06, 0.86)},
|
||||
white= {hsv(0.01, 0.02, 0.99)},
|
||||
|
||||
xGray= {hsv(0.00, 0.00, 0.35,.8)},
|
||||
lxGray= {hsv(0.00, 0.00, 0.62,.8)},
|
||||
dxGray= {hsv(0.00, 0.00, 0.16,.8)},
|
||||
}
|
||||
local map={
|
||||
R="red", G="green", B="blue", C="cyan", Y="yellow", M="magenta",
|
||||
lR="lRed", lG="lGreen",lB="lBlue", lC="lCyan", lY="lYellow", lM="lMagenta",
|
||||
dR="dRed", dG="dGreen",dB="dBlue", dC="dCyan", dY="dYellow", dM="dMagenta",
|
||||
W="white",
|
||||
}for k,v in next,map do COLOR[k]=COLOR[v]end
|
||||
for k,v in next,{
|
||||
R='red', F='fire', O='orange', Y='yellow', L='lime', J='jade', G='green', A='aqua', C='cyan', N='navy', S='sea', B='blue', V='violet', P='purple', M='magenta', W='wine',
|
||||
lR='lRed',lF='lFire',lO='lOrange',lY='lYellow',lL='lLime',lJ='lJade',lG='lGreen',lA='lAqua',lC='lCyan',lN='lNavy',lS='lSea',lB='lBlue',lV='lViolet',lP='lPurple',lM='lMagenta',lW='lWine',
|
||||
dR='dRed',dF='dFire',dO='dOrange',dY='dYellow',dL='dLime',dJ='dJade',dG='dGreen',dA='dAqua',dC='dCyan',dN='dNavy',dS='dSea',dB='dBlue',dV='dViolet',dP='dPurple',dM='dMagenta',dW='dWine',
|
||||
D='black',dH='dGray',H='gray',lH='lGray',Z='white',
|
||||
X='xGray',lX='lxGray',dX='dxGray',
|
||||
--Remain letter: EIKQTUX
|
||||
}do
|
||||
COLOR[k]=COLOR[v]
|
||||
end
|
||||
setmetatable(COLOR,{__index=function(_,k)
|
||||
error("No color: "..tostring(k))
|
||||
end})
|
||||
|
||||
local list_norm={"red","fire","orange","yellow","lame","grass","green","water","cyan","sky","sea","blue","purple","grape","magenta","pink"}
|
||||
local len_list_norm=#list_norm
|
||||
local rnd=math.random
|
||||
function COLOR.random_norm()
|
||||
return COLOR[list_norm[rnd(len_list_norm)]]
|
||||
|
||||
do--Random generators
|
||||
local rnd=math.random
|
||||
local list_norm={'red','fire','orange','yellow','lime','jade','green','aqua','cyan','navy','sea','blue','violet','purple','magenta','wine'}
|
||||
local len_list_norm=#list_norm
|
||||
function COLOR.random_norm()
|
||||
return COLOR[list_norm[rnd(len_list_norm)]]
|
||||
end
|
||||
|
||||
local list_bright={'lRed','lFire','lOrange','lYellow','lLime','lJade','lGreen','lAqua','lCyan','lNavy','lSea','lBlue','lViolet','lPurple','lMagenta','lWine'}
|
||||
local len_list_bright=#list_bright
|
||||
function COLOR.random_bright()
|
||||
return COLOR[list_bright[rnd(len_list_bright)]]
|
||||
end
|
||||
|
||||
local list_dark={'dRed','dFire','dOrange','dYellow','dLime','dJade','dGreen','dAqua','dCyan','dNavy','dSea','dBlue','dViolet','dPurple','dMagenta','dWine'}
|
||||
local len_list_dark=#list_dark
|
||||
function COLOR.random_dark()
|
||||
return COLOR[list_dark[rnd(len_list_dark)]]
|
||||
end
|
||||
end
|
||||
|
||||
local list_bright={"lRed","lFire","lOrange","lYellow","lLame","lGrass","lGreen","lWater","lCyan","lSky","lSea","lBlue","lPurple","lGrape","lMagenta","lPink"}
|
||||
local len_list_bright=#list_bright
|
||||
function COLOR.random_bright()
|
||||
return COLOR[list_bright[rnd(len_list_bright)]]
|
||||
do--Rainbow generators
|
||||
local sin=math.sin
|
||||
function COLOR.rainbow(phase,a)
|
||||
return
|
||||
sin(phase)*.4+.6,
|
||||
sin(phase+2.0944)*.4+.6,
|
||||
sin(phase-2.0944)*.4+.6,
|
||||
a
|
||||
end
|
||||
function COLOR.rainbow_light(phase,a)
|
||||
return
|
||||
sin(phase)*.2+.7,
|
||||
sin(phase+2.0944)*.2+.7,
|
||||
sin(phase-2.0944)*.2+.7,
|
||||
a
|
||||
end
|
||||
function COLOR.rainbow_dark(phase,a)
|
||||
return
|
||||
sin(phase)*.2+.4,
|
||||
sin(phase+2.0944)*.2+.4,
|
||||
sin(phase-2.0944)*.2+.4,
|
||||
a
|
||||
end
|
||||
function COLOR.rainbow_gray(phase,a)
|
||||
return
|
||||
sin(phase)*.16+.5,
|
||||
sin(phase+2.0944)*.16+.5,
|
||||
sin(phase-2.0944)*.16+.5,
|
||||
a
|
||||
end
|
||||
end
|
||||
|
||||
local list_dark={"dRed","dFire","dOrange","dYellow","dLame","dGrass","dGreen","dWater","dCyan","dSky","dSea","dBlue","dPurple","dGrape","dMagenta","dPink"}
|
||||
local len_list_dark=#list_dark
|
||||
function COLOR.random_bright()
|
||||
return COLOR[list_dark[rnd(len_list_dark)]]
|
||||
end
|
||||
|
||||
local sin=math.sin
|
||||
function COLOR.rainbow(phase)
|
||||
return
|
||||
sin(phase)*.4+.6,
|
||||
sin(phase+2.0944)*.4+.6,
|
||||
sin(phase-2.0944)*.4+.6
|
||||
end
|
||||
|
||||
return COLOR
|
||||
return COLOR
|
||||
|
||||
@@ -1,58 +1,105 @@
|
||||
local fs=love.filesystem
|
||||
local FILE={}
|
||||
function FILE.load(name)
|
||||
name=name..".dat"
|
||||
local F=fs.newFile(name)
|
||||
if F:open("r")then
|
||||
local s=F:read()
|
||||
F:close()
|
||||
if s:sub(1,6)=="return"then
|
||||
s=loadstring(s)
|
||||
if s then
|
||||
setfenv(s,{})
|
||||
return s()
|
||||
else
|
||||
LOG.print(name.." "..text.loadError,COLOR.red)
|
||||
return{}
|
||||
end
|
||||
else
|
||||
local res=json.decode(s)
|
||||
if res then
|
||||
return res
|
||||
else
|
||||
LOG.print(name.." "..text.loadError,COLOR.red)
|
||||
return{}
|
||||
end
|
||||
end
|
||||
end
|
||||
function FILE.load(name,args)
|
||||
if not args then args=''end
|
||||
if fs.getInfo(name)then
|
||||
local F=fs.newFile(name)
|
||||
assert(F:open'r','open error')
|
||||
local s=F:read()F:close()
|
||||
local mode=
|
||||
STRING.sArg(args,'-luaon')and'luaon'or
|
||||
STRING.sArg(args,'-lua')and'lua'or
|
||||
STRING.sArg(args,'-json')and'json'or
|
||||
STRING.sArg(args,'-string')and'string'or
|
||||
s:sub(1,6)=='return{'and'luaon'or
|
||||
(s:sub(1,1)=='['and s:sub(-1)==']'or s:sub(1,1)=='{'and s:sub(-1)=='}')and'json'or
|
||||
'string'
|
||||
if mode=='luaon'then
|
||||
local func,err_mes=loadstring(s)
|
||||
if func then
|
||||
setfenv(func,{})
|
||||
local res=func()
|
||||
return assert(res,'decode error')
|
||||
else
|
||||
error('decode error: '..err_mes)
|
||||
end
|
||||
elseif mode=='lua'then
|
||||
local func,err_mes=loadstring(s)
|
||||
if func then
|
||||
local res=func()
|
||||
return assert(res,'run error')
|
||||
else
|
||||
error('compile error: '..err_mes)
|
||||
end
|
||||
elseif mode=='json'then
|
||||
local res=JSON.decode(s)
|
||||
if res then
|
||||
return res
|
||||
end
|
||||
error('decode error')
|
||||
elseif mode=='string'then
|
||||
return s
|
||||
else
|
||||
error('unknown mode')
|
||||
end
|
||||
else
|
||||
error('no file')
|
||||
end
|
||||
end
|
||||
function FILE.save(data,name,mode)
|
||||
if not mode then mode=""end
|
||||
name=name..".dat"
|
||||
if mode:find("l")then
|
||||
data=dumpTable(data)
|
||||
if not data then
|
||||
LOG.print(name.." "..text.saveError.."dump error","error")
|
||||
return
|
||||
end
|
||||
else
|
||||
data=json.encode(data)
|
||||
if not data then
|
||||
LOG.print(name.." "..text.saveError.."json error","error")
|
||||
return
|
||||
end
|
||||
end
|
||||
function FILE.save(data,name,args)
|
||||
if not args then args=''end
|
||||
if STRING.sArg(args,'-d')and fs.getInfo(name)then
|
||||
error('duplicate')
|
||||
end
|
||||
|
||||
local F=fs.newFile(name)
|
||||
F:open("w")
|
||||
local success,mes=F:write(data)
|
||||
F:flush()F:close()
|
||||
if success then
|
||||
if mode:find("q")then
|
||||
LOG.print(text.saveDone,COLOR.green)
|
||||
end
|
||||
else
|
||||
LOG.print(text.saveError..(mes or"unknown error"),"error")
|
||||
end
|
||||
if type(data)=='table'then
|
||||
if STRING.sArg(args,'-luaon')then
|
||||
data=TABLE.dump(data)
|
||||
if not data then
|
||||
error('encode error')
|
||||
end
|
||||
else
|
||||
data=JSON.encode(data)
|
||||
if not data then
|
||||
error('encode error')
|
||||
end
|
||||
end
|
||||
else
|
||||
data=tostring(data)
|
||||
end
|
||||
|
||||
local F=fs.newFile(name)
|
||||
assert(F:open('w'),'open error')
|
||||
F:write(data)F:flush()F:close()
|
||||
end
|
||||
return FILE
|
||||
function FILE.clear(path)
|
||||
if fs.getRealDirectory(path)==SAVEDIR and fs.getInfo(path).type=='directory'then
|
||||
for _,name in next,fs.getDirectoryItems(path)do
|
||||
name=path..'/'..name
|
||||
if fs.getRealDirectory(name)==SAVEDIR then
|
||||
local t=fs.getInfo(name).type
|
||||
if t=='file'then
|
||||
fs.remove(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function FILE.clear_s(path)
|
||||
if path==''or(fs.getRealDirectory(path)==SAVEDIR and fs.getInfo(path).type=='directory')then
|
||||
for _,name in next,fs.getDirectoryItems(path)do
|
||||
name=path..'/'..name
|
||||
if fs.getRealDirectory(name)==SAVEDIR then
|
||||
local t=fs.getInfo(name).type
|
||||
if t=='file'then
|
||||
fs.remove(name)
|
||||
elseif t=='directory'then
|
||||
FILE.clear_s(name)
|
||||
fs.remove(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
fs.remove(path)
|
||||
end
|
||||
end
|
||||
return FILE
|
||||
|
||||
60
Zframework/font.lua
Normal file
60
Zframework/font.lua
Normal file
@@ -0,0 +1,60 @@
|
||||
local gc=love.graphics
|
||||
local set=gc.setFont
|
||||
local fontFiles,fontCache={},{}
|
||||
local defaultFont,defaultFallBack
|
||||
local curFont=false--Current using font object
|
||||
|
||||
local FONT={}
|
||||
function FONT.setDefault(name)defaultFont=name end
|
||||
function FONT.setFallback(name)defaultFallBack=name end
|
||||
function FONT.rawget(s)
|
||||
if not fontCache[s]then
|
||||
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
|
||||
end
|
||||
return fontCache[s]
|
||||
end
|
||||
function FONT.rawset(s)
|
||||
set(fontCache[s]or FONT.rawget(s))
|
||||
end
|
||||
function FONT.load(fonts)
|
||||
for name,path in next,fonts do
|
||||
assert(love.filesystem.getInfo(path),STRING.repD("Font file $1($2) not exist!",name,path))
|
||||
fontFiles[name]=love.filesystem.newFile(path)
|
||||
fontCache[name]={}
|
||||
end
|
||||
FONT.reset()
|
||||
end
|
||||
function FONT.get(size,name)
|
||||
if not name then name=defaultFont end
|
||||
local f=fontCache[name][size]
|
||||
if not f then
|
||||
f=gc.setNewFont(fontFiles[name],size,'light',gc.getDPIScale()*SCR.k*2)
|
||||
if defaultFallBack and name~=defaultFallBack then
|
||||
f:setFallbacks(FONT.get(size,defaultFallBack))
|
||||
end
|
||||
fontCache[name][size]=f
|
||||
end
|
||||
return f
|
||||
end
|
||||
function FONT.set(size,name)
|
||||
if not name then name=defaultFont end
|
||||
|
||||
local f=fontCache[name][size]
|
||||
if f~=curFont then
|
||||
curFont=f or FONT.get(size,name)
|
||||
set(curFont)
|
||||
end
|
||||
end
|
||||
function FONT.reset()
|
||||
for name,cache in next,fontCache do
|
||||
if type(cache)=='table'then
|
||||
for size in next,cache do
|
||||
cache[size]=FONT.get(size,name)
|
||||
end
|
||||
else
|
||||
fontCache[name]=FONT.rawget(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return FONT
|
||||
164
Zframework/gcExtend.lua
Normal file
164
Zframework/gcExtend.lua
Normal file
@@ -0,0 +1,164 @@
|
||||
local gc=love.graphics
|
||||
local setColor,printf,draw=gc.setColor,gc.printf,gc.draw
|
||||
local GC={}
|
||||
function GC.mStr(obj,x,y)printf(obj,x-626,y,1252,'center')end--Printf a string with 'center'
|
||||
function GC.simpX(obj,x,y)draw(obj,x-obj:getWidth()*.5,y)end--Simply draw an obj with x=obj:getWidth()/2
|
||||
function GC.simpY(obj,x,y)draw(obj,x,y-obj:getHeight()*.5)end--Simply draw an obj with y=obj:getWidth()/2
|
||||
function GC.X(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,0)end--Draw an obj with x=obj:getWidth()/2
|
||||
function GC.Y(obj,x,y,a,k)draw(obj,x,y,a,k,nil,0,obj:getHeight()*.5)end--Draw an obj with y=obj:getWidth()/2
|
||||
function GC.draw(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,obj:getHeight()*.5)end--Draw an obj with both middle X & Y
|
||||
function GC.outDraw(obj,div,x,y,a,k)
|
||||
local w,h=obj:getWidth()*.5,obj:getHeight()*.5
|
||||
draw(obj,x-div,y-div,a,k,nil,w,h)
|
||||
draw(obj,x-div,y+div,a,k,nil,w,h)
|
||||
draw(obj,x+div,y-div,a,k,nil,w,h)
|
||||
draw(obj,x+div,y+div,a,k,nil,w,h)
|
||||
end
|
||||
function GC.shadedPrint(str,x,y,mode,d,clr1,clr2)
|
||||
local w=1280
|
||||
if mode=='center'then
|
||||
x=x-w*.5
|
||||
elseif mode=='right'then
|
||||
x=x-w
|
||||
end
|
||||
if not d then d=1 end
|
||||
setColor(clr1 or COLOR.D)
|
||||
printf(str,x-d,y-d,w,mode)
|
||||
printf(str,x-d,y+d,w,mode)
|
||||
printf(str,x+d,y-d,w,mode)
|
||||
printf(str,x+d,y+d,w,mode)
|
||||
setColor(clr2 or COLOR.Z)
|
||||
printf(str,x,y,w,mode)
|
||||
end
|
||||
function GC.regularPolygon(mode,x,y,R,segments,r,phase)
|
||||
local X,Y={},{}
|
||||
local ang=phase or 0
|
||||
local angStep=6.283185307179586/segments
|
||||
for i=1,segments do
|
||||
X[i]=x+R*math.cos(ang)
|
||||
Y[i]=y+R*math.sin(ang)
|
||||
ang=ang+angStep
|
||||
end
|
||||
X[segments+1]=x+R*math.cos(ang)
|
||||
Y[segments+1]=y+R*math.sin(ang)
|
||||
local halfAng=6.283185307179586/segments/2
|
||||
local erasedLen=r*math.tan(halfAng)
|
||||
if mode=='line'then
|
||||
erasedLen=erasedLen+1--Fix 1px cover
|
||||
for i=1,segments do
|
||||
--Line
|
||||
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
|
||||
local dir=math.atan2(y2-y1,x2-x1)
|
||||
gc.line(x1+erasedLen*math.cos(dir),y1+erasedLen*math.sin(dir),x2-erasedLen*math.cos(dir),y2-erasedLen*math.sin(dir))
|
||||
|
||||
--Arc
|
||||
ang=ang+angStep
|
||||
local R2=R-r/math.cos(halfAng)
|
||||
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
|
||||
gc.arc('line','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
|
||||
end
|
||||
elseif mode=='fill'then
|
||||
local L={}
|
||||
for i=1,segments do
|
||||
--Line
|
||||
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
|
||||
local dir=math.atan2(y2-y1,x2-x1)
|
||||
table.insert(L,x1+erasedLen*math.cos(dir))
|
||||
table.insert(L,y1+erasedLen*math.sin(dir))
|
||||
table.insert(L,x2-erasedLen*math.cos(dir))
|
||||
table.insert(L,y2-erasedLen*math.sin(dir))
|
||||
|
||||
--Arc
|
||||
ang=ang+angStep
|
||||
local R2=R-r/math.cos(halfAng)
|
||||
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
|
||||
gc.arc('fill','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
|
||||
end
|
||||
gc.polygon('fill',L)
|
||||
else
|
||||
error("Draw mode should be 'line' or 'fill'")
|
||||
end
|
||||
end
|
||||
do--function GC.DO(L)
|
||||
local cmds={
|
||||
origin="origin",
|
||||
move="translate",
|
||||
scale="scale",
|
||||
rotate="rotate",
|
||||
shear="shear",
|
||||
clear="clear",
|
||||
|
||||
setCL="setColor",
|
||||
setCM="setColorMask",
|
||||
setLW="setLineWidth",
|
||||
setLS="setLineStyle",
|
||||
setLJ="setLineJoin",
|
||||
|
||||
print="print",
|
||||
rawFT=function(...)FONT.rawset(...)end,
|
||||
setFT=function(...)FONT.set(...)end,
|
||||
mText=GC.mStr,
|
||||
mDraw=GC.draw,
|
||||
mDrawX=GC.X,
|
||||
mDrawY=GC.Y,
|
||||
mOutDraw=GC.outDraw,
|
||||
|
||||
draw="draw",
|
||||
line="line",
|
||||
fRect=function(...)gc.rectangle('fill',...)end,
|
||||
dRect=function(...)gc.rectangle('line',...)end,
|
||||
fCirc=function(...)gc.circle('fill',...)end,
|
||||
dCirc=function(...)gc.circle('line',...)end,
|
||||
fElps=function(...)gc.ellipse('fill',...)end,
|
||||
dElps=function(...)gc.ellipse('line',...)end,
|
||||
fPoly=function(...)gc.polygon('fill',...)end,
|
||||
dPoly=function(...)gc.polygon('line',...)end,
|
||||
|
||||
dPie=function(...)gc.arc('line',...)end,
|
||||
dArc=function(...)gc.arc('line','open',...)end,
|
||||
dBow=function(...)gc.arc('line','closed',...)end,
|
||||
fPie=function(...)gc.arc('fill',...)end,
|
||||
fArc=function(...)gc.arc('fill','open',...)end,
|
||||
fBow=function(...)gc.arc('fill','closed',...)end,
|
||||
|
||||
fRPol=function(...)GC.regularPolygon('fill',...)end,
|
||||
dRPol=function(...)GC.regularPolygon('line',...)end,
|
||||
}
|
||||
local sizeLimit=gc.getSystemLimits().texturesize
|
||||
function GC.DO(L)
|
||||
gc.push()
|
||||
::REPEAT_tryAgain::
|
||||
local success,canvas=pcall(gc.newCanvas,math.min(L[1],sizeLimit),math.min(L[2],sizeLimit))
|
||||
if not success then
|
||||
sizeLimit=math.floor(sizeLimit*.8)
|
||||
goto REPEAT_tryAgain
|
||||
end
|
||||
gc.setCanvas(canvas)
|
||||
gc.origin()
|
||||
gc.clear(1,1,1,0)
|
||||
gc.setColor(1,1,1)
|
||||
gc.setLineWidth(1)
|
||||
for i=3,#L do
|
||||
local cmd=L[i][1]
|
||||
if type(cmd)=='boolean'and cmd then
|
||||
table.remove(L[i],1)
|
||||
cmd=L[i][1]
|
||||
end
|
||||
if type(cmd)=='string'then
|
||||
local func=cmds[cmd]
|
||||
if type(func)=='string'then
|
||||
func=gc[func]
|
||||
end
|
||||
if func then
|
||||
func(unpack(L[i],2))
|
||||
else
|
||||
error("No gc command: "..cmd)
|
||||
end
|
||||
end
|
||||
end
|
||||
gc.setCanvas()
|
||||
gc.pop()
|
||||
return canvas
|
||||
end
|
||||
end
|
||||
return GC
|
||||
@@ -1,42 +1,25 @@
|
||||
local IMG={
|
||||
batteryImage="/mess/power.png",
|
||||
title="mess/title.png",
|
||||
title_color="mess/title_colored.png",
|
||||
dialCircle="mess/dialCircle.png",
|
||||
dialNeedle="mess/dialNeedle.png",
|
||||
lifeIcon="mess/life.png",
|
||||
badgeIcon="mess/badge.png",
|
||||
spinCenter="mess/spinCenter.png",
|
||||
ctrlSpeedLimit="mess/ctrlSpeedLimit.png",
|
||||
speedLimit="mess/speedLimit.png",
|
||||
pay1="mess/pay1.png",
|
||||
pay2="mess/pay2.png",
|
||||
local IMG={}
|
||||
function IMG.init(list)
|
||||
IMG.init=nil
|
||||
|
||||
miyaCH="miya/ch.png",
|
||||
miyaF1="miya/f1.png",
|
||||
miyaF2="miya/f2.png",
|
||||
miyaF3="miya/f3.png",
|
||||
miyaF4="miya/f4.png",
|
||||
setmetatable(IMG,{__index=function(self,name)
|
||||
if type(list[name])=='table'then
|
||||
self[name]={}
|
||||
for i=1,#list[name]do
|
||||
self[name][i]=love.graphics.newImage(list[name][i])
|
||||
end
|
||||
elseif type(list[name])=='string'then
|
||||
self[name]=love.graphics.newImage(list[name])
|
||||
else
|
||||
LOG("No IMG: "..name)
|
||||
self[name]=PAPER
|
||||
end
|
||||
return self[name]
|
||||
end})
|
||||
|
||||
electric="mess/electric.png",
|
||||
hbm="mess/hbm.png",
|
||||
}
|
||||
local list={}
|
||||
local count=0
|
||||
for k,_ in next,IMG do
|
||||
count=count+1
|
||||
list[count]=k
|
||||
function IMG.loadAll()
|
||||
for k in next,list do local _=IMG[k]end
|
||||
IMG.loadAll=nil
|
||||
end
|
||||
end
|
||||
function IMG.getCount()
|
||||
return count
|
||||
end
|
||||
function IMG.loadOne(_)
|
||||
local N=list[_]
|
||||
IMG[N]=love.graphics.newImage("media/image/"..IMG[N])
|
||||
end
|
||||
function IMG.loadAll()
|
||||
for i=1,count do
|
||||
IMG.loadOne(i)
|
||||
end
|
||||
end
|
||||
return IMG
|
||||
return IMG
|
||||
|
||||
1289
Zframework/init.lua
1289
Zframework/init.lua
File diff suppressed because it is too large
Load Diff
340
Zframework/json.lua
Normal file
340
Zframework/json.lua
Normal file
@@ -0,0 +1,340 @@
|
||||
-- json.lua
|
||||
|
||||
-- Copyright (c) 2020 rxi
|
||||
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
-- this software and associated documentation files (the "Software"), to deal in
|
||||
-- the Software without restriction, including without limitation the rights to
|
||||
-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
-- of the Software, and to permit persons to whom the Software is furnished to do
|
||||
-- so, subject to the following conditions:
|
||||
|
||||
-- The above copyright notice and this permission notice shall be included in all
|
||||
-- copies or substantial portions of the Software.
|
||||
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
-- SOFTWARE.
|
||||
|
||||
-- Editted by MrZ
|
||||
|
||||
local ins,char=table.insert,string.char
|
||||
local json = {}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Encode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local _encode
|
||||
|
||||
local escape_char_map = {
|
||||
["\\"] = "\\",
|
||||
["\""] = "\"",
|
||||
["\b"] = "b",
|
||||
["\f"] = "f",
|
||||
["\n"] = "n",
|
||||
["\r"] = "r",
|
||||
["\t"] = "t"
|
||||
}
|
||||
|
||||
local escape_char_map_inv = {["/"] = "/"}
|
||||
for k, v in pairs(escape_char_map) do escape_char_map_inv[v] = k end
|
||||
|
||||
local function escape_char(c)
|
||||
return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte()))
|
||||
end
|
||||
|
||||
local function encode_nil() return "null" end
|
||||
|
||||
local function encode_table(val, stack)
|
||||
local res = {}
|
||||
stack = stack or {}
|
||||
|
||||
-- Circular reference?
|
||||
if stack[val] then error("circular reference") end
|
||||
|
||||
stack[val] = true
|
||||
|
||||
if rawget(val, 1) ~= nil or next(val) == nil then
|
||||
-- Treat as array -- check keys are valid and it is not sparse
|
||||
local n = 0
|
||||
for k in pairs(val) do
|
||||
if type(k) ~= 'number' then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
n = n + 1
|
||||
end
|
||||
if n ~= #val then error("invalid table: sparse array") end
|
||||
-- Encode
|
||||
for _, v in ipairs(val) do ins(res, _encode(v, stack)) end
|
||||
stack[val] = nil
|
||||
return "[" .. table.concat(res, ",") .. "]"
|
||||
|
||||
else
|
||||
-- Treat as an object
|
||||
for k, v in pairs(val) do
|
||||
if type(k) ~= 'string' then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
ins(res, _encode(k, stack) .. ":" .. _encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "{" .. table.concat(res, ",") .. "}"
|
||||
end
|
||||
end
|
||||
|
||||
local function encode_string(val)
|
||||
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
|
||||
end
|
||||
|
||||
local function encode_number(val)
|
||||
-- Check for NaN, -inf and inf
|
||||
if val ~= val or val <= -math.huge or val >= math.huge then
|
||||
error("unexpected number value '" .. tostring(val) .. "'")
|
||||
end
|
||||
return string.format("%.14g", val)
|
||||
end
|
||||
|
||||
local type_func_map = {
|
||||
['nil'] = encode_nil,
|
||||
['table'] = encode_table,
|
||||
['string'] = encode_string,
|
||||
['number'] = encode_number,
|
||||
['boolean'] = tostring
|
||||
}
|
||||
|
||||
_encode = function(val, stack)
|
||||
local t = type(val)
|
||||
local f = type_func_map[t]
|
||||
if f then return f(val, stack) end
|
||||
error("unexpected type '" .. t .. "'")
|
||||
end
|
||||
|
||||
json.encode=_encode
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Decode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local parse
|
||||
|
||||
local function create_set(...)
|
||||
local res = {}
|
||||
for i = 1, select("#", ...) do res[select(i, ...)] = true end
|
||||
return res
|
||||
end
|
||||
|
||||
local space_chars = create_set(" ", "\t", "\r", "\n")
|
||||
local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
|
||||
local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
|
||||
local literals = create_set("true", "false", "null")
|
||||
|
||||
local literal_map = {["true"] = true, ["false"] = false, ["null"] = nil}
|
||||
|
||||
local function next_char(str, idx, set, negate)
|
||||
for i = idx, #str do if set[str:sub(i, i)] ~= negate then return i end end
|
||||
return #str + 1
|
||||
end
|
||||
|
||||
local function decode_error(str, idx, msg)
|
||||
local line_count = 1
|
||||
local col_count = 1
|
||||
for i = 1, idx - 1 do
|
||||
col_count = col_count + 1
|
||||
if str:sub(i, i) == "\n" then
|
||||
line_count = line_count + 1
|
||||
col_count = 1
|
||||
end
|
||||
end
|
||||
error(string.format("%s at line %d col %d", msg, line_count, col_count))
|
||||
end
|
||||
|
||||
local function codepoint_to_utf8(n)
|
||||
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
|
||||
local f = bit.rshift
|
||||
if n <= 0x7f then
|
||||
return char(n)
|
||||
elseif n <= 0x7ff then
|
||||
return char(f(n, 6) + 192, n % 64 + 128)
|
||||
elseif n <= 0xffff then
|
||||
return char(f(n, 12) + 224, f(n % 4096, 6) + 128, n % 64 + 128)
|
||||
elseif n <= 0x10ffff then
|
||||
return char(f(n, 18) + 240, f(n % 262144, 12) + 128, f(n % 4096, 6) + 128, n % 64 + 128)
|
||||
end
|
||||
error(string.format("invalid unicode codepoint '%x'", n))
|
||||
end
|
||||
|
||||
local function parse_unicode_escape(s)
|
||||
local n1 = tonumber(s:sub(1, 4), 16)
|
||||
local n2 = tonumber(s:sub(7, 10), 16)
|
||||
-- Surrogate pair?
|
||||
if n2 then
|
||||
return
|
||||
codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
|
||||
else
|
||||
return codepoint_to_utf8(n1)
|
||||
end
|
||||
end
|
||||
|
||||
local function parse_string(str, i)
|
||||
local res = ""
|
||||
local j = i + 1
|
||||
local k = j
|
||||
|
||||
while j <= #str do
|
||||
local x = str:byte(j)
|
||||
|
||||
if x < 32 then
|
||||
decode_error(str, j, "control character in string")
|
||||
|
||||
elseif x == 92 then -- `\`: Escape
|
||||
res = res .. str:sub(k, j - 1)
|
||||
j = j + 1
|
||||
local c = str:sub(j, j)
|
||||
if c == "u" then
|
||||
local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) or
|
||||
str:match("^%x%x%x%x", j + 1) or
|
||||
decode_error(str, j - 1,
|
||||
"invalid unicode escape in string")
|
||||
res = res .. parse_unicode_escape(hex)
|
||||
j = j + #hex
|
||||
else
|
||||
if not escape_chars[c] then
|
||||
decode_error(str, j - 1,
|
||||
"invalid escape char '" .. c .. "' in string")
|
||||
end
|
||||
res = res .. escape_char_map_inv[c]
|
||||
end
|
||||
k = j + 1
|
||||
|
||||
elseif x == 34 then -- `"`: End of string
|
||||
res = res .. str:sub(k, j - 1)
|
||||
return res, j + 1
|
||||
end
|
||||
|
||||
j = j + 1
|
||||
end
|
||||
|
||||
decode_error(str, i, "expected closing quote for string")
|
||||
end
|
||||
|
||||
local function parse_number(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local s = str:sub(i, x - 1)
|
||||
local n = tonumber(s)
|
||||
if not n then decode_error(str, i, "invalid number '" .. s .. "'") end
|
||||
return n, x
|
||||
end
|
||||
|
||||
local function parse_literal(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local word = str:sub(i, x - 1)
|
||||
if not literals[word] then
|
||||
decode_error(str, i, "invalid literal '" .. word .. "'")
|
||||
end
|
||||
return literal_map[word], x
|
||||
end
|
||||
|
||||
local function parse_array(str, i)
|
||||
local res = {}
|
||||
local n = 1
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local x
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of array?
|
||||
if str:sub(i, i) == "]" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read token
|
||||
x, i = parse(str, i)
|
||||
res[n] = x
|
||||
n = n + 1
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "]" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
local function parse_object(str, i)
|
||||
local res = {}
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local key, val
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of object?
|
||||
if str:sub(i, i) == "}" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read key
|
||||
if str:sub(i, i) ~= '"' then
|
||||
decode_error(str, i, "expected string for key")
|
||||
end
|
||||
key, i = parse(str, i)
|
||||
-- Read ':' delimiter
|
||||
i = next_char(str, i, space_chars, true)
|
||||
if str:sub(i, i) ~= ":" then
|
||||
decode_error(str, i, "expected ':' after key")
|
||||
end
|
||||
i = next_char(str, i + 1, space_chars, true)
|
||||
-- Read value
|
||||
val, i = parse(str, i)
|
||||
-- Set
|
||||
res[key] = val
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "}" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
local char_func_map = {
|
||||
['"'] = parse_string,
|
||||
["0"] = parse_number,
|
||||
["1"] = parse_number,
|
||||
["2"] = parse_number,
|
||||
["3"] = parse_number,
|
||||
["4"] = parse_number,
|
||||
["5"] = parse_number,
|
||||
["6"] = parse_number,
|
||||
["7"] = parse_number,
|
||||
["8"] = parse_number,
|
||||
["9"] = parse_number,
|
||||
["-"] = parse_number,
|
||||
["t"] = parse_literal,
|
||||
["f"] = parse_literal,
|
||||
["n"] = parse_literal,
|
||||
["["] = parse_array,
|
||||
["{"] = parse_object
|
||||
}
|
||||
|
||||
function parse(str, idx)
|
||||
local chr = str:sub(idx, idx)
|
||||
local f = char_func_map[chr]
|
||||
if f then return f(str, idx) end
|
||||
decode_error(str, idx, "unexpected character '" .. chr .. "'")
|
||||
end
|
||||
|
||||
function json.decode(str)
|
||||
if type(str) ~= 'string' then
|
||||
error("expected argument of type string, got " .. type(str))
|
||||
end
|
||||
local res, idx = parse(str, next_char(str, 1, space_chars, true))
|
||||
idx = next_char(str, idx, space_chars, true)
|
||||
if idx <= #str then decode_error(str, idx, "trailing garbage") end
|
||||
return res
|
||||
end
|
||||
return json
|
||||
@@ -1,105 +1,57 @@
|
||||
local langList={
|
||||
require"parts/language/lang_zh",
|
||||
require"parts/language/lang_zh2",
|
||||
require"parts/language/lang_en",
|
||||
require"parts/language/lang_fr",
|
||||
require"parts/language/lang_sp",
|
||||
require"parts/language/lang_symbol",
|
||||
require"parts/language/lang_yygq",
|
||||
--Add new language file to LANG folder. Attention, new language won't show in-game when you add language
|
||||
}
|
||||
local publicText={
|
||||
block={
|
||||
"Z","S","J","L","T","O","I",
|
||||
"Z5","S5","Q","P","F","E",
|
||||
"T5","U","V","W","X",
|
||||
"J5","L5","R","Y","N","H","I5"
|
||||
},
|
||||
}
|
||||
local publicWidgetText={
|
||||
calculator={
|
||||
_1="1",_2="2",_3="3",
|
||||
_4="4",_5="5",_6="6",
|
||||
_7="7",_8="8",_9="9",
|
||||
_0="0",["."]=".",e="e",
|
||||
["+"]="+",["-"]="-",["*"]="*",["/"]="/",
|
||||
["<"]="<",["="]="=",
|
||||
play="-->",
|
||||
},
|
||||
staff={},
|
||||
history={
|
||||
prev="↑",
|
||||
next="↓",
|
||||
},
|
||||
lang={
|
||||
zh="中文",
|
||||
zh2="全中文",
|
||||
en="English",
|
||||
fr="Français",
|
||||
sp="Español",
|
||||
symbol="?????",
|
||||
yygq="就这?",
|
||||
},
|
||||
custom_field={
|
||||
b0="",b1="",b2="",b3="",b4="",b5="",b6="",b7="",
|
||||
b8="",b9="",b10="",b11="",b12="",b13="",b14="",b15="",b16="",
|
||||
b17="[ ]",b18="N",b19="B",b20="_",b21="_",b22="_",b23="_",b24="_",
|
||||
},
|
||||
mg_cubefield={},
|
||||
}
|
||||
local function langFallback(T0,T)
|
||||
for k,v in next,T0 do
|
||||
if type(v)=="table"and not v.refuseCopy then--refuseCopy: just copy pointer, not contents
|
||||
if not T[k]then T[k]={}end
|
||||
if type(T[k])=="table"then langFallback(v,T[k])end
|
||||
elseif not T[k]then
|
||||
T[k]=v
|
||||
end
|
||||
end
|
||||
end
|
||||
local tipMeta={__call=function(L)return L[math.random(#L)]end}
|
||||
for i=1,#langList do
|
||||
local L=langList[i]
|
||||
|
||||
--Set public text
|
||||
for key,list in next,publicText do
|
||||
L[key]=list
|
||||
end
|
||||
|
||||
--Set public widget text
|
||||
for key,list in next,publicWidgetText do
|
||||
local WT=L.WidgetText
|
||||
if not WT[key]then WT[key]={}end
|
||||
for k,v in next,list do
|
||||
WT[key][k]=v
|
||||
end
|
||||
end
|
||||
|
||||
--Fallback to other language, default zh
|
||||
if i>1 then
|
||||
langFallback(langList[L.fallback or 1],L)
|
||||
end
|
||||
|
||||
--Metatable:__call for table:getTip
|
||||
if type(L.getTip)=="table"then
|
||||
setmetatable(L.getTip,tipMeta)
|
||||
end
|
||||
|
||||
--set global name for all back button
|
||||
for _,v in next,L.WidgetText do
|
||||
v.back=L.back
|
||||
end
|
||||
end
|
||||
|
||||
local LANG={}
|
||||
function LANG.getLen()
|
||||
return #langList
|
||||
--ONLY FIRST CALL MAKE SENSE
|
||||
--Create LANG.get() and LANG.addScene()
|
||||
function LANG.init(defaultLang,langList,publicText,pretreatFunc)
|
||||
local function _langFallback(T0,T)
|
||||
for k,v in next,T0 do
|
||||
if type(v)=='table'and not v.refuseCopy then--refuseCopy: just copy pointer, not contents
|
||||
if not T[k]then T[k]={}end
|
||||
if type(T[k])=='table'then
|
||||
_langFallback(v,T[k])
|
||||
end
|
||||
elseif not T[k]then
|
||||
T[k]=v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Set public text
|
||||
if publicText then
|
||||
for _,L in next,langList do
|
||||
for key,list in next,publicText do L[key]=list end
|
||||
end
|
||||
end
|
||||
|
||||
--Fallback to default language
|
||||
for name,L in next,langList do
|
||||
if name~=defaultLang then
|
||||
_langFallback(langList[L.fallback or defaultLang],L)
|
||||
end
|
||||
end
|
||||
|
||||
--Custom pretreatment for each language
|
||||
if pretreatFunc then
|
||||
for _,L in next,langList do
|
||||
pretreatFunc(L)
|
||||
end
|
||||
end
|
||||
|
||||
function LANG.get(l)
|
||||
if not langList[l]then
|
||||
LOG("Wrong language: "..tostring(l))
|
||||
l=defaultLang
|
||||
end
|
||||
return langList[l]
|
||||
end
|
||||
|
||||
function LANG.addScene(name)
|
||||
for _,L in next,langList do
|
||||
if L.WidgetText and not L.WidgetText[name]then
|
||||
L.WidgetText[name]={}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function LANG.init()end
|
||||
end
|
||||
function LANG.set(l)
|
||||
text=langList[l]
|
||||
WIDGET.setLang(text.WidgetText)
|
||||
for _,s in next,drawableTextLoad do
|
||||
drawableText[s]:set(text[s])
|
||||
end
|
||||
end
|
||||
return LANG
|
||||
return LANG
|
||||
|
||||
@@ -1,89 +1,86 @@
|
||||
--LIGHT MODULE (Optimized by MrZ, Original on github/love2d community/simple-love-lights)
|
||||
--LIGHT MODULE (Optimized by MrZ, Original on github/LÖVE community/simple-love-lights)
|
||||
--Heavily based on mattdesl's libGDX implementation:
|
||||
--https://github.com/mattdesl/lwjgl-basics/wiki/2D-Pixel-Perfect-Shadows
|
||||
local gc=love.graphics
|
||||
local clear,translate=gc.clear,gc.translate
|
||||
local setCanvas,setShader=gc.setCanvas,gc.setShader
|
||||
local render=gc.draw
|
||||
local clear,gc_translate=gc.clear,gc.translate
|
||||
local gc_setCanvas,gc_setShader=gc.setCanvas,gc.setShader
|
||||
local gc_setColor,gc_draw=gc.setColor,gc.draw
|
||||
|
||||
local shadowMapShader=gc.newShader("Zframework/light/shadowMap.glsl")--Shader for caculating the 1D shadow map.
|
||||
local lightRenderShader=gc.newShader("Zframework/light/lightRender.glsl")--Shader for rendering blurred lights and shadows.
|
||||
local shadowMapShader=gc.newShader('Zframework/light/shadowMap.glsl')--Shader for caculating the 1D shadow map.
|
||||
local lightRenderShader=gc.newShader('Zframework/light/lightRender.glsl')--Shader for rendering blurred lights and shadows.
|
||||
local Lights={}--Lightsource objects
|
||||
local function move(L,x,y)
|
||||
L.x,L.y=x,y
|
||||
L.x,L.y=x,y
|
||||
end
|
||||
local function setPow(L,pow)
|
||||
L.size=pow
|
||||
L.size=pow
|
||||
end
|
||||
local function destroy(L)
|
||||
L.blackCanvas:release()
|
||||
L.shadowCanvas:release()
|
||||
L.renderCanvas:release()
|
||||
end
|
||||
local function draw(L)
|
||||
--Initialization
|
||||
local r,g,b,a=gc.getColor()
|
||||
setCanvas(L.blackCanvas)clear()
|
||||
setCanvas(L.shadowCanvas)clear()
|
||||
setCanvas(L.renderCanvas)clear()
|
||||
lightRenderShader:send("xresolution",L.size)
|
||||
shadowMapShader:send("yresolution",L.size)
|
||||
local function drawLight(L)
|
||||
local s=L.size
|
||||
|
||||
--Get up-left of light
|
||||
local X=L.x-L.size*.5
|
||||
local Y=L.y-L.size*.5
|
||||
--Initialization
|
||||
gc_setCanvas(L.blackCanvas)clear()
|
||||
gc_setCanvas(L.shadowCanvas)clear()
|
||||
gc_setCanvas(L.renderCanvas)clear()
|
||||
lightRenderShader:send('xresolution',s)
|
||||
shadowMapShader:send('yresolution',s)
|
||||
|
||||
--Render solid
|
||||
translate(-X,-Y)
|
||||
L.blackCanvas:renderTo(L.blackFn)
|
||||
translate(X,Y)
|
||||
--Get up-left of light
|
||||
local X=L.x-s*.5
|
||||
local Y=L.y-s*.5
|
||||
|
||||
--Render shade canvas by solid
|
||||
setShader(shadowMapShader)
|
||||
setCanvas(L.shadowCanvas)
|
||||
render(L.blackCanvas)
|
||||
--Render solid
|
||||
gc_translate(-X,-Y)
|
||||
L.blackCanvas:renderTo(L.blackFn)
|
||||
gc_translate(X,Y)
|
||||
|
||||
--Render light canvas by shade
|
||||
setShader(lightRenderShader)
|
||||
setCanvas(L.renderCanvas)
|
||||
render(L.shadowCanvas,0,0,0,1,L.size)
|
||||
--Render shade canvas by solid
|
||||
gc_setShader(shadowMapShader)
|
||||
gc_setCanvas(L.shadowCanvas)
|
||||
gc_draw(L.blackCanvas)
|
||||
|
||||
--Ready to final render
|
||||
setShader()setCanvas()gc.setBlendMode("add")
|
||||
--Render light canvas by shade
|
||||
gc_setShader(lightRenderShader)
|
||||
gc_setCanvas(L.renderCanvas)
|
||||
gc_draw(L.shadowCanvas,0,0,0,1,s)
|
||||
|
||||
--Render to screes
|
||||
gc.setColor(r,g,b,a)
|
||||
render(L.renderCanvas,X,Y+L.size,0,1,-1)
|
||||
--Ready to final render
|
||||
gc_setShader()gc_setCanvas()gc.setBlendMode('add')
|
||||
|
||||
--Reset
|
||||
gc.setBlendMode("alpha")
|
||||
--Render to screen
|
||||
gc_draw(L.renderCanvas,X,Y+s,0,1,-1)
|
||||
|
||||
--Reset
|
||||
gc.setBlendMode('alpha')
|
||||
end
|
||||
|
||||
local LIGHT={}
|
||||
function LIGHT.draw()
|
||||
for i=1,#Lights do
|
||||
draw(Lights[i])
|
||||
end
|
||||
gc_setColor(1,1,1)
|
||||
for i=1,#Lights do
|
||||
drawLight(Lights[i])
|
||||
end
|
||||
end
|
||||
function LIGHT.clear()
|
||||
for i=#Lights,1,-1 do
|
||||
Lights[i]:destroy()
|
||||
Lights[i]=nil
|
||||
end
|
||||
for i=1,#Lights do
|
||||
Lights[i].blackCanvas:release()
|
||||
Lights[i].shadowCanvas:release()
|
||||
Lights[i].renderCanvas:release()
|
||||
Lights[i]=nil
|
||||
end
|
||||
end
|
||||
function LIGHT.add(x,y,radius,solidFunc)
|
||||
local id=#Lights+1
|
||||
Lights[id]={
|
||||
id=id,
|
||||
x=x,y=y,size=radius,
|
||||
blackCanvas=gc.newCanvas(radius,radius),--Solid canvas
|
||||
shadowCanvas=gc.newCanvas(radius,1),--1D vis-depth canvas
|
||||
renderCanvas=gc.newCanvas(radius,radius),--Light canvas
|
||||
blackFn=solidFunc,--Solid draw funcion
|
||||
local id=#Lights+1
|
||||
Lights[id]={
|
||||
id=id,
|
||||
x=x,y=y,size=radius,
|
||||
blackCanvas=gc.newCanvas(radius,radius),--Solid canvas
|
||||
shadowCanvas=gc.newCanvas(radius,1),--1D vis-depth canvas
|
||||
renderCanvas=gc.newCanvas(radius,radius),--Light canvas
|
||||
blackFn=solidFunc,--Solid draw function
|
||||
|
||||
move=move,
|
||||
setPow=setPow,
|
||||
destroy=destroy,
|
||||
}
|
||||
move=move,
|
||||
setPow=setPow,
|
||||
}
|
||||
end
|
||||
return LIGHT
|
||||
return LIGHT
|
||||
|
||||
@@ -2,28 +2,28 @@
|
||||
extern float xresolution;
|
||||
// Sample from 1D vis-depth map
|
||||
float samp(vec2 coord,float r,Image u_texture){
|
||||
return step(r,Texel(u_texture,coord).r);
|
||||
return step(r,Texel(u_texture,coord).r);
|
||||
}
|
||||
vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){
|
||||
// Cartesian to polar, y of 1D sample is always 0
|
||||
vec2 norm=texture_coords.st*2.-1.;
|
||||
vec2 tc=vec2((atan(norm.y,norm.x)+PI)/(2.*PI),0.);
|
||||
float r=length(norm);
|
||||
vec4 effect(vec4 color,Image tex,vec2 tex_coords,vec2 screen_coords){
|
||||
// Cartesian to polar, y of 1D sample is always 0
|
||||
vec2 norm=tex_coords.st*2.-1.;
|
||||
vec2 tc=vec2((atan(norm.y,norm.x)+PI)/(2.*PI),0.);
|
||||
float r=length(norm);
|
||||
|
||||
// Enlarge blur parameter by distance, light scattering simulation
|
||||
float blur=(1./xresolution)*smoothstep(0.3,1.,r);
|
||||
// Enlarge blur parameter by distance, light scattering simulation
|
||||
float blur=(1./xresolution)*smoothstep(0.3,1.,r);
|
||||
|
||||
// Simple Gaussian blur
|
||||
float sum=// Brightness(0~1)
|
||||
samp(vec2(tc.x-3.*blur,tc.y),r,texture)*0.1
|
||||
+samp(vec2(tc.x-2.*blur,tc.y),r,texture)*0.13
|
||||
+samp(vec2(tc.x-1.*blur,tc.y),r,texture)*0.17
|
||||
// Simple Gaussian blur
|
||||
float sum=// Brightness(0~1)
|
||||
samp(vec2(tc.x-3.*blur,tc.y),r,tex)*0.1
|
||||
+samp(vec2(tc.x-2.*blur,tc.y),r,tex)*0.13
|
||||
+samp(vec2(tc.x-1.*blur,tc.y),r,tex)*0.17
|
||||
|
||||
+samp(tc,r,texture)*0.2// The center tex coord, which gives us hard shadows.
|
||||
+samp(vec2(tc.x+1.*blur,tc.y),r,texture)*0.17
|
||||
+samp(vec2(tc.x+2.*blur,tc.y),r,texture)*0.13
|
||||
+samp(vec2(tc.x+3.*blur,tc.y),r,texture)*0.1;
|
||||
+samp(tc,r,tex)*0.2// The center tex coord, which gives us hard shadows.
|
||||
+samp(vec2(tc.x+1.*blur,tc.y),r,tex)*0.17
|
||||
+samp(vec2(tc.x+2.*blur,tc.y),r,tex)*0.13
|
||||
+samp(vec2(tc.x+3.*blur,tc.y),r,tex)*0.1;
|
||||
|
||||
// Multiply the distance to get a soft fading
|
||||
return vec4(vec3(1.),sum*smoothstep(1.,0.,r));
|
||||
}
|
||||
// Multiply the distance to get a soft fading
|
||||
return vec4(vec3(1.),sum*smoothstep(1.,0.,r));
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#define PI 3.14
|
||||
extern float yresolution;
|
||||
vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){
|
||||
// Iterate through the occluder map's y-axis.
|
||||
for(float y=0.;y<yresolution;y++){
|
||||
// Cartesian to polar
|
||||
// y/yresolution=distance to light source(0~1)
|
||||
vec2 norm=vec2(texture_coords.s,y/yresolution)*2.-1.;
|
||||
float theta=PI*1.5+norm.x*PI;
|
||||
float r=(1.+norm.y)*0.5;
|
||||
vec4 effect(vec4 color,Image tex,vec2 tex_coords,vec2 screen_coords){
|
||||
// Iterate through the occluder map's y-axis.
|
||||
for(float y=0.;y<yresolution;y++){
|
||||
// Cartesian to polar
|
||||
// y/yresolution=distance to light source(0~1)
|
||||
vec2 norm=vec2(tex_coords.s,y/yresolution)*2.-1.;
|
||||
float theta=PI*1.5+norm.x*PI;
|
||||
float r=(1.+norm.y)*0.5;
|
||||
|
||||
//sample from solid
|
||||
if(
|
||||
Texel(texture,(
|
||||
vec2(-r*sin(theta),-r*cos(theta))*0.5+0.5// Coord of solid sampling
|
||||
)).a>0.1
|
||||
)return vec4(vec3(y/yresolution),1.);// Collision check, alpha>0.1 means transparent
|
||||
}
|
||||
return vec4(1.);// Return max distance 1
|
||||
}
|
||||
//sample from solid
|
||||
if(
|
||||
Texel(tex,(
|
||||
vec2(-r*sin(theta),-r*cos(theta))*0.5+0.5// Coord of solid sampling
|
||||
)).a>0.1
|
||||
)return vec4(vec3(y/yresolution),1.);// Collision check, alpha>0.1 means transparent
|
||||
}
|
||||
return vec4(1.);// Return max distance 1
|
||||
}
|
||||
|
||||
@@ -1,72 +1,20 @@
|
||||
local gc=love.graphics
|
||||
local int,min=math.floor,math.min
|
||||
local ins,rem=table.insert,table.remove
|
||||
local ins=table.insert
|
||||
|
||||
local debugMesList={}
|
||||
local debugMesHistory={
|
||||
"Version: "..VERSION_NAME,
|
||||
os.date("Launched at %Y/%m/%d %H:%M"),
|
||||
}
|
||||
local LOG={}
|
||||
function LOG.update()
|
||||
if debugMesList[1]then
|
||||
for i=#debugMesList,1,-1 do
|
||||
local M=debugMesList[i]
|
||||
if M.blink>0 then
|
||||
M.blink=M.blink-1
|
||||
else
|
||||
M.time=M.time-1
|
||||
if M.time==0 then
|
||||
rem(debugMesList,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local logs={os.date("Techmino logs %Y/%m/%d %A")}
|
||||
|
||||
local function log(message)
|
||||
ins(logs,os.date("[%H:%M:%S] ")..message)
|
||||
end
|
||||
function LOG.draw()
|
||||
if debugMesList[1]then
|
||||
gc.push("transform")
|
||||
local k=SCR.w/SCR.w0
|
||||
setFont(int(4*k)*5)
|
||||
for i=1,#debugMesList do
|
||||
local M=debugMesList[i]
|
||||
local t=M.time
|
||||
gc.setColor(M.r,M.g,M.b,M.blink>0 and int(M.blink/3)%2 or min(t/26,1))
|
||||
gc.print(M.text,10+(20-min(t,20))^1.5/4,25*i*k)
|
||||
end
|
||||
gc.pop()
|
||||
end
|
||||
|
||||
local LOG=setmetatable({logs=logs},{
|
||||
__call=function(_,message)
|
||||
print(message)
|
||||
log(message)
|
||||
end
|
||||
})
|
||||
|
||||
function LOG.read()
|
||||
return table.concat(logs,"\n")
|
||||
end
|
||||
function LOG.print(text,T,C)--text,type/time,color
|
||||
local time
|
||||
local his
|
||||
if T=="warn"then
|
||||
C=C or COLOR.yellow
|
||||
his=true
|
||||
time=180
|
||||
elseif T=="error"then
|
||||
C=C or COLOR.red
|
||||
his=true
|
||||
time=210
|
||||
elseif T=="message"then
|
||||
C=C or COLOR.sky
|
||||
his=true
|
||||
elseif type(T)=="number"then
|
||||
C=C or COLOR.white
|
||||
time=T
|
||||
elseif type(T)=="table"then
|
||||
C,T=T
|
||||
elseif not C then
|
||||
C=COLOR.white
|
||||
end
|
||||
if his then
|
||||
ins(debugMesHistory,SCN.cur..": "..tostring(text))
|
||||
end
|
||||
ins(debugMesList,{text=text,r=C[1],g=C[2],b=C[3],blink=30,time=time or 120})
|
||||
end
|
||||
function LOG.copy()
|
||||
local str=table.concat(debugMesHistory,"\n")
|
||||
love.system.setClipboardText(str)
|
||||
LOG.print("Log copied",COLOR.blue)
|
||||
end
|
||||
return LOG
|
||||
|
||||
return LOG
|
||||
|
||||
37
Zframework/mathExtend.lua
Normal file
37
Zframework/mathExtend.lua
Normal file
@@ -0,0 +1,37 @@
|
||||
local MATH={}for k,v in next,math do MATH[k]=v end
|
||||
|
||||
local rnd=math.random
|
||||
|
||||
MATH.tau=2*math.pi
|
||||
|
||||
function MATH.sign(a)
|
||||
return a>0 and 1 or a<0 and -1 or 0
|
||||
end
|
||||
|
||||
function MATH.roll(chance)
|
||||
return rnd()<(chance or .5)
|
||||
end
|
||||
|
||||
function MATH.coin(a,b)
|
||||
if rnd()<.5 then
|
||||
return a
|
||||
else
|
||||
return b
|
||||
end
|
||||
end
|
||||
|
||||
function MATH.interval(v,low,high)
|
||||
if v<=low then
|
||||
return low
|
||||
elseif v>=high then
|
||||
return high
|
||||
else
|
||||
return v
|
||||
end
|
||||
end
|
||||
|
||||
function MATH.expApproach(a,b,k)
|
||||
return b+(a-b)*2.718281828459045^-k
|
||||
end
|
||||
|
||||
return MATH
|
||||
148
Zframework/message.lua
Normal file
148
Zframework/message.lua
Normal file
@@ -0,0 +1,148 @@
|
||||
local gc=love.graphics
|
||||
local gc_push,gc_pop=gc.push,gc.pop
|
||||
local gc_translate,gc_setColor,gc_draw=gc.translate,gc.setColor,gc.draw
|
||||
|
||||
local ins,rem=table.insert,table.remove
|
||||
local max=math.max
|
||||
|
||||
local mesList={}
|
||||
local mesIcon={
|
||||
check=GC.DO{40,40,
|
||||
{'setLW',10},
|
||||
{'setCL',0,0,0},
|
||||
{'line',4,19,15,30,36,9},
|
||||
{'setLW',6},
|
||||
{'setCL',.7,1,.6},
|
||||
{'line',5,20,15,30,35,10},
|
||||
},
|
||||
info=GC.DO{40,40,
|
||||
{'setCL',.2,.25,.85},
|
||||
{'fCirc',20,20,15},
|
||||
{'setCL',1,1,1},
|
||||
{'setLW',2},
|
||||
{'dCirc',20,20,15},
|
||||
{'fRect',18,11,4,4},
|
||||
{'fRect',18,17,4,12},
|
||||
},
|
||||
broadcast=GC.DO{40,40,
|
||||
{'setCL',1,1,1},
|
||||
{'fRect',2,4,36,26,3},
|
||||
{'fPoly',2,27,2,37,14,25},
|
||||
{'setCL',.5,.5,.5},
|
||||
{'fRect',6,11,4,4,1},{'fRect',14,11,19,4,1},
|
||||
{'fRect',6,19,4,4,1},{'fRect',14,19,19,4,1},
|
||||
},
|
||||
warn=GC.DO{40,40,
|
||||
{'setCL',.95,.83,.4},
|
||||
{'fPoly',20.5,1,0,38,40,38},
|
||||
{'setCL',0,0,0},
|
||||
{'dPoly',20.5,1,0,38,40,38},
|
||||
{'fRect',17,10,7,18,2},
|
||||
{'fRect',17,29,7,7,2},
|
||||
{'setCL',1,1,1},
|
||||
{'fRect',18,11,5,16,2},
|
||||
{'fRect',18,30,5,5,2},
|
||||
},
|
||||
error=GC.DO{40,40,
|
||||
{'setCL',.95,.3,.3},
|
||||
{'fCirc',20,20,19},
|
||||
{'setCL',0,0,0},
|
||||
{'dCirc',20,20,19},
|
||||
{'setLW',6},
|
||||
{'line',10.2,10.2,29.8,29.8},
|
||||
{'line',10.2,29.8,29.8,10.2},
|
||||
{'setLW',4},
|
||||
{'setCL',1,1,1},
|
||||
{'line',11,11,29,29},
|
||||
{'line',11,29,29,11},
|
||||
},
|
||||
music=GC.DO{40,40,
|
||||
{'setLW',2},
|
||||
{'dRect',1,3,38,34,3},
|
||||
{'setLW',4},
|
||||
{'line',21,26,21,10,28,10},
|
||||
{'fElps',17,26,6,5},
|
||||
},
|
||||
}
|
||||
|
||||
local MES={}
|
||||
local backColors={
|
||||
check={.3,.6,.3,.7},
|
||||
broadcast={.3,.3,.6,.8},
|
||||
warn={.4,.4,.2,.9},
|
||||
error={.4,.2,.2,.9},
|
||||
music={.2,.4,.4,.9},
|
||||
}
|
||||
function MES.new(icon,str,time)
|
||||
local backColor={.5,.5,.5,.7}
|
||||
if type(icon)=='string'then
|
||||
backColor=backColors[icon]or backColor
|
||||
icon=mesIcon[icon]
|
||||
end
|
||||
local t=gc.newText(FONT.get(30),str)
|
||||
local w=math.max(t:getWidth()+(icon and 45 or 5),200)+15
|
||||
local h=math.max(t:getHeight(),46)+2
|
||||
local L={w,h,
|
||||
{'clear',backColor},
|
||||
{'setCL',.7,.7,.7},
|
||||
{'setLW',2},
|
||||
{'dRect',1,1,w-2,h-2},
|
||||
{'setCL',1,1,1},
|
||||
}
|
||||
if icon then
|
||||
ins(L,{'draw',icon,4,4,nil,40/icon:getWidth(),40/icon:getHeight()})
|
||||
end
|
||||
ins(L,{'mDrawY',t,icon and 50 or 10,h/2})
|
||||
|
||||
ins(mesList,{
|
||||
startTime=.5,
|
||||
endTime=.5,
|
||||
time=time or 3,
|
||||
canvas=GC.DO(L),
|
||||
width=w,height=h,
|
||||
scale=h>400 and 1/math.min(h/400,2.6)or 1
|
||||
})
|
||||
end
|
||||
|
||||
function MES.update(dt)
|
||||
for i=#mesList,1,-1 do
|
||||
local m=mesList[i]
|
||||
if m.startTime>0 then
|
||||
m.startTime=max(m.startTime-dt,0)
|
||||
elseif m.time>0 then
|
||||
m.time=max(m.time-dt,0)
|
||||
elseif m.endTime>0 then
|
||||
m.endTime=m.endTime-dt
|
||||
else
|
||||
rem(mesList,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MES.draw()
|
||||
gc_push('transform')
|
||||
if #mesList>0 then
|
||||
gc_translate(SCR.safeX,30)
|
||||
for i=1,#mesList do
|
||||
local m=mesList[i]
|
||||
gc_setColor(1,1,1,2*(m.endTime-m.startTime))
|
||||
gc_draw(m.canvas,40-80*(m.endTime+m.startTime),0,nil,m.scale)
|
||||
gc_translate(0,m.height*m.scale+2)
|
||||
end
|
||||
end
|
||||
gc_pop()
|
||||
end
|
||||
|
||||
function MES.traceback()
|
||||
local mes=
|
||||
debug.traceback('',1)
|
||||
:gsub(': in function',', in')
|
||||
:gsub(':',' ')
|
||||
:gsub('\t','')
|
||||
MES.new('error',mes:sub(
|
||||
mes:find("\n",2)+1,
|
||||
mes:find("\n%[C%], in 'xpcall'")
|
||||
),5)
|
||||
end
|
||||
|
||||
return MES
|
||||
@@ -1,168 +1,157 @@
|
||||
local clock = os.clock
|
||||
local clock=os.clock
|
||||
|
||||
local profile = {}
|
||||
local profile={}
|
||||
|
||||
-- function labels
|
||||
local _labeled = {}
|
||||
-- function definitions
|
||||
local _defined = {}
|
||||
-- time of last call
|
||||
local _tcalled = {}
|
||||
-- total execution time
|
||||
local _telapsed = {}
|
||||
-- number of calls
|
||||
local _ncalls = {}
|
||||
-- list of internal profiler functions
|
||||
local _internal = {}
|
||||
local _labeled={} -- function labels
|
||||
local _defined={} -- function definitions
|
||||
local _tcalled={} -- time of last call
|
||||
local _telapsed={}-- total execution time
|
||||
local _ncalls={} -- number of calls
|
||||
local _internal={}-- list of internal profiler functions
|
||||
|
||||
local getInfo = debug.getinfo
|
||||
function profile.hooker(event, line, info)
|
||||
info = info or getInfo(2, 'fnS')
|
||||
local f = info.func
|
||||
-- ignore the profiler itself
|
||||
if _internal[f] or info.what ~= "Lua" then return end
|
||||
-- get the function name if available
|
||||
if info.name then _labeled[f] = info.name end
|
||||
-- find the line definition
|
||||
if not _defined[f] then
|
||||
_defined[f] = info.short_src .. ":" .. info.linedefined
|
||||
_ncalls[f] = 0
|
||||
_telapsed[f] = 0
|
||||
end
|
||||
if _tcalled[f] then
|
||||
local dt = clock() - _tcalled[f]
|
||||
_telapsed[f] = _telapsed[f] + dt
|
||||
_tcalled[f] = nil
|
||||
end
|
||||
if event == "tail call" then
|
||||
local prev = getInfo(3, 'fnS')
|
||||
profile.hooker("return", line, prev)
|
||||
profile.hooker("call", line, info)
|
||||
elseif event == 'call' then
|
||||
_tcalled[f] = clock()
|
||||
else
|
||||
_ncalls[f] = _ncalls[f] + 1
|
||||
end
|
||||
local getInfo=debug.getinfo
|
||||
function profile.hooker(event,line,info)
|
||||
info=info or getInfo(2,'fnS')
|
||||
local f=info.func
|
||||
if _internal[f]then return end-- ignore the profiler itself
|
||||
if info.name then _labeled[f]=info.name end-- get the function name if available
|
||||
-- find the line definition
|
||||
if not _defined[f]then
|
||||
_defined[f]=info.short_src..":"..info.linedefined
|
||||
_ncalls[f]=0
|
||||
_telapsed[f]=0
|
||||
end
|
||||
if _tcalled[f]then
|
||||
local dt=clock()-_tcalled[f]
|
||||
_telapsed[f]=_telapsed[f]+dt
|
||||
_tcalled[f]=nil
|
||||
end
|
||||
if event=='tail call'then
|
||||
local prev=getInfo(3,'fnS')
|
||||
profile.hooker('return',line,prev)
|
||||
profile.hooker('call',line,info)
|
||||
elseif event=='call'then
|
||||
_tcalled[f]=clock()
|
||||
else
|
||||
_ncalls[f]=_ncalls[f]+1
|
||||
end
|
||||
end
|
||||
|
||||
--- Starts collecting data.
|
||||
function profile.start()
|
||||
if rawget(_G, 'jit') then
|
||||
jit.off()
|
||||
jit.flush()
|
||||
end
|
||||
debug.sethook(profile.hooker, "cr")
|
||||
if jit then
|
||||
jit.off()
|
||||
jit.flush()
|
||||
end
|
||||
debug.sethook(profile.hooker,'cr')
|
||||
end
|
||||
|
||||
--- Stops collecting data.
|
||||
function profile.stop()
|
||||
debug.sethook()
|
||||
for f in next, _tcalled do
|
||||
local dt = clock() - _tcalled[f]
|
||||
_telapsed[f] = _telapsed[f] + dt
|
||||
_tcalled[f] = nil
|
||||
end
|
||||
-- merge closures
|
||||
local lookup = {}
|
||||
for f, d in next, _defined do
|
||||
local id = (_labeled[f] or '?') .. d
|
||||
local f2 = lookup[id]
|
||||
if f2 then
|
||||
_ncalls[f2] = _ncalls[f2] + (_ncalls[f] or 0)
|
||||
_telapsed[f2] = _telapsed[f2] + (_telapsed[f] or 0)
|
||||
_defined[f], _labeled[f] = nil, nil
|
||||
_ncalls[f], _telapsed[f] = nil, nil
|
||||
else
|
||||
lookup[id] = f
|
||||
end
|
||||
end
|
||||
collectgarbage('collect')
|
||||
debug.sethook()
|
||||
for f in next,_tcalled do
|
||||
local dt=clock()-_tcalled[f]
|
||||
_telapsed[f]=_telapsed[f]+dt
|
||||
_tcalled[f]=nil
|
||||
end
|
||||
-- merge closures
|
||||
local lookup={}
|
||||
for f,d in next,_defined do
|
||||
local id=(_labeled[f]or"?")..d
|
||||
local f2=lookup[id]
|
||||
if f2 then
|
||||
_ncalls[f2]=_ncalls[f2]+(_ncalls[f]or 0)
|
||||
_telapsed[f2]=_telapsed[f2]+(_telapsed[f]or 0)
|
||||
_defined[f],_labeled[f]=nil,nil
|
||||
_ncalls[f],_telapsed[f]=nil,nil
|
||||
else
|
||||
lookup[id]=f
|
||||
end
|
||||
end
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
--- Resets all collected data.
|
||||
function profile.reset()
|
||||
for f in next, _ncalls do _ncalls[f] = 0 end
|
||||
for f in next, _telapsed do _telapsed[f] = 0 end
|
||||
for f in next, _tcalled do _tcalled[f] = nil end
|
||||
collectgarbage('collect')
|
||||
for f in next,_ncalls do
|
||||
_ncalls[f]=0
|
||||
_telapsed[f]=0
|
||||
_tcalled[f]=nil
|
||||
end
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
function profile.comp(a, b)
|
||||
local dt = _telapsed[b] - _telapsed[a]
|
||||
return dt == 0 and _ncalls[b] < _ncalls[a] or dt < 0
|
||||
local function _comp(a,b)
|
||||
local dt=_telapsed[b]-_telapsed[a]
|
||||
return dt==0 and _ncalls[b]<_ncalls[a]or dt<0
|
||||
end
|
||||
|
||||
--- Iterates all functions that have been called since the profile was started.
|
||||
-- @param n Number of results (optional)
|
||||
function profile.query(limit)
|
||||
local t = {}
|
||||
for f, n in next, _ncalls do
|
||||
if n > 0 then
|
||||
t[#t + 1] = f
|
||||
end
|
||||
end
|
||||
table.sort(t, profile.comp)
|
||||
if limit then
|
||||
while #t > limit do
|
||||
table.remove(t)
|
||||
end
|
||||
end
|
||||
for i, f in ipairs(t) do
|
||||
local dt = 0
|
||||
if _tcalled[f] then
|
||||
dt = clock() - _tcalled[f]
|
||||
end
|
||||
t[i] = {i, _labeled[f] or '?', _ncalls[f], _telapsed[f] + dt, _defined[f]}
|
||||
end
|
||||
return t
|
||||
local t={}
|
||||
for f,n in next,_ncalls do
|
||||
if n>0 then
|
||||
t[#t+1]=f
|
||||
end
|
||||
end
|
||||
table.sort(t,_comp)
|
||||
|
||||
if limit then while #t>limit do table.remove(t)end end
|
||||
|
||||
for i,f in ipairs(t)do
|
||||
local dt=0
|
||||
if _tcalled[f]then
|
||||
dt=clock()-_tcalled[f]
|
||||
end
|
||||
t[i]={i,_labeled[f]or"?",math.floor((_telapsed[f]+dt)*1e6)/1e6,_ncalls[f],_defined[f]}
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local cols = {3, 29, 11, 24, 32}
|
||||
local cols={3,20,8,6,32}
|
||||
function profile.report(n)
|
||||
local out = {}
|
||||
local report = profile.query(n)
|
||||
for i, row in ipairs(report) do
|
||||
for j = 1, 5 do
|
||||
local s = row[j]
|
||||
local l2 = cols[j]
|
||||
s = tostring(s)
|
||||
local l1 = s:len()
|
||||
if l1 < l2 then
|
||||
s = s .. (' '):rep(l2 - l1)
|
||||
elseif l1 > l2 then
|
||||
s = s:sub(l1 - l2 + 1, l1)
|
||||
end
|
||||
row[j] = s
|
||||
end
|
||||
out[i] = table.concat(row, ' | ')
|
||||
end
|
||||
local out={}
|
||||
local report=profile.query(n)
|
||||
for i,row in ipairs(report)do
|
||||
for j=1,5 do
|
||||
local s=tostring(row[j])
|
||||
local l1,l2=#s,cols[j]
|
||||
if l1<l2 then
|
||||
s=s..(" "):rep(l2-l1)
|
||||
elseif l1>l2 then
|
||||
s=s:sub(l1-l2+1,l1)
|
||||
end
|
||||
row[j]=s
|
||||
end
|
||||
out[i]=table.concat(row," | ")
|
||||
end
|
||||
|
||||
local row = " +-----+-------------------------------+-------------+--------------------------+----------------------------------+ \n"
|
||||
local col = " | # | Function | Calls | Time | Code | \n"
|
||||
local sz = row .. col .. row
|
||||
if #out > 0 then
|
||||
sz = sz .. ' | ' .. table.concat(out, ' | \n | ') .. ' | \n'
|
||||
end
|
||||
return '\n' .. sz .. row
|
||||
local row=" +-----+----------------------+----------+--------+----------------------------------+ \n"
|
||||
local col=" | # | Function | Time | Calls | Code | \n"
|
||||
local sz=row..col..row
|
||||
if #out>0 then
|
||||
sz=sz.." | "..table.concat(out," | \n | ").." | \n"
|
||||
end
|
||||
return "\n"..sz..row
|
||||
end
|
||||
|
||||
local switch = false
|
||||
local switch=false
|
||||
function profile.switch()
|
||||
if switch then
|
||||
profile.stop()
|
||||
love.system.setClipboardText(PROFILE.report())
|
||||
PROFILE.reset()
|
||||
LOG.print("profile report copied!")
|
||||
else
|
||||
PROFILE.start()
|
||||
LOG.print("profile start!")
|
||||
end
|
||||
switch = not switch
|
||||
switch=not switch
|
||||
if not switch then
|
||||
profile.stop()
|
||||
love.system.setClipboardText(profile.report())
|
||||
profile.reset()
|
||||
return false
|
||||
else
|
||||
profile.start()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- store all internal profiler functions
|
||||
for _, v in next, profile do
|
||||
if type(v) == "function" then _internal[v] = true end
|
||||
for _,v in next,profile do
|
||||
_internal[v]=type(v)=='function'
|
||||
end
|
||||
|
||||
return profile
|
||||
|
||||
33
Zframework/require.lua
Normal file
33
Zframework/require.lua
Normal file
@@ -0,0 +1,33 @@
|
||||
package.cpath=package.cpath..';'..SAVEDIR..'/lib/lib?.so;'..'?.dylib'
|
||||
local loaded={}
|
||||
return function(libName)
|
||||
local require=require
|
||||
if love.system.getOS()=='OS X'then
|
||||
require=package.loadlib(libName..'.dylib','luaopen_'..libName)
|
||||
libname=nil
|
||||
elseif love.system.getOS()=='Android'then
|
||||
if not loaded[libName]then
|
||||
local platform=(function()
|
||||
local p=io.popen('uname -m')
|
||||
local arch=p:read('*a'):lower()
|
||||
p:close()
|
||||
if arch:find('v8')or arch:find('64')then
|
||||
return'arm64-v8a'
|
||||
else
|
||||
return'armeabi-v7a'
|
||||
end
|
||||
end)()
|
||||
love.filesystem.write(
|
||||
'lib/libCCloader.so',
|
||||
love.filesystem.read('data','libAndroid/'..platform..'/libCCloader.so')
|
||||
)
|
||||
loaded[libName]=true
|
||||
end
|
||||
end
|
||||
local success,res=pcall(require,libName)
|
||||
if success and res then
|
||||
return res
|
||||
else
|
||||
MES.new('error',"Cannot load "..libName..": "..res)
|
||||
end
|
||||
end
|
||||
@@ -1,162 +1,210 @@
|
||||
local gc=love.graphics
|
||||
local abs=math.abs
|
||||
local SCR=SCR
|
||||
|
||||
local scenes={}
|
||||
|
||||
local SCN={
|
||||
cur="NULL",--Current scene name
|
||||
swapping=false,--If Swapping
|
||||
stat={
|
||||
tar=nil, --Swapping target
|
||||
style=nil, --Swapping style
|
||||
mid=nil, --Loading point
|
||||
time=nil, --Full swap time
|
||||
draw=nil, --Swap draw func
|
||||
},
|
||||
stack={"quit","slowFade"},--Scene stack
|
||||
mainTouchID=nil, --First touching ID(userdata)
|
||||
cur='NULL', --Current scene name
|
||||
swapping=false, --If Swapping
|
||||
stat={
|
||||
tar=false, --Swapping target
|
||||
style=false, --Swapping style
|
||||
changeTime=false,--Loading point
|
||||
time=false, --Full swap time
|
||||
draw=false, --Swap draw func
|
||||
},
|
||||
stack={},--Scene stack
|
||||
prev=false,
|
||||
args={},--Arguments from previous scene
|
||||
|
||||
scenes=scenes,
|
||||
scenes=scenes,
|
||||
|
||||
--Events
|
||||
update=nil,
|
||||
draw=nil,
|
||||
mouseClick=nil,
|
||||
touchClick=nil,
|
||||
mouseDown=nil,
|
||||
mouseMove=nil,
|
||||
mouseUp=nil,
|
||||
wheelMoved=nil,
|
||||
touchDown=nil,
|
||||
touchUp=nil,
|
||||
touchMove=nil,
|
||||
keyDown=nil,
|
||||
keyUp=nil,
|
||||
gamepadDown=nil,
|
||||
gamepadUp=nil,
|
||||
socketRead=nil,
|
||||
--Events
|
||||
update=false,
|
||||
draw=false,
|
||||
mouseClick=false,
|
||||
touchClick=false,
|
||||
mouseDown=false,
|
||||
mouseMove=false,
|
||||
mouseUp=false,
|
||||
wheelMoved=false,
|
||||
touchDown=false,
|
||||
touchUp=false,
|
||||
touchMove=false,
|
||||
keyDown=false,
|
||||
keyUp=false,
|
||||
gamepadDown=false,
|
||||
gamepadUp=false,
|
||||
fileDropped=false,
|
||||
directoryDropped=false,
|
||||
resize=false,
|
||||
socketRead=false,
|
||||
}--Scene datas, returned
|
||||
|
||||
function SCN.add(name,scene)
|
||||
scenes[name]=scene
|
||||
scenes[name]=scene
|
||||
if scene.widgetList then
|
||||
setmetatable(scene.widgetList,WIDGET.indexMeta)
|
||||
end
|
||||
end
|
||||
|
||||
function SCN.swapUpdate()
|
||||
local S=SCN.stat
|
||||
S.time=S.time-1
|
||||
if S.time==S.mid then
|
||||
SCN.init(S.tar,SCN.cur)
|
||||
collectgarbage()
|
||||
--Scene swapped this moment
|
||||
end
|
||||
if S.time==0 then
|
||||
SCN.swapping=false
|
||||
end
|
||||
function SCN.swapUpdate(dt)
|
||||
local S=SCN.stat
|
||||
S.time=S.time-dt
|
||||
if S.time<S.changeTime and S.time+dt>=S.changeTime then
|
||||
--Scene swapped this frame
|
||||
SCN.prev=SCN.cur
|
||||
SCN.init(S.tar)
|
||||
SCN.mainTouchID=nil
|
||||
end
|
||||
if S.time<0 then
|
||||
SCN.swapping=false
|
||||
end
|
||||
end
|
||||
function SCN.init(s,org)
|
||||
local S=scenes[s]
|
||||
SCN.cur=s
|
||||
function SCN.init(s)
|
||||
love.keyboard.setTextInput(false)
|
||||
|
||||
SCN.sceneInit=S.sceneInit
|
||||
SCN.sceneBack=S.sceneBack
|
||||
SCN.update=S.update
|
||||
SCN.draw=S.draw
|
||||
SCN.mouseClick=S.mouseClick
|
||||
SCN.touchClick=S.touchClick
|
||||
SCN.mouseDown=S.mouseDown
|
||||
SCN.mouseMove=S.mouseMove
|
||||
SCN.mouseUp=S.mouseUp
|
||||
SCN.wheelMoved=S.wheelMoved
|
||||
SCN.touchDown=S.touchDown
|
||||
SCN.touchUp=S.touchUp
|
||||
SCN.touchMove=S.touchMove
|
||||
SCN.keyDown=S.keyDown
|
||||
SCN.keyUp=S.keyUp
|
||||
SCN.gamepadDown=S.gamepadDown
|
||||
SCN.gamepadUp=S.gamepadUp
|
||||
SCN.socketRead=S.socketRead
|
||||
if S.sceneInit then S.sceneInit(org)end
|
||||
WIDGET.set(s)
|
||||
local S=scenes[s]
|
||||
SCN.cur=s
|
||||
|
||||
WIDGET.setScrollHeight(S.widgetScrollHeight)
|
||||
WIDGET.setWidgetList(S.widgetList)
|
||||
SCN.sceneInit=S.sceneInit
|
||||
SCN.sceneBack=S.sceneBack
|
||||
SCN.mouseDown=S.mouseDown
|
||||
SCN.mouseMove=S.mouseMove
|
||||
SCN.mouseUp=S.mouseUp
|
||||
SCN.mouseClick=S.mouseClick
|
||||
SCN.wheelMoved=S.wheelMoved
|
||||
SCN.touchDown=S.touchDown
|
||||
SCN.touchUp=S.touchUp
|
||||
SCN.touchMove=S.touchMove
|
||||
SCN.touchClick=S.touchClick
|
||||
SCN.keyDown=S.keyDown
|
||||
SCN.keyUp=S.keyUp
|
||||
SCN.gamepadDown=S.gamepadDown
|
||||
SCN.gamepadUp=S.gamepadUp
|
||||
SCN.fileDropped=S.fileDropped
|
||||
SCN.directoryDropped=S.directoryDropped
|
||||
SCN.resize=S.resize
|
||||
SCN.socketRead=S.socketRead
|
||||
SCN.update=S.update
|
||||
SCN.draw=S.draw
|
||||
if S.sceneInit then
|
||||
S.sceneInit()
|
||||
end
|
||||
end
|
||||
function SCN.push(tar,style)
|
||||
if not SCN.swapping then
|
||||
local m=#SCN.stack
|
||||
SCN.stack[m+1]=tar or SCN.cur
|
||||
SCN.stack[m+2]=style or"fade"
|
||||
end
|
||||
if not SCN.swapping then
|
||||
local m=#SCN.stack
|
||||
SCN.stack[m+1]=tar or SCN.cur
|
||||
SCN.stack[m+2]=style or'fade'
|
||||
end
|
||||
end
|
||||
function SCN.pop()
|
||||
local _=SCN.stack
|
||||
_[#_],_[#_-1]=nil
|
||||
local s=SCN.stack
|
||||
s[#s],s[#s-1]=nil
|
||||
end
|
||||
|
||||
local swap={
|
||||
none={1,0,NULL},--swapTime, changeTime, drawFunction
|
||||
flash={8,1,function()gc.clear(1,1,1)end},
|
||||
fade={30,15,function(t)
|
||||
t=t>15 and 2-t/15 or t/15
|
||||
gc.setColor(0,0,0,t)
|
||||
gc.rectangle("fill",0,0,SCR.w,SCR.h)
|
||||
end},
|
||||
fade_togame={120,20,function(t)
|
||||
t=t>20 and(120-t)/100 or t/20
|
||||
gc.setColor(0,0,0,t)
|
||||
gc.rectangle("fill",0,0,SCR.w,SCR.h)
|
||||
end},
|
||||
slowFade={180,90,function(t)
|
||||
t=t>90 and 2-t/90 or t/90
|
||||
gc.setColor(0,0,0,t)
|
||||
gc.rectangle("fill",0,0,SCR.w,SCR.h)
|
||||
end},
|
||||
swipeL={30,15,function(t)
|
||||
t=t/30
|
||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||
t=t*t*(3-2*t)*2-1
|
||||
gc.rectangle("fill",t*SCR.w,0,SCR.w,SCR.h)
|
||||
end},
|
||||
swipeR={30,15,function(t)
|
||||
t=t/30
|
||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||
t=t*t*(2*t-3)*2+1
|
||||
gc.rectangle("fill",t*SCR.w,0,SCR.w,SCR.h)
|
||||
end},
|
||||
swipeD={30,15,function(t)
|
||||
t=t/30
|
||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||
t=t*t*(2*t-3)*2+1
|
||||
gc.rectangle("fill",0,t*SCR.h,SCR.w,SCR.h)
|
||||
end},
|
||||
none={
|
||||
duration=0,changeTime=0,
|
||||
draw=function()end
|
||||
},
|
||||
flash={
|
||||
duration=.16,changeTime=.08,
|
||||
draw=function()gc.clear(1,1,1)end
|
||||
},
|
||||
fade={
|
||||
duration=.5,changeTime=.25,
|
||||
draw=function(t)
|
||||
t=t>.25 and 2-t*4 or t*4
|
||||
gc.setColor(0,0,0,t)
|
||||
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
||||
end
|
||||
},
|
||||
fade_togame={
|
||||
duration=2,changeTime=.5,
|
||||
draw=function(t)
|
||||
t=t>.5 and(2-t)/1.5 or t*.5
|
||||
gc.setColor(0,0,0,t)
|
||||
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
||||
end
|
||||
},
|
||||
slowFade={
|
||||
duration=3,changeTime=1.5,
|
||||
draw=function(t)
|
||||
t=t>1.5 and (3-t)/1.5 or t/1.5
|
||||
gc.setColor(0,0,0,t)
|
||||
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
||||
end
|
||||
},
|
||||
swipeL={
|
||||
duration=.5,changeTime=.25,
|
||||
draw=function(t)
|
||||
t=t*2
|
||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||
t=t*t*(3-2*t)*2-1
|
||||
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
|
||||
end
|
||||
},
|
||||
swipeR={
|
||||
duration=.5,changeTime=.25,
|
||||
draw=function(t)
|
||||
t=t*2
|
||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||
t=t*t*(2*t-3)*2+1
|
||||
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
|
||||
end
|
||||
},
|
||||
swipeD={
|
||||
duration=.5,changeTime=.25,
|
||||
draw=function(t)
|
||||
t=t*2
|
||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||
t=t*t*(2*t-3)*2+1
|
||||
gc.rectangle('fill',0,t*SCR.h,SCR.w,SCR.h)
|
||||
end
|
||||
},
|
||||
}--Scene swapping animations
|
||||
function SCN.swapTo(tar,style)--Parallel scene swapping, cannot back
|
||||
if scenes[tar]then
|
||||
local S=SCN.stat
|
||||
if not SCN.swapping and tar~=SCN.cur then
|
||||
if not style then style="fade"end
|
||||
SCN.swapping=true
|
||||
S.tar,S.style=tar,style
|
||||
S.time,S.mid,S.draw=unpack(swap[style])
|
||||
end
|
||||
else
|
||||
LOG.print("No Scene: "..tar,"warn")
|
||||
end
|
||||
function SCN.swapTo(tar,style,...)--Parallel scene swapping, cannot back
|
||||
if scenes[tar]then
|
||||
if not SCN.swapping and tar~=SCN.cur then
|
||||
style=style or'fade'
|
||||
SCN.swapping=true
|
||||
SCN.args={...}
|
||||
local S=SCN.stat
|
||||
S.tar,S.style=tar,style
|
||||
S.time=swap[style].duration
|
||||
S.changeTime=swap[style].changeTime
|
||||
S.draw=swap[style].draw
|
||||
end
|
||||
else
|
||||
MES.new('warn',"No Scene: "..tar)
|
||||
end
|
||||
end
|
||||
function SCN.go(tar,style)--Normal scene swapping, can back
|
||||
if scenes[tar]then
|
||||
SCN.push()
|
||||
SCN.swapTo(tar,style)
|
||||
else
|
||||
LOG.print("No Scene: "..tar,"warn")
|
||||
end
|
||||
function SCN.go(tar,style,...)--Normal scene swapping, can back
|
||||
if scenes[tar]then
|
||||
SCN.push()
|
||||
SCN.swapTo(tar,style,...)
|
||||
else
|
||||
MES.new('warn',"No Scene: "..tar)
|
||||
end
|
||||
end
|
||||
function SCN.back()
|
||||
--Leave scene
|
||||
if SCN.sceneBack then SCN.sceneBack()end
|
||||
function SCN.back(...)
|
||||
if SCN.swapping then return end
|
||||
|
||||
--Poll&Back to previous Scene
|
||||
local m=#SCN.stack
|
||||
if m>0 then
|
||||
SCN.swapTo(SCN.stack[m-1],SCN.stack[m])
|
||||
SCN.stack[m],SCN.stack[m-1]=nil
|
||||
end
|
||||
--Leave scene
|
||||
if SCN.sceneBack then
|
||||
SCN.sceneBack()
|
||||
end
|
||||
|
||||
--Poll&Back to previous Scene
|
||||
local m=#SCN.stack
|
||||
if m>0 then
|
||||
SCN.swapTo(SCN.stack[m-1],SCN.stack[m],...)
|
||||
SCN.stack[m],SCN.stack[m-1]=nil
|
||||
end
|
||||
end
|
||||
return SCN
|
||||
return SCN
|
||||
|
||||
@@ -1,14 +1,73 @@
|
||||
local SCR={
|
||||
w0=1280,h0=720,--Default Screen Size
|
||||
x=0,y=0,--Up-left Coord on screen
|
||||
w=0,h=0,--Fullscreen w/h in gc
|
||||
W=0,H=0,--Fullscreen w/h in shader
|
||||
rad=0,--Radius
|
||||
k=1,--Scale size
|
||||
dpi=1,--DPI from gc.getDPIScale()
|
||||
xOy=love.math.newTransform(),--Screen transformation object
|
||||
w0=1280,h0=720, --Default Screen Size
|
||||
x=0,y=0, --Up-left Coord on screen
|
||||
cx=0,cy=0, --Center Coord on screen (Center X/Y)
|
||||
ex=0,ey=0, --Down-right Coord on screen (End X/Y)
|
||||
w=0,h=0, --Fullscreen w/h for graphic functions
|
||||
W=0,H=0, --Fullscreen w/h for shader
|
||||
safeX=0,safeY=0,--Safe area
|
||||
safeW=0,safeH=0,--Safe area
|
||||
rad=0, --Radius
|
||||
k=1, --Scale size
|
||||
dpi=1, --DPI from gc.getDPIScale()
|
||||
|
||||
--Screen transformation objects
|
||||
origin=love.math.newTransform(),
|
||||
xOy=love.math.newTransform(),
|
||||
xOy_m=love.math.newTransform(),
|
||||
xOy_ul=love.math.newTransform(),
|
||||
xOy_u=love.math.newTransform(),
|
||||
xOy_ur=love.math.newTransform(),
|
||||
xOy_l=love.math.newTransform(),
|
||||
xOy_r=love.math.newTransform(),
|
||||
xOy_dl=love.math.newTransform(),
|
||||
xOy_d=love.math.newTransform(),
|
||||
xOy_dr=love.math.newTransform(),
|
||||
}
|
||||
function SCR.setSize(w,h)
|
||||
SCR.w0,SCR.h0=w,h
|
||||
SCR.w0,SCR.h0=w,h
|
||||
end
|
||||
return SCR
|
||||
function SCR.resize(w,h)
|
||||
SCR.w,SCR.h,SCR.dpi=w,h,love.graphics.getDPIScale()
|
||||
SCR.W,SCR.H=SCR.w*SCR.dpi,SCR.h*SCR.dpi
|
||||
SCR.r=h/w
|
||||
SCR.rad=(w^2+h^2)^.5
|
||||
|
||||
SCR.x,SCR.y=0,0
|
||||
if SCR.r>=SCR.h0/SCR.w0 then
|
||||
SCR.k=w/SCR.w0
|
||||
SCR.y=(h-SCR.h0*SCR.k)/2
|
||||
else
|
||||
SCR.k=h/SCR.h0
|
||||
SCR.x=(w-SCR.w0*SCR.k)/2
|
||||
end
|
||||
SCR.cx,SCR.cy=SCR.w/2,SCR.h/2
|
||||
SCR.ex,SCR.ey=SCR.w-SCR.x,SCR.h-SCR.y
|
||||
SCR.safeX,SCR.safeY,SCR.safeW,SCR.safeH=love.window.getSafeArea()
|
||||
|
||||
SCR.origin:setTransformation(0,0)
|
||||
SCR.xOy:setTransformation(SCR.x,SCR.y,0,SCR.k)
|
||||
SCR.xOy_m:setTransformation(w/2,h/2,0,SCR.k)
|
||||
SCR.xOy_ul:setTransformation(0,0,0,SCR.k)
|
||||
SCR.xOy_u:setTransformation(w/2,0,0,SCR.k)
|
||||
SCR.xOy_ur:setTransformation(w,0,0,SCR.k)
|
||||
SCR.xOy_l:setTransformation(0,h/2,0,SCR.k)
|
||||
SCR.xOy_r:setTransformation(w,h/2,0,SCR.k)
|
||||
SCR.xOy_dl:setTransformation(0,h,0,SCR.k)
|
||||
SCR.xOy_d:setTransformation(w/2,h,0,SCR.k)
|
||||
SCR.xOy_dr:setTransformation(w,h,0,SCR.k)
|
||||
end
|
||||
function SCR.info()
|
||||
return{
|
||||
("w0,h0 : %d, %d"):format(SCR.w0,SCR.h0),
|
||||
("x,y : %d, %d"):format(SCR.x,SCR.y),
|
||||
("cx,cy : %d, %d"):format(SCR.cx,SCR.cy),
|
||||
("ex,ey : %d, %d"):format(SCR.ex,SCR.ey),
|
||||
("w,h : %d, %d"):format(SCR.w,SCR.h),
|
||||
("W,H : %d, %d"):format(SCR.W,SCR.H),
|
||||
("safeX,safeY : %d, %d"):format(SCR.safeX,SCR.safeY),
|
||||
("safeW,safeH : %d, %d"):format(SCR.safeW,SCR.safeH),
|
||||
("k,dpi,rad : %.2f, %d, %.2f"):format(SCR.k,SCR.dpi,SCR.rad),
|
||||
}
|
||||
end
|
||||
return SCR
|
||||
|
||||
@@ -1,85 +1,170 @@
|
||||
local rem=table.remove
|
||||
local type,rem=type,table.remove
|
||||
local int,rnd=math.floor,math.random
|
||||
local interval=MATH.interval
|
||||
|
||||
local sfxList={}
|
||||
local packSetting={}
|
||||
local Sources={}
|
||||
local volume=1
|
||||
local stereo=1
|
||||
|
||||
local noteVal={
|
||||
C=1,c=1,
|
||||
D=3,d=3,
|
||||
E=5,e=5,
|
||||
F=6,f=6,
|
||||
G=8,g=8,
|
||||
A=10,a=10,
|
||||
B=12,b=12,
|
||||
}
|
||||
local noteName={'C','C#','D','D#','E','F','F#','G','G#','A','A#','B'}
|
||||
local function _getTuneHeight(tune)
|
||||
local octave=tonumber(tune:sub(-1,-1))
|
||||
if octave then
|
||||
local tuneHeight=noteVal[tune:sub(1,1)]
|
||||
if tuneHeight then
|
||||
tuneHeight=tuneHeight+(octave-1)*12
|
||||
local s=tune:sub(2,2)
|
||||
if s=='s'or s=='#'then
|
||||
tuneHeight=tuneHeight+1
|
||||
elseif s=='f'or s=='b'then
|
||||
tuneHeight=tuneHeight-1
|
||||
end
|
||||
return tuneHeight
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local SFX={}
|
||||
function SFX.set(L)
|
||||
SFX.list=L
|
||||
SFX.len=#L
|
||||
|
||||
function SFX.init(list)
|
||||
assert(type(list)=='table',"Initialize SFX lib with a list of filenames!")
|
||||
for i=1,#list do table.insert(sfxList,list[i])end
|
||||
end
|
||||
function SFX.loadOne(_)
|
||||
_,SFX.list[_]=SFX.list[_]
|
||||
local N="media/SFX/".._..".ogg"
|
||||
if love.filesystem.getInfo(N)then
|
||||
SFX.list[_]={love.audio.newSource(N,"static")}
|
||||
else
|
||||
LOG.print("No SFX file: "..N,5,COLOR.orange)
|
||||
end
|
||||
function SFX.load(path)
|
||||
local c=0
|
||||
local missing=0
|
||||
for i=1,#sfxList do
|
||||
local fullPath=path..sfxList[i]..'.ogg'
|
||||
if love.filesystem.getInfo(fullPath)then
|
||||
if Sources[sfxList[i]]then
|
||||
for j=1,#Sources[sfxList[i]]do
|
||||
Sources[sfxList[i]][j]:release()
|
||||
end
|
||||
end
|
||||
Sources[sfxList[i]]={love.audio.newSource(fullPath,'static')}
|
||||
c=c+1
|
||||
else
|
||||
LOG("No SFX: "..sfxList[i]..'.ogg',.1)
|
||||
missing=missing+1
|
||||
end
|
||||
end
|
||||
LOG(c.."/"..#sfxList.." SFX files loaded")
|
||||
LOG(missing.." SFX files missing")
|
||||
if missing>0 then
|
||||
MES.new('info',missing.." SFX files missing")
|
||||
end
|
||||
collectgarbage()
|
||||
end
|
||||
function SFX.loadAll()
|
||||
for i=1,#SFX.list do
|
||||
SFX.loadOne(i)
|
||||
end
|
||||
function SFX.loadSample(pack)
|
||||
assert(type(pack)=='table',"Usage: SFX.loadsample([table])")
|
||||
assert(pack.name,"No field: name")
|
||||
assert(pack.path,"No field: path")
|
||||
local num=1
|
||||
while love.filesystem.getInfo(pack.path..'/'..num..'.ogg')do
|
||||
Sources[pack.name..num]={love.audio.newSource(pack.path..'/'..num..'.ogg','static')}
|
||||
num=num+1
|
||||
end
|
||||
local base=(_getTuneHeight(pack.base)or 37)-1
|
||||
local top=base+num-1
|
||||
packSetting[pack.name]={base=base,top=top}
|
||||
LOG((num-1).." "..pack.name.." samples loaded")
|
||||
end
|
||||
function SFX.fieldPlay(s,v,P)
|
||||
SFX.play(s,v,(P.curX+P.sc[2]-5.5)*.15)
|
||||
|
||||
function SFX.getCount()
|
||||
return #sfxList
|
||||
end
|
||||
function SFX.play(s,vol,pos)
|
||||
if SETTING.sfx==0 then return end
|
||||
local S=SFX.list[s]--Source list
|
||||
if not S then return end
|
||||
local n=1
|
||||
while S[n]:isPlaying()do
|
||||
n=n+1
|
||||
if not S[n]then
|
||||
S[n]=S[1]:clone()
|
||||
S[n]:seek(0)
|
||||
break
|
||||
end
|
||||
end
|
||||
S=S[n]--AU_SRC
|
||||
if S:getChannelCount()==1 then
|
||||
if pos then
|
||||
pos=pos*SETTING.stereo
|
||||
S:setPosition(pos,1-pos^2,0)
|
||||
else
|
||||
S:setPosition(0,0,0)
|
||||
end
|
||||
end
|
||||
S:setVolume(((vol or 1)*SETTING.sfx)^1.626)
|
||||
S:play()
|
||||
function SFX.setVol(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||
volume=v
|
||||
end
|
||||
function SFX.fplay(s,vol,pos)
|
||||
local S=SFX.list[s]--Source list
|
||||
if not S then return end
|
||||
local n=1
|
||||
while S[n]:isPlaying()do
|
||||
n=n+1
|
||||
if not S[n]then
|
||||
S[n]=S[1]:clone()
|
||||
S[n]:seek(0)
|
||||
break
|
||||
end
|
||||
end
|
||||
S=S[n]--AU_SRC
|
||||
if S:getChannelCount()==1 then
|
||||
if pos then
|
||||
pos=pos*SETTING.stereo
|
||||
S:setPosition(pos,1-pos^2,0)
|
||||
else
|
||||
S:setPosition(0,0,0)
|
||||
end
|
||||
end
|
||||
S:setVolume(vol^1.626)
|
||||
S:play()
|
||||
function SFX.setStereo(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1,'Wrong stereo')
|
||||
stereo=v
|
||||
end
|
||||
|
||||
function SFX.getNoteName(note)
|
||||
if note<1 then
|
||||
return'---'
|
||||
else
|
||||
note=note-1
|
||||
local octave=int(note/12)+1
|
||||
return noteName[note%12+1]..octave
|
||||
end
|
||||
end
|
||||
function SFX.playSample(pack,...)--vol-1, sampSet1, vol-2, sampSet2
|
||||
if ... then
|
||||
local arg={...}
|
||||
local vol
|
||||
for i=1,#arg do
|
||||
local a=arg[i]
|
||||
if type(a)=='number'and a<=1 then
|
||||
vol=a
|
||||
else
|
||||
local base=packSetting[pack].base
|
||||
local top=packSetting[pack].top
|
||||
local tune=type(a)=='string'and _getTuneHeight(a)or a--Absolute tune in number
|
||||
local playTune=tune+rnd(-2,2)
|
||||
if playTune<=base then--Too low notes
|
||||
playTune=base+1
|
||||
elseif playTune>top then--Too high notes
|
||||
playTune=top
|
||||
end
|
||||
SFX.play(pack..playTune-base,vol,nil,tune-playTune)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local function _play(name,vol,pos,pitch)
|
||||
if volume==0 or vol==0 then return end
|
||||
local S=Sources[name]--Source list
|
||||
if not S then return end
|
||||
local n=1
|
||||
while S[n]:isPlaying()do
|
||||
n=n+1
|
||||
if not S[n]then
|
||||
S[n]=S[1]:clone()
|
||||
S[n]:seek(0)
|
||||
break
|
||||
end
|
||||
end
|
||||
S=S[n]--AU_SRC
|
||||
if S:getChannelCount()==1 then
|
||||
if pos then
|
||||
pos=interval(pos,-1,1)*stereo
|
||||
S:setPosition(pos,1-pos^2,0)
|
||||
else
|
||||
S:setPosition(0,0,0)
|
||||
end
|
||||
end
|
||||
S:setVolume(vol^1.626)
|
||||
S:setPitch(pitch and 1.0594630943592953^pitch or 1)
|
||||
S:play()
|
||||
end
|
||||
SFX.fplay=_play--Play sounds without apply module's volume setting
|
||||
function SFX.play(name,vol,pos,pitch)
|
||||
_play(name,(vol or 1)*volume,pos,pitch)
|
||||
end
|
||||
function SFX.reset()
|
||||
for _,L in next,SFX.list do
|
||||
if type(L)=="table"then
|
||||
for i=#L,1,-1 do
|
||||
if not L[i]:isPlaying()then
|
||||
rem(L,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for _,L in next,Sources do
|
||||
if type(L)=='table'then
|
||||
for i=#L,1,-1 do
|
||||
if not L[i]:isPlaying()then
|
||||
rem(L,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return SFX
|
||||
|
||||
return SFX
|
||||
|
||||
231
Zframework/stringExtend.lua
Normal file
231
Zframework/stringExtend.lua
Normal file
@@ -0,0 +1,231 @@
|
||||
local data=love.data
|
||||
local STRING={}
|
||||
local assert,tostring,tonumber=assert,tostring,tonumber
|
||||
local int,format=math.floor,string.format
|
||||
local find,sub,gsub,upper=string.find,string.sub,string.gsub,string.upper
|
||||
local char,byte=string.char,string.byte
|
||||
|
||||
--"Replace dollars", replace all $n with ...
|
||||
function STRING.repD(str,...)
|
||||
local l={...}
|
||||
for i=#l,1,-1 do
|
||||
str=gsub(str,'$'..i,l[i])
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
--"Scan arg", scan if str has the arg (format of str is like "-json -q", arg is like "-q")
|
||||
function STRING.sArg(str,switch)
|
||||
if find(str.." ",switch.." ")then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
do--function STRING.shiftChar(c)
|
||||
local shiftMap={
|
||||
['1']='!',['2']='@',['3']='#',['4']='$',['5']='%',
|
||||
['6']='^',['7']='&',['8']='*',['9']='(',['0']=')',
|
||||
['`']='~',['-']='_',['=']='+',
|
||||
['[']='{',[']']='}',['\\']='|',
|
||||
[';']=':',['\'']='"',
|
||||
[',']='<',['.']='>',['/']='?',
|
||||
}
|
||||
function STRING.shiftChar(c)
|
||||
return shiftMap[c]or upper(c)
|
||||
end
|
||||
end
|
||||
|
||||
function STRING.trim(s)
|
||||
if not s:find("%S")then return""end
|
||||
s=s:sub((s:find("%S"))):reverse()
|
||||
return s:sub((s:find("%S"))):reverse()
|
||||
end
|
||||
|
||||
function STRING.split(s,sep,regex)
|
||||
local L={}
|
||||
local p1,p2=1--start,target
|
||||
if regex then
|
||||
while p1<=#s do
|
||||
p2=find(s,sep,p1)or #s+1
|
||||
L[#L+1]=sub(s,p1,p2-1)
|
||||
p1=p2+#sep
|
||||
end
|
||||
else
|
||||
while p1<=#s do
|
||||
p2=find(s,sep,p1,true)or #s+1
|
||||
L[#L+1]=sub(s,p1,p2-1)
|
||||
p1=p2+#sep
|
||||
end
|
||||
end
|
||||
return L
|
||||
end
|
||||
|
||||
function STRING.simpEmailCheck(e)
|
||||
e=STRING.split(e,"@")
|
||||
if #e~=2 then return false end
|
||||
if e[1]:sub(-1)=="."or e[2]:sub(-1)=="."then return false end
|
||||
local e1,e2=STRING.split(e[1],"."),STRING.split(e[2],".")
|
||||
if #e1*#e2==0 then return false end
|
||||
for _,v in next,e1 do if #v==0 then return false end end
|
||||
for _,v in next,e2 do if #v==0 then return false end end
|
||||
return true
|
||||
end
|
||||
|
||||
function STRING.time_simp(t)
|
||||
return format("%02d:%02d",int(t/60),int(t%60))
|
||||
end
|
||||
|
||||
function STRING.time(t)
|
||||
if t<60 then
|
||||
return format("%.3f\"",t)
|
||||
elseif t<3600 then
|
||||
return format("%d'%05.2f\"",int(t/60),int(t%60*100)/100)
|
||||
else
|
||||
return format("%d:%.2d'%05.2f\"",int(t/3600),int(t/60%60),int(t%60*100)/100)
|
||||
end
|
||||
end
|
||||
|
||||
function STRING.UTF8(n)--Simple utf8 coding
|
||||
assert(type(n)=='number',"Wrong type ("..type(n)..")")
|
||||
assert(n>=0 and n<2^31,"Out of range ("..n..")")
|
||||
if n<2^7 then return char(n)
|
||||
elseif n<2^11 then return char(192+int(n/2^06),128+n%2^6)
|
||||
elseif n<2^16 then return char(224+int(n/2^12),128+int(n/2^06)%2^6,128+n%2^6)
|
||||
elseif n<2^21 then return char(240+int(n/2^18),128+int(n/2^12)%2^6,128+int(n/2^06)%2^6,128+n%2^6)
|
||||
elseif n<2^26 then return char(248+int(n/2^24),128+int(n/2^18)%2^6,128+int(n/2^12)%2^6,128+int(n/2^06)%2^6,128+n%2^6)
|
||||
elseif n<2^31 then return char(252+int(n/2^30),128+int(n/2^24)%2^6,128+int(n/2^18)%2^6,128+int(n/2^12)%2^6,128+int(n/2^06)%2^6,128+n%2^6)
|
||||
end
|
||||
end
|
||||
|
||||
do--function STRING.bigInt(t)
|
||||
local lg=math.log10
|
||||
local units={"","K","M","B","T","Qa","Qt","Sx","Sp","Oc","No"}
|
||||
local preUnits={"","U","D","T","Qa","Qt","Sx","Sp","O","N"}
|
||||
local secUnits={"Dc","Vg","Tg","Qd","Qi","Se","St","Og","Nn","Ce"}--Ce is next-level unit, but DcCe is not used so used here
|
||||
for _,preU in next,preUnits do for _,secU in next,secUnits do table.insert(units,preU..secU)end end
|
||||
function STRING.bigInt(t)
|
||||
if t<1000 then
|
||||
return tostring(t)
|
||||
elseif t~=1e999 then
|
||||
local e=int(lg(t)/3)
|
||||
return(t/10^(e*3))..units[e+1]
|
||||
else
|
||||
return"INF"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function STRING.hexColor(str)--[LOW PERFORMENCE]
|
||||
assert(type(str)=='string')
|
||||
if str:sub(1,1)=="#"then str=str:sub(2)end
|
||||
assert(#str<=8)
|
||||
local r=(tonumber(str:sub(1,2),16)or 0)/255
|
||||
local g=(tonumber(str:sub(3,4),16)or 0)/255
|
||||
local b=(tonumber(str:sub(5,6),16)or 0)/255
|
||||
local a=(tonumber(str:sub(7,8),16)or 255)/255
|
||||
return r,g,b,a
|
||||
end
|
||||
|
||||
do--function STRING.urlEncode(s)
|
||||
local rshift=bit.rshift
|
||||
local b16={[0]='0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
|
||||
function STRING.urlEncode(s)
|
||||
local out=""
|
||||
for i=1,#s do
|
||||
if s:sub(i,i):match("[a-zA-Z0-9]")then
|
||||
out=out..s:sub(i,i)
|
||||
else
|
||||
local b=s:byte(i)
|
||||
out=out.."%"..b16[rshift(b,4)]..b16[b%16]
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
end
|
||||
|
||||
function STRING.vcsEncrypt(text,key)
|
||||
local keyLen=#key
|
||||
local result=""
|
||||
local buffer=""
|
||||
for i=0,#text-1 do
|
||||
buffer=buffer..char((byte(text,i+1)-32+byte(key,i%keyLen+1))%95+32)
|
||||
if #buffer==26 then
|
||||
result=result..buffer
|
||||
buffer=""
|
||||
end
|
||||
end
|
||||
return result..buffer
|
||||
end
|
||||
function STRING.vcsDecrypt(text,key)
|
||||
local keyLen=#key
|
||||
local result=""
|
||||
local buffer=""
|
||||
for i=0,#text-1 do
|
||||
buffer=buffer..char((byte(text,i+1)-32-byte(key,i%keyLen+1))%95+32)
|
||||
if #buffer==26 then
|
||||
result=result..buffer
|
||||
buffer=""
|
||||
end
|
||||
end
|
||||
return result..buffer
|
||||
end
|
||||
function STRING.digezt(text)--Not powerful hash, just protect the original text
|
||||
local out={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||
local seed=26
|
||||
for i=1,#text do
|
||||
local c=byte(text,i)
|
||||
seed=(seed+c)%26
|
||||
c=c+seed
|
||||
local pos=c*i%16
|
||||
local step=(c+i)%4+1
|
||||
local times=2+(c%6)
|
||||
for _=1,times do
|
||||
out[pos+1]=(out[pos+1]+c)%256
|
||||
pos=(pos+step)%16
|
||||
end
|
||||
end
|
||||
local result=""
|
||||
for i=1,16 do result=result..char(out[i])end
|
||||
return result
|
||||
end
|
||||
|
||||
function STRING.readLine(str)
|
||||
local p=str:find("\n")
|
||||
if p then
|
||||
return str:sub(1,p-1),str:sub(p+1)
|
||||
else
|
||||
return str,""
|
||||
end
|
||||
end
|
||||
function STRING.readChars(str,n)
|
||||
return sub(str,1,n),sub(str,n+1)
|
||||
end
|
||||
|
||||
function STRING.packBin(s)
|
||||
return data.encode('string','base64',data.compress('string','zlib',s))
|
||||
end
|
||||
function STRING.unpackBin(str)
|
||||
local res
|
||||
res,str=pcall(data.decode,'string','base64',str)
|
||||
if not res then return end
|
||||
res,str=pcall(data.decompress,'string','zlib',str)
|
||||
if res then return str end
|
||||
end
|
||||
function STRING.packText(s)
|
||||
return data.encode('string','base64',data.compress('string','gzip',s))
|
||||
end
|
||||
function STRING.unpackText(str)
|
||||
local res
|
||||
res,str=pcall(data.decode,'string','base64',str)
|
||||
if not res then return end
|
||||
res,str=pcall(data.decompress,'string','gzip',str)
|
||||
if res then return str end
|
||||
end
|
||||
function STRING.packTable(t)
|
||||
return STRING.packText(JSON.encode(t))
|
||||
end
|
||||
function STRING.unpackTable(t)
|
||||
return JSON.decode(STRING.unpackText(t))
|
||||
end
|
||||
|
||||
return STRING
|
||||
@@ -1,169 +1,205 @@
|
||||
local gc=love.graphics
|
||||
local setColor,setWidth=gc.setColor,gc.setLineWidth
|
||||
local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
|
||||
local gc_draw,gc_line=gc.draw,gc.line
|
||||
local gc_rectangle,gc_circle=gc.rectangle,gc.circle
|
||||
|
||||
local max,min=math.max,math.min
|
||||
local rnd=math.random
|
||||
local rem=table.remove
|
||||
local ins,rem=table.insert,table.remove
|
||||
|
||||
local fx={}
|
||||
|
||||
local function normUpdate(S,dt)
|
||||
S.t=S.t+dt*S.rate
|
||||
return S.t>1
|
||||
local function _normUpdate(S,dt)
|
||||
S.t=S.t+dt*S.rate
|
||||
return S.t>1
|
||||
end
|
||||
|
||||
local FXupdate={}
|
||||
function FXupdate.badge(S,dt)
|
||||
S.t=S.t+dt
|
||||
if S.t<.2 then
|
||||
S.x,S.y=S.x1-14,S.y1-14
|
||||
elseif S.t<.8 then
|
||||
local t=((S.t-.2)*1.6667)
|
||||
t=(3-2*t)*t*t
|
||||
S.x,S.y=S.x1*(1-t)+S.x2*t-14,S.y1*(1-t)+S.y2*t-14
|
||||
else
|
||||
S.x,S.y=S.x2-14,S.y2-14
|
||||
end
|
||||
return S.t>=1
|
||||
S.t=S.t+dt
|
||||
if S.t<.2 then
|
||||
S.x,S.y=S.x1-14,S.y1-14
|
||||
elseif S.t<.8 then
|
||||
local t=((S.t-.2)*1.6667)
|
||||
t=(3-2*t)*t*t
|
||||
S.x,S.y=S.x1*(1-t)+S.x2*t-14,S.y1*(1-t)+S.y2*t-14
|
||||
else
|
||||
S.x,S.y=S.x2-14,S.y2-14
|
||||
end
|
||||
return S.t>=1
|
||||
end
|
||||
FXupdate.attack=normUpdate
|
||||
FXupdate.ripple=normUpdate
|
||||
FXupdate.rectRipple=normUpdate
|
||||
FXupdate.shade=normUpdate
|
||||
FXupdate.attack=_normUpdate
|
||||
FXupdate.tap=_normUpdate
|
||||
FXupdate.ripple=_normUpdate
|
||||
FXupdate.rectRipple=_normUpdate
|
||||
FXupdate.shade=_normUpdate
|
||||
function FXupdate.cell(S,dt)
|
||||
if S.vx then
|
||||
S.x=S.x+S.vx*S.rate
|
||||
S.y=S.y+S.vy*S.rate
|
||||
if S.ax then
|
||||
S.vx=S.vx+S.ax*S.rate
|
||||
S.vy=S.vy+S.ay*S.rate
|
||||
end
|
||||
end
|
||||
S.t=S.t+dt*S.rate
|
||||
return S.t>1
|
||||
if S.vx then
|
||||
S.x=S.x+S.vx*S.rate
|
||||
S.y=S.y+S.vy*S.rate
|
||||
if S.ax then
|
||||
S.vx=S.vx+S.ax*S.rate
|
||||
S.vy=S.vy+S.ay*S.rate
|
||||
end
|
||||
end
|
||||
S.t=S.t+dt*S.rate
|
||||
return S.t>1
|
||||
end
|
||||
FXupdate.line=_normUpdate
|
||||
|
||||
local FXdraw={}
|
||||
function FXdraw.badge(S)
|
||||
setColor(1,1,1,S.t<.2 and S.t*.6 or S.t<.8 and 1 or(1-S.t)*.6)
|
||||
gc.draw(IMG.badgeIcon,S.x,S.y)
|
||||
gc_setColor(1,1,1,S.t<.2 and S.t*.6 or S.t<.8 and 1 or(1-S.t)*.6)
|
||||
gc_draw(IMG.badgeIcon,S.x,S.y)
|
||||
end
|
||||
function FXdraw.attack(S)
|
||||
setColor(S.r*2,S.g*2,S.b*2,S.a*min(4-S.t*4,1))
|
||||
gc_setColor(S.r*2,S.g*2,S.b*2,S.a*min(4-S.t*4,1))
|
||||
|
||||
setWidth(S.wid)
|
||||
local t1,t2=max(5*S.t-4,0),min(S.t*4,1)
|
||||
gc.line(
|
||||
S.x1*(1-t1)+S.x2*t1,
|
||||
S.y1*(1-t1)+S.y2*t1,
|
||||
S.x1*(1-t2)+S.x2*t2,
|
||||
S.y1*(1-t2)+S.y2*t2
|
||||
)
|
||||
gc_setLineWidth(S.wid)
|
||||
local t1,t2=max(5*S.t-4,0),min(S.t*4,1)
|
||||
gc_line(
|
||||
S.x1*(1-t1)+S.x2*t1,
|
||||
S.y1*(1-t1)+S.y2*t1,
|
||||
S.x1*(1-t2)+S.x2*t2,
|
||||
S.y1*(1-t2)+S.y2*t2
|
||||
)
|
||||
|
||||
setWidth(S.wid*.6)
|
||||
t1,t2=max(4*S.t-3,0),min(S.t*5,1)
|
||||
gc.line(
|
||||
S.x1*(1-t1)+S.x2*t1,
|
||||
S.y1*(1-t1)+S.y2*t1,
|
||||
S.x1*(1-t2)+S.x2*t2,
|
||||
S.y1*(1-t2)+S.y2*t2
|
||||
)
|
||||
gc_setLineWidth(S.wid*.6)
|
||||
t1,t2=max(4*S.t-3,0),min(S.t*5,1)
|
||||
gc_line(
|
||||
S.x1*(1-t1)+S.x2*t1,
|
||||
S.y1*(1-t1)+S.y2*t1,
|
||||
S.x1*(1-t2)+S.x2*t2,
|
||||
S.y1*(1-t2)+S.y2*t2
|
||||
)
|
||||
end
|
||||
function FXdraw.tap(S)
|
||||
local t=S.t
|
||||
gc_setColor(1,1,1,(1-t)*.4)
|
||||
gc_circle('fill',S.x,S.y,30*(1-t)^.5)
|
||||
end
|
||||
function FXdraw.ripple(S)
|
||||
local t=S.t
|
||||
setWidth(2)
|
||||
setColor(1,1,1,1-t)
|
||||
gc.circle("line",S.x,S.y,t*(2-t)*S.r)
|
||||
local t=S.t
|
||||
gc_setLineWidth(2)
|
||||
gc_setColor(1,1,1,1-t)
|
||||
gc_circle('line',S.x,S.y,t*(2-t)*S.r)
|
||||
end
|
||||
function FXdraw.rectRipple(S)
|
||||
setWidth(6)
|
||||
setColor(1,1,1,1-S.t)
|
||||
local r=(10*S.t)^1.2
|
||||
gc.rectangle("line",S.x-r,S.y-r,S.w+2*r,S.h+2*r)
|
||||
gc_setLineWidth(6)
|
||||
gc_setColor(1,1,1,1-S.t)
|
||||
local r=(10*S.t)^1.2
|
||||
gc_rectangle('line',S.x-r,S.y-r,S.w+2*r,S.h+2*r)
|
||||
end
|
||||
function FXdraw.shade(S)
|
||||
setColor(S.r,S.g,S.b,1-S.t)
|
||||
gc.rectangle("fill",S.x,S.y,S.w,S.h,2)
|
||||
gc_setColor(S.r,S.g,S.b,1-S.t)
|
||||
gc_rectangle('fill',S.x,S.y,S.w,S.h,2)
|
||||
end
|
||||
function FXdraw.cell(S)
|
||||
setColor(1,1,1,1-S.t)
|
||||
gc.draw(S.image,S.x,S.y,nil,S.size,nil,S.cx,S.cy)
|
||||
gc_setColor(1,1,1,1-S.t)
|
||||
gc_draw(S.image,S.x,S.y,nil,S.size,nil,S.cx,S.cy)
|
||||
end
|
||||
function FXdraw.line(S)
|
||||
gc_setColor(1,1,1,S.a*(1-S.t))
|
||||
gc_line(S.x1,S.y1,S.x2,S.y2)
|
||||
end
|
||||
|
||||
local SYSFX={}
|
||||
function SYSFX.update(dt)
|
||||
for i=#fx,1,-1 do
|
||||
if fx[i]:update(dt) then
|
||||
rem(fx,i)
|
||||
end
|
||||
end
|
||||
for i=#fx,1,-1 do
|
||||
if fx[i]:update(dt)then
|
||||
rem(fx,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
function SYSFX.draw()
|
||||
for i=1,#fx do
|
||||
fx[i]:draw()
|
||||
end
|
||||
for i=1,#fx do
|
||||
fx[i]:draw()
|
||||
end
|
||||
end
|
||||
|
||||
function SYSFX.newBadge(x1,y1,x2,y2)
|
||||
fx[#fx+1]={
|
||||
update=FXupdate.badge,
|
||||
draw=FXdraw.badge,
|
||||
t=0,
|
||||
x=x1,y=y1,
|
||||
x1=x1,y1=y1,
|
||||
x2=x2,y2=y2,
|
||||
}
|
||||
ins(fx,{
|
||||
update=FXupdate.badge,
|
||||
draw=FXdraw.badge,
|
||||
t=0,
|
||||
x=x1,y=y1,
|
||||
x1=x1,y1=y1,
|
||||
x2=x2,y2=y2,
|
||||
})
|
||||
end
|
||||
function SYSFX.newAttack(rate,x1,y1,x2,y2,wid,r,g,b,a)
|
||||
fx[#fx+1]={
|
||||
update=FXupdate.attack,
|
||||
draw=FXdraw.attack,
|
||||
t=0,
|
||||
rate=rate,
|
||||
x1=x1,y1=y1,--Start pos
|
||||
x2=x2,y2=y2,--End pos
|
||||
wid=wid,--Line width
|
||||
r=r,g=g,b=b,a=a,
|
||||
}
|
||||
ins(fx,{
|
||||
update=FXupdate.attack,
|
||||
draw=FXdraw.attack,
|
||||
t=0,
|
||||
rate=rate,
|
||||
x1=x1,y1=y1,--Start pos
|
||||
x2=x2,y2=y2,--End pos
|
||||
wid=wid,--Line width
|
||||
r=r,g=g,b=b,a=a,
|
||||
})
|
||||
end
|
||||
function SYSFX.newTap(rate,x,y)
|
||||
local T=
|
||||
{
|
||||
update=FXupdate.tap,
|
||||
draw=FXdraw.tap,
|
||||
t=0,
|
||||
rate=rate,
|
||||
x=x,y=y,
|
||||
}
|
||||
ins(fx,T)
|
||||
end
|
||||
function SYSFX.newRipple(rate,x,y,r)
|
||||
fx[#fx+1]={
|
||||
update=FXupdate.ripple,
|
||||
draw=FXdraw.ripple,
|
||||
t=0,
|
||||
rate=rate,
|
||||
x=x,y=y,r=r,
|
||||
}
|
||||
ins(fx,{
|
||||
update=FXupdate.ripple,
|
||||
draw=FXdraw.ripple,
|
||||
t=0,
|
||||
rate=rate,
|
||||
x=x,y=y,r=r,
|
||||
})
|
||||
end
|
||||
function SYSFX.newRectRipple(rate,x,y,w,h)
|
||||
fx[#fx+1]={
|
||||
update=FXupdate.rectRipple,
|
||||
draw=FXdraw.rectRipple,
|
||||
t=0,
|
||||
rate=rate,
|
||||
x=x,y=y,w=w,h=h,
|
||||
}
|
||||
ins(fx,{
|
||||
update=FXupdate.rectRipple,
|
||||
draw=FXdraw.rectRipple,
|
||||
t=0,
|
||||
rate=rate,
|
||||
x=x,y=y,w=w,h=h,
|
||||
})
|
||||
end
|
||||
function SYSFX.newShade(rate,r,g,b,x,y,w,h)
|
||||
fx[#fx+1]={
|
||||
update=FXupdate.shade,
|
||||
draw=FXdraw.shade,
|
||||
t=0,
|
||||
rate=rate,
|
||||
r=r,g=g,b=b,
|
||||
x=x,y=y,w=w,h=h,
|
||||
}
|
||||
function SYSFX.newShade(rate,x,y,w,h,r,g,b)
|
||||
ins(fx,{
|
||||
update=FXupdate.shade,
|
||||
draw=FXdraw.shade,
|
||||
t=0,
|
||||
rate=rate,
|
||||
x=x,y=y,w=w,h=h,
|
||||
r=r or 1,g=g or 1,b=b or 1,
|
||||
})
|
||||
end
|
||||
function SYSFX.newCell(rate,image,size,x,y,vx,vy,ax,ay)
|
||||
fx[#fx+1]={
|
||||
update=FXupdate.cell,
|
||||
draw=FXdraw.cell,
|
||||
t=0,
|
||||
rate=rate*(.9+rnd()*.2),
|
||||
image=image,size=size,
|
||||
cx=image:getWidth()*.5,cy=image:getHeight()*.5,
|
||||
x=x,y=y,
|
||||
vx=vx,vy=vy,
|
||||
ax=ax,ay=ay,
|
||||
}
|
||||
ins(fx,{
|
||||
update=FXupdate.cell,
|
||||
draw=FXdraw.cell,
|
||||
t=0,
|
||||
rate=rate*(.9+rnd()*.2),
|
||||
image=image,size=size,
|
||||
cx=image:getWidth()*.5,cy=image:getHeight()*.5,
|
||||
x=x,y=y,
|
||||
vx=vx,vy=vy,
|
||||
ax=ax,ay=ay,
|
||||
})
|
||||
end
|
||||
return SYSFX
|
||||
function SYSFX.newLine(rate,x1,y1,x2,y2,r,g,b,a)
|
||||
ins(fx,{
|
||||
update=FXupdate.line,
|
||||
draw=FXdraw.line,
|
||||
t=0,
|
||||
rate=rate,
|
||||
x1=x1 or 0,y1=y1 or 0,
|
||||
x2=x2 or x1 or 1280,y2=y2 or y1 or 720,
|
||||
r=r or 1,g=g or 1,b=b or 1,a=a or 1,
|
||||
})
|
||||
end
|
||||
return SYSFX
|
||||
|
||||
255
Zframework/tableExtend.lua
Normal file
255
Zframework/tableExtend.lua
Normal file
@@ -0,0 +1,255 @@
|
||||
local find=string.find
|
||||
local rem=table.remove
|
||||
local next,type=next,type
|
||||
local TABLE={}
|
||||
|
||||
--Get a new filled table
|
||||
function TABLE.new(val,count)
|
||||
local L={}
|
||||
for i=1,count do
|
||||
L[i]=val
|
||||
end
|
||||
return L
|
||||
end
|
||||
|
||||
--Get a copy of [1~#] elements
|
||||
function TABLE.shift(org,depth)
|
||||
if not depth then depth=1e99 end
|
||||
local L={}
|
||||
for i=1,#org do
|
||||
if type(org[i])=='table'and depth>0 then
|
||||
L[i]=TABLE.shift(org[i],depth-1)
|
||||
else
|
||||
L[i]=org[i]
|
||||
end
|
||||
end
|
||||
return L
|
||||
end
|
||||
|
||||
--Get a full copy of a table, depth = how many layers will be recreate, default to inf
|
||||
function TABLE.copy(org,depth)
|
||||
if not depth then depth=1e99 end
|
||||
local L={}
|
||||
for k,v in next,org do
|
||||
if type(v)=='table'and depth>0 then
|
||||
L[k]=TABLE.copy(v,depth-1)
|
||||
else
|
||||
L[k]=v
|
||||
end
|
||||
end
|
||||
return L
|
||||
end
|
||||
|
||||
--For all things in new, push to old
|
||||
function TABLE.cover(new,old)
|
||||
for k,v in next,new do
|
||||
old[k]=v
|
||||
end
|
||||
end
|
||||
|
||||
--For all things in new, push to old
|
||||
function TABLE.coverR(new,old)
|
||||
for k,v in next,new do
|
||||
if type(v)=='table'and type(old[k])=='table'then
|
||||
TABLE.coverR(v,old[k])
|
||||
else
|
||||
old[k]=v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--For all things in new if same type in old, push to old
|
||||
function TABLE.update(new,old)
|
||||
for k,v in next,new do
|
||||
if type(v)==type(old[k])then
|
||||
if type(v)=='table'then
|
||||
TABLE.update(v,old[k])
|
||||
else
|
||||
old[k]=v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--For all things in new if no val in old, push to old
|
||||
function TABLE.complete(new,old)
|
||||
for k,v in next,new do
|
||||
if type(v)=='table'then
|
||||
if old[k]==nil then old[k]={}end
|
||||
TABLE.complete(v,old[k])
|
||||
elseif old[k]==nil then
|
||||
old[k]=v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Remove [1~#] of table
|
||||
function TABLE.cut(G)
|
||||
for i=1,#G do
|
||||
G[i]=nil
|
||||
end
|
||||
end
|
||||
|
||||
--Clear table
|
||||
function TABLE.clear(G)
|
||||
for k in next,G do
|
||||
G[k]=nil
|
||||
end
|
||||
end
|
||||
|
||||
--Remove duplicated value of [1~#]
|
||||
function TABLE.trimDuplicate(org)
|
||||
local cache={}
|
||||
for i=1,#org,-1 do
|
||||
if cache[org[i]]then
|
||||
rem(org,i)
|
||||
else
|
||||
cache[org[i]]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Discard duplicated value
|
||||
function TABLE.remDuplicate(org)
|
||||
local cache={}
|
||||
for k,v in next,org do
|
||||
if cache[v]then
|
||||
org[k]=nil
|
||||
else
|
||||
cache[v]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--Reverse [1~#]
|
||||
function TABLE.reverse(org)
|
||||
local l=#org
|
||||
for i=1,math.floor(l/2)do
|
||||
org[i],org[l+1-i]=org[l+1-i],org[i]
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------
|
||||
|
||||
--Find value in [1~#]
|
||||
function TABLE.find(t,val)
|
||||
for i=1,#t do if t[i]==val then return i end end
|
||||
end
|
||||
|
||||
--Return next value of [1~#] (by value)
|
||||
function TABLE.next(t,val)
|
||||
for i=1,#t do if t[i]==val then return t[i%#t+1]end end
|
||||
end
|
||||
|
||||
--------------------------
|
||||
|
||||
--Find value in whole table
|
||||
function TABLE.search(t,val)
|
||||
for k,v in next,t do if v==val then return k end end
|
||||
end
|
||||
|
||||
--Re-index string value of a table
|
||||
function TABLE.reIndex(org)
|
||||
for k,v in next,org do
|
||||
if type(v)=='string'then
|
||||
org[k]=org[v]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------
|
||||
|
||||
--Dump a simple lua table
|
||||
do--function TABLE.dump(L,t)
|
||||
local tabs={
|
||||
[0]="",
|
||||
"\t",
|
||||
"\t\t",
|
||||
"\t\t\t",
|
||||
"\t\t\t\t",
|
||||
"\t\t\t\t\t",
|
||||
}
|
||||
local function dump(L,t)
|
||||
local s
|
||||
if t then
|
||||
s="{\n"
|
||||
else
|
||||
s="return{\n"
|
||||
t=1
|
||||
if type(L)~='table'then
|
||||
return
|
||||
end
|
||||
end
|
||||
local count=1
|
||||
for k,v in next,L do
|
||||
local T=type(k)
|
||||
if T=='number'then
|
||||
if k==count then
|
||||
k=""
|
||||
count=count+1
|
||||
else
|
||||
k="["..k.."]="
|
||||
end
|
||||
elseif T=='string'then
|
||||
if find(k,"[^0-9a-zA-Z_]")then
|
||||
k="[\""..k.."\"]="
|
||||
else
|
||||
k=k.."="
|
||||
end
|
||||
elseif T=='boolean'then k="["..k.."]="
|
||||
else error("Error key type!")
|
||||
end
|
||||
T=type(v)
|
||||
if T=='number'then v=tostring(v)
|
||||
elseif T=='string'then v="\""..v.."\""
|
||||
elseif T=='table'then v=dump(v,t+1)
|
||||
elseif T=='boolean'then v=tostring(v)
|
||||
else error("Error data type!")
|
||||
end
|
||||
s=s..tabs[t]..k..v..",\n"
|
||||
end
|
||||
return s..tabs[t-1].."}"
|
||||
end
|
||||
TABLE.dump=dump
|
||||
end
|
||||
|
||||
--Dump a simple lua table (no whitespaces)
|
||||
do--function TABLE.dumpDeflate(L,t)
|
||||
local function dump(L)
|
||||
local s="return{"
|
||||
if type(L)~='table'then return end
|
||||
local count=1
|
||||
for k,v in next,L do
|
||||
local T=type(k)
|
||||
if T=='number'then
|
||||
if k==count then
|
||||
k=""
|
||||
count=count+1
|
||||
else
|
||||
k="["..k.."]="
|
||||
end
|
||||
elseif T=='string'then
|
||||
if find(k,"[^0-9a-zA-Z_]")then
|
||||
k="[\""..k.."\"]="
|
||||
else
|
||||
k=k.."="
|
||||
end
|
||||
elseif T=='boolean'then k="["..k.."]="
|
||||
else error("Error key type!")
|
||||
end
|
||||
T=type(v)
|
||||
if T=='number'then v=tostring(v)
|
||||
elseif T=='string'then v="\""..v.."\""
|
||||
elseif T=='table'then v=dump(v)
|
||||
elseif T=='boolean'then v=tostring(v)
|
||||
else error("Error data type!")
|
||||
end
|
||||
end
|
||||
return s.."}"
|
||||
end
|
||||
TABLE.dumpDeflate=dump
|
||||
end
|
||||
|
||||
return TABLE
|
||||
@@ -1,74 +1,56 @@
|
||||
local rem=table.remove
|
||||
local ct=coroutine
|
||||
local assert=assert
|
||||
local assert,resume,status=assert,coroutine.resume,coroutine.status
|
||||
local tasks={}
|
||||
|
||||
local TASK={
|
||||
netTaskCount=0,
|
||||
}
|
||||
local TASK={}
|
||||
function TASK.getCount()
|
||||
return #tasks
|
||||
return #tasks
|
||||
end
|
||||
function TASK.update()
|
||||
for i=#tasks,1,-1 do
|
||||
local T=tasks[i]
|
||||
assert(ct.resume(T.thread))
|
||||
if ct.status(T.thread)=="dead"then
|
||||
if T.net then
|
||||
TASK.netTaskCount=TASK.netTaskCount-1
|
||||
end
|
||||
rem(tasks,i)
|
||||
end
|
||||
end
|
||||
local trigFrame=0
|
||||
function TASK.update(dt)
|
||||
trigFrame=trigFrame+dt*60
|
||||
while trigFrame>=1 do
|
||||
for i=#tasks,1,-1 do
|
||||
local T=tasks[i]
|
||||
if status(T.thread)=='dead'then
|
||||
rem(tasks,i)
|
||||
else
|
||||
assert(resume(T.thread))
|
||||
end
|
||||
end
|
||||
trigFrame=trigFrame-1
|
||||
end
|
||||
end
|
||||
function TASK.new(code,...)
|
||||
local thread=ct.create(code)
|
||||
if ...~=nil then ct.resume(thread,...)end
|
||||
if ct.status(thread)~="dead"then
|
||||
tasks[#tasks+1]={
|
||||
thread=thread,
|
||||
code=code,
|
||||
args={...},
|
||||
}
|
||||
end
|
||||
end
|
||||
function TASK.newNet(code,...)
|
||||
local thread=ct.create(code)
|
||||
if ...~=nil then ct.resume(thread,...)end
|
||||
if ct.status(thread)~="dead"then
|
||||
tasks[#tasks+1]={
|
||||
thread=thread,
|
||||
code=code,
|
||||
args={...},
|
||||
net=true,
|
||||
}
|
||||
end
|
||||
local thread=coroutine.create(code)
|
||||
assert(resume(thread,...))
|
||||
if status(thread)~='dead'then
|
||||
tasks[#tasks+1]={
|
||||
thread=thread,
|
||||
code=code,
|
||||
args={...},
|
||||
}
|
||||
end
|
||||
end
|
||||
function TASK.removeTask_code(code)
|
||||
for i=#tasks,1,-1 do
|
||||
if tasks[i].code==code then
|
||||
if tasks[i].net then
|
||||
TASK.netTaskCount=TASK.netTaskCount-1
|
||||
end
|
||||
rem(tasks,i)
|
||||
end
|
||||
end
|
||||
for i=#tasks,1,-1 do
|
||||
if tasks[i].code==code then
|
||||
rem(tasks,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
function TASK.removeTask_iterate(func,...)
|
||||
for i=#tasks,1,-1 do
|
||||
if func(tasks[i],...)then
|
||||
if tasks[i].net then
|
||||
TASK.netTaskCount=TASK.netTaskCount-1
|
||||
end
|
||||
rem(tasks,i)
|
||||
end
|
||||
end
|
||||
for i=#tasks,1,-1 do
|
||||
if func(tasks[i],...)then
|
||||
rem(tasks,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
function TASK.clear()
|
||||
local i=#tasks
|
||||
while i>0 do
|
||||
tasks[i]=nil
|
||||
i=i-1
|
||||
end
|
||||
local i=#tasks
|
||||
while i>0 do
|
||||
tasks[i]=nil
|
||||
i=i-1
|
||||
end
|
||||
end
|
||||
return TASK
|
||||
return TASK
|
||||
|
||||
12
Zframework/test.lua
Normal file
12
Zframework/test.lua
Normal file
@@ -0,0 +1,12 @@
|
||||
local TEST={}
|
||||
|
||||
--Wait for the scene swapping animation to finish
|
||||
function TEST.yieldUntilNextScene()
|
||||
while SCN.swapping do YIELD()end
|
||||
end
|
||||
|
||||
function TEST.yieldN(frames)
|
||||
for _=1,frames do YIELD()end
|
||||
end
|
||||
|
||||
return TEST
|
||||
@@ -1,126 +1,153 @@
|
||||
local gc=love.graphics
|
||||
local rnd=math.random
|
||||
local rem=table.remove
|
||||
local setFont,mStr=setFont,mStr
|
||||
local getColor,setColor=gc.getColor,gc.setColor
|
||||
|
||||
local int,rnd=math.floor,math.random
|
||||
local ins,rem=table.insert,table.remove
|
||||
local draw=gc.draw
|
||||
|
||||
local texts={}
|
||||
|
||||
local textFX={}
|
||||
function textFX.appear(t)
|
||||
mStr(t.text,t.x,t.y-t.font*.7)
|
||||
draw(
|
||||
t.text,t.x,t.y,
|
||||
nil,
|
||||
nil,nil,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||
)
|
||||
end
|
||||
function textFX.sudden(t)
|
||||
gc.setColor(1,1,1,1-t.c)
|
||||
mStr(t.text,t.x,t.y-t.font*.7)
|
||||
setColor(1,1,1,1-t.c)
|
||||
draw(
|
||||
t.text,t.x,t.y,
|
||||
nil,
|
||||
nil,nil,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||
)
|
||||
end
|
||||
function textFX.fly(t)
|
||||
mStr(t.text,t.x+(t.c-.5)^3*300,t.y-t.font*.7)
|
||||
draw(
|
||||
t.text,t.x+(t.c-.5)^3*300,t.y,
|
||||
nil,
|
||||
nil,nil,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||
)
|
||||
end
|
||||
function textFX.stretch(t)
|
||||
gc.push("transform")
|
||||
gc.translate(t.x,t.y)
|
||||
if t.c<.3 then gc.scale((.3-t.c)*1.6+1,1)end
|
||||
mStr(t.text,0,-t.font*.7)
|
||||
gc.pop()
|
||||
draw(
|
||||
t.text,t.x,t.y,
|
||||
nil,
|
||||
t.c<.3 and(.3-t.c)*1.6+1 or 1,1,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||
)
|
||||
end
|
||||
function textFX.drive(t)
|
||||
gc.push("transform")
|
||||
gc.translate(t.x,t.y)
|
||||
if t.c<.3 then gc.shear((.3-t.c)*2,0)end
|
||||
mStr(t.text,0,-t.font*.7)
|
||||
gc.pop()
|
||||
draw(
|
||||
t.text,t.x,t.y,
|
||||
nil,
|
||||
nil,nil,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5,
|
||||
t.c<.3 and(.3-t.c)*2 or 0,0
|
||||
)
|
||||
end
|
||||
function textFX.spin(t)
|
||||
gc.push("transform")
|
||||
gc.translate(t.x,t.y)
|
||||
if t.c<.3 then
|
||||
gc.rotate((.3-t.c)^2*4)
|
||||
elseif t.c>.8 then
|
||||
gc.rotate((t.c-.8)^2*-4)
|
||||
end
|
||||
mStr(t.text,0,-t.font*.7)
|
||||
gc.pop()
|
||||
draw(
|
||||
t.text,t.x,t.y,
|
||||
t.c<.3 and(.3-t.c)^2*4 or t.c<.8 and 0 or(t.c-.8)^2*-4,
|
||||
nil,nil,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||
)
|
||||
end
|
||||
function textFX.flicker(t)
|
||||
local _,_,_,T=gc.getColor()
|
||||
gc.setColor(1,1,1,T*(rnd()+.5))
|
||||
mStr(t.text,t.x,t.y-t.font*.7)
|
||||
local _,_,_,T=getColor()
|
||||
setColor(1,1,1,T*(rnd()+.5))
|
||||
draw(
|
||||
t.text,t.x,t.y,
|
||||
nil,
|
||||
nil,nil,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||
)
|
||||
end
|
||||
function textFX.zoomout(t)
|
||||
gc.push("transform")
|
||||
local k=t.c^.5*.1+1
|
||||
gc.translate(t.x,t.y)
|
||||
gc.scale(k,k)
|
||||
mStr(t.text,0,-t.font*.7)
|
||||
gc.pop()
|
||||
draw(
|
||||
t.text,t.x,t.y,
|
||||
nil,
|
||||
t.c^.5*.1+1,nil,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||
)
|
||||
end
|
||||
function textFX.beat(t)
|
||||
gc.push("transform")
|
||||
gc.translate(t.x,t.y)
|
||||
if t.c<.3 then
|
||||
local k=1.3-t.c^2/.3
|
||||
gc.scale(k,k)
|
||||
end
|
||||
mStr(t.text,0,-t.font*.7)
|
||||
gc.pop()
|
||||
local k=t.c<.3 and 1.3-t.c^2/.3 or 1
|
||||
draw(
|
||||
t.text,t.x,t.y,
|
||||
nil,
|
||||
k,k,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||
)
|
||||
end
|
||||
function textFX.score(t)
|
||||
local _,_,_,T=gc.getColor()
|
||||
gc.setColor(1,1,1,T*.5)
|
||||
mStr(t.text,t.x,t.y-t.font*.7-t.c^.2*50)
|
||||
local _,_,_,T=getColor()
|
||||
setColor(1,1,1,T*.5)
|
||||
draw(
|
||||
t.text,t.x,t.y-0-t.c^.2*50,
|
||||
nil,
|
||||
nil,nil,
|
||||
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||
)
|
||||
end
|
||||
|
||||
local TEXT={}
|
||||
function TEXT.clear()
|
||||
texts={}
|
||||
end
|
||||
function TEXT.getText(text,x,y,font,style,spd,stop)--Another version of TEXT()
|
||||
return{
|
||||
c=0,
|
||||
text=text,
|
||||
x=x or 0,
|
||||
y=y or 0,
|
||||
font=font or 40,
|
||||
spd=(spd or 1)/60,
|
||||
stop=stop,
|
||||
draw=textFX[style]or assert(false,"unavailable type:"..style),
|
||||
}
|
||||
texts={}
|
||||
end
|
||||
function TEXT.show(text,x,y,font,style,spd,stop)
|
||||
texts[#texts+1]={
|
||||
c=0, --Timer
|
||||
text=text, --String
|
||||
x=x or 0, --X
|
||||
y=y or 0, --Y
|
||||
font=font or 40, --Font
|
||||
spd=(spd or 1)/60, --Timing speed(1=last 1 sec)
|
||||
stop=stop, --Stop time(sustained text)
|
||||
draw=textFX[style]or assert(false,"unavailable type:"..style), --Draw method
|
||||
}
|
||||
ins(texts,{
|
||||
c=0, --Timer
|
||||
text=gc.newText(FONT.get(int(font/5)*5 or 40),text), --String
|
||||
x=x or 0, --X
|
||||
y=y or 0, --Y
|
||||
spd=(spd or 1), --Timing speed(1=last 1 sec)
|
||||
stop=stop, --Stop time(sustained text)
|
||||
draw=assert(textFX[style or'appear'],"no text type:"..style),--Draw method
|
||||
})
|
||||
end
|
||||
function TEXT.update(list)
|
||||
if not list then list=texts end
|
||||
for i=#list,1,-1 do
|
||||
local t=list[i]
|
||||
t.c=t.c+t.spd
|
||||
if t.stop then
|
||||
if t.c>t.stop then
|
||||
t.c=t.stop
|
||||
end
|
||||
end
|
||||
if t.c>1 then
|
||||
rem(list,i)
|
||||
end
|
||||
end
|
||||
function TEXT.getText(text,x,y,font,style,spd,stop)--Another version of TEXT.show(), but only return text object, need manual management
|
||||
return{
|
||||
c=0,
|
||||
text=gc.newText(FONT.get(int(font/5)*5 or 40),text),
|
||||
x=x or 0,
|
||||
y=y or 0,
|
||||
spd=(spd or 1),
|
||||
stop=stop,
|
||||
draw=textFX[style or'appear']or error("unavailable type:"..style),
|
||||
}
|
||||
end
|
||||
function TEXT.update(dt,list)
|
||||
if not list then
|
||||
list=texts
|
||||
end
|
||||
for i=#list,1,-1 do
|
||||
local t=list[i]
|
||||
t.c=t.c+t.spd*dt
|
||||
if t.stop then
|
||||
if t.c>t.stop then
|
||||
t.c=t.stop
|
||||
end
|
||||
end
|
||||
if t.c>1 then
|
||||
rem(list,i)
|
||||
end
|
||||
end
|
||||
end
|
||||
function TEXT.draw(list)
|
||||
if not list then list=texts end
|
||||
for i=1,#list do
|
||||
local t=list[i]
|
||||
local p=t.c
|
||||
gc.setColor(1,1,1,p<.2 and p*5 or p<.8 and 1 or 5-p*5)
|
||||
setFont(t.font)
|
||||
t:draw()
|
||||
end
|
||||
if not list then
|
||||
list=texts
|
||||
end
|
||||
for i=1,#list do
|
||||
local t=list[i]
|
||||
local p=t.c
|
||||
setColor(1,1,1,p<.2 and p*5 or p<.8 and 1 or 5-p*5)
|
||||
t:draw()
|
||||
end
|
||||
end
|
||||
return TEXT
|
||||
return TEXT
|
||||
|
||||
@@ -1,688 +0,0 @@
|
||||
local gc=love.graphics
|
||||
local int=math.floor
|
||||
local sub,find,format=string.sub,string.find,string.format
|
||||
local ins=table.insert
|
||||
|
||||
do--LOADLIB
|
||||
local libs={
|
||||
CC={
|
||||
Windows="CCloader",
|
||||
Linux="CCloader",
|
||||
Android="libCCloader.so",
|
||||
libFunc="luaopen_CCloader",
|
||||
},
|
||||
NETlib={
|
||||
Windows="client",
|
||||
Linux="client",
|
||||
Android="client.so",
|
||||
libFunc="luaopen_client",
|
||||
},
|
||||
}
|
||||
function LOADLIB(name)
|
||||
local libName=libs[name]
|
||||
if SYSTEM=="Windows"or SYSTEM=="Linux"then
|
||||
local success,message=require(libName[SYSTEM])
|
||||
if success then
|
||||
return success
|
||||
else
|
||||
LOG.print("Cannot load "..name..": "..message,"warn",COLOR.red)
|
||||
end
|
||||
elseif SYSTEM=="Android"then
|
||||
local fs=love.filesystem
|
||||
local platform={"arm64-v8a","armeabi-v7a"}
|
||||
local libFunc
|
||||
for i=1,#platform do
|
||||
local soFile,size=fs.read("data","libAndroid/"..platform[i].."/"..libName.Android)
|
||||
if soFile then
|
||||
local success,message=fs.write(libName.Android,soFile,size)
|
||||
if success then
|
||||
libFunc,message=package.loadlib(table.concat({fs.getSaveDirectory(),libName.Android},"/"),libName.libFunc)
|
||||
if libFunc then
|
||||
LOG.print(name.." lib loaded","warn",COLOR.green)
|
||||
break
|
||||
else
|
||||
LOG.print("Cannot load "..name..": "..message,"warn",COLOR.red)
|
||||
end
|
||||
else
|
||||
LOG.print("Write "..name.."-"..platform[i].." to saving failed: "..message,"warn",COLOR.red)
|
||||
end
|
||||
else
|
||||
LOG.print("Read "..name.."-"..platform[i].." failed","warn",COLOR.red)
|
||||
end
|
||||
end
|
||||
if not libFunc then
|
||||
LOG.print("failed to load "..name,"warn",COLOR.red)
|
||||
return
|
||||
end
|
||||
return libFunc()
|
||||
else
|
||||
LOG.print("No "..name.." for "..SYSTEM,"warn",COLOR.red)
|
||||
return
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
do--setFont
|
||||
local newFont=gc.setNewFont
|
||||
local setNewFont=gc.setFont
|
||||
local fontCache,currentFontSize={}
|
||||
if love.filesystem.getInfo("font.ttf")then
|
||||
local fontData=love.filesystem.newFile("font.ttf")
|
||||
function setFont(s)
|
||||
if s~=currentFontSize then
|
||||
if not fontCache[s]then
|
||||
fontCache[s]=newFont(fontData,s)
|
||||
end
|
||||
setNewFont(fontCache[s])
|
||||
currentFontSize=s
|
||||
end
|
||||
end
|
||||
function getFont(s)
|
||||
if not fontCache[s]then
|
||||
fontCache[s]=newFont(fontData,s)
|
||||
end
|
||||
return fontCache[s]
|
||||
end
|
||||
else
|
||||
function setFont(s)
|
||||
if s~=currentFontSize then
|
||||
if not fontCache[s]then
|
||||
fontCache[s]=newFont(s)
|
||||
end
|
||||
setNewFont(fontCache[s])
|
||||
currentFontSize=s
|
||||
end
|
||||
end
|
||||
function getFont(s)
|
||||
if not fontCache[s]then
|
||||
fontCache[s]=newFont(s)
|
||||
end
|
||||
return fontCache[s]
|
||||
end
|
||||
end
|
||||
end
|
||||
do--upperChar
|
||||
local upper=string.upper
|
||||
upperList={
|
||||
["1"]="!",["2"]="@",["3"]="#",["4"]="$",["5"]="%",
|
||||
["6"]="^",["7"]="&",["8"]="*",["9"]="(",["0"]=")",
|
||||
["`"]="~",["-"]="_",["="]="+",
|
||||
["["]="{",["]"]="}",["\\"]="|",
|
||||
[";"]=":",["'"]="\"",
|
||||
[","]="<",["."]=">",["/"]="?",
|
||||
}
|
||||
function upperChar(c)
|
||||
return upperList[c]or upper(c)
|
||||
end
|
||||
end
|
||||
do--dumpTable
|
||||
local tabs={
|
||||
[0]="",
|
||||
"\t",
|
||||
"\t\t",
|
||||
"\t\t\t",
|
||||
"\t\t\t\t",
|
||||
"\t\t\t\t\t",
|
||||
}
|
||||
function dumpTable(L,t)
|
||||
local s
|
||||
if t then
|
||||
s="{\n"
|
||||
else
|
||||
s="return{\n"
|
||||
t=1
|
||||
if type(L)~="table"then
|
||||
return
|
||||
end
|
||||
end
|
||||
local count=1
|
||||
for k,v in next,L do
|
||||
local T=type(k)
|
||||
if T=="number"then
|
||||
if k==count then
|
||||
k=""
|
||||
count=count+1
|
||||
else
|
||||
k="["..k.."]="
|
||||
end
|
||||
elseif T=="string"then
|
||||
if find(k,"[^0-9a-zA-Z_]")then
|
||||
k="[\""..k.."\"]="
|
||||
else
|
||||
k=k.."="
|
||||
end
|
||||
elseif T=="boolean"then k="["..k.."]="
|
||||
else assert(false,"Error key type!")
|
||||
end
|
||||
T=type(v)
|
||||
if T=="number"then v=tostring(v)
|
||||
elseif T=="string"then v="\""..v.."\""
|
||||
elseif T=="table"then v=dumpTable(v,t+1)
|
||||
elseif T=="boolean"then v=tostring(v)
|
||||
else assert(false,"Error data type!")
|
||||
end
|
||||
s=s..tabs[t]..k..v..",\n"
|
||||
end
|
||||
return s..tabs[t-1].."}"
|
||||
end
|
||||
end
|
||||
do--json
|
||||
--
|
||||
-- json.lua
|
||||
--
|
||||
-- Copyright (c) 2020 rxi
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
-- this software and associated documentation files (the "Software"), to deal in
|
||||
-- the Software without restriction, including without limitation the rights to
|
||||
-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
-- of the Software, and to permit persons to whom the Software is furnished to do
|
||||
-- so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in all
|
||||
-- copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
-- SOFTWARE.
|
||||
--
|
||||
|
||||
local char=string.char
|
||||
json = {}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Encode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local encode
|
||||
|
||||
local escape_char_map = {
|
||||
["\\"] = "\\",
|
||||
["\""] = "\"",
|
||||
["\b"] = "b",
|
||||
["\f"] = "f",
|
||||
["\n"] = "n",
|
||||
["\r"] = "r",
|
||||
["\t"] = "t"
|
||||
}
|
||||
|
||||
local escape_char_map_inv = {["/"] = "/"}
|
||||
for k, v in pairs(escape_char_map) do escape_char_map_inv[v] = k end
|
||||
|
||||
local function escape_char(c)
|
||||
return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte()))
|
||||
end
|
||||
|
||||
local function encode_nil() return "null" end
|
||||
|
||||
local function encode_table(val, stack)
|
||||
local res = {}
|
||||
stack = stack or {}
|
||||
|
||||
-- Circular reference?
|
||||
if stack[val] then error("circular reference") end
|
||||
|
||||
stack[val] = true
|
||||
|
||||
if rawget(val, 1) ~= nil or next(val) == nil then
|
||||
-- Treat as array -- check keys are valid and it is not sparse
|
||||
local n = 0
|
||||
for k in pairs(val) do
|
||||
if type(k) ~= "number" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
n = n + 1
|
||||
end
|
||||
if n ~= #val then error("invalid table: sparse array") end
|
||||
-- Encode
|
||||
for _, v in ipairs(val) do ins(res, encode(v, stack)) end
|
||||
stack[val] = nil
|
||||
return "[" .. table.concat(res, ",") .. "]"
|
||||
|
||||
else
|
||||
-- Treat as an object
|
||||
for k, v in pairs(val) do
|
||||
if type(k) ~= "string" then
|
||||
error("invalid table: mixed or invalid key types")
|
||||
end
|
||||
ins(res, encode(k, stack) .. ":" .. encode(v, stack))
|
||||
end
|
||||
stack[val] = nil
|
||||
return "{" .. table.concat(res, ",") .. "}"
|
||||
end
|
||||
end
|
||||
|
||||
local function encode_string(val)
|
||||
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
|
||||
end
|
||||
|
||||
local function encode_number(val)
|
||||
-- Check for NaN, -inf and inf
|
||||
if val ~= val or val <= -math.huge or val >= math.huge then
|
||||
error("unexpected number value '" .. tostring(val) .. "'")
|
||||
end
|
||||
return string.format("%.14g", val)
|
||||
end
|
||||
|
||||
local type_func_map = {
|
||||
["nil"] = encode_nil,
|
||||
["table"] = encode_table,
|
||||
["string"] = encode_string,
|
||||
["number"] = encode_number,
|
||||
["boolean"] = tostring
|
||||
}
|
||||
|
||||
encode = function(val, stack)
|
||||
local t = type(val)
|
||||
local f = type_func_map[t]
|
||||
if f then return f(val, stack) end
|
||||
error("unexpected type '" .. t .. "'")
|
||||
end
|
||||
|
||||
function json.encode(val)
|
||||
local a,b=pcall(encode,val)
|
||||
if a then
|
||||
return b
|
||||
else
|
||||
LOG.print(text.jsonError..": "..(b or"uknErr"),"warn")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Decode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local parse
|
||||
|
||||
local function create_set(...)
|
||||
local res = {}
|
||||
for i = 1, select("#", ...) do res[select(i, ...)] = true end
|
||||
return res
|
||||
end
|
||||
|
||||
local space_chars = create_set(" ", "\t", "\r", "\n")
|
||||
local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
|
||||
local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
|
||||
local literals = create_set("true", "false", "null")
|
||||
|
||||
local literal_map = {["true"] = true, ["false"] = false, ["null"] = nil}
|
||||
|
||||
local function next_char(str, idx, set, negate)
|
||||
for i = idx, #str do if set[str:sub(i, i)] ~= negate then return i end end
|
||||
return #str + 1
|
||||
end
|
||||
|
||||
local function decode_error(str, idx, msg)
|
||||
local line_count = 1
|
||||
local col_count = 1
|
||||
for i = 1, idx - 1 do
|
||||
col_count = col_count + 1
|
||||
if str:sub(i, i) == "\n" then
|
||||
line_count = line_count + 1
|
||||
col_count = 1
|
||||
end
|
||||
end
|
||||
error(string.format("%s at line %d col %d", msg, line_count, col_count))
|
||||
end
|
||||
|
||||
local function codepoint_to_utf8(n)
|
||||
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
|
||||
local f = math.floor
|
||||
if n <= 0x7f then
|
||||
return char(n)
|
||||
elseif n <= 0x7ff then
|
||||
return char(f(n / 64) + 192, n % 64 + 128)
|
||||
elseif n <= 0xffff then
|
||||
return char(f(n / 4096) + 224, f(n % 4096 / 64) + 128,
|
||||
n % 64 + 128)
|
||||
elseif n <= 0x10ffff then
|
||||
return char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,
|
||||
f(n % 4096 / 64) + 128, n % 64 + 128)
|
||||
end
|
||||
error(string.format("invalid unicode codepoint '%x'", n))
|
||||
end
|
||||
|
||||
local function parse_unicode_escape(s)
|
||||
local n1 = tonumber(s:sub(1, 4), 16)
|
||||
local n2 = tonumber(s:sub(7, 10), 16)
|
||||
-- Surrogate pair?
|
||||
if n2 then
|
||||
return
|
||||
codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
|
||||
else
|
||||
return codepoint_to_utf8(n1)
|
||||
end
|
||||
end
|
||||
|
||||
local function parse_string(str, i)
|
||||
local res = ""
|
||||
local j = i + 1
|
||||
local k = j
|
||||
|
||||
while j <= #str do
|
||||
local x = str:byte(j)
|
||||
|
||||
if x < 32 then
|
||||
decode_error(str, j, "control character in string")
|
||||
|
||||
elseif x == 92 then -- `\`: Escape
|
||||
res = res .. str:sub(k, j - 1)
|
||||
j = j + 1
|
||||
local c = str:sub(j, j)
|
||||
if c == "u" then
|
||||
local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) or
|
||||
str:match("^%x%x%x%x", j + 1) or
|
||||
decode_error(str, j - 1,
|
||||
"invalid unicode escape in string")
|
||||
res = res .. parse_unicode_escape(hex)
|
||||
j = j + #hex
|
||||
else
|
||||
if not escape_chars[c] then
|
||||
decode_error(str, j - 1,
|
||||
"invalid escape char '" .. c .. "' in string")
|
||||
end
|
||||
res = res .. escape_char_map_inv[c]
|
||||
end
|
||||
k = j + 1
|
||||
|
||||
elseif x == 34 then -- `"`: End of string
|
||||
res = res .. str:sub(k, j - 1)
|
||||
return res, j + 1
|
||||
end
|
||||
|
||||
j = j + 1
|
||||
end
|
||||
|
||||
decode_error(str, i, "expected closing quote for string")
|
||||
end
|
||||
|
||||
local function parse_number(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local s = str:sub(i, x - 1)
|
||||
local n = tonumber(s)
|
||||
if not n then decode_error(str, i, "invalid number '" .. s .. "'") end
|
||||
return n, x
|
||||
end
|
||||
|
||||
local function parse_literal(str, i)
|
||||
local x = next_char(str, i, delim_chars)
|
||||
local word = str:sub(i, x - 1)
|
||||
if not literals[word] then
|
||||
decode_error(str, i, "invalid literal '" .. word .. "'")
|
||||
end
|
||||
return literal_map[word], x
|
||||
end
|
||||
|
||||
local function parse_array(str, i)
|
||||
local res = {}
|
||||
local n = 1
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local x
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of array?
|
||||
if str:sub(i, i) == "]" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read token
|
||||
x, i = parse(str, i)
|
||||
res[n] = x
|
||||
n = n + 1
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "]" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
local function parse_object(str, i)
|
||||
local res = {}
|
||||
i = i + 1
|
||||
while 1 do
|
||||
local key, val
|
||||
i = next_char(str, i, space_chars, true)
|
||||
-- Empty / end of object?
|
||||
if str:sub(i, i) == "}" then
|
||||
i = i + 1
|
||||
break
|
||||
end
|
||||
-- Read key
|
||||
if str:sub(i, i) ~= '"' then
|
||||
decode_error(str, i, "expected string for key")
|
||||
end
|
||||
key, i = parse(str, i)
|
||||
-- Read ':' delimiter
|
||||
i = next_char(str, i, space_chars, true)
|
||||
if str:sub(i, i) ~= ":" then
|
||||
decode_error(str, i, "expected ':' after key")
|
||||
end
|
||||
i = next_char(str, i + 1, space_chars, true)
|
||||
-- Read value
|
||||
val, i = parse(str, i)
|
||||
-- Set
|
||||
res[key] = val
|
||||
-- Next token
|
||||
i = next_char(str, i, space_chars, true)
|
||||
local chr = str:sub(i, i)
|
||||
i = i + 1
|
||||
if chr == "}" then break end
|
||||
if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
|
||||
end
|
||||
return res, i
|
||||
end
|
||||
|
||||
local char_func_map = {
|
||||
['"'] = parse_string,
|
||||
["0"] = parse_number,
|
||||
["1"] = parse_number,
|
||||
["2"] = parse_number,
|
||||
["3"] = parse_number,
|
||||
["4"] = parse_number,
|
||||
["5"] = parse_number,
|
||||
["6"] = parse_number,
|
||||
["7"] = parse_number,
|
||||
["8"] = parse_number,
|
||||
["9"] = parse_number,
|
||||
["-"] = parse_number,
|
||||
["t"] = parse_literal,
|
||||
["f"] = parse_literal,
|
||||
["n"] = parse_literal,
|
||||
["["] = parse_array,
|
||||
["{"] = parse_object
|
||||
}
|
||||
|
||||
function parse(str, idx)
|
||||
local chr = str:sub(idx, idx)
|
||||
local f = char_func_map[chr]
|
||||
if f then return f(str, idx) end
|
||||
decode_error(str, idx, "unexpected character '" .. chr .. "'")
|
||||
end
|
||||
|
||||
local function decode(str)
|
||||
if type(str) ~= "string" then
|
||||
error("expected argument of type string, got " .. type(str))
|
||||
end
|
||||
local res, idx = parse(str, next_char(str, 1, space_chars, true))
|
||||
idx = next_char(str, idx, space_chars, true)
|
||||
if idx <= #str then decode_error(str, idx, "trailing garbage") end
|
||||
return res
|
||||
end
|
||||
function json.decode(str)
|
||||
local a,b=pcall(decode,str)
|
||||
if a then
|
||||
return b
|
||||
else
|
||||
LOG.print(text.jsonError..": "..(b or"uknErr"),"warn")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
do--urlencode
|
||||
local rshift=bit.rshift
|
||||
local b16={[0]="0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"}
|
||||
function urlEncode(str)
|
||||
local out=""
|
||||
for i=1,#str do
|
||||
if str:sub(i,i):match("[a-zA-Z0-9]")then
|
||||
out=out..str:sub(i,i)
|
||||
else
|
||||
local b=str:byte(i)
|
||||
out=out.."%"..b16[rshift(b,4)]..b16[b%16]
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
end
|
||||
do--httpRequest & wsConnect
|
||||
client=LOADLIB("NETlib")
|
||||
if client then
|
||||
function httpRequest(tick,path,method,header,body)
|
||||
local task,err=client.httpraw{
|
||||
url="http://krakens.tpddns.cn:10026"..path,
|
||||
method=method or"GET",
|
||||
header=header,
|
||||
body=body,
|
||||
}
|
||||
if task then
|
||||
TASK.newNet(tick,task)
|
||||
else
|
||||
LOG.print("NETlib error: "..err,"warn")
|
||||
end
|
||||
TASK.netTaskCount=TASK.netTaskCount+1
|
||||
end
|
||||
|
||||
function wsConnect(tick,path,header)
|
||||
local task,err=client.wsraw{
|
||||
url="ws://krakens.tpddns.cn:10026"..path,
|
||||
origin="krakens.tpddns.cn",
|
||||
header=header,
|
||||
}
|
||||
if task then
|
||||
TASK.newNet(tick,task)
|
||||
else
|
||||
LOG.print("NETlib error: "..err,"warn")
|
||||
end
|
||||
TASK.netTaskCount=TASK.netTaskCount+1
|
||||
end
|
||||
|
||||
function wsWrite(data)
|
||||
if WSCONN then
|
||||
local writeErr=client.write(WSCONN,data)
|
||||
if writeErr then
|
||||
LOG.print(writeErr,"error")
|
||||
return
|
||||
end
|
||||
return true
|
||||
else
|
||||
LOG.print(text.wsNoConn,"warn")
|
||||
end
|
||||
end
|
||||
else
|
||||
local function noNetLib()
|
||||
LOG.print("[NO NETlib]",5,COLOR.yellow)
|
||||
end
|
||||
httpRequest=noNetLib
|
||||
wsConnect=noNetLib
|
||||
wsWrite=noNetLib
|
||||
end
|
||||
end
|
||||
do--wheelScroll
|
||||
local floatWheel=0
|
||||
function wheelScroll(y)
|
||||
if y>0 then
|
||||
if floatWheel<0 then floatWheel=0 end
|
||||
floatWheel=floatWheel+y^1.2
|
||||
elseif y<0 then
|
||||
if floatWheel>0 then floatWheel=0 end
|
||||
floatWheel=floatWheel-(-y)^1.2
|
||||
end
|
||||
while floatWheel>=1 do
|
||||
love.keypressed("up")
|
||||
floatWheel=floatWheel-1
|
||||
end
|
||||
while floatWheel<=-1 do
|
||||
love.keypressed("down")
|
||||
floatWheel=floatWheel+1
|
||||
end
|
||||
end
|
||||
end
|
||||
function copyList(org)
|
||||
local L={}
|
||||
for i=1,#org do
|
||||
if type(org[i])~="table"then
|
||||
L[i]=org[i]
|
||||
else
|
||||
L[i]=copyList(org[i])
|
||||
end
|
||||
end
|
||||
return L
|
||||
end
|
||||
function copyTable(org)
|
||||
local L={}
|
||||
for k,v in next,org do
|
||||
if type(v)~="table"then
|
||||
L[k]=v
|
||||
else
|
||||
L[k]=copyTable(v)
|
||||
end
|
||||
end
|
||||
return L
|
||||
end
|
||||
function addToTable(G,base)--For all things in G if same type in base, push to base
|
||||
for k,v in next,G do
|
||||
if type(v)==type(base[k])then
|
||||
if type(v)=="table"then
|
||||
addToTable(v,base[k])
|
||||
else
|
||||
base[k]=v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function completeTable(G,base)--For all things in G if no val in base, push to base
|
||||
for k,v in next,G do
|
||||
if base[k]==nil then
|
||||
base[k]=v
|
||||
elseif type(v)=="table"and type(base[k])=="table"then
|
||||
completeTable(v,base[k])
|
||||
end
|
||||
end
|
||||
end
|
||||
function splitStr(s,sep)
|
||||
local L={}
|
||||
local p1,p2=1--start,target
|
||||
while p1<=#s do
|
||||
p2=find(s,sep,p1)or #s+1
|
||||
L[#L+1]=sub(s,p1,p2-1)
|
||||
p1=p2+#sep
|
||||
end
|
||||
return L
|
||||
end
|
||||
function toTime(s)
|
||||
if s<60 then
|
||||
return format("%.3fs",s)
|
||||
elseif s<3600 then
|
||||
return format("%d:%.2f",int(s/60),s%60)
|
||||
else
|
||||
local h=int(s/3600)
|
||||
return format("%d:%d:%.2f",h,int(s/60%60),s%60)
|
||||
end
|
||||
end
|
||||
function mStr(s,x,y)
|
||||
gc.printf(s,x-626,y,1252,"center")
|
||||
end
|
||||
function mText(s,x,y)
|
||||
gc.draw(s,x-s:getWidth()*.5,y)
|
||||
end
|
||||
function mDraw(s,x,y,a,k)
|
||||
gc.draw(s,x,y,a,k,nil,s:getWidth()*.5,s:getHeight()*.5)
|
||||
end
|
||||
@@ -1,8 +1,12 @@
|
||||
local level={0,0,.01,.015,.02,.03,.04,.05,.06,.07}
|
||||
local level={0,0,.01,.016,.023,.03,.04,.05,.06,.07,.08,.09,.12,.15}
|
||||
local vib=love.system.vibrate
|
||||
return function(t)
|
||||
local L=SETTING.vib
|
||||
if L>0 then
|
||||
vib(level[L+t])
|
||||
end
|
||||
end
|
||||
return love.system.getOS()=='iOS'and
|
||||
function(t)
|
||||
t=level[t]
|
||||
if t then vib(t<=.03 and 1 or t<=.09 and 2 or 3)end
|
||||
end
|
||||
or
|
||||
function(t)
|
||||
t=level[t]
|
||||
if t then vib(t)end
|
||||
end
|
||||
@@ -1,117 +1,132 @@
|
||||
local rnd=math.random
|
||||
local rem=table.remove
|
||||
local voiceQueue={free=0}
|
||||
local bank={}--{vocName1={SRC1s},vocName2={SRC2s},...}
|
||||
local VOC={}
|
||||
VOC.list={}
|
||||
local volume=1
|
||||
local diversion=0
|
||||
local VOC={
|
||||
getCount=function()return 0 end,
|
||||
getQueueCount=function()return 0 end,
|
||||
load=function()error("Cannot load before init!")end,
|
||||
getFreeChannel=NULL,
|
||||
play=NULL,
|
||||
update=NULL,
|
||||
}
|
||||
function VOC.setDiversion(n)
|
||||
assert(type(n)=='number'and n>0 and n<12,'Wrong div')
|
||||
diversion=n
|
||||
end
|
||||
function VOC.setVol(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||
volume=v
|
||||
end
|
||||
function VOC.init(list)
|
||||
VOC.init=nil
|
||||
local rem=table.remove
|
||||
local voiceQueue={free=0}
|
||||
local bank={}--{vocName1={SRC1s},vocName2={SRC2s},...}
|
||||
local Source={}
|
||||
|
||||
local function loadVoiceFile(N,vocName)
|
||||
local fileName="media/VOICE/"..SETTING.cv.."/"..vocName..".ogg"
|
||||
if love.filesystem.getInfo(fileName)then
|
||||
bank[vocName]={love.audio.newSource(fileName,"static")}
|
||||
table.insert(VOC.list[N],vocName)
|
||||
return true
|
||||
end
|
||||
end
|
||||
function VOC.set(L)
|
||||
VOC.name=L
|
||||
VOC.len=#L
|
||||
end
|
||||
local count=#list function VOC.getCount()return count end
|
||||
local function _loadVoiceFile(path,N,vocName)
|
||||
local fullPath=path..vocName..'.ogg'
|
||||
if love.filesystem.getInfo(fullPath)then
|
||||
bank[vocName]={love.audio.newSource(fullPath,'stream')}
|
||||
table.insert(Source[N],vocName)
|
||||
return true
|
||||
end
|
||||
end
|
||||
--Load voice with string
|
||||
local function _getVoice(str)
|
||||
local L=bank[str]
|
||||
local n=1
|
||||
while L[n]:isPlaying()do
|
||||
n=n+1
|
||||
if not L[n]then
|
||||
L[n]=L[1]:clone()
|
||||
L[n]:seek(0)
|
||||
break
|
||||
end
|
||||
end
|
||||
return L[n]
|
||||
end
|
||||
function VOC.load(path)
|
||||
for i=1,count do
|
||||
Source[list[i]]={}
|
||||
|
||||
function VOC.loadOne(name)
|
||||
local N=VOC.name[name]
|
||||
VOC.list[N]={}
|
||||
local n=0
|
||||
repeat n=n+1 until not _loadVoiceFile(path,list[i],list[i]..'_'..n)
|
||||
|
||||
local i=0
|
||||
repeat i=i+1 until not loadVoiceFile(N,N.."_"..i)
|
||||
if n==1 then
|
||||
if not _loadVoiceFile(path,list[i],list[i])then
|
||||
LOG("No VOC: "..list[i],.1)
|
||||
end
|
||||
end
|
||||
if not Source[list[i]][1]then
|
||||
Source[list[i]]=nil
|
||||
end
|
||||
end
|
||||
|
||||
if i==1 then
|
||||
if not loadVoiceFile(N,N)then
|
||||
LOG.print("No VOICE file: "..N,5,COLOR.orange)
|
||||
end
|
||||
end
|
||||
if not VOC.list[N][1]then VOC.list[N]=nil end
|
||||
end
|
||||
function VOC.loadAll()
|
||||
for i=1,#VOC.name do
|
||||
VOC.loadOne(i)
|
||||
end
|
||||
collectgarbage()
|
||||
end
|
||||
function VOC.getQueueCount()
|
||||
return #voiceQueue
|
||||
end
|
||||
function VOC.getFreeChannel()
|
||||
local l=#voiceQueue
|
||||
for i=1,l do
|
||||
if #voiceQueue[i]==0 then return i end
|
||||
end
|
||||
voiceQueue[l+1]={s=0}
|
||||
return l+1
|
||||
end
|
||||
|
||||
function VOC.getFreeChannel()
|
||||
local l=#voiceQueue
|
||||
for i=1,l do
|
||||
if #voiceQueue[i]==0 then return i end
|
||||
end
|
||||
voiceQueue[l+1]={s=0}
|
||||
return l+1
|
||||
function VOC.play(s,chn)
|
||||
if volume>0 then
|
||||
local _=Source[s]
|
||||
if not _ then return end
|
||||
if chn then
|
||||
local L=voiceQueue[chn]
|
||||
L[#L+1]=_[rnd(#_)]
|
||||
L.s=1
|
||||
--Add to queue[chn]
|
||||
else
|
||||
voiceQueue[VOC.getFreeChannel()]={s=1,_[rnd(#_)]}
|
||||
--Create new channel & play
|
||||
end
|
||||
end
|
||||
end
|
||||
function VOC.update()
|
||||
for i=#voiceQueue,1,-1 do
|
||||
local Q=voiceQueue[i]
|
||||
if Q.s==0 then--Free channel, auto delete when >3
|
||||
if i>3 then
|
||||
rem(voiceQueue,i)
|
||||
end
|
||||
elseif Q.s==1 then--Waiting load source
|
||||
Q[1]=_getVoice(Q[1])
|
||||
Q[1]:setVolume(volume)
|
||||
Q[1]:setPitch(1.0594630943592953^(diversion*(rnd()*2-1)))
|
||||
Q[1]:play()
|
||||
Q.s=Q[2]and 2 or 4
|
||||
elseif Q.s==2 then--Playing 1,ready 2
|
||||
if Q[1]:getDuration()-Q[1]:tell()<.08 then
|
||||
Q[2]=_getVoice(Q[2])
|
||||
Q[2]:setVolume(volume)
|
||||
Q[1]:setPitch(1.0594630943592953^(diversion*(rnd()*2-1)))
|
||||
Q[2]:play()
|
||||
Q.s=3
|
||||
end
|
||||
elseif Q.s==3 then--Playing 12 same time
|
||||
if not Q[1]:isPlaying()then
|
||||
for j=1,#Q do
|
||||
Q[j]=Q[j+1]
|
||||
end
|
||||
Q.s=Q[2]and 2 or 4
|
||||
end
|
||||
elseif Q.s==4 then--Playing last
|
||||
if not Q[1].isPlaying(Q[1])then
|
||||
Q[1]=nil
|
||||
Q.s=0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function VOC.getCount()
|
||||
return #voiceQueue
|
||||
end
|
||||
|
||||
local function getVoice(str)
|
||||
local L=bank[str]
|
||||
local n=1
|
||||
while L[n]:isPlaying()do
|
||||
n=n+1
|
||||
if not L[n]then
|
||||
L[n]=L[1]:clone()
|
||||
L[n]:seek(0)
|
||||
break
|
||||
end
|
||||
end
|
||||
return L[n]
|
||||
--Load voice with string
|
||||
end
|
||||
function VOC.update()
|
||||
for i=#voiceQueue,1,-1 do
|
||||
local Q=voiceQueue[i]
|
||||
if Q.s==0 then--Free channel, auto delete when >3
|
||||
if i>3 then
|
||||
rem(voiceQueue,i)
|
||||
end
|
||||
elseif Q.s==1 then--Waiting load source
|
||||
Q[1]=getVoice(Q[1])
|
||||
Q[1]:setVolume(SETTING.voc)
|
||||
Q[1]:play()
|
||||
Q.s=Q[2]and 2 or 4
|
||||
elseif Q.s==2 then--Playing 1,ready 2
|
||||
if Q[1]:getDuration()-Q[1]:tell()<.08 then
|
||||
Q[2]=getVoice(Q[2])
|
||||
Q[2]:setVolume(SETTING.voc)
|
||||
Q[2]:play()
|
||||
Q.s=3
|
||||
end
|
||||
elseif Q.s==3 then--Playing 12 same time
|
||||
if not Q[1]:isPlaying()then
|
||||
for j=1,#Q do
|
||||
Q[j]=Q[j+1]
|
||||
end
|
||||
Q.s=Q[2]and 2 or 4
|
||||
end
|
||||
elseif Q.s==4 then--Playing last
|
||||
if not Q[1].isPlaying(Q[1])then
|
||||
Q[1]=nil
|
||||
Q.s=0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function VOC.play(s,chn)
|
||||
if SETTING.voc>0 then
|
||||
local _=VOC.list[s]
|
||||
if not _ then return end
|
||||
if chn then
|
||||
local L=voiceQueue[chn]
|
||||
L[#L+1]=_[rnd(#_)]
|
||||
L.s=1
|
||||
--Add to queue[chn]
|
||||
else
|
||||
voiceQueue[VOC.getFreeChannel()]={s=1,_[rnd(#_)]}
|
||||
--Create new channel & play
|
||||
end
|
||||
end
|
||||
end
|
||||
return VOC
|
||||
return VOC
|
||||
|
||||
191
Zframework/websocket.lua
Normal file
191
Zframework/websocket.lua
Normal file
@@ -0,0 +1,191 @@
|
||||
local host=
|
||||
-- '127.0.0.1'
|
||||
-- '192.168.114.102'
|
||||
'game.techmino.org'
|
||||
local port='10026'
|
||||
local path='/tech/socket/v1'
|
||||
|
||||
-- lua + LÖVE threading websocket client
|
||||
-- Original pure lua ver. by flaribbit and Particle_G
|
||||
-- Threading version by MrZ
|
||||
|
||||
local type=type
|
||||
local timer=love.timer.getTime
|
||||
local CHN=love.thread.newChannel()
|
||||
local CHN_getCount,CHN_push,CHN_pop=CHN.getCount,CHN.push,CHN.pop
|
||||
local TRD=love.thread.newThread("\n")
|
||||
local TRD_isRunning=TRD.isRunning
|
||||
|
||||
local WS={}
|
||||
local wsList=setmetatable({},{
|
||||
__index=function(l,k)
|
||||
local ws={
|
||||
real=false,
|
||||
status='dead',
|
||||
lastPongTime=timer(),
|
||||
sendTimer=0,
|
||||
alertTimer=0,
|
||||
pongTimer=0,
|
||||
}
|
||||
l[k]=ws
|
||||
return ws
|
||||
end
|
||||
})
|
||||
|
||||
function WS.switchHost(_1,_2,_3)
|
||||
for k in next,wsList do
|
||||
WS.close(k)
|
||||
end
|
||||
host=_1
|
||||
port=_2 or port
|
||||
path=_3 or path
|
||||
end
|
||||
|
||||
function WS.connect(name,subPath,body,timeout)
|
||||
if wsList[name]and wsList[name].thread then
|
||||
wsList[name].thread:release()
|
||||
end
|
||||
local ws={
|
||||
real=true,
|
||||
thread=love.thread.newThread('Zframework/websocket_thread.lua'),
|
||||
triggerCHN=love.thread.newChannel(),
|
||||
sendCHN=love.thread.newChannel(),
|
||||
readCHN=love.thread.newChannel(),
|
||||
lastPingTime=0,
|
||||
lastPongTime=timer(),
|
||||
pingInterval=6,
|
||||
status='connecting',--'connecting', 'running', 'dead'
|
||||
sendTimer=0,
|
||||
alertTimer=0,
|
||||
pongTimer=0,
|
||||
}
|
||||
wsList[name]=ws
|
||||
ws.thread:start(ws.triggerCHN,ws.sendCHN,ws.readCHN)
|
||||
CHN_push(ws.sendCHN,host)
|
||||
CHN_push(ws.sendCHN,port)
|
||||
CHN_push(ws.sendCHN,path..subPath)
|
||||
CHN_push(ws.sendCHN,body or"")
|
||||
CHN_push(ws.sendCHN,timeout or 2.6)
|
||||
end
|
||||
|
||||
function WS.status(name)
|
||||
local ws=wsList[name]
|
||||
return ws.status or'dead'
|
||||
end
|
||||
|
||||
function WS.getTimers(name)
|
||||
local ws=wsList[name]
|
||||
return ws.pongTimer,ws.sendTimer,ws.alertTimer
|
||||
end
|
||||
|
||||
function WS.setPingInterval(name,time)
|
||||
local ws=wsList[name]
|
||||
ws.pingInterval=math.max(time or 2.6,2.6)
|
||||
end
|
||||
|
||||
function WS.alert(name)
|
||||
local ws=wsList[name]
|
||||
ws.alertTimer=2.6
|
||||
end
|
||||
|
||||
local OPcode={
|
||||
continue=0,
|
||||
text=1,
|
||||
binary=2,
|
||||
close=8,
|
||||
ping=9,
|
||||
pong=10,
|
||||
}
|
||||
local OPname={
|
||||
[0]='continue',
|
||||
[1]='text',
|
||||
[2]='binary',
|
||||
[8]='close',
|
||||
[9]='ping',
|
||||
[10]='pong',
|
||||
}
|
||||
function WS.send(name,message,op)
|
||||
if type(message)=='string'then
|
||||
local ws=wsList[name]
|
||||
if ws.real and ws.status=='running'then
|
||||
CHN_push(ws.sendCHN,op and OPcode[op]or 2)--2=binary
|
||||
CHN_push(ws.sendCHN,message)
|
||||
ws.lastPingTime=timer()
|
||||
ws.sendTimer=1
|
||||
end
|
||||
else
|
||||
MES.new('error',"Attempt to send non-string value!")
|
||||
MES.traceback()
|
||||
end
|
||||
end
|
||||
|
||||
function WS.read(name)
|
||||
local ws=wsList[name]
|
||||
if ws.real and ws.status~='connecting'and CHN_getCount(ws.readCHN)>=2 then
|
||||
local op,message=CHN_pop(ws.readCHN),CHN_pop(ws.readCHN)
|
||||
if op==8 then--8=close
|
||||
ws.status='dead'
|
||||
elseif op==9 then--9=ping
|
||||
WS.send(name,message or"",'pong')
|
||||
end
|
||||
ws.lastPongTime=timer()
|
||||
ws.pongTimer=1
|
||||
return message,OPname[op]or op
|
||||
end
|
||||
end
|
||||
|
||||
function WS.close(name)
|
||||
local ws=wsList[name]
|
||||
if ws.real then
|
||||
CHN_push(ws.sendCHN,8)--close
|
||||
CHN_push(ws.sendCHN,"")
|
||||
ws.status='dead'
|
||||
end
|
||||
end
|
||||
|
||||
function WS.update(dt)
|
||||
local time=timer()
|
||||
for name,ws in next,wsList do
|
||||
if ws.real and ws.status~='dead'then
|
||||
if TRD_isRunning(ws.thread)then
|
||||
if CHN_getCount(ws.triggerCHN)==0 then
|
||||
CHN_push(ws.triggerCHN,0)
|
||||
end
|
||||
if ws.status=='connecting'then
|
||||
local mes=CHN_pop(ws.readCHN)
|
||||
if mes then
|
||||
if mes=='success'then
|
||||
ws.status='running'
|
||||
ws.lastPingTime=time
|
||||
ws.lastPongTime=time
|
||||
ws.pongTimer=1
|
||||
else
|
||||
ws.status='dead'
|
||||
MES.new('warn',text.wsFailed..": "..(mes=="timeout"and text.netTimeout or mes))
|
||||
end
|
||||
end
|
||||
elseif ws.status=='running'then
|
||||
if time-ws.lastPingTime>ws.pingInterval then
|
||||
WS.send(name,"",'pong')
|
||||
end
|
||||
if time-ws.lastPongTime>6+2*ws.pingInterval then
|
||||
WS.close(name)
|
||||
end
|
||||
end
|
||||
if ws.sendTimer>0 then ws.sendTimer=ws.sendTimer-dt end
|
||||
if ws.pongTimer>0 then ws.pongTimer=ws.pongTimer-dt end
|
||||
if ws.alertTimer>0 then ws.alertTimer=ws.alertTimer-dt end
|
||||
else
|
||||
ws.status='dead'
|
||||
local err=ws.thread:getError()
|
||||
if err then
|
||||
err=err:sub((err:find(":",(err:find(":")or 0)+1)or 0)+1,(err:find("\n")or 0)-1)
|
||||
MES.new('warn',text.wsClose..err)
|
||||
WS.alert(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return WS
|
||||
191
Zframework/websocket_thread.lua
Normal file
191
Zframework/websocket_thread.lua
Normal file
@@ -0,0 +1,191 @@
|
||||
local triggerCHN,sendCHN,readCHN=...
|
||||
|
||||
local CHN_demand,CHN_getCount=triggerCHN.demand,triggerCHN.getCount
|
||||
local CHN_push,CHN_pop=triggerCHN.push,triggerCHN.pop
|
||||
|
||||
local SOCK=require'socket'.tcp()
|
||||
local JSON=require'Zframework.json'
|
||||
|
||||
do--Connect
|
||||
local host=CHN_demand(sendCHN)
|
||||
local port=CHN_demand(sendCHN)
|
||||
local path=CHN_demand(sendCHN)
|
||||
local body=CHN_demand(sendCHN)
|
||||
local timeout=CHN_demand(sendCHN)
|
||||
|
||||
SOCK:settimeout(timeout)
|
||||
local res,err=SOCK:connect(host,port)
|
||||
assert(res,err)
|
||||
|
||||
--WebSocket handshake
|
||||
if not body then body=''end
|
||||
SOCK:send(
|
||||
'GET '..path..' HTTP/1.1\r\n'..
|
||||
'Host: '..host..':'..port..'\r\n'..
|
||||
'Connection: Upgrade\r\n'..
|
||||
'Upgrade: websocket\r\n'..
|
||||
'Content-Type: application/json\r\n'..
|
||||
'Content-Length: '..#body..'\r\n'..
|
||||
'Sec-WebSocket-Version: 13\r\n'..
|
||||
'Sec-WebSocket-Key: osT3F7mvlojIvf3/8uIsJQ==\r\n\r\n'..--secKey
|
||||
body
|
||||
)
|
||||
|
||||
--First line of HTTP
|
||||
res,err=SOCK:receive('*l')
|
||||
assert(res,err)
|
||||
local code,ctLen
|
||||
code=res:find(' ')
|
||||
code=res:sub(code+1,code+3)
|
||||
|
||||
--Get body length from headers and remove headers
|
||||
repeat
|
||||
res,err=SOCK:receive('*l')
|
||||
assert(res,err)
|
||||
if not ctLen and res:find('length')then
|
||||
ctLen=tonumber(res:match('%d+'))
|
||||
end
|
||||
until res==''
|
||||
|
||||
--Result
|
||||
if ctLen then
|
||||
if code=='101'then
|
||||
CHN_push(readCHN,'success')
|
||||
else
|
||||
res,err=SOCK:receive(ctLen)
|
||||
res=JSON.decode(assert(res,err))
|
||||
error((code or"XXX")..":"..(res and res.reason or"Server Error"))
|
||||
end
|
||||
end
|
||||
SOCK:settimeout(0)
|
||||
end
|
||||
|
||||
local YIELD=coroutine.yield
|
||||
local byte,char=string.byte,string.char
|
||||
local band,bor,bxor=bit.band,bit.bor,bit.bxor
|
||||
local shl,shr=bit.lshift,bit.rshift
|
||||
|
||||
local mask_key={1,14,5,14}
|
||||
local mask_str=char(unpack(mask_key))
|
||||
local function _send(op,message)
|
||||
--Message type
|
||||
SOCK:send(char(bor(op,0x80)))
|
||||
|
||||
if message then
|
||||
--Length
|
||||
local length=#message
|
||||
if length>65535 then
|
||||
SOCK:send(char(bor(127,0x80),0,0,0,0,band(shr(length,24),0xff),band(shr(length,16),0xff),band(shr(length,8),0xff),band(length,0xff)))
|
||||
elseif length>125 then
|
||||
SOCK:send(char(bor(126,0x80),band(shr(length,8),0xff),band(length,0xff)))
|
||||
else
|
||||
SOCK:send(char(bor(length,0x80)))
|
||||
end
|
||||
local msgbyte={byte(message,1,length)}
|
||||
for i=1,length do
|
||||
msgbyte[i]=bxor(msgbyte[i],mask_key[(i-1)%4+1])
|
||||
end
|
||||
return SOCK:send(mask_str..char(unpack(msgbyte)))
|
||||
else
|
||||
SOCK:send('\128'..mask_str)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
local sendThread=coroutine.wrap(function()
|
||||
while true do
|
||||
while CHN_getCount(sendCHN)>=2 do
|
||||
_send(CHN_pop(sendCHN),CHN_pop(sendCHN))
|
||||
end
|
||||
YIELD()
|
||||
end
|
||||
end)
|
||||
|
||||
local function _receive(sock,len)
|
||||
local buffer=""
|
||||
while true do
|
||||
local r,e,p=sock:receive(len)
|
||||
if r then
|
||||
buffer=buffer..r
|
||||
len=len-#r
|
||||
elseif p then
|
||||
buffer=buffer..p
|
||||
len=len-#p
|
||||
elseif e then
|
||||
return nil,e
|
||||
end
|
||||
if len==0 then
|
||||
return buffer
|
||||
end
|
||||
YIELD()
|
||||
end
|
||||
end
|
||||
local readThread=coroutine.wrap(function()
|
||||
local res,err
|
||||
local op,fin
|
||||
local lBuffer=""--Long multi-pack buffer
|
||||
while true do
|
||||
--Byte 0-1
|
||||
res,err=_receive(SOCK,2)
|
||||
assert(res,err)
|
||||
|
||||
op=band(byte(res,1),0x0f)
|
||||
fin=band(byte(res,1),0x80)==0x80
|
||||
|
||||
--Calculating data length
|
||||
local length=band(byte(res,2),0x7f)
|
||||
if length==126 then
|
||||
res,err=_receive(SOCK,2)
|
||||
assert(res,err)
|
||||
length=shl(byte(res,1),8)+byte(res,2)
|
||||
elseif length==127 then
|
||||
local lenData
|
||||
lenData,err=_receive(SOCK,8)
|
||||
assert(res,err)
|
||||
local _,_,_,_,_5,_6,_7,_8=byte(lenData,1,8)
|
||||
length=shl(_5,24)+shl(_6,16)+shl(_7,8)+_8
|
||||
end
|
||||
res,err=_receive(SOCK,length)
|
||||
assert(res,err)
|
||||
|
||||
--React
|
||||
if op==8 then--8=close
|
||||
CHN_push(readCHN,8)--close
|
||||
if type(res)=='string'then
|
||||
CHN_push(readCHN,res:sub(3))--[Warning] 2 bytes close code at start so :sub(3)
|
||||
else
|
||||
CHN_push(readCHN,"WS closed")
|
||||
end
|
||||
return
|
||||
elseif op==0 then--0=continue
|
||||
lBuffer=lBuffer..res
|
||||
if fin then
|
||||
CHN_push(readCHN,lBuffer)
|
||||
lBuffer=""
|
||||
end
|
||||
else
|
||||
CHN_push(readCHN,op)
|
||||
if fin then
|
||||
CHN_push(readCHN,res)
|
||||
lBuffer=""
|
||||
else
|
||||
lBuffer=res
|
||||
end
|
||||
end
|
||||
YIELD()
|
||||
end
|
||||
end)
|
||||
|
||||
local success,err
|
||||
|
||||
while true do--Running
|
||||
CHN_demand(triggerCHN)
|
||||
success,err=pcall(sendThread)
|
||||
if not success or err then break end
|
||||
success,err=pcall(readThread)
|
||||
if not success or err then break end
|
||||
end
|
||||
|
||||
SOCK:close()
|
||||
CHN_push(readCHN,8)--close
|
||||
CHN_push(readCHN,err or"Disconnected")
|
||||
error()
|
||||
19
Zframework/wheelScroll.lua
Normal file
19
Zframework/wheelScroll.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
local love=love
|
||||
local max,min=math.max,math.min
|
||||
local trigDist=0
|
||||
return function(y,key1,key2)
|
||||
if y>0 then
|
||||
trigDist=max(trigDist,0)+y^1.2
|
||||
elseif y<0 then
|
||||
if trigDist>0 then trigDist=0 end
|
||||
trigDist=min(trigDist,0)-(-y)^1.2
|
||||
end
|
||||
while trigDist>=1 do
|
||||
love.keypressed(key1 or'up')
|
||||
trigDist=trigDist-1
|
||||
end
|
||||
while trigDist<=-1 do
|
||||
love.keypressed(key2 or'down')
|
||||
trigDist=trigDist+1
|
||||
end
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
67
conf.lua
67
conf.lua
@@ -1,39 +1,34 @@
|
||||
VERSION_CODE=1204
|
||||
VERSION_NAME="Alpha V0.12.4"
|
||||
love.setDeprecationOutput(false)
|
||||
function love.conf(t)
|
||||
t.identity="Techmino"--Saving folder
|
||||
t.version="11.1"
|
||||
t.gammacorrect=false
|
||||
t.appendidentity=true--Search files in source then in save directory
|
||||
t.accelerometerjoystick=false--Accelerometer=joystick on ios/android
|
||||
if t.audio then
|
||||
t.audio.mic=false
|
||||
t.audio.mixwithsystem=true
|
||||
end
|
||||
t.identity='Techmino'--Saving folder
|
||||
t.version="11.1"
|
||||
t.gammacorrect=false
|
||||
t.appendidentity=true--Search files in source then in save directory
|
||||
t.accelerometerjoystick=false--Accelerometer=joystick on ios/android
|
||||
if t.audio then
|
||||
t.audio.mic=false
|
||||
t.audio.mixwithsystem=true
|
||||
end
|
||||
|
||||
local W=t.window
|
||||
W.title="Techmino "..VERSION_NAME
|
||||
W.icon="media/image/icon.png"
|
||||
W.width,W.height=1280,720
|
||||
W.minwidth,W.minheight=640,360
|
||||
W.borderless=false
|
||||
W.resizable=true
|
||||
W.fullscreentype="desktop"--"exclusive"
|
||||
W.fullscreen=false
|
||||
W.vsync=0--Do not limit FPS
|
||||
W.msaa=false--Num of samples to use with multi-sampled antialiasing
|
||||
W.depth=0--Bits/samp of depth buffer
|
||||
W.stencil=1--Bits/samp of stencil buffer
|
||||
W.display=1--Monitor ID
|
||||
W.highdpi=true--High-dpi mode for the window on a Retina display
|
||||
W.x,W.y=nil
|
||||
local W=t.window
|
||||
W.title="Techmino "..require"version".string
|
||||
W.width,W.height=1280,720
|
||||
W.minwidth,W.minheight=640,360
|
||||
W.borderless=false
|
||||
W.resizable=true
|
||||
W.fullscreen=false
|
||||
W.vsync=0--Unlimited FPS
|
||||
W.msaa=0--Multi-sampled antialiasing
|
||||
W.depth=0--Bits/samp of depth buffer
|
||||
W.stencil=1--Bits/samp of stencil buffer
|
||||
W.display=1--Monitor ID
|
||||
W.highdpi=true--High-dpi mode for the window on a Retina display
|
||||
W.x,W.y=nil
|
||||
|
||||
local M=t.modules
|
||||
M.window,M.system,M.event=true,true,true
|
||||
M.audio,M.sound=true,true
|
||||
M.math,M.data=true,true
|
||||
M.timer,M.graphics,M.font,M.image=true,true,true,true
|
||||
M.mouse,M.touch,M.keyboard,M.joystick=true,true,true,true
|
||||
M.physics,M.thread,M.video=false,false,false
|
||||
end
|
||||
local M=t.modules
|
||||
M.window,M.system,M.event,M.thread=true,true,true,true
|
||||
M.timer,M.math,M.data=true,true,true
|
||||
M.video,M.audio,M.sound=true,true,true
|
||||
M.graphics,M.font,M.image=true,true,true
|
||||
M.mouse,M.touch,M.keyboard,M.joystick=true,true,true,true
|
||||
M.physics=false
|
||||
end
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
游戏方法:
|
||||
系统会提供的一个个四连骨牌("方块",总共7种),玩家需要控制(左右移动和旋转90,180,270度),每填满场地的一行就会将其消除,根据消除方式会给对手攻击(如果有对手的话)
|
||||
活到最后或者完成目标即胜利.
|
||||
|
||||
旋转系统:
|
||||
使用Techmino专属旋转系统,细节懒得写(
|
||||
|
||||
spin判定:
|
||||
满足三角判定+2分
|
||||
满足不可移动判定+2分
|
||||
--满足以上之一就算是spin
|
||||
满足非第二个test+1分
|
||||
--如果分数只有2,方块是SZJLT之一,并且没有把当前方块整个消除那么就是mini
|
||||
|
||||
攻击系统:
|
||||
普通消除:
|
||||
消<4行打出[消行数-0.5]攻击
|
||||
特殊消除:
|
||||
如果是spin,打出[2*消行数]攻击,
|
||||
B2B攻击+[1/1/2/4/8(spin1~5)]
|
||||
B3B攻击在B2B基础上+消行数*0.5,+1额外抵挡
|
||||
mini减至25%
|
||||
不是spin但是单次消>=4行,打出[消行数]攻击,
|
||||
B2B攻击+1
|
||||
B3B攻击+50%,+1额外抵挡
|
||||
特殊消除会增加B2B点数,让之后的特殊消除获得B2B(B3B)增益(详细说明见下文)
|
||||
半全消("下方有剩余方块"的全消,如果是I消1行则必须不剩余玩家放置的方块):伤害+2,额外抵挡+2
|
||||
全消:将上述伤害之和减半,再+8~20(本局内递增2),+2额外抵挡(注:本局消行数>4时会将B2B点数拉满)
|
||||
连击:每次连击给予上述攻击[连击数*25%(如果只消一行就是15%)]的加成,12combo达到上限,连击>=3次时再额外加1攻击
|
||||
根据上述规则计算后,向下取整,攻击打出
|
||||
|
||||
分数系统:
|
||||
操作越牛逼得分越高嗷(
|
||||
|
||||
攻击延迟:
|
||||
消2/3的攻击生效最快,消四其次,spin攻击生效较慢,高连击生效最慢
|
||||
B2B或者B3B增加攻击力的同时也会减缓一点生效速度,mini大幅减缓生效速度
|
||||
|
||||
抵消逻辑:
|
||||
发动攻击时,若缓冲条有攻击则先用额外抵挡再用攻击力1:1抵消最先受到的攻击
|
||||
没有用上的额外抵挡会被丢弃,最后剩下的攻击力会发送给对手
|
||||
|
||||
back to back(B2B)点数说明:
|
||||
B2B点数的范围在0~1200,在点数>=40时进行特殊消除为B2B,>1000时特殊消除为B3B
|
||||
普通消除:-250
|
||||
spin1~5:+[50/100/180/1000/1200](mini变为原来25%)
|
||||
消四/五:+[100/200]
|
||||
空spin:+20,此法得到的点数不能超过1000
|
||||
当点数在1000以上时空放一块-40(不低于1000)
|
||||
|
||||
混战模式说明:
|
||||
许多玩家同时进行一局游戏(对手都是AI,不是真人).随着玩家数量的减少,方块下落/垃圾生效速度/垃圾升起速度都会增加.淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力.
|
||||
玩家可选四个攻击模式:
|
||||
1.随机:每次攻击后10%随机挑选一个玩家锁定
|
||||
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
|
||||
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
|
||||
4.反击:攻击所有锁定自己的玩家(攻击AOE),若未被任何人锁定则攻击随机玩家(不锁定)
|
||||
坚持到最后的玩家就是胜利者.
|
||||
|
||||
自定义模式说明:
|
||||
玩家可以自由调整大多数参数(不包括上述各种游戏模式的特殊效果),也可以画一个场地去消除或者是作为提示模板来进行拼图模式.
|
||||
在拼图模式下,按功能键切换是否展示提示.其中打"X"的格子不允许有方块,空的格子可以是任何状态,普通的七种彩色方块必须颜色对应,垃圾行方块的为止只要有方块就可以,但是不能是空气,玩家拼出自己画的图后就会判定胜利.
|
||||
@@ -1,64 +0,0 @@
|
||||
Gameplay:
|
||||
The system will provide you with tetrominoes (4-block pieces), with a total of 7 types, and the player needs to control them (move left and right, rotate 90, 180 or 270 degrees), and each row filled with the field will be cleared, and depending on the line clear type, an attack will be sent (if there is an opponent)
|
||||
Play until the end or achieve the level's goal to win.
|
||||
|
||||
Rotation system:
|
||||
Uses Techmino's custom rotation system. Too lazy to write the details
|
||||
|
||||
Spin detection:
|
||||
Satisfies "3 corner" rule +2 points
|
||||
Satisfies "immobile" rule +2 points
|
||||
- As long as one of the above is true, it is a Spin
|
||||
|
||||
If the rotation was not using the second check in the kick table, +1 point
|
||||
- The Spin is a Mini if it only has 2 points; the piece is one of S, Z, J, L, T; AND the line clear did not clear the entire piece.
|
||||
|
||||
Attack system:
|
||||
Normal line clears (1 to 3 lines):
|
||||
Sends (lines cleared -0.5) attack
|
||||
Special line clears:
|
||||
Spin sends (lines cleared x2) attack,
|
||||
- B2B sends extra 1/1/2/4/8 (for Spin Single/Double/Triple/Techrash/Techrash+ respectively)
|
||||
- B2B2B sends (lines cleared x0.5), and +1 extra blocking
|
||||
- Minis reduces the attack to 25% (x0.25 multiplier)
|
||||
Non-Spin Techrash/Techrash+ sends (lines cleared) attack,
|
||||
- B2B sends 1 additional line
|
||||
- B2B2B will have an attack boost of 50% and +1 extra blocking
|
||||
|
||||
Special line clears will the increase B2B gauge, making later special line clears have either a B2B or B2B2B bonus (see below)
|
||||
Half Perfect Clear (a Perfect Clear "with blocks left below". If it's an I clearing 1 line, then the remaining blocks must not be player-placed): Attack +2, Extra Blocking +2
|
||||
Perfect Clear (also known as All Clear): half the sum of the damage above, plus additional 8 to 20 attack (increasing by 2 in a single round for each PC) and +2 extra blocking. (note: if lines cleared in this round >4, then B2B gauge will be filled)
|
||||
Combos: All damage above will be given a (combo x25%) bonus, or (combo x15%) if the line clear is a Single, capped at 12 combo. +1 more attack for 3 Combo or more.
|
||||
After calculating all above, the damage value will be rounded down then sent
|
||||
|
||||
Score system:
|
||||
The better you play, the higher the score.
|
||||
|
||||
Attack delay:
|
||||
Attacks from Doubles/Triples take effect the fastest, followed by Techrash, Spins, which send slow attacks, and high combos are the slowest
|
||||
For B2B or B2B2B, while they increase lines sent, they also increase the attack delay. Minis will greatly increase the delay.
|
||||
|
||||
Countering:
|
||||
When you send attacks, if there is garbage in queue, extra blocking will be used first, then attack, countering the earliest attack at a 1:1 ratio.
|
||||
Any extra blocking you didn't use will be discarded, and finally the remaining attack power will be sent to your opponent.
|
||||
|
||||
Back to Back (B2B) gauge:
|
||||
The B2B gauge ranges from 0 to 1,200. Special line clears are B2B if the gauge is >=40, B2B2B if >1,000.
|
||||
A regular line clear -250
|
||||
Spin Single/Double/Triple/Techrash/Techrash+ +50/100/180/1000/1200 (x25% if Mini)
|
||||
Techrash/Techrash+ +100/200
|
||||
Spin (0 lines) +20. Do note that the B2B gauge cannot exceed 1000 using this method.
|
||||
When gauge is above 1,000, a drop without clearing lines decreases it by 40, but cannot drop below 1,000
|
||||
|
||||
Battle Royale modes:
|
||||
Many players play a game at the same time (against AI bots, not real players). As players get eliminated, blocks fall faster, and garbage take effect faster, as well as rise faster. Eliminate other players to gain a badge and the player's badge to increase your attack power.
|
||||
Players can choose between four attack modes:
|
||||
1. Random: Every time you attack, 10% chance to lock onto a random player.
|
||||
2. Badges: After you attack or when your target dies, lock onto the player with the most badges.
|
||||
3. KOs: After you attack or when your target dies, lock onto the player with the highest field. (This refreshes every second)
|
||||
4. Attackers: attack all players locking onto yourself. Your attack will be sent to all of them. If you are not targetted, you attack a random player (not locking).
|
||||
When all opponents have been eliminated, the last player in the match is the winner.
|
||||
|
||||
Custom mode:
|
||||
You can freely adjust most parameters (not including special effects of other game modes), and you can also draw a field to clear or make a template to build.
|
||||
In build (puzzle) mode, you can toggle template display with Function key. Cells with a X cannot have blocks; empty cells can be in any state; regular colored cells have to be made of the corresponding block; garbage-colored cells can be any block but not air. Once you make the shape, you will win.
|
||||
@@ -1,144 +0,0 @@
|
||||
一个正确的模式文件应是一个合法lua程序,其必须立刻返回一个table,里面的内容包括:
|
||||
color:模式的颜色,用于点击地图图标后显示的提示文本
|
||||
env:
|
||||
必选
|
||||
模式环境变量,决定了关卡的各项属性
|
||||
table值:
|
||||
drop:下落延迟(帧,支持自然数和2的整数次幂)
|
||||
lock:锁定延迟(帧)
|
||||
wait:出块延迟(帧)
|
||||
fall:下落延迟(帧)
|
||||
bone:是否开启骨块模式
|
||||
nextCount:显示next个数
|
||||
nextStartPos:next从第几个开始显示
|
||||
holdCount:hold个数,
|
||||
infHold:是否能无限hold
|
||||
ospin=是否能O-spin
|
||||
RS:旋转系统名
|
||||
|
||||
das:DAS
|
||||
arr:ARR
|
||||
sddas:软降DAS
|
||||
sdarr:软降ARR
|
||||
mindas:允许的最小DAS
|
||||
minarr:允许的最小ARR
|
||||
minsdarr:允许的最小软降ARR
|
||||
ihs:提前Hold
|
||||
irs:提前旋转
|
||||
ims:提前移动
|
||||
maxNext:最大next数
|
||||
|
||||
skin:方块颜色,包含25个整数(1~16)的table
|
||||
face:方块朝向,包含25个整数(0~3)的table
|
||||
|
||||
block:是否显示方块
|
||||
ghost:影子透明度(0~1)
|
||||
center:旋转中心透明度(0~1)
|
||||
smooth:是否平滑下落
|
||||
grid:是否显示网格
|
||||
bagLine:是否显示包分界线
|
||||
lockFX:特效等级(0,5)
|
||||
dropFX:特效等级(0,5)
|
||||
moveFX:特效等级(0,5)
|
||||
clearFX:特效等级(0,5)
|
||||
splashFX:特效等级(0,5)
|
||||
shakeFX:特效等级(0,5)
|
||||
atkFX:特效等级(0,5)
|
||||
|
||||
text:是否显示消行文本
|
||||
score:是否显示落块分数
|
||||
warn:是否开启死亡预警
|
||||
highCam:是否开启超屏视野
|
||||
nextPos:是否开启生成预览
|
||||
|
||||
sequence:序列模式,可以使用默认的几个函数用字符串表示,也可以自己写
|
||||
freshMethod=放一块后对next序列的刷新函数,不使用默认sequence的话就要自己写
|
||||
bag:一包的方块(本质是基准序列,不一定是包)
|
||||
mission:包含任务的table,说明暂时略
|
||||
|
||||
life:生命数,
|
||||
pushSpeed:上涨速度
|
||||
noTele:是否禁止10个高级按键,
|
||||
visible:方块可见性,填写固定的几个字符串
|
||||
freshLimit:锁延刷新次数限制
|
||||
easyFresh:是否使用简单锁延刷新规则
|
||||
|
||||
Fkey:按下功能键后执行的函数
|
||||
keyCancel:包含禁止使用的按键的id们的table
|
||||
fineKill:是否开启非极简即死
|
||||
b2bKill:是否开启断b2b即死
|
||||
missionKill:是否开启强制任务
|
||||
target:目标行数,如果dropPiece使用了默认的几个通用通关函数或者自己有一个目标数字就要写
|
||||
dropPiece:放一块后要执行的函数,输入玩家对象
|
||||
|
||||
bg:背景,只能填写默认背景的名字
|
||||
bgm:背景音乐,只能填写默认音乐库的音乐名
|
||||
noMod:是否禁用玩家开启mod
|
||||
load:
|
||||
必选
|
||||
模式初始化函数,一般创建一个玩家即可
|
||||
无输入和输出
|
||||
mesDisp:
|
||||
必选
|
||||
模式显示信息,是一个绘图函数,坐标系原点是玩家对象最左上角
|
||||
输入玩家对象
|
||||
无输出
|
||||
|
||||
score:
|
||||
可选(不填就没有分数保存和计算)
|
||||
一局打完后要存储的数据
|
||||
输入玩家对象
|
||||
输出游戏结束瞬间返回一个包含直接决定该模式成绩的数据table(会被强制加上date标签)
|
||||
|
||||
scoreDisp:
|
||||
可选(当模式不出现在地图上的时候)
|
||||
是把score()存起来的table转换为字符串显示出来的函数
|
||||
输入一个成绩table
|
||||
输出一个字符串
|
||||
|
||||
comp:
|
||||
可选(当没有score函数的时候)
|
||||
是成绩table之间对比并排序的规则
|
||||
输入两个成绩table
|
||||
输出[第一个是不是排在第二个前面]的布尔值(可以类比"小于"运算)
|
||||
|
||||
getRank:
|
||||
可选,模式评级函数
|
||||
是用于评价玩家表现的函数
|
||||
输入玩家对象
|
||||
返回0~5,0表示除了记录到排行榜外什么都不做;1/2/3/4/5表示D/C/B/A/S级,能解锁连接的模式,还会让模式图标在地图上显示不同的颜色
|
||||
|
||||
以下是40行的模式文件内容:
|
||||
//sprint_40.lua
|
||||
return{--返回一个table,你也可以在之前定义一些常量或者函数什么的
|
||||
color=COLOR.green,--颜色
|
||||
env={--模式环境变量
|
||||
drop=60,lock=60,
|
||||
target=40,dropPiece=PLY.check_lineReach,
|
||||
bg="bg2",bgm="race",
|
||||
},
|
||||
load=function()--生成玩家
|
||||
PLY.newPlayer(1,340,15)
|
||||
end,
|
||||
mesDisp=function(P)--40行模式需要显示的信息
|
||||
setFont(55)
|
||||
local r=40-P.stat.row
|
||||
if r<0 then r=0 end
|
||||
mStr(r,69,335)--把计算出来的剩余行数r显示出来
|
||||
PLY.draw.drawTargetLine(P,r)--使用自带的境界高度线绘制函数
|
||||
end,
|
||||
score=function(P)return{P.stat.frame/60,P.stat.piece}end,--游戏结束时需要保存的本局关键信息
|
||||
scoreDisp=function(D)return toTime(D[1]).." "..D[2].." Pieces"end,--把score返回的数据显示出来的方法
|
||||
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,--按照时间排序,时间一样就看块数
|
||||
getRank=function(P)--计算评级
|
||||
if P.stat.row<40 then return end--你总得打完40行对吧,否则直接return空掉,成绩都不记录
|
||||
local T=P.stat.frame/60
|
||||
return
|
||||
T<=26 and 5 or--时间小于等于26秒,S级要求,至于为什么是26秒不解释
|
||||
T<=32.6 and 4 or--A级要求
|
||||
T<=52.6 and 3 or--B级要求
|
||||
T<=92.9 and 2 or--C级要求
|
||||
T<=183 and 1 or--D级要求,是解锁别的模式的最低标准
|
||||
0--打完了40行那成绩就给你记一下
|
||||
end,
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
以下是Techmino使用/将要使用/未来也许会使用的语音文件, 每一个都可以录任意多条
|
||||
有多个文件的语音在播放时会随机挑选一个播放, 所以组合性的语音大概率不能随意发挥, 不然和其他组合起来可能就会出现奇怪的现象
|
||||
|
||||
例如多个mini语音文件名: mini_1.ogg, mini_2.ogg, ......
|
||||
如果只有一个, "_1"可以省略, 但是多个文件的数字不能跳跃
|
||||
|
||||
要投稿语音包的话如果没有经过后期处理, 建议使用wav格式;
|
||||
如果打算自己导入游戏的话需要降噪+裁剪+调整音量后再转为ogg格式 (不支持别的, 因为ogg音质好体积小)
|
||||
|
||||
目前游戏内正在使用, 必须录制的音频文件名们:
|
||||
single, double, triple, techrash
|
||||
以上直接念就可以,用于普通直接消行
|
||||
|
||||
mini, b2b, b3b
|
||||
以上直接念就可以,用于组合进spin消除
|
||||
|
||||
zspin, sspin, lspin, jspin, tspin, ospin, ispin
|
||||
以上的每一个都要衍生出数条语音,例如zpin的是这五条:
|
||||
z-spin (用于不消行)
|
||||
z-spin single
|
||||
z-spin double
|
||||
z-spin triple
|
||||
z-spin techrash
|
||||
(z-spin pentacrash)
|
||||
(z-spin hexacrash)
|
||||
对于 S L J T O I 每一个都是这样, 五种语音, 加括号的是消5和消6, 一般不用所以可以不录
|
||||
|
||||
另:对于P, Q, F, E, U, V, W, X, R, Y, N, H
|
||||
这些方块也可以有上面那些语音,但由于仅在五连块使用还会显著增加语音包体积, 所以不录也可以
|
||||
|
||||
perfect_clear, half_clear
|
||||
这俩可以直接念也可以略做修改
|
||||
|
||||
win, lose, bye
|
||||
这几个可以自由发挥
|
||||
|
||||
test, happy, doubt, sad, egg
|
||||
第一个是拉语音条预览音量播放的, 剩下的是彩蛋音效(不录也行, 反正一般不会触发)
|
||||
|
||||
welcome_voc
|
||||
进入游戏播放的欢迎语音(类似osu)
|
||||
|
||||
目前没有用到但是将要加入的:
|
||||
split
|
||||
|
||||
未来可能加入的:
|
||||
暂无
|
||||
51
legals.md
Normal file
51
legals.md
Normal file
@@ -0,0 +1,51 @@
|
||||
TECHMINO © 2019-2021 26F Studio. Some rights reserved.
|
||||
|
||||
TECHMINO and "26F Studio" are trademarks of 26F Studio. The TECHMINO game and source code are under a GNU Lesser General Public License Version 3.
|
||||
|
||||
|
||||
"Tetris" is the registered trademark of The Tetris Holding, LLC, licensed to The Tetris Company, Inc. TECHMINO is not a fan game of Tetris. TECHMINO and 26F Studio are not affiliated with Tetris Holding, LLC or The Tetris Company, Inc. in any way.
|
||||
|
||||
|
||||
Powered by LÖVE, © 2006-2021 LÖVE Development Team.
|
||||
|
||||
Lua is free software distributed under the terms of the MIT license. Copyright © 1994-2021 by Lua.org, PUC-Rio.
|
||||
|
||||
SIMPLE LOVE LIGHTS is under a MIT License. Created by Dylan Hunn.
|
||||
|
||||
json.lua is copyrighted by rxi. © 2021 rxi.
|
||||
|
||||
IBM Plex is copyrighted by the International Business Machines Corporation. IBM and IBM Plex are trademarks of IBM Corp, registered in many jurisdictions worldwide. IBM Plex is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
||||
|
||||
Source Han Sans is copyrighted by Adobe Inc. Source Han Sans and Adobe are registered trademarks of Adobe Inc. in United States and other countries or regions. Source Han Sans is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
||||
|
||||
JetBrains Mono is copyrighted by the JetBrains Mono Project authors. JetBrains Mono is a trademark of JetBrains s.r.o. JetBrains Mono is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
||||
|
||||
"PlayStation", "PS", "PlayStation Family Mark", "PS logo", "DualSense" and "Play Has No Limits" are registered trademarks or trademarks of Sony Interactive Entertainment Inc. "SONY" is a registered trademark of Sony Corporation. © 2021 Sony Interactive Entertainment LLC.
|
||||
|
||||
|
||||
"Windows", the Windows logo, "Xbox", Xbox logo, and "Microsoft" are registered trademarks of Microsoft Corporation in the United States of America and other countries or regions.
|
||||
|
||||
|
||||
The Apple logo, "Apple Inc.," iOS, iPadOS, macOS, iPhone, and Mac are registered trademarks of Apple Inc. in the United States of America and other countries or regions.
|
||||
|
||||
|
||||
"EA" and "Electronic Arts" are registered trademarks of Electronic Arts Inc. © 2021 Electronic Arts Inc.
|
||||
|
||||
SEGA and the SEGA logo are registered trademarks of Sega Corporation. © 2021 Sega Corporation.
|
||||
|
||||
Oculus Quest is a registered trademark of Facebook Technologies, LLC. © Meta Platforms, Inc.
|
||||
|
||||
"Nintendo" is a registered trademarks of Nintendo Co., Ltd. © 2021 Nintendo Co., Ltd.
|
||||
|
||||
N3TWORK is a registered trademark of N3TWORK Inc. © 2021 N3TWORK Inc.
|
||||
|
||||
GoldWave is a registered trademark of GoldWave, Inc.
|
||||
|
||||
Linux is a registered trademark of Linus Torvalds.
|
||||
|
||||
Touhou Project © Team Shanghai Alice 2002-2021.
|
||||
|
||||
All other trademarks, logos, and copyrights are the properties of their respective owners.
|
||||
165
license.txt
Normal file
165
license.txt
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
808
main.lua
808
main.lua
@@ -1,242 +1,644 @@
|
||||
--[[
|
||||
______ __ _
|
||||
/_ __/___ _____ / /_ ____ ___ (_)____ ____
|
||||
/ / / _ \ / ___// __ \ / __ `__ \ / // __ \ / __ \
|
||||
/ / / __// /__ / / / // / / / / // // / / // /_/ /
|
||||
/_/ \___/ \___//_/ /_//_/ /_/ /_//_//_/ /_/ \____/
|
||||
Techmino is my first "huge project"
|
||||
optimization is welcomed if you also love tetromino game
|
||||
# ______ __ _ #
|
||||
# /_ __/___ _____ / /_ ____ ___ (_)____ ____ #
|
||||
# / / / _ \ / ___// __ \ / __ `__ \ / // __ \ / __ \ #
|
||||
# / / / __// /__ / / / // / / / / // // / / // /_/ / #
|
||||
# /_/ \___/ \___//_/ /_//_/ /_/ /_//_//_/ /_/ \____/ #
|
||||
Techmino is my first "huge project"
|
||||
optimization is welcomed if you also love tetromino stacking game
|
||||
|
||||
Instructions:
|
||||
1. I made a framework called Zframework, *most* code in Zframework are not directly relevant to game;
|
||||
2. "xxx" are texts for reading by player, 'xxx' are string values just used in program;
|
||||
3. Some goto statement are used for better performance. All goto-labes have detailed names so don't be afraid;
|
||||
4. Except "gcinfo" function of lua itself, other "gc" are short for "graphics";
|
||||
]]--
|
||||
|
||||
local fs=love.filesystem
|
||||
|
||||
--?
|
||||
NONE={}function NULL()end
|
||||
DBP=print--Use this in permanent code
|
||||
SYSTEM=love.system.getOS()
|
||||
MOBILE=SYSTEM=="Android"or SYSTEM=="iOS"
|
||||
--Var leak check
|
||||
-- setmetatable(_G,{__newindex=function(self,k,v)print('>>'..k)print(debug.traceback():match("\n.-\n\t(.-): "))rawset(self,k,v)end})
|
||||
|
||||
--System Global Vars Declaration
|
||||
local fs=love.filesystem
|
||||
VERSION=require"version"
|
||||
TIME=love.timer.getTime
|
||||
YIELD=coroutine.yield
|
||||
SYSTEM=love.system.getOS()if SYSTEM=='OS X'then SYSTEM='macOS'end
|
||||
FNNS=SYSTEM:find'\79\83'--What does FNSF stand for? IDK so don't ask me lol
|
||||
MOBILE=SYSTEM=='Android'or SYSTEM=='iOS'
|
||||
SAVEDIR=fs.getSaveDirectory()
|
||||
|
||||
--Global Vars & Settings
|
||||
MARKING=true
|
||||
LOADED=false
|
||||
NOGAME=false
|
||||
LOGIN=false
|
||||
EDITING=""
|
||||
WSCONN=nil
|
||||
SFXPACKS={'chiptune'}
|
||||
VOCPACKS={'miya',--[['mono',]]'xiaoya','miku'}
|
||||
FIRSTLAUNCH=false
|
||||
DAILYLAUNCH=false
|
||||
|
||||
--System setting
|
||||
math.randomseed(os.time()*626)
|
||||
love.setDeprecationOutput(false)
|
||||
love.keyboard.setKeyRepeat(true)
|
||||
love.keyboard.setTextInput(false)
|
||||
love.mouse.setVisible(false)
|
||||
if MOBILE then
|
||||
local w,h,f=love.window.getMode()
|
||||
f.resizable=false
|
||||
love.window.setMode(w,h,f)
|
||||
end
|
||||
|
||||
local _LOADTIMELIST_={}
|
||||
local _LOADTIME_=TIME()
|
||||
|
||||
--Load modules
|
||||
require"Zframework"
|
||||
|
||||
require"parts/list"
|
||||
require"parts/globalTables"
|
||||
require"parts/gametoolfunc"
|
||||
Z=require'Zframework'
|
||||
FONT.load{
|
||||
norm='parts/fonts/proportional.ttf',
|
||||
mono='parts/fonts/monospaced.ttf',
|
||||
}
|
||||
FONT.setDefault('norm')
|
||||
FONT.setFallback('norm')
|
||||
|
||||
SCR.setSize(1280,720)--Initialize Screen size
|
||||
FIELD[1]=newBoard()--Initialize field[1]
|
||||
BGM.setMaxSources(5)
|
||||
BGM.setChange(function(name)MES.new('music',text.nowPlaying..name,5)end)
|
||||
VOC.setDiversion(.62)
|
||||
|
||||
BLOCKS= require"parts/mino"
|
||||
AIBUILDER= require"parts/AITemplate"
|
||||
FREEROW= require"parts/freeRow"
|
||||
WIDGET.setOnChange(function()
|
||||
if SCN.cur~='custom_field'then
|
||||
local colorList=THEME.getThemeColor()
|
||||
if not colorList then return end
|
||||
local rnd=math.random
|
||||
for _,W in next,SCN.scenes[SCN.cur].widgetList do
|
||||
if W.color then
|
||||
W.color=colorList[rnd(#colorList)]
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
TEXTURE=require"parts/texture"
|
||||
SKIN= require"parts/skin"
|
||||
PLY= require"parts/player"
|
||||
AIFUNC= require"parts/ai"
|
||||
MODES= require"parts/modes"
|
||||
TICK= require"parts/tick"
|
||||
table.insert(_LOADTIMELIST_,("Load Zframework: %.3fs"):format(TIME()-_LOADTIME_))
|
||||
|
||||
--Initialize sound libs
|
||||
SFX.set{
|
||||
--Stereo sfxs(cannot set position)
|
||||
"welcome_sfx",
|
||||
"click","enter",
|
||||
"finesseError","finesseError_long",
|
||||
--Create shortcuts
|
||||
setFont=FONT.set
|
||||
getFont=FONT.get
|
||||
mStr=GC.mStr
|
||||
mText=GC.simpX
|
||||
mDraw=GC.draw
|
||||
Snd=SFX.playSample
|
||||
string.repD=STRING.repD
|
||||
string.sArg=STRING.sArg
|
||||
string.split=STRING.split
|
||||
|
||||
--Mono sfxs
|
||||
"virtualKey",
|
||||
"button","swipe",
|
||||
"ready","start","win","fail","collect",
|
||||
"spawn_1","spawn_2","spawn_3","spawn_4","spawn_5","spawn_6","spawn_7",
|
||||
"move","rotate","rotatekick","hold",
|
||||
"prerotate","prehold",
|
||||
"lock","drop","fall",
|
||||
"reach",
|
||||
"ren_1","ren_2","ren_3","ren_4","ren_5","ren_6","ren_7","ren_8","ren_9","ren_10","ren_11","ren_mega",
|
||||
"clear_1","clear_2","clear_3","clear_4",
|
||||
"spin_0","spin_1","spin_2","spin_3",
|
||||
"emit","blip_1","blip_2",
|
||||
"clear",
|
||||
"error",
|
||||
}
|
||||
BGM.set{
|
||||
"blank",--menu
|
||||
"race",--sprint, solo
|
||||
"infinite",--infinite norm/dig, ultra, zen, tech-finesse
|
||||
"push",--marathon, round, tsd, blind-5/6
|
||||
"way",--dig sprint
|
||||
"reason",--drought, blind-1/2/3/4
|
||||
--Delete all naked files (from too old version)
|
||||
FILE.clear('')
|
||||
|
||||
"secret8th",--master-1, survivor-2
|
||||
"secret7th",--master-2, survivor-3
|
||||
"waterfall",--sprint Penta/MPH
|
||||
"new era",--bigbang, survivor-1, tech-normal
|
||||
"oxygen",--c4w/pc train
|
||||
"truth",--pc challenge
|
||||
"sugar fairy",--classic2
|
||||
--Create directories
|
||||
for _,v in next,{'conf','record','replay','cache','lib'}do
|
||||
local info=fs.getInfo(v)
|
||||
if not info then
|
||||
fs.createDirectory(v)
|
||||
elseif info.type~='directory'then
|
||||
fs.remove(v)
|
||||
fs.createDirectory(v)
|
||||
end
|
||||
end
|
||||
|
||||
"distortion",--master-3
|
||||
"far",--GM
|
||||
"shining terminal",--attacker
|
||||
"storm",--defender, survivor-4/5
|
||||
"down",--dig, tech-hard/lunatic
|
||||
|
||||
"rockblock",--classic, 49/99
|
||||
"cruelty","final","8-bit happiness","end","how feeling",--49/99
|
||||
}
|
||||
VOC.set{
|
||||
"zspin","sspin","lspin","jspin","tspin","ospin","ispin",
|
||||
"single","double","triple","techrash",
|
||||
"mini","b2b","b3b",
|
||||
"perfect_clear","half_clear",
|
||||
"win","lose","bye",
|
||||
"test","happy","doubt","sad","egg",
|
||||
"welcome_voc",
|
||||
}
|
||||
CHAR=require'parts.char'
|
||||
require'parts.gameTables'
|
||||
require'parts.gameFuncs'
|
||||
|
||||
--Load shader files from SOURCE ONLY
|
||||
SHADER={}
|
||||
for _,v in next,love.filesystem.getDirectoryItems("parts/shaders")do
|
||||
if love.filesystem.getRealDirectory("parts/shaders/"..v)~=SAVEDIR then
|
||||
local name=v:sub(1,-6)
|
||||
SHADER[name]=love.graphics.newShader("parts/shaders/"..name..".glsl")
|
||||
else
|
||||
LOG.print("Dangerous file : %SAVE%/parts/shaders/"..v)
|
||||
end
|
||||
for _,v in next,fs.getDirectoryItems('parts/shaders')do
|
||||
if isSafeFile('parts/shaders/'..v)then
|
||||
local name=v:sub(1,-6)
|
||||
SHADER[name]=love.graphics.newShader('parts/shaders/'..name..'.glsl')
|
||||
end
|
||||
end
|
||||
|
||||
THEME= require'parts.theme'
|
||||
LINE= require'parts.line'
|
||||
DATA= require'parts.data'
|
||||
|
||||
TEXTURE= require'parts.texture'
|
||||
SKIN= require'parts.skin'
|
||||
USERS= require'parts.users'
|
||||
NET= require'parts.net'
|
||||
VK= require'parts.virtualKey'
|
||||
BOT= require'parts.bot'
|
||||
RSlist= require'parts.RSlist'DSCP=RSlist.TRS.centerPos
|
||||
PLY= require'parts.player'
|
||||
NETPLY= require'parts.netPlayer'
|
||||
MODETREE= require'parts.modeTree'
|
||||
|
||||
setmetatable(TEXTURE,{__index=function(self,k)
|
||||
MES.new('warn',"No texture called: "..k)
|
||||
self[k]=PAPER
|
||||
return self[k]
|
||||
end})
|
||||
|
||||
table.insert(_LOADTIMELIST_,("Load Parts: %.3fs"):format(TIME()-_LOADTIME_))
|
||||
|
||||
--Init Zframework
|
||||
do--Z.setCursor
|
||||
local normImg=GC.DO{16,16,
|
||||
{'fCirc',8,8,4},
|
||||
{'setCL',1,1,1,.7},
|
||||
{'fCirc',8,8,6},
|
||||
}
|
||||
local holdImg=GC.DO{16,16,
|
||||
{'setLW',2},
|
||||
{'dCirc',8,8,7},
|
||||
{'fCirc',8,8,3},
|
||||
}
|
||||
local min,int,abs=math.min,math.floor,math.abs
|
||||
local gc_setColor,gc_draw=love.graphics.setColor,love.graphics.draw
|
||||
local ms=love.mouse
|
||||
Z.setCursor(function(time,x,y)
|
||||
if not SETTING.sysCursor then
|
||||
local R=int((time+1)/2)%7+1
|
||||
_=BLOCK_COLORS[SETTING.skin[R]]
|
||||
gc_setColor(_[1],_[2],_[3],min(abs(1-time%2),.3))
|
||||
_=DSCP[R][0]
|
||||
gc_draw(TEXTURE.miniBlock[R],x,y,time%3.14159265359*4,16,16,_[2]+.5,#BLOCKS[R][0]-_[1]-.5)
|
||||
gc_setColor(1,1,1)
|
||||
gc_draw(ms.isDown(1)and holdImg or normImg,x,y,nil,nil,nil,8,8)
|
||||
end
|
||||
end)
|
||||
end
|
||||
Z.setOnFnKeys({
|
||||
function()MES.new('check',PROFILE.switch()and"profile start!"or"profile report copied!")end,
|
||||
function()MES.new('info',("System:%s[%s]\nluaVer:%s\njitVer:%s\njitVerNum:%s"):format(SYSTEM,jit.arch,_VERSION,jit.version,jit.version_num))end,
|
||||
function()MES.new('error',"挂了")end,
|
||||
function()
|
||||
if GAME.playing and not GAME.net then
|
||||
for _=1,8 do
|
||||
if #PLY_ALIVE>1 then
|
||||
local P=PLY_ALIVE[math.random(2,#PLY_ALIVE)]
|
||||
P.lastRecv=PLAYERS[1]
|
||||
P:lose()
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
function()print(WIDGET.getSelected()or"no widget selected")end,
|
||||
function()for k,v in next,_G do print(k,v)end end,
|
||||
function()if love['_openConsole']then love['_openConsole']()end end,
|
||||
})
|
||||
Z.setOnResize(function(w,_)
|
||||
SHADER.warning:send('w',w*SCR.dpi)
|
||||
end)
|
||||
do--Z.setOnFocus
|
||||
local function task_autoSoundOff()
|
||||
while true do
|
||||
coroutine.yield()
|
||||
local v=love.audio.getVolume()
|
||||
love.audio.setVolume(math.max(v-.05,0))
|
||||
if v==0 then return end
|
||||
end
|
||||
end
|
||||
local function task_autoSoundOn()
|
||||
while true do
|
||||
coroutine.yield()
|
||||
local v=love.audio.getVolume()
|
||||
if v<SETTING.mainVol then
|
||||
love.audio.setVolume(math.min(v+.05,SETTING.mainVol,1))
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
Z.setOnFocus(function(f)
|
||||
if f then
|
||||
love.timer.step()
|
||||
if SETTING.autoMute then
|
||||
TASK.removeTask_code(task_autoSoundOff)
|
||||
TASK.new(task_autoSoundOn)
|
||||
end
|
||||
else
|
||||
if SCN.cur=='game'and SETTING.autoPause then
|
||||
pauseGame()
|
||||
end
|
||||
if SETTING.autoMute then
|
||||
TASK.removeTask_code(task_autoSoundOn)
|
||||
TASK.new(task_autoSoundOff)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
Z.setOnQuit(destroyPlayers)
|
||||
|
||||
--Load settings and statistics
|
||||
TABLE.cover (loadFile('conf/user','-canSkip')or{},USER)
|
||||
TABLE.cover (loadFile('conf/unlock','-canSkip')or{},RANKS)
|
||||
TABLE.update(loadFile('conf/settings','-canSkip')or{},SETTING)
|
||||
TABLE.coverR(loadFile('conf/data','-canSkip')or{},STAT)
|
||||
TABLE.cover (loadFile('conf/key','-canSkip')or{},KEY_MAP)
|
||||
TABLE.cover (loadFile('conf/virtualkey','-json -canSkip')or{},VK_ORG)
|
||||
|
||||
--Initialize fields, sequence, missions, gameEnv for cutsom game
|
||||
local fieldData=loadFile('conf/customBoards','-string -canSkip')
|
||||
if fieldData then
|
||||
fieldData=STRING.split(fieldData,"!")
|
||||
for i=1,#fieldData do
|
||||
DATA.pasteBoard(fieldData[i],i)
|
||||
end
|
||||
else
|
||||
FIELD[1]=DATA.newBoard()
|
||||
end
|
||||
local sequenceData=loadFile('conf/customSequence','-string -canSkip')
|
||||
if sequenceData then
|
||||
DATA.pasteSequence(sequenceData)
|
||||
end
|
||||
local missionData=loadFile('conf/customMissions','-string -canSkip')
|
||||
if missionData then
|
||||
DATA.pasteMission(missionData)
|
||||
end
|
||||
local customData=loadFile('conf/customEnv','-canSkip')
|
||||
if customData and customData['version']==VERSION.code then
|
||||
TABLE.complete(customData,CUSTOMENV)
|
||||
end
|
||||
TABLE.complete(require"parts.customEnv0",CUSTOMENV)
|
||||
|
||||
|
||||
--Initialize image libs
|
||||
IMG.init{
|
||||
lock='media/image/mess/lock.png',
|
||||
dialCircle='media/image/mess/dialCircle.png',
|
||||
dialNeedle='media/image/mess/dialNeedle.png',
|
||||
lifeIcon='media/image/mess/life.png',
|
||||
badgeIcon='media/image/mess/badge.png',
|
||||
ctrlSpeedLimit='media/image/mess/ctrlSpeedLimit.png',
|
||||
speedLimit='media/image/mess/speedLimit.png',--Not used, for future C2-mode
|
||||
pay1='media/image/mess/pay1.png',
|
||||
pay2='media/image/mess/pay2.png',
|
||||
drought='media/image/mess/drought.png',
|
||||
|
||||
miyaCH1='media/image/characters/miya1.png',
|
||||
miyaCH2='media/image/characters/miya2.png',
|
||||
miyaCH3='media/image/characters/miya3.png',
|
||||
miyaCH4='media/image/characters/miya4.png',
|
||||
miyaHeart='media/image/characters/miya_heart.png',
|
||||
miyaGlow='media/image/characters/miya_glow.png',
|
||||
monoCH='media/image/characters/mono.png',
|
||||
xiaoyaCH='media/image/characters/xiaoya.png',
|
||||
xiaoyaOmino='media/image/characters/xiaoya_Omino.png',
|
||||
mikuCH='media/image/characters/miku.png',
|
||||
electric='media/image/characters/electric.png',
|
||||
hbm='media/image/characters/hbm.png',
|
||||
|
||||
lanterns={
|
||||
'media/image/lanterns/1.png',
|
||||
'media/image/lanterns/2.png',
|
||||
'media/image/lanterns/3.png',
|
||||
'media/image/lanterns/4.png',
|
||||
'media/image/lanterns/5.png',
|
||||
'media/image/lanterns/6.png',
|
||||
},
|
||||
}
|
||||
SKIN.load{
|
||||
{name="crystal_scf",path='media/image/skin/crystal_scf.png'},
|
||||
{name="matte_mrz",path='media/image/skin/matte_mrz.png'},
|
||||
{name="shiny_chno",path='media/image/skin/shiny_chno.png'},
|
||||
{name="contrast_mrz",path='media/image/skin/contrast_mrz.png'},
|
||||
{name="polkadots_scf",path='media/image/skin/polkadots_scf.png'},
|
||||
{name="toy_scf",path='media/image/skin/toy_scf.png'},
|
||||
{name="smooth_mrz",path='media/image/skin/smooth_mrz.png'},
|
||||
{name="simple_scf",path='media/image/skin/simple_scf.png'},
|
||||
{name="glass_scf",path='media/image/skin/glass_scf.png'},
|
||||
{name="penta_scf",path='media/image/skin/penta_scf.png'},
|
||||
{name="bubble_scf",path='media/image/skin/bubble_scf.png'},
|
||||
{name="minoes_scf",path='media/image/skin/minoes_scf.png'},
|
||||
{name="pure_mrz",path='media/image/skin/pure_mrz.png'},
|
||||
{name="bright_scf",path='media/image/skin/bright_scf.png'},
|
||||
{name="glow_mrz",path='media/image/skin/glow_mrz.png'},
|
||||
{name="plastic_mrz",path='media/image/skin/plastic_mrz.png'},
|
||||
{name="paper_mrz",path='media/image/skin/paper_mrz.png'},
|
||||
{name="yinyang_scf",path='media/image/skin/yinyang_scf.png'},
|
||||
{name="cartooncup_earety",path='media/image/skin/cartooncup_earety.png'},
|
||||
{name="jelly_miya",path='media/image/skin/jelly_miya.png'},
|
||||
{name="brick_notypey",path='media/image/skin/brick_notypey.png'},
|
||||
{name="gem_notypey",path='media/image/skin/gem_notypey.png'},
|
||||
{name="classic",path='media/image/skin/classic_unknown.png'},
|
||||
{name="ball_shaw",path='media/image/skin/ball_shaw.png'},
|
||||
{name="retro_notypey",path='media/image/skin/retro_notypey.png'},
|
||||
{name="pixel_chno",path='media/image/skin/pixel_chno.png'},
|
||||
{name="textbone_mrz",path='media/image/skin/textbone_mrz.png'},
|
||||
{name="coloredbone_mrz",path='media/image/skin/coloredbone_mrz.png'},
|
||||
{name="wtf",path='media/image/skin/wtf_mrz.png'},
|
||||
}
|
||||
|
||||
--Initialize sound libs
|
||||
SFX.init((function()--[Warning] Not loading files here, just get the list of sound needed
|
||||
local L={}
|
||||
for _,v in next,fs.getDirectoryItems('media/effect/chiptune/')do
|
||||
if isSafeFile('media/effect/chiptune/'..v,"Dangerous file : %SAVE%/media/effect/chiptune/"..v)then
|
||||
table.insert(L,v:sub(1,-5))
|
||||
end
|
||||
end
|
||||
return L
|
||||
end)())
|
||||
BGM.load((function()
|
||||
local L={}
|
||||
for _,v in next,fs.getDirectoryItems('media/music')do
|
||||
if isSafeFile('media/music/'..v,"Dangerous file : %SAVE%/media/music/"..v)then
|
||||
L[v:sub(1,-5)]='media/music/'..v
|
||||
end
|
||||
end
|
||||
return L
|
||||
end)())
|
||||
VOC.init{
|
||||
'zspin','sspin','jspin','lspin','tspin','ospin','ispin','pspin','qspin','fspin','espin','uspin','vspin','wspin','xspin','rspin','yspin','nspin','hspin','cspin',
|
||||
'single','double','triple','techrash','pentacrash','hexacrash',
|
||||
'mini','b2b','b3b',
|
||||
'perfect_clear','half_clear',
|
||||
'win','lose','bye',
|
||||
'test','happy','doubt',
|
||||
'welcome',
|
||||
}
|
||||
|
||||
--Initialize language lib
|
||||
LANG.init('zh',
|
||||
{
|
||||
zh=require'parts.language.lang_zh',
|
||||
zh_trad=require'parts.language.lang_zh_trad',
|
||||
zh_full=require'parts.language.lang_zh_full',
|
||||
en=require'parts.language.lang_en',
|
||||
fr=require'parts.language.lang_fr',
|
||||
es=require'parts.language.lang_es',
|
||||
pt=require'parts.language.lang_pt',
|
||||
id=require'parts.language.lang_id',
|
||||
zh_grass=require'parts.language.lang_zh_grass',
|
||||
zh_yygq=require'parts.language.lang_yygq',
|
||||
symbol=require'parts.language.lang_symbol',
|
||||
--1. Add language file to LANG folder;
|
||||
--2. Require it;
|
||||
--3. Add a button in parts/scenes/lang.lua;
|
||||
},
|
||||
{
|
||||
block=BLOCK_NAMES
|
||||
},
|
||||
(function()
|
||||
local tipMeta={__call=function(L)return L[math.random(#L)]end}
|
||||
return function(L)
|
||||
if type(rawget(L,'getTip'))=='table'then setmetatable(L.getTip,tipMeta)end
|
||||
setmetatable(L,{__index=function(self,k)
|
||||
local mes="No Text ("..SETTING.locale.."): "..k
|
||||
LOG(mes)
|
||||
MES.new('warn',mes)
|
||||
self[k]=CHAR.zChan.thinking
|
||||
return self[k]
|
||||
end})
|
||||
end
|
||||
end)()
|
||||
)
|
||||
|
||||
table.insert(_LOADTIMELIST_,("Initialize Parts: %.3fs"):format(TIME()-_LOADTIME_))
|
||||
|
||||
--Load background files from SOURCE ONLY
|
||||
for _,v in next,love.filesystem.getDirectoryItems("parts/backgrounds")do
|
||||
if love.filesystem.getRealDirectory("parts/backgrounds/"..v)~=SAVEDIR then
|
||||
local name=v:sub(1,-5)
|
||||
BG.add(name,require("parts/backgrounds/"..name))
|
||||
else
|
||||
LOG.print("Dangerous file : %SAVE%/parts/backgrounds/"..v)
|
||||
end
|
||||
for _,v in next,fs.getDirectoryItems('parts/backgrounds')do
|
||||
if isSafeFile('parts/backgrounds/'..v)and v:sub(-3)=='lua'then
|
||||
local name=v:sub(1,-5)
|
||||
BG.add(name,require('parts.backgrounds.'..name))
|
||||
end
|
||||
end
|
||||
|
||||
BG.remList('none')BG.remList('gray')BG.remList('custom')
|
||||
--Load scene files from SOURCE ONLY
|
||||
for _,v in next,fs.getDirectoryItems("parts/scenes")do
|
||||
if fs.getRealDirectory("parts/scenes/"..v)~=SAVEDIR then
|
||||
local sceneName=v:sub(1,-5)
|
||||
local scene=require("parts/scenes/"..sceneName)
|
||||
SCN.add(sceneName,scene)
|
||||
if scene.widgetList then WIDGET.init(sceneName,scene.widgetList)end
|
||||
else
|
||||
LOG.print("Dangerous file : %SAVE%/parts/scenes/"..v)
|
||||
end
|
||||
for _,v in next,fs.getDirectoryItems('parts/scenes')do
|
||||
if isSafeFile('parts/scenes/'..v)then
|
||||
local sceneName=v:sub(1,-5)
|
||||
SCN.add(sceneName,require('parts.scenes.'..sceneName))
|
||||
LANG.addScene(sceneName)
|
||||
end
|
||||
end
|
||||
|
||||
--Load files
|
||||
if fs.getInfo("settings.dat")then
|
||||
addToTable(FILE.load("settings"),SETTING)
|
||||
else
|
||||
if MOBILE then
|
||||
SETTING.VKSwitch=true
|
||||
SETTING.swap=false
|
||||
SETTING.vib=2
|
||||
SETTING.powerInfo=true
|
||||
SETTING.fullscreen=true
|
||||
love.window.setFullscreen(true)
|
||||
love.resize(love.graphics.getWidth(),love.graphics.getHeight())
|
||||
end
|
||||
end
|
||||
if SETTING.fullscreen then love.window.setFullscreen(true)end
|
||||
LANG.set(SETTING.lang)
|
||||
|
||||
if fs.getInfo("unlock.dat")then RANKS=FILE.load("unlock")end
|
||||
if fs.getInfo("data.dat")then STAT=FILE.load("data")end
|
||||
if fs.getInfo("key.dat")then keyMap=FILE.load("key")end
|
||||
if fs.getInfo("virtualkey.dat")then VK_org=FILE.load("virtualkey")end
|
||||
if fs.getInfo("account.dat")then ACCOUNT=FILE.load("account")end
|
||||
|
||||
if fs.getInfo("tech_ultimate.dat")then fs.remove("tech_ultimate.dat")end
|
||||
if fs.getInfo("tech_ultimate+.dat")then fs.remove("tech_ultimate+.dat")end
|
||||
table.insert(_LOADTIMELIST_,("Load Files: %.3fs"):format(TIME()-_LOADTIME_))
|
||||
|
||||
--Update data
|
||||
do
|
||||
--Check Ranks
|
||||
local R=RANKS
|
||||
R.sprint_10=R.sprint_10 or 0
|
||||
if R.infinite and R.infinite~=6 then
|
||||
R.infinite=6
|
||||
R.infinite_dig=6
|
||||
fs.remove("infinite.dat")
|
||||
fs.remove("infinite_dig.dat")
|
||||
end
|
||||
if not text.modes[STAT.lastPlay]then
|
||||
STAT.lastPlay="sprint_10"
|
||||
end
|
||||
local needSave
|
||||
|
||||
--Check setting file
|
||||
local S=SETTING
|
||||
if
|
||||
type(S.block)~="boolean"or
|
||||
type(S.spawn)~="number"or
|
||||
type(S.ghost)~="number"or
|
||||
type(S.center)~="number"or
|
||||
S.bgm>1 or S.sfx>1 or S.voc>1 or
|
||||
S.stereo>1 or S.VKSFX>1 or S.VKAlpha>1
|
||||
then
|
||||
NOGAME=true
|
||||
fs.remove("settings.dat")
|
||||
end
|
||||
if not fs.getInfo('conf/data')then
|
||||
needSave=true
|
||||
end
|
||||
if type(STAT.version)~='number'then
|
||||
STAT.version=0
|
||||
needSave=true
|
||||
end
|
||||
if STAT.version<1500 then
|
||||
FILE.clear_s('')
|
||||
end
|
||||
if STAT.version<1505 then
|
||||
fs.remove('record/bigbang.rec')
|
||||
fs.remove('conf/replay')
|
||||
end
|
||||
if STAT.version==1506 then
|
||||
local temp1,temp2
|
||||
if fs.getInfo('record/master_l.rec')then
|
||||
temp1=fs.read('record/master_l.rec')
|
||||
end
|
||||
if fs.getInfo('record/master_u.rec')then
|
||||
temp2=fs.read('record/master_u.rec')
|
||||
end
|
||||
if temp1 then
|
||||
fs.write('record/master_u.rec',temp1)
|
||||
end
|
||||
if temp2 then
|
||||
fs.write('record/master_l.rec',temp2)
|
||||
end
|
||||
RANKS.master_l,RANKS.master_u=RANKS.master_u,RANKS.master_l
|
||||
if RANKS.tsd_u then
|
||||
RANKS.tsd_u=0
|
||||
end
|
||||
end
|
||||
if STAT.version==1601 then
|
||||
RANKS.round_e=nil
|
||||
RANKS.round_n=nil
|
||||
RANKS.round_h=nil
|
||||
RANKS.round_l=nil
|
||||
RANKS.round_u=nil
|
||||
fs.remove('record/round_e.rec')
|
||||
fs.remove('record/round_n.rec')
|
||||
fs.remove('record/round_h.rec')
|
||||
fs.remove('record/round_l.rec')
|
||||
fs.remove('record/round_u.rec')
|
||||
end
|
||||
if STAT.version<1700 and SETTING.dascut<5 then
|
||||
SETTING.dascut=SETTING.dascut+1
|
||||
needSave=true
|
||||
end
|
||||
if SETTING.vocPack=='mono'then
|
||||
SETTING.vocPack='miya'
|
||||
end
|
||||
if RANKS.stack_e then
|
||||
RANKS.stack_e=nil
|
||||
RANKS.stack_h=nil
|
||||
RANKS.stack_u=nil
|
||||
fs.remove('record/stack_e.rec')
|
||||
fs.remove('record/stack_h.rec')
|
||||
fs.remove('record/stack_u.rec')
|
||||
end
|
||||
if RANKS.stack_20l then
|
||||
RANKS.stack_20l=nil
|
||||
RANKS.stack_40l=nil
|
||||
RANKS.stack_100l=nil
|
||||
fs.remove('record/stack_20l.rec')
|
||||
fs.remove('record/stack_40l.rec')
|
||||
fs.remove('record/stack_100l.rec')
|
||||
end
|
||||
if RANKS.rhythm_e then
|
||||
RANKS.rhythm_e=nil
|
||||
RANKS.rhythm_h=nil
|
||||
RANKS.rhythm_u=nil
|
||||
fs.remove('record/rhythm_e.rec')
|
||||
fs.remove('record/rhythm_h.rec')
|
||||
fs.remove('record/rhythm_u.rec')
|
||||
end
|
||||
if RANKS.bigbang then
|
||||
RANKS.clearRush,RANKS.bigbang=RANKS.bigbang
|
||||
fs.remove('record/bigbang.rec')
|
||||
end
|
||||
if STAT.version~=VERSION.code then
|
||||
for k,v in next,MODE_UPDATE_MAP do
|
||||
if RANKS[k]then
|
||||
RANKS[v]=RANKS[k]
|
||||
RANKS[k]=nil
|
||||
end
|
||||
k='record/'..k
|
||||
if fs.getInfo(k..'.dat')then
|
||||
fs.write('record/'..v..'.rec',fs.read(k..'.dat'))
|
||||
fs.remove(k..'.dat')
|
||||
end
|
||||
if fs.getInfo(k..'.rec')then
|
||||
fs.write('record/'..v..'.rec',fs.read(k..'.rec'))
|
||||
fs.remove(k..'.rec')
|
||||
end
|
||||
end
|
||||
STAT.version=VERSION.code
|
||||
needSave=true
|
||||
end
|
||||
SETTING.appLock,SETTING.dataSaving,SETTING.swap=nil
|
||||
if not SETTING.VKSkin then SETTING.VKSkin=1 end
|
||||
for _,v in next,SETTING.skin do if v<1 or v>17 then v=17 end end
|
||||
if not RSlist[SETTING.RS]then SETTING.RS='TRS'end
|
||||
if SETTING.ghostType=='greyCell'then SETTING.ghostType='grayCell'end
|
||||
if type(SETTING.skinSet)=='number'then SETTING.skinSet='crystal_scf'end
|
||||
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then SETTING.frameMul=100 end
|
||||
if SETTING.cv then SETTING.vocPack,SETTING.cv=SETTING.cv end
|
||||
if type(SETTING.bg)~='string'then SETTING.bg='on'end
|
||||
if SETTING.skin[18]==10 then SETTING.skin[18]=4 end
|
||||
if SETTING.reTime>3 or SETTING.reTime<.5 then SETTING.reTime=2 end
|
||||
if RANKS.infinite then RANKS.infinite=0 end
|
||||
if RANKS.infinite_dig then RANKS.infinite_dig=0 end
|
||||
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
|
||||
if RANKS.master_l then RANKS.master_n,RANKS.master_l=RANKS.master_l needSave=true end
|
||||
if RANKS.master_u then RANKS.master_h,RANKS.master_u=RANKS.master_u needSave=true end
|
||||
for _,v in next,VK_ORG do v.color=nil end
|
||||
for name,rank in next,RANKS do
|
||||
if type(name)=='number'or type(rank)~='number'then
|
||||
RANKS[name]=nil
|
||||
needSave=true
|
||||
end
|
||||
end
|
||||
|
||||
if fs.getInfo("cold_clear.dll")then
|
||||
NOGAME=true
|
||||
fs.remove("cold_clear.dll")
|
||||
fs.remove("CCloader.dll")
|
||||
end
|
||||
if needSave then
|
||||
saveStats()
|
||||
saveProgress()
|
||||
saveSettings()
|
||||
love.event.quit('restart')
|
||||
end
|
||||
end
|
||||
|
||||
--Update data file
|
||||
S=STAT
|
||||
freshDate()
|
||||
if S.extraRate then
|
||||
S.finesseRate=5*(S.piece-S.extraRate)
|
||||
end
|
||||
if S.version~=VERSION_CODE then
|
||||
if(tonumber(S.version)or 0)<1204 then
|
||||
STAT.frame=math.floor(STAT.time*60)
|
||||
STAT.lastPlay="sprint_10"
|
||||
RANKS.sprintFix=nil
|
||||
RANKS.sprintLock=nil
|
||||
fs.remove("sprintFix.dat")
|
||||
fs.remove("sprintLock.dat")
|
||||
end
|
||||
newVersionLaunch=true
|
||||
--First start
|
||||
FIRSTLAUNCH=STAT.run==0
|
||||
if FIRSTLAUNCH and MOBILE then
|
||||
SETTING.VKSwitch=true
|
||||
SETTING.powerInfo=true
|
||||
SETTING.cleanCanvas=true
|
||||
end
|
||||
|
||||
--Try unlock modes which should be unlocked
|
||||
for name,rank in next,RANKS do
|
||||
if rank and rank>0 then
|
||||
for _,mode in next,MODES do
|
||||
if mode.name==name and mode.unlock then
|
||||
for _,unlockName in next,mode.unlock do
|
||||
if not RANKS[unlockName]then
|
||||
RANKS[unlockName]=0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--Apply system setting
|
||||
applySettings()
|
||||
|
||||
S.version=VERSION_CODE
|
||||
FILE.save(RANKS,"unlock","q")
|
||||
FILE.save(STAT,"data")
|
||||
end
|
||||
end
|
||||
--Load replays
|
||||
for _,fileName in next,fs.getDirectoryItems('replay')do
|
||||
if fileName:sub(12,12):match("[a-zA-Z]")then
|
||||
local date,mode,version,player,seed,setting,mod
|
||||
local fileData=fs.read('replay/'..fileName)
|
||||
date, fileData=STRING.readLine(fileData)date=date:gsub("[a-zA-Z]","")
|
||||
mode, fileData=STRING.readLine(fileData)mode=MODE_UPDATE_MAP[mode]or mode
|
||||
version,fileData=STRING.readLine(fileData)
|
||||
player, fileData=STRING.readLine(fileData)if player=="Local Player"then player="Stacker"end
|
||||
local success
|
||||
success,fileData=pcall(love.data.decompress,'string','zlib',fileData)
|
||||
if not success then goto BREAK_cannotParse end
|
||||
seed, fileData=STRING.readLine(fileData)
|
||||
setting,fileData=STRING.readLine(fileData)setting=JSON.decode(setting)
|
||||
mod, fileData=STRING.readLine(fileData)mod=JSON.decode(mod)
|
||||
if
|
||||
not setting or
|
||||
not mod or
|
||||
not mode or
|
||||
#mode==0
|
||||
then goto BREAK_cannotParse end
|
||||
|
||||
fs.remove('replay/'..fileName)
|
||||
local newName=fileName:sub(1,10)..fileName:sub(15)
|
||||
fs.write('replay/'..newName,
|
||||
love.data.compress('string','zlib',
|
||||
JSON.encode{
|
||||
date=date,
|
||||
mode=mode,
|
||||
version=version,
|
||||
player=player,
|
||||
seed=seed,
|
||||
setting=setting,
|
||||
mod=mod,
|
||||
}.."\n"..
|
||||
fileData
|
||||
)
|
||||
)
|
||||
fileName=newName
|
||||
end
|
||||
::BREAK_cannotParse::
|
||||
local rep=DATA.parseReplay('replay/'..fileName)
|
||||
table.insert(REPLAY,rep)
|
||||
end
|
||||
table.sort(REPLAY,function(a,b)return a.fileName>b.fileName end)
|
||||
|
||||
table.insert(_LOADTIMELIST_,("Initialize Data: %.3fs"):format(TIME()-_LOADTIME_))
|
||||
|
||||
for i=1,#_LOADTIMELIST_ do LOG(_LOADTIMELIST_[i])end
|
||||
|
||||
--Launch testing task if launch param received
|
||||
if TABLE.find(arg,'--test')then
|
||||
TASK.new(function()
|
||||
while not LOADED do YIELD()end
|
||||
|
||||
LOG("\27[92m\27[1mAutomatic Test Started\27[0m")
|
||||
BGM.setVol(0)SFX.setVol(0)
|
||||
love.keypressed('space')
|
||||
TEST.yieldUntilNextScene()
|
||||
|
||||
for k,mode in next,MODES do
|
||||
if k~='netBattle'then
|
||||
LOG("Scanning mode: "..mode.name)
|
||||
loadGame(mode.name,true)
|
||||
TEST.yieldUntilNextScene()
|
||||
SCN.back()
|
||||
TEST.yieldUntilNextScene()
|
||||
end
|
||||
end
|
||||
LOG("\27[92m\27[1mAutomatic Test Passed :)\27[0m")
|
||||
TEST.yieldN(60)
|
||||
love.event.quit(0)
|
||||
end)
|
||||
TASK.new(function()
|
||||
while true do
|
||||
YIELD()
|
||||
if Z.getErr(1)then break end
|
||||
end
|
||||
LOG("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(Z.getErr(1).mes,"\n").."\27[91m\nAborting\27[0m")
|
||||
TEST.yieldN(60)
|
||||
love.event.quit(1)
|
||||
end)
|
||||
end
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user