mirror of
https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile.git
synced 2025-01-08 17:33:09 +08:00
Compare commits
13 Commits
v.0.0.v.2.
...
v1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9a97856fd | ||
|
|
8f902caa22 | ||
|
|
4e0815e13a | ||
|
|
c555e98081 | ||
|
|
fbfd9ee0db | ||
|
|
3c473fd5f3 | ||
|
|
dd55171204 | ||
|
|
6beacc51f5 | ||
|
|
c14c702d17 | ||
|
|
9679378b1b | ||
|
|
d7726c1854 | ||
|
|
e79bf246bf | ||
|
|
7cf450868a |
18
README.md
18
README.md
@@ -36,22 +36,22 @@ Ported to Android (mobile and TV) by SweetSea with on-screen control (with some
|
||||
Navigate to where you put ``tromi_mobile.love`` in the File manager (the one you downloaded from the link in Install for TV section), just opening and Tromi should be launched.
|
||||
|
||||
# Differences from original Tromi
|
||||
> This is required, to follow the used license (GNU GPL v3)
|
||||
> I must make this list to follow the used license (GNU GPL v3)<br>
|
||||
> :no_entry: There are ***very much*** breaking changes right now, and I can't always finish this list. I may try hard to do it.
|
||||
* No differences in gameplay
|
||||
* Files will be saved into ``Android/data/org.love2d.android/tromi_mobile`` instead the location where the game files in
|
||||
* Add ``simple-button`` module, made by SweetSea
|
||||
* Add ``simple-button`` module, made by me (SweetSea)
|
||||
* All UIs are touch-able
|
||||
* Add on-screen buttons
|
||||
* Replaced icons for 3 direction buttons (Left, Down, Right)
|
||||
* Replaced icons for 3 direction buttons (Left, Down, Right), using from Techmino's font (outdated image)
|
||||
<img src="https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile/raw/branch/main/screenshot/Replay_screen_differences.png">
|
||||
* Add a special pre-made keybind for Android TV (only supports TV models have their remote has numerical area (0-9))<img src="https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile/raw/branch/main/screenshot/SPOILER_tv_code.png">
|
||||
* <details><summary>Changes the way to input secret code to activate Pentominoes mode</summary><img src="https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile/raw/branch/main/screenshot/SPOILER_pento_code.png">To insert the left arrow, tap on the left, so does to right arrow.</details>
|
||||
* Add a loading screen (this need to be updated later)
|
||||
* Add a loading screen ~~(this need to be updated later)~~
|
||||
* Update ``binser`` library, this fixes some weird bugs related to saving
|
||||
* Replaced old Cambridge's ``config`` module with the new one inspired by "the sequel of Techmino"s ``SETTINGS`` module
|
||||
|
||||
# TODO
|
||||
|
||||
- [ ] Add a way to export ~~replay~~ data for Android > 11
|
||||
- [x] Revert ``bitser`` with ``binser`` (if and only if I can make it works)
|
||||
- [x] Design a new on-screen buttons skin (the current one is come from [C₂₉H₂₅N₃O₅](https://github.com/C29H25N3O5), I am aware that it's not fit to Tromi's design language)
|
||||
@@ -63,15 +63,15 @@ Please read ``COPYING.txt`` for more information.<br>
|
||||
|
||||
A small note about the music:
|
||||
> Only mycophobia right now having the permission to music from Jerry Martin, I haven't got.<br>
|
||||
>
|
||||
>
|
||||
> I sent an email about this issue (not mentioning about this game), but I haven't got any replies from them (I checked both my main inbox and spam too, nothing)<br>
|
||||
>
|
||||
>
|
||||
> Both me and mycophobia can't give you a sub-license if you ask. What can I do is suggesting you to send an email about this (there is a chance that you may not receive any replies, but it's better than do nothing)
|
||||
|
||||
# Special thanks
|
||||
* mycophobia for writing the original Tromi
|
||||
* MrZ_26 for the base of ``VCTRL`` module (yea I stole from him his code ;-;)
|
||||
* C₂₉H₂₅N₃O₅ for his virtual key design, I used it during developing when I hadn't made my own yet
|
||||
* MrZ_26 for the base of ``VCTRL`` module (yea I stole from him his code ;-; )
|
||||
* C₂₉H₂₅N₃O₅ for his virtual key design (used while during inital development), and icon font (from Techmino).
|
||||
|
||||
# Don't forget to check
|
||||
* [Original Tromi](https://mycophobia.org/tromi)
|
||||
|
||||
415
char.lua
Normal file
415
char.lua
Normal file
@@ -0,0 +1,415 @@
|
||||
local function utf8_convert(n)
|
||||
local floorint = math.floor
|
||||
local char = string.char
|
||||
|
||||
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+floorint(n/2^06),128+n%2^6)
|
||||
elseif n<2^16 then return char(224+floorint(n/2^12),128+floorint(n/2^06)%2^6,128+n%2^6)
|
||||
elseif n<2^21 then return char(240+floorint(n/2^18),128+floorint(n/2^12)%2^6,128+floorint(n/2^06)%2^6,128+n%2^6)
|
||||
elseif n<2^26 then return char(248+floorint(n/2^24),128+floorint(n/2^18)%2^6,128+floorint(n/2^12)%2^6,128+floorint(n/2^06)%2^6,128+n%2^6)
|
||||
elseif n<2^31 then return char(252+floorint(n/2^30),128+floorint(n/2^24)%2^6,128+floorint(n/2^18)%2^6,128+floorint(n/2^12)%2^6,128+floorint(n/2^06)%2^6,128+n%2^6)
|
||||
end
|
||||
end
|
||||
|
||||
local L={
|
||||
zChan={-- F0000 - F003F
|
||||
none= 0xF0000,
|
||||
normal= 0xF0001,
|
||||
full= 0xF0002,
|
||||
happy= 0xF0003,
|
||||
confused= 0xF0004,
|
||||
grinning= 0xF0005,
|
||||
frowning= 0xF0006,
|
||||
tears= 0xF0007,
|
||||
anxious= 0xF0008,
|
||||
rage= 0xF0009,
|
||||
fear= 0xF000A,
|
||||
question= 0xF000B,
|
||||
angry= 0xF000C,
|
||||
shocked= 0xF000D,
|
||||
ellipses= 0xF000E,
|
||||
sweatDrop= 0xF000F,
|
||||
cry= 0xF0010,
|
||||
cracked= 0xF0011,
|
||||
qualified= 0xF0012,
|
||||
unqualified= 0xF0013,
|
||||
understand= 0xF0014,
|
||||
thinking= 0xF0015,
|
||||
spark= 0xF0016,
|
||||
},
|
||||
mino={-- F0040 - F007F
|
||||
Z=0xF0040,
|
||||
S=0xF0041,
|
||||
J=0xF0042,
|
||||
L=0xF0043,
|
||||
T=0xF0044,
|
||||
O=0xF0045,
|
||||
I=0xF0046,
|
||||
|
||||
Z5=0xF0047,
|
||||
S5=0xF0048,
|
||||
P= 0xF0049,
|
||||
Q= 0xF004A,
|
||||
F= 0xF004B,
|
||||
E= 0xF004C,
|
||||
T5=0xF004D,
|
||||
U= 0xF004E,
|
||||
V= 0xF004F,
|
||||
W= 0xF0050,
|
||||
X= 0xF0051,
|
||||
J5=0xF0052,
|
||||
L5=0xF0053,
|
||||
R= 0xF0054,
|
||||
Y= 0xF0055,
|
||||
N= 0xF0056,
|
||||
H= 0xF0057,
|
||||
I5=0xF0058,
|
||||
|
||||
I3=0xF0059,
|
||||
C= 0xF005A,
|
||||
I2=0xF005B,
|
||||
O1=0xF005C,
|
||||
},
|
||||
icon={-- F0080 - F00FF
|
||||
menu= 0xF0080,
|
||||
music= 0xF0081,
|
||||
language= 0xF0082,
|
||||
back= 0xF0083,
|
||||
play_pause= 0xF0084,
|
||||
info= 0xF0085,
|
||||
help= 0xF0086,
|
||||
mute= 0xF0087,
|
||||
volume_up= 0xF0088,
|
||||
volume_down= 0xF0089,
|
||||
retry_spin= 0xF008A,
|
||||
filledLogo= 0xF008B,
|
||||
hollowLogo= 0xF008C,
|
||||
toUp= 0xF008D,
|
||||
toDown= 0xF008E,
|
||||
toLeft= 0xF008F,
|
||||
toRight= 0xF0090,
|
||||
checkMark= 0xF0091,
|
||||
crossMark= 0xF0092,
|
||||
musicMark= 0xF0093,
|
||||
infoMark= 0xF0094,
|
||||
warnMark= 0xF0095,
|
||||
console= 0xF0096,
|
||||
globe= 0xF0097,
|
||||
video_camera= 0xF0098,
|
||||
settings= 0xF0099,
|
||||
mrz= 0xF009A,
|
||||
apple= 0xF009B,
|
||||
home= 0xF009C,
|
||||
cross_thick= 0xF009D,
|
||||
num0InSpin= 0xF009E,
|
||||
num1InSpin= 0xF009F,
|
||||
num2InSpin= 0xF00A0,
|
||||
num3InSpin= 0xF00A1,
|
||||
num4InSpin= 0xF00A2,
|
||||
play= 0xF00A3,
|
||||
pause= 0xF00A4,
|
||||
nextFrame= 0xF00A5,
|
||||
yen= 0xF00A6,
|
||||
dollar= 0xF00A7,
|
||||
euro= 0xF00A8,
|
||||
pound= 0xF00A9,
|
||||
bitcoin= 0xF00AA,
|
||||
onebag= 0xF00AB,
|
||||
export= 0xF00AC,
|
||||
import= 0xF00AD,
|
||||
trash= 0xF00AE,
|
||||
loadOne= 0xF00AF,
|
||||
saveOne= 0xF00B0,
|
||||
loadTwo= 0xF00B1,
|
||||
saveTwo= 0xF00B2,
|
||||
zBook= 0xF00B3,
|
||||
rankX= 0xF00B4,
|
||||
rankU= 0xF00B5,
|
||||
rankA= 0xF00B6,
|
||||
rankB= 0xF00B7,
|
||||
rankC= 0xF00B8,
|
||||
rankD= 0xF00B9,
|
||||
rankE= 0xF00BA,
|
||||
rankF= 0xF00BB,
|
||||
rankZ= 0xF00BC,
|
||||
rankS= 0xF00C2,
|
||||
speedOneEights= 0xF00BD,
|
||||
speedOneHalf= 0xF00BE,
|
||||
speedOne= 0xF00BF,
|
||||
speedTwo= 0xF00C0,
|
||||
speedFive= 0xF00C1,
|
||||
bone= 0xF00C3,
|
||||
invis= 0xF00C4,
|
||||
bomb= 0xF00C5,
|
||||
garbage= 0xF00C6,
|
||||
copy= 0xF00C7,
|
||||
tas= 0xF00C8,
|
||||
pencil= 0xF00C9,
|
||||
magGlass= 0xF00CA,
|
||||
zoomIn= 0xF00CB,
|
||||
zoomOut= 0xF00CC,
|
||||
zoomDefault= 0xF00CD,
|
||||
share= 0xF00CE,
|
||||
save= 0xF00CF,
|
||||
fastForward= 0xF00D0,
|
||||
rewind= 0xF00D1,
|
||||
nextSong= 0xF00D2,
|
||||
previousSong= 0xF00D3,
|
||||
cycle= 0xF00D4,
|
||||
cycleOne= 0xF00D5,
|
||||
cycleOff= 0xF00D6,
|
||||
random= 0xF00D7,
|
||||
randomOff= 0xF00D8,
|
||||
randomAuto= 0xF00D9,
|
||||
closedCaption= 0xF00DA,
|
||||
fullBeat= 0xF00DB,
|
||||
rewind10= 0xF00DC,
|
||||
rewind30= 0xF00DD,
|
||||
foward10= 0xF00DE,
|
||||
foward30= 0xF00DF,
|
||||
fontUp= 0xF00E0,
|
||||
fontDown= 0xF00E1,
|
||||
erase= 0xF00E2,
|
||||
auto= 0xF00E3,
|
||||
},
|
||||
key={-- F0100 - F017F
|
||||
macCmd= 0xF0100,
|
||||
macOpt= 0xF0101,
|
||||
macCtrl= 0xF0102,
|
||||
shift= 0xF0103,
|
||||
capsLock= 0xF0104,
|
||||
enter_or_return= 0xF0105,
|
||||
backspace= 0xF0106,
|
||||
clear= 0xF0107,
|
||||
macFowardDel= 0xF0108,
|
||||
macEsc= 0xF0109,
|
||||
macTab= 0xF010A,
|
||||
fn= 0xF010B,
|
||||
macHome= 0xF010C,
|
||||
macEnd= 0xF010D,
|
||||
macPgup= 0xF010E,
|
||||
macPgdn= 0xF010F,
|
||||
macEnter= 0xF0110,
|
||||
space= 0xF0111,
|
||||
windows= 0xF0112,
|
||||
alt= 0xF0113,
|
||||
ctrl= 0xF0114,
|
||||
winMenu= 0xF0115,
|
||||
tab= 0xF0116,
|
||||
esc= 0xF0117,
|
||||
up= 0xF0118,
|
||||
down= 0xF0119,
|
||||
left= 0xF011A,
|
||||
right= 0xF011B,
|
||||
del= 0xF011C,
|
||||
enterText= 0xF011D,
|
||||
keyboard= 0xF011E,
|
||||
macMediaEject= 0xF011F,
|
||||
isoCtrl= 0xF0120,
|
||||
isoAlt= 0xF0121,
|
||||
macHomeAlt= 0xF0122,
|
||||
macEndAlt= 0xF0123,
|
||||
macPgupAlt= 0xF0124,
|
||||
macPgdnAlt= 0xF0125,
|
||||
iecPower= 0xF0126,
|
||||
},
|
||||
controller={-- F0180 - F01FF
|
||||
xbox= 0xF0180,
|
||||
lt= 0xF0181,
|
||||
rt= 0xF0182,
|
||||
lb= 0xF0183,
|
||||
rb= 0xF0184,
|
||||
xboxX= 0xF0185,
|
||||
xboxY= 0xF0186,
|
||||
xboxA= 0xF0187,
|
||||
xboxB= 0xF0188,
|
||||
joystickL= 0xF0189,
|
||||
joystickR= 0xF018A,
|
||||
jsLU= 0xF018B,
|
||||
jsLD= 0xF018C,
|
||||
jsLR= 0xF018D,
|
||||
jsLL= 0xF018E,
|
||||
jsRU= 0xF018F,
|
||||
jsRD= 0xF0190,
|
||||
jsRR= 0xF0191,
|
||||
jsRL= 0xF0192,
|
||||
jsLPress= 0xF0193,
|
||||
jsRPress= 0xF0194,
|
||||
dpad= 0xF0195,
|
||||
dpadU= 0xF0196,
|
||||
dpadD= 0xF0197,
|
||||
dpadL= 0xF0198,
|
||||
dpadR= 0xF0199,
|
||||
xboxView= 0xF019A,
|
||||
xboxMenu= 0xF019B,
|
||||
xboxShare= 0xF019C,
|
||||
xboxConnect= 0xF019D,
|
||||
ps= 0xF019E,
|
||||
psTriangle= 0xF019F,
|
||||
psCircle= 0xF01A0,
|
||||
psCross= 0xF01A1,
|
||||
psSquare= 0xF01A2,
|
||||
psMute= 0xF01A3,
|
||||
psCreate= 0xF01A4,
|
||||
psOption= 0xF01A5,
|
||||
},
|
||||
mahjong={-- F0200 - F027F
|
||||
m1= 0xF0200,
|
||||
m2= 0xF0201,
|
||||
m3= 0xF0202,
|
||||
m4= 0xF0203,
|
||||
m5= 0xF0204,
|
||||
m6= 0xF0205,
|
||||
m7= 0xF0206,
|
||||
m8= 0xF0207,
|
||||
m9= 0xF0208,
|
||||
s1= 0xF0209,
|
||||
s2= 0xF020A,
|
||||
s3= 0xF020B,
|
||||
s4= 0xF020C,
|
||||
s5= 0xF020D,
|
||||
s6= 0xF020E,
|
||||
s7= 0xF020F,
|
||||
s8= 0xF0210,
|
||||
s9= 0xF0211,
|
||||
p1= 0xF0212,
|
||||
p2= 0xF0213,
|
||||
p3= 0xF0214,
|
||||
p4= 0xF0215,
|
||||
p5= 0xF0216,
|
||||
p6= 0xF0217,
|
||||
p7= 0xF0218,
|
||||
p8= 0xF0219,
|
||||
p9= 0xF021A,
|
||||
ton= 0xF021B,
|
||||
nan= 0xF021C,
|
||||
sha= 0xF021D,
|
||||
pe= 0xF021E,
|
||||
chun= 0xF021F,
|
||||
hatsu= 0xF0220,
|
||||
haku= 0xF0221,
|
||||
hatsuAlt= 0xF0222,
|
||||
hakuAlt= 0xF0223,
|
||||
haru= 0xF0224,
|
||||
natsu= 0xF0225,
|
||||
aki= 0xF0226,
|
||||
fuyu= 0xF0227,
|
||||
ume= 0xF0228,
|
||||
ran= 0xF0229,
|
||||
kiku= 0xF022A,
|
||||
take= 0xF022B,
|
||||
m5Red= 0xF022C,
|
||||
s5Red= 0xF022D,
|
||||
p5Red= 0xF022E,
|
||||
m1Base= 0xF022F,
|
||||
m2Base= 0xF0230,
|
||||
m3Base= 0xF0231,
|
||||
m4Base= 0xF0232,
|
||||
m5Base= 0xF0233,
|
||||
m6Base= 0xF0234,
|
||||
m7Base= 0xF0235,
|
||||
m8Base= 0xF0236,
|
||||
m9Base= 0xF0237,
|
||||
mComb= 0xF0238,
|
||||
s1Base= 0xF0239,
|
||||
s1Comb= 0xF023A,
|
||||
s5Base= 0xF023B,
|
||||
s5Comb= 0xF023C,
|
||||
s7Base= 0xF023D,
|
||||
s7Comb= 0xF023E,
|
||||
s9Base= 0xF023F,
|
||||
s9Comb= 0xF0240,
|
||||
p2Base= 0xF0241,
|
||||
p2Comb= 0xF0242,
|
||||
p3Base= 0xF0243,
|
||||
p3Comb1= 0xF0244,
|
||||
p3Comb2= 0xF0245,
|
||||
p4Base= 0xF0246,
|
||||
p4Comb= 0xF0247,
|
||||
p5Base= 0xF0248,
|
||||
p5Comb1= 0xF0249,
|
||||
p5Comb2= 0xF024A,
|
||||
p6Base= 0xF024B,
|
||||
p6Comb= 0xF024C,
|
||||
p7Base= 0xF024D,
|
||||
p7Comb= 0xF024E,
|
||||
p9Base= 0xF024F,
|
||||
p9Comb1= 0xF0250,
|
||||
p9Comb2= 0xF0251,
|
||||
frameComb= 0xF0252,
|
||||
s1j= 0xF0253,
|
||||
s1jBase= 0xF0254,
|
||||
s1jComb= 0xF0255,
|
||||
},
|
||||
cards={-- F0300 - F070F
|
||||
cardBack= 0xF0300,
|
||||
clubA= 0xF0301,
|
||||
club2= 0xF0302,
|
||||
club3= 0xF0303,
|
||||
club4= 0xF0304,
|
||||
club5= 0xF0305,
|
||||
club6= 0xF0306,
|
||||
club7= 0xF0307,
|
||||
club8= 0xF0308,
|
||||
club9= 0xF0309,
|
||||
club10= 0xF030A,
|
||||
clubJ= 0xF030B,
|
||||
clubC= 0xF030C,
|
||||
clubQ= 0xF030D,
|
||||
clubK= 0xF030E,
|
||||
heartA= 0xF0401,
|
||||
heart2= 0xF0402,
|
||||
heart3= 0xF0403,
|
||||
heart4= 0xF0404,
|
||||
heart5= 0xF0405,
|
||||
heart6= 0xF0406,
|
||||
heart7= 0xF0407,
|
||||
heart8= 0xF0408,
|
||||
heart9= 0xF0409,
|
||||
heart10= 0xF040A,
|
||||
heartJ= 0xF040B,
|
||||
heartC= 0xF040C,
|
||||
heartQ= 0xF040D,
|
||||
heartK= 0xF040E,
|
||||
diamondA= 0xF0501,
|
||||
diamond2= 0xF0502,
|
||||
diamond3= 0xF0503,
|
||||
diamond4= 0xF0504,
|
||||
diamond5= 0xF0505,
|
||||
diamond6= 0xF0506,
|
||||
diamond7= 0xF0507,
|
||||
diamond8= 0xF0508,
|
||||
diamond9= 0xF0509,
|
||||
diamond10= 0xF050A,
|
||||
diamondJ= 0xF050B,
|
||||
diamondC= 0xF050C,
|
||||
diamondQ= 0xF050D,
|
||||
diamondK= 0xF050E,
|
||||
jokerBlack= 0xF050F,
|
||||
clubA= 0xF0601,
|
||||
club2= 0xF0602,
|
||||
club3= 0xF0603,
|
||||
club4= 0xF0604,
|
||||
club5= 0xF0605,
|
||||
club6= 0xF0606,
|
||||
club7= 0xF0607,
|
||||
club8= 0xF0608,
|
||||
club9= 0xF0609,
|
||||
club10= 0xF060A,
|
||||
clubJ= 0xF060B,
|
||||
clubC= 0xF060C,
|
||||
clubQ= 0xF060D,
|
||||
clubK= 0xF060E,
|
||||
jokerWhite= 0xF060F,
|
||||
}
|
||||
}
|
||||
|
||||
for _,pack in next,L do
|
||||
for name,unicode in next,pack do
|
||||
pack[name]=utf8_convert(unicode)
|
||||
end
|
||||
end
|
||||
|
||||
return L
|
||||
2
conf.lua
2
conf.lua
@@ -1,5 +1,5 @@
|
||||
function love.conf(t)
|
||||
t.identity = "tromi_ver3"
|
||||
t.identity = "tromi_mobile"
|
||||
t.externalstorage=true
|
||||
|
||||
t.console = true
|
||||
|
||||
@@ -143,6 +143,15 @@ function drawText(text, x, y, size, orientation, color)
|
||||
love.graphics.printf(text, x, y, size*2, orientation, nil, 0.5)
|
||||
end
|
||||
|
||||
function drawBoldText(text, x, y, size, orientation, color)
|
||||
if color == nil then color = {1, 1, 1, 1} end
|
||||
love.graphics.setFont(FONT_bold)
|
||||
love.graphics.setColor(0, 0, 0, 0.8)
|
||||
love.graphics.printf(text, x+1, y+1, size*2, orientation, nil, 0.50)
|
||||
love.graphics.setColor(color)
|
||||
love.graphics.printf(text, x, y, size*2, orientation, nil, 0.5)
|
||||
end
|
||||
|
||||
function drawBigText(text, x, y, size, orientation, color)
|
||||
if color == nil then color = {1, 1, 1, 1} end
|
||||
love.graphics.setFont(FONT_big)
|
||||
|
||||
@@ -13,9 +13,9 @@ local GameMode = Object:extend()
|
||||
function GameMode:new(player_name, input_file, replay_grade)
|
||||
VCTRL.toggle(MOBILE and not input_file and not SETTINGS.tvMode)
|
||||
|
||||
if player_name == nil then self.training = true else self.training = false end
|
||||
if player_name == nil then self.training = true else self.training = false end
|
||||
if input_file ~= nil then
|
||||
input_file = love.filesystem.newFile(REPLAY_DIR..input_file, 'r'):read()
|
||||
input_file = love.filesystem.read(REPLAY_DIR..input_file)
|
||||
input_file = lualzw.decompress(input_file)
|
||||
local seed = self:getInputPieceSeq(input_file)
|
||||
self.replay_inputs = self:getReplayInputs(input_file)
|
||||
@@ -23,10 +23,10 @@ function GameMode:new(player_name, input_file, replay_grade)
|
||||
self.input_playback = true
|
||||
self.grade = replay_grade
|
||||
self.frames = 1
|
||||
elseif self.training then
|
||||
player_name = 'TRN'
|
||||
replay_grade = 'N/A'
|
||||
self.randomizer = Randomizer(false, nil)
|
||||
elseif self.training then
|
||||
player_name = 'TRN'
|
||||
replay_grade = 'N/A'
|
||||
self.randomizer = Randomizer(false, nil)
|
||||
self.input_playback = false
|
||||
self.frames = 0
|
||||
else
|
||||
@@ -64,22 +64,22 @@ function GameMode:new(player_name, input_file, replay_grade)
|
||||
"9k", "8k", "7k", "6k", "5k", "4k", "3k", "2k", "1k",
|
||||
"1D", "2D", "3D", "4D", "5D", "6D", "7D", "8D", "9D"
|
||||
}
|
||||
self.promo_table = {
|
||||
self.promo_table = {
|
||||
26666, 53333, 79999, 106666, 133333, 159999, 186666, 213333, 239999, 266666,
|
||||
293333, 319999, 346666, 373333, 399999, 426666, 453333, 479999, 506666,
|
||||
533333, 559999, 586666, 613333, 639999, 666666, 693333, 719999, 719999
|
||||
}
|
||||
self.autopromo_table = {
|
||||
self.autopromo_table = {
|
||||
79999, 106666, 133333, 159999, 186666, 213333, 239999, 266666, 293333, 319999,
|
||||
346666, 373333, 399999, 426666, 453333, 479999, 506666, 533333, 559999,
|
||||
586666, 613333, 639999, 666666, 693333, 719999, 746666, 773333, 1000000
|
||||
}
|
||||
self.demo_table = {
|
||||
}
|
||||
self.demo_table = {
|
||||
-1, 13332, 25000, 40000, 50000, 60000, 60000, 120000, 120000, 120000,
|
||||
180000, 180000, 240000, 240000, 300000, 300000, 360000, 360000, 360000,
|
||||
420000, 420000, 480000, 480000, 480000, 480000, 540000, 540000, 540000
|
||||
}
|
||||
self.speed_divisor = 10000
|
||||
self.speed_divisor = 10000
|
||||
self.line_clear_flash = 0
|
||||
self.lines_cleared = 0
|
||||
SOUNDS['bgm_firsthalf']:setVolume(0.3)
|
||||
@@ -89,7 +89,7 @@ function GameMode:new(player_name, input_file, replay_grade)
|
||||
self.input_saved = false
|
||||
self.end_grid_clear = false
|
||||
self.last_active = 0
|
||||
self.move_count = 0
|
||||
self.move_count = 0
|
||||
self.target = 0
|
||||
self.last_percent = 0
|
||||
self.total_speed_loss = 0
|
||||
@@ -162,15 +162,15 @@ end
|
||||
|
||||
function GameMode:updateGradeHistory()
|
||||
if self.grade_score >= self.promo_table[self.grade] then
|
||||
if (self.grade == 28 and self.grade_history[2] < 4) or self.grade < 28 then self.grade_history[2] = self.grade_history[2] + 1 end
|
||||
self.point_flash = 60
|
||||
self.point_flash_color = {0,1,0,1}
|
||||
elseif self.grade_score <= self.demo_table[self.grade] then
|
||||
if (self.grade == 1 and self.grade_history[2] > 0) or self.grade > 1 then self.grade_history[2] = self.grade_history[2] - 1 end
|
||||
self.point_flash = 60
|
||||
self.point_flash_color = {1,0,0,1}
|
||||
end
|
||||
local auto_flag = false
|
||||
if (self.grade == 28 and self.grade_history[2] < 4) or self.grade < 28 then self.grade_history[2] = self.grade_history[2] + 1 end
|
||||
self.point_flash = 60
|
||||
self.point_flash_color = {0,1,0,1}
|
||||
elseif self.grade_score <= self.demo_table[self.grade] then
|
||||
if (self.grade == 1 and self.grade_history[2] > 0) or self.grade > 1 then self.grade_history[2] = self.grade_history[2] - 1 end
|
||||
self.point_flash = 60
|
||||
self.point_flash_color = {1,0,0,1}
|
||||
end
|
||||
local auto_flag = false
|
||||
while self.grade_score >= self.autopromo_table[self.grade] and self.grade < 28 do
|
||||
self.grade = self.grade + 1
|
||||
self.point_flash = 1
|
||||
@@ -178,7 +178,7 @@ function GameMode:updateGradeHistory()
|
||||
self.grade_change_color = {0,0,1,1}
|
||||
self.end_game_sound = "autopromote"
|
||||
auto_flag = true
|
||||
end
|
||||
end
|
||||
if self.grade_history[2] >= 5 and self.grade < 28 and auto_flag == false then
|
||||
self.grade = self.grade + 1
|
||||
self.point_flash = 1
|
||||
@@ -194,7 +194,7 @@ function GameMode:updateGradeHistory()
|
||||
end
|
||||
if self.starting_grade ~= self.grade then
|
||||
self.grade_history[1] = self.grade
|
||||
self.grade_history[2] = 2
|
||||
self.grade_history[2] = 2
|
||||
end
|
||||
self.grade_history[4] = self.grade_history[4] + 1
|
||||
end
|
||||
@@ -227,31 +227,31 @@ end
|
||||
function GameMode:getARR() return 1 end
|
||||
function GameMode:getDropSpeed() return 1 end
|
||||
function GameMode:getARE()
|
||||
if self.training then return 20 end
|
||||
if self.speed_level <= #self.delay_table then return self.delay_table[self.speed_level][2]
|
||||
if self.training then return 20 end
|
||||
if self.speed_level <= #self.delay_table then return self.delay_table[self.speed_level][2]
|
||||
else return self.delay_table[#self.delay_table][2] end
|
||||
end
|
||||
|
||||
function GameMode:getLineARE() return self:getARE() end
|
||||
|
||||
function GameMode:getLockDelay()
|
||||
if self.training then return 99999999999 end
|
||||
if self.speed_level <= #self.delay_table then return self.delay_table[self.speed_level][3]
|
||||
if self.training then return 99999999999 end
|
||||
if self.speed_level <= #self.delay_table then return self.delay_table[self.speed_level][3]
|
||||
else return self.delay_table[#self.delay_table][3] end
|
||||
end
|
||||
|
||||
function GameMode:getLineClearDelay() return self:getARE() end
|
||||
|
||||
function GameMode:getDasLimit()
|
||||
if self.training then return 8 end
|
||||
if self.speed_level <= #self.delay_table then return self.delay_table[self.speed_level][4]
|
||||
if self.training then return 8 end
|
||||
if self.speed_level <= #self.delay_table then return self.delay_table[self.speed_level][4]
|
||||
else return self.delay_table[#self.delay_table][4] end
|
||||
end
|
||||
function GameMode:getDasCutDelay() return 0 end
|
||||
|
||||
function GameMode:getGravity()
|
||||
if self.training then return 20 end
|
||||
if self.speed_level <= #self.delay_table then return self.delay_table[self.speed_level][1]
|
||||
if self.training then return 20 end
|
||||
if self.speed_level <= #self.delay_table then return self.delay_table[self.speed_level][1]
|
||||
else return self.delay_table[#self.delay_table][1] end
|
||||
end
|
||||
|
||||
@@ -346,8 +346,8 @@ function GameMode:update(inputs, ruleset)
|
||||
if self.grade_change_flash > 0 and self.game_over_frames >= 2 then self.grade_change_flash = self.grade_change_flash - 1 end
|
||||
if self.point_flash > 0 and self.game_over_frames >= 2 then self.point_flash = self.point_flash - 1 end
|
||||
if self.game_over_frames == 2 then
|
||||
PlaySEOnce(self.end_game_sound)
|
||||
end
|
||||
PlaySEOnce(self.end_game_sound)
|
||||
end
|
||||
if self.game_over or self.completed then
|
||||
self.game_over_frames = self.game_over_frames + 1
|
||||
if self.game_over_frames == 1 then self:storeInput(inputs) end
|
||||
@@ -369,24 +369,24 @@ function GameMode:update(inputs, ruleset)
|
||||
self.up_lock = true
|
||||
end
|
||||
if not inputs["up"] then self.up_lock = false end
|
||||
local dir_list = {"down", "left", "right"}
|
||||
for i = 1, #dir_list do
|
||||
if inputs[dir_list[i]] and not table.contains(self.directions_pressed, dir_list[i]) then
|
||||
table.insert(self.directions_pressed, dir_list[i])
|
||||
elseif not inputs[dir_list[i]] then
|
||||
for j=1, #self.directions_pressed do
|
||||
if self.directions_pressed[j] == dir_list[i] then table.remove(self.directions_pressed, j) end
|
||||
end
|
||||
end
|
||||
end
|
||||
if #self.directions_pressed > 0 then
|
||||
for i=1, #self.directions_pressed-1 do
|
||||
inputs[self.directions_pressed[i]] = false
|
||||
end
|
||||
inputs[self.directions_pressed[#self.directions_pressed]] = true
|
||||
if inputs['left'] then self.lastdir = -1
|
||||
elseif inputs['right'] then self.lastdir = 1 end
|
||||
end
|
||||
local dir_list = {"down", "left", "right"}
|
||||
for i = 1, #dir_list do
|
||||
if inputs[dir_list[i]] and not table.contains(self.directions_pressed, dir_list[i]) then
|
||||
table.insert(self.directions_pressed, dir_list[i])
|
||||
elseif not inputs[dir_list[i]] then
|
||||
for j=1, #self.directions_pressed do
|
||||
if self.directions_pressed[j] == dir_list[i] then table.remove(self.directions_pressed, j) end
|
||||
end
|
||||
end
|
||||
end
|
||||
if #self.directions_pressed > 0 then
|
||||
for i=1, #self.directions_pressed-1 do
|
||||
inputs[self.directions_pressed[i]] = false
|
||||
end
|
||||
inputs[self.directions_pressed[#self.directions_pressed]] = true
|
||||
if inputs['left'] then self.lastdir = -1
|
||||
elseif inputs['right'] then self.lastdir = 1 end
|
||||
end
|
||||
|
||||
-- advance one frame
|
||||
|
||||
@@ -521,7 +521,7 @@ function GameMode:stackQualityCheck()
|
||||
local stack_clean = self:detectHoles(x, y)
|
||||
if not stack_clean then
|
||||
hole_num = hole_num + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -541,26 +541,26 @@ function GameMode:doStackQuality()
|
||||
if total_speed <= 0 then total_speed = 0.001 end
|
||||
self.total_speed_loss = total_speed / #self.speed_table
|
||||
if #self.speed_table == 0 then self.total_speed_loss = 0 end
|
||||
self.last_holes = contiguous_holes
|
||||
self.last_holes = contiguous_holes
|
||||
end
|
||||
|
||||
function GameMode:doSpeedCheck()
|
||||
self.target = self.move_count
|
||||
local speed = (self.target/self.active_frames)
|
||||
if speed > 1 then speed = 1 end
|
||||
table.insert(self.speed_table, 1, speed)
|
||||
self.target = self.move_count
|
||||
local speed = (self.target/self.active_frames)
|
||||
if speed > 1 then speed = 1 end
|
||||
table.insert(self.speed_table, 1, speed)
|
||||
while #self.speed_table > 50 do
|
||||
table.remove(self.speed_table, #self.speed_table)
|
||||
end
|
||||
local total_speed = 0
|
||||
for i=1, #self.speed_table do
|
||||
total_speed = total_speed + self.speed_table[i]
|
||||
end
|
||||
local total_speed = 0
|
||||
for i=1, #self.speed_table do
|
||||
total_speed = total_speed + self.speed_table[i]
|
||||
end
|
||||
if total_speed <= 0 then total_speed = 0.001 end
|
||||
self.total_speed_loss = total_speed / #self.speed_table
|
||||
self.total_speed_loss = total_speed / #self.speed_table
|
||||
if #self.speed_table == 0 then self.total_speed_loss = 0 end
|
||||
self.last_active = self.active_frames
|
||||
self.last_percent = speed
|
||||
self.last_active = self.active_frames
|
||||
self.last_percent = speed
|
||||
self.active_frames = 0
|
||||
self.move_count = 0
|
||||
end
|
||||
@@ -571,7 +571,7 @@ function GameMode:updateScore(cleared_lines)
|
||||
while cleared_lines+self.total_lines > 300 do
|
||||
cleared_lines = cleared_lines - 1
|
||||
end
|
||||
self.last_speed = math.ceil(self.total_speed_loss * self.bonus_components['speed'] * cleared_lines)
|
||||
self.last_speed = math.ceil(self.total_speed_loss * self.bonus_components['speed'] * cleared_lines)
|
||||
self.line_clear_flash = 240
|
||||
self.lines_cleared = cleared_lines
|
||||
self.score_to_add = self.lineClearPoints[cleared_lines] + self.last_speed
|
||||
@@ -590,25 +590,25 @@ function GameMode:advanceOneFrame()
|
||||
love.audio.stop()
|
||||
self.audio_stopped = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.training and not SOUNDS['bgm_title']:isPlaying() and SETTINGS["music"] then SOUNDS['bgm_title']:play() end
|
||||
if not self.training then
|
||||
if self.nextbgmflag and SOUNDS['bgm_firsthalf']:isPlaying() then
|
||||
if SOUNDS['bgm_firsthalf']:getVolume() > 0.1 then
|
||||
SOUNDS['bgm_firsthalf']:setVolume(SOUNDS['bgm_firsthalf']:getVolume()-0.01)
|
||||
else
|
||||
SOUNDS['bgm_firsthalf']:stop()
|
||||
end
|
||||
end
|
||||
if self.ready_frames < 1 and not SOUNDS['bgm_firsthalf']:isPlaying() and not SOUNDS['bgm_secondhalf']:isPlaying() and SETTINGS["music"] then
|
||||
if not self.nextbgmflag then SOUNDS['bgm_firsthalf']:play()
|
||||
elseif self.total_lines < 296 then SOUNDS['bgm_secondhalf']:play() end
|
||||
end
|
||||
if self.total_lines >= 296 then
|
||||
SOUNDS['bgm_firsthalf']:stop()
|
||||
SOUNDS['bgm_secondhalf']:stop()
|
||||
end
|
||||
end
|
||||
if not self.training then
|
||||
if self.nextbgmflag and SOUNDS['bgm_firsthalf']:isPlaying() then
|
||||
if SOUNDS['bgm_firsthalf']:getVolume() > 0.1 then
|
||||
SOUNDS['bgm_firsthalf']:setVolume(SOUNDS['bgm_firsthalf']:getVolume()-0.01)
|
||||
else
|
||||
SOUNDS['bgm_firsthalf']:stop()
|
||||
end
|
||||
end
|
||||
if self.ready_frames < 1 and not SOUNDS['bgm_firsthalf']:isPlaying() and not SOUNDS['bgm_secondhalf']:isPlaying() and SETTINGS["music"] then
|
||||
if not self.nextbgmflag then SOUNDS['bgm_firsthalf']:play()
|
||||
elseif self.total_lines < 296 then SOUNDS['bgm_secondhalf']:play() end
|
||||
end
|
||||
if self.total_lines >= 296 then
|
||||
SOUNDS['bgm_firsthalf']:stop()
|
||||
SOUNDS['bgm_secondhalf']:stop()
|
||||
end
|
||||
end
|
||||
if self.clear then
|
||||
self.completed = true
|
||||
end
|
||||
@@ -637,29 +637,29 @@ end
|
||||
function GameMode:onAttemptPieceMove(piece, grid) end
|
||||
function GameMode:onAttemptPieceRotate(piece, grid) end
|
||||
function GameMode:onPieceMove(piece, grid, dx)
|
||||
if not self.moved then
|
||||
self.move_count = self.move_count + 1
|
||||
self.moved = true
|
||||
end
|
||||
if not self.moved then
|
||||
self.move_count = self.move_count + 1
|
||||
self.moved = true
|
||||
end
|
||||
end
|
||||
function GameMode:onPieceRotate(piece, grid, drot)
|
||||
if not self.moved then
|
||||
self.move_count = self.move_count + 1
|
||||
self.moved = true
|
||||
end
|
||||
if not self.moved then
|
||||
self.move_count = self.move_count + 1
|
||||
self.moved = true
|
||||
end
|
||||
end
|
||||
function GameMode:onPieceDrop(piece, grid, dy)
|
||||
if not self.moved then
|
||||
self.move_count = self.move_count + 1
|
||||
self.moved = true
|
||||
end
|
||||
if not self.moved then
|
||||
self.move_count = self.move_count + 1
|
||||
self.moved = true
|
||||
end
|
||||
end
|
||||
function GameMode:onPieceLock(piece, cleared_row_count)
|
||||
if not self.moved then
|
||||
self.move_count = self.move_count + 1
|
||||
self.moved = true
|
||||
end
|
||||
self.lastdir = 0
|
||||
if not self.moved then
|
||||
self.move_count = self.move_count + 1
|
||||
self.moved = true
|
||||
end
|
||||
self.lastdir = 0
|
||||
PlaySE("lock")
|
||||
end
|
||||
|
||||
@@ -677,9 +677,10 @@ function GameMode:onPieceEnter()
|
||||
end
|
||||
|
||||
function GameMode:onGameOver()
|
||||
if not self.training then VCTRL.toggle(false) end
|
||||
if not self.input_playback and not self.training and not PENTO_MODE then
|
||||
if not self.did_grades then
|
||||
self.grade_score = self.grade_score + self.speed_level
|
||||
self.grade_score = self.grade_score + self.speed_level
|
||||
if #self.speed_table >= 49 then
|
||||
self:updateGradeHistory()
|
||||
end
|
||||
@@ -689,16 +690,16 @@ function GameMode:onGameOver()
|
||||
end
|
||||
self:drawEndScoringInfo()
|
||||
elseif not self.did_grades then
|
||||
self.grade_score = self.grade_score + self.speed_level
|
||||
self.did_grades = true
|
||||
end
|
||||
self.grade_score = self.grade_score + self.speed_level
|
||||
self.did_grades = true
|
||||
end
|
||||
if PENTO_MODE and not self.training then self:drawEndScoringInfo() end
|
||||
end
|
||||
|
||||
function GameMode:drawEndScoringInfo()
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
drawText("Score: ", 247, 135, 1000, "left")
|
||||
drawBigText(string.format("%s", self.grade_score), 247, 150, 100, "center")
|
||||
drawText("Score: ", 247, 135, 1000, "left")
|
||||
drawBigText(string.format("%s", self.grade_score), 247, 150, 100, "center")
|
||||
if not PENTO_MODE then
|
||||
drawText("Best scores:", 247, 220, 1000, "left")
|
||||
|
||||
@@ -868,10 +869,10 @@ function GameMode:drawLineClearAnimation()
|
||||
fade_timer = self.lcd/20
|
||||
love.graphics.setColor(1,1,1,fade_timer)
|
||||
love.graphics.draw(BLOCKS[block.skin][block.colour..'_d'], real_x, real_y+fall_timer)
|
||||
if self.lcd > self:getLineClearDelay() - 5 then
|
||||
love.graphics.setColor(1,1,1,fade_timer*0.3)
|
||||
love.graphics.draw(BLOCKS[block.skin]['W'], real_x, real_y+fall_timer)
|
||||
end
|
||||
if self.lcd > self:getLineClearDelay() - 5 then
|
||||
love.graphics.setColor(1,1,1,fade_timer*0.3)
|
||||
love.graphics.draw(BLOCKS[block.skin]['W'], real_x, real_y+fall_timer)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -920,61 +921,61 @@ function GameMode:drawGrid()
|
||||
end
|
||||
|
||||
function GameMode:drawInputDisplay(left, top)
|
||||
if self.replay_inputs[self.frames] ~= nil then
|
||||
drawText("+", left+10, top+8, 1000, "left")
|
||||
drawText("▼", left+10, top+18, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['down']),1,1-boolToInt(self.replay_inputs[self.frames]['down']),1})
|
||||
drawText("◀", left, top+8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['left']),1,1-boolToInt(self.replay_inputs[self.frames]['left']),1})
|
||||
drawText("▶", left+20, top+8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['right']),1,1-boolToInt(self.replay_inputs[self.frames]['right']),1})
|
||||
drawText("L", left+35, top+8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['rotate_left']),1,1-boolToInt(self.replay_inputs[self.frames]['rotate_left']),1})
|
||||
drawText("R", left+50, top+8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['rotate_right']),1,1-boolToInt(self.replay_inputs[self.frames]['rotate_right']),1})
|
||||
drawText("L", left+65, top+8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['rotate_left2']),1,1-boolToInt(self.replay_inputs[self.frames]['rotate_left2']),1})
|
||||
drawText("R", left+80, top+8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['rotate_right2']),1,1-boolToInt(self.replay_inputs[self.frames]['rotate_right2']),1})
|
||||
else
|
||||
drawText("+", left+10, top+8, 1000, "left")
|
||||
drawText("▼", left+10, top+18, 1000, "left")
|
||||
drawText("◀", left, top+8, 1000, "left")
|
||||
drawText("▶", left+20, top+8, 1000, "left")
|
||||
drawText("L", left+35, top+8, 1000, "left")
|
||||
drawText("R", left+50, top+8, 1000, "left")
|
||||
drawText("L", left+65, top+8, 1000, "left")
|
||||
drawText("R", left+80, top+8, 1000, "left")
|
||||
end
|
||||
if self.replay_inputs[self.frames] ~= nil then
|
||||
drawText("•", left+7.5, top+ 8, 1000, "left")
|
||||
drawText(CHAR.key.down , left+ 5, top+18, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['down']),1,1-boolToInt(self.replay_inputs[self.frames]['down']),1})
|
||||
drawText(CHAR.key.left , left- 5, top+ 8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['left']),1,1-boolToInt(self.replay_inputs[self.frames]['left']),1})
|
||||
drawText(CHAR.key.right, left+ 15, top+ 8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['right']),1,1-boolToInt(self.replay_inputs[self.frames]['right']),1})
|
||||
drawText("L", left+ 35, top+ 8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['rotate_left']),1,1-boolToInt(self.replay_inputs[self.frames]['rotate_left']),1})
|
||||
drawText("R", left+ 50, top+ 8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['rotate_right']),1,1-boolToInt(self.replay_inputs[self.frames]['rotate_right']),1})
|
||||
drawText("L", left+ 65, top+ 8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['rotate_left2']),1,1-boolToInt(self.replay_inputs[self.frames]['rotate_left2']),1})
|
||||
drawText("R", left+ 80, top+ 8, 1000, "left",{1-boolToInt(self.replay_inputs[self.frames]['rotate_right2']),1,1-boolToInt(self.replay_inputs[self.frames]['rotate_right2']),1})
|
||||
else
|
||||
drawText("•" , left+7.5, top+ 8, 1000, "left")
|
||||
drawText(CHAR.key.down , left+ 5, top+18, 1000)
|
||||
drawText(CHAR.key.left , left- 5, top+ 8, 1000)
|
||||
drawText(CHAR.key.right, left+ 15, top+ 8, 1000)
|
||||
drawText("L" , left+ 35, top+ 8, 1000, "left")
|
||||
drawText("R" , left+ 50, top+ 8, 1000, "left")
|
||||
drawText("L" , left+ 65, top+ 8, 1000, "left")
|
||||
drawText("R" , left+ 80, top+ 8, 1000, "left")
|
||||
end
|
||||
end
|
||||
|
||||
function GameMode:drawSpeedStats(left, top)
|
||||
love.graphics.setColor(0,0,0,0.5)
|
||||
love.graphics.rectangle("fill", left+3, top+3, 190, 145, 10, 10)
|
||||
love.graphics.setColor(0.05,0.05,0.05,1)
|
||||
love.graphics.rectangle("fill", left, top, 190, 145, 10, 10)
|
||||
drawText("Efficiency Bonus: ", left+15, top+10, 1000, "left")
|
||||
love.graphics.setColor(0,0,0,0.5)
|
||||
love.graphics.rectangle("fill", left+3, top+3, 190, 145, 10, 10)
|
||||
love.graphics.setColor(0.05,0.05,0.05,1)
|
||||
love.graphics.rectangle("fill", left, top, 190, 145, 10, 10)
|
||||
drawText("Efficiency Bonus: ", left+15, top+5, 1000, "left")
|
||||
local lines = self.total_lines
|
||||
if lines == 0 then lines = 1 end
|
||||
if self.move_count == 0 then
|
||||
drawText(string.format(" %4d Num. of Moves", self.target), left+15, top+25, 1000, "left")
|
||||
else
|
||||
drawText(string.format(" %4d Num. of Moves", self.move_count), left+15, top+25, 1000, "left")
|
||||
end
|
||||
drawText(string.format("/ %4d Active Frames", self.last_active), left+15, top+40, 1000, "left")
|
||||
drawText(string.format("= %1.2f\n (0 added for hole)\n %1.2f %dpc Average\nx %s x Lines\n+ %4d", self.last_percent, self.total_speed_loss, #self.speed_table, self.bonus_components['speed'], self.last_speed), left+15, top+55, 1000, "left")
|
||||
if lines == 0 then lines = 1 end
|
||||
if self.move_count == 0 then
|
||||
drawText(string.format(" %4d Num. of Moves", self.target), left+15, top+20, 1000, "left")
|
||||
else
|
||||
drawText(string.format(" %4d Num. of Moves", self.move_count), left+15, top+20, 1000, "left")
|
||||
end
|
||||
drawText(string.format("/ %4d Active Frames", self.last_active), left+15, top+35, 1000, "left")
|
||||
drawText(string.format("= %1.2f\n (0 added for hole)\n %1.2f %dpc Average\nx %s x Lines\n+ %4d", self.last_percent, self.total_speed_loss, #self.speed_table, self.bonus_components['speed'], self.last_speed), left+15, top+50, 1000, "left")
|
||||
end
|
||||
|
||||
function GameMode:drawLinesStats(left, top)
|
||||
love.graphics.setColor(0,0,0,0.5)
|
||||
love.graphics.rectangle("fill", left+3, top+3, 190, 90, 10, 10)
|
||||
love.graphics.setColor(0.05,0.05,0.05,1)
|
||||
love.graphics.rectangle("fill", left, top, 190, 90, 10, 10)
|
||||
love.graphics.setColor(0,0,0,0.5)
|
||||
love.graphics.rectangle("fill", left+3, top+3, 190, 90, 10, 10)
|
||||
love.graphics.setColor(0.05,0.05,0.05,1)
|
||||
love.graphics.rectangle("fill", left, top, 190, 90, 10, 10)
|
||||
local lines = self.total_lines
|
||||
if lines == 0 then lines = 1 end
|
||||
if lines == 0 then lines = 1 end
|
||||
drawText("Lines Bonus: ", left+15, top+10, 1000, "left")
|
||||
-- drawText(string.format("+ %4d %3d%%", self.lineClearPoints[self.lines_cleared], (self.score_totals['lines']/(self.lineClearPoints[4]*math.ceil(lines/4)))*100), left+15, top+25, 1000, "left")
|
||||
drawText(string.format("2 x Lines = %d\n3 x Lines = %d\n4 x Lines = %d", self.lineClearPoints[2], self.lineClearPoints[3], self.lineClearPoints[4]), left+15, top+25, 1000, "left")
|
||||
-- drawText(string.format("+ %4d %3d%%", self.lineClearPoints[self.lines_cleared], (self.score_totals['lines']/(self.lineClearPoints[4]*math.ceil(lines/4)))*100), left+15, top+25, 1000, "left")
|
||||
drawText(string.format("2 x Lines = %d\n3 x Lines = %d\n4 x Lines = %d", self.lineClearPoints[2], self.lineClearPoints[3], self.lineClearPoints[4]), left+15, top+25, 1000, "left")
|
||||
end
|
||||
|
||||
function GameMode:drawScoringInfo()
|
||||
-- Name & Grade
|
||||
love.graphics.setColor(0,0,0,0.5)
|
||||
love.graphics.rectangle("fill", 98, 83, 110, 180, 10, 10)
|
||||
love.graphics.setColor(0.05,0.05,0.05,1)
|
||||
love.graphics.setColor(0.05,0.05,0.05,1)
|
||||
love.graphics.rectangle("fill", 95, 80, 110, 180, 10, 10)
|
||||
if not PENTO_MODE then drawText("Grade:", 100, 128, 1000, "left") end
|
||||
-- Line & Level
|
||||
@@ -987,46 +988,46 @@ function GameMode:drawScoringInfo()
|
||||
end
|
||||
-- REPLAY
|
||||
if self.input_playback then
|
||||
love.graphics.setColor(0,0,0,0.5)
|
||||
love.graphics.rectangle("fill", 68, 270, 140, 190, 10, 10)
|
||||
love.graphics.setColor(0.05,0.05,0.05,1)
|
||||
love.graphics.rectangle("fill", 65, 267, 140, 190, 10, 10)
|
||||
drawText(string.format("Replay in progress\n\n\n\n\n\n\n\n\n%s", formatTime(self.frames)), 70, 275, 1000, "left")
|
||||
love.graphics.setColor(0,0,0,0.5)
|
||||
love.graphics.rectangle("fill", 68, 270, 140, 190, 10, 10)
|
||||
love.graphics.setColor(0.05,0.05,0.05,1)
|
||||
love.graphics.rectangle("fill", 65, 267, 140, 190, 10, 10)
|
||||
drawBoldText(string.format("REPLAY IN PROGRESS\n\n\n\n\n\n\n\n\n%s", formatTime(self.frames)), 70, 275, 1000, "left")
|
||||
drawBigText(string.format("%s", self.grade), 100, 143, 1000, "left")
|
||||
self:drawInputDisplay(103,185)
|
||||
elseif not PENTO_MODE then
|
||||
if math.mod(self.grade_change_flash, 5) ~= 0 then
|
||||
drawBigText(string.format("%s", self.gradeNames[self.grade]), 100, 143, 1000, "left", self.grade_change_color)
|
||||
else
|
||||
drawBigText(string.format("%s", self.gradeNames[self.grade]), 100, 143, 1000, "left")
|
||||
end
|
||||
local points_text = nil
|
||||
elseif not PENTO_MODE then
|
||||
if math.mod(self.grade_change_flash, 5) ~= 0 then
|
||||
drawBigText(string.format("%s", self.gradeNames[self.grade]), 100, 143, 1000, "left", self.grade_change_color)
|
||||
else
|
||||
drawBigText(string.format("%s", self.gradeNames[self.grade]), 100, 143, 1000, "left")
|
||||
end
|
||||
local points_text = nil
|
||||
if self.grade == 1 and self.grade_history[2] == 2 then
|
||||
points_text = " |.."
|
||||
elseif self.grade == 1 and self.grade_history[2] == 3 then
|
||||
points_text = " .|."
|
||||
elseif self.grade == 1 and self.grade_history[2] == 4 then
|
||||
points_text = " ..|"
|
||||
elseif self.grade_history[2] == 0 then
|
||||
points_text = "|...."
|
||||
elseif self.grade_history[2] == 1 then
|
||||
points_text = ".|..."
|
||||
elseif self.grade_history[2] == 2 then
|
||||
points_text = "..|.."
|
||||
elseif self.grade_history[2] == 3 then
|
||||
points_text = "...|."
|
||||
elseif self.grade_history[2] == 4 then
|
||||
points_text = "....|"
|
||||
end
|
||||
if self.grade > 1 then points_text = '-'..points_text
|
||||
else points_text = ' '..points_text end
|
||||
if self.grade < 28 then points_text = points_text..'+' end
|
||||
drawText("Promotion\nMeter:", 100, 174, 1000, "left")
|
||||
if self.point_flash > 0 then
|
||||
drawBigText(points_text, 100, 208, 1000, "left", self.point_flash_color)
|
||||
else
|
||||
drawBigText(points_text, 100, 208, 1000, "left")
|
||||
end
|
||||
elseif self.grade_history[2] == 0 then
|
||||
points_text = "|...."
|
||||
elseif self.grade_history[2] == 1 then
|
||||
points_text = ".|..."
|
||||
elseif self.grade_history[2] == 2 then
|
||||
points_text = "..|.."
|
||||
elseif self.grade_history[2] == 3 then
|
||||
points_text = "...|."
|
||||
elseif self.grade_history[2] == 4 then
|
||||
points_text = "....|"
|
||||
end
|
||||
if self.grade > 1 then points_text = '-'..points_text
|
||||
else points_text = ' '..points_text end
|
||||
if self.grade < 28 then points_text = points_text..'+' end
|
||||
drawText("Promotion\nMeter:", 100, 174, 1000, "left")
|
||||
if self.point_flash > 0 then
|
||||
drawBigText(points_text, 100, 208, 1000, "left", self.point_flash_color)
|
||||
else
|
||||
drawBigText(points_text, 100, 208, 1000, "left")
|
||||
end
|
||||
end
|
||||
if (self.game_over or self.completed) and self.game_over_frames <= 50 and not self.input_playback and not self.training and not PENTO_MODE then
|
||||
drawText("SAVING, PLEASE WAIT", 232, 460, 1000, "left")
|
||||
@@ -1035,8 +1036,8 @@ function GameMode:drawScoringInfo()
|
||||
drawBigText(self.player_name:upper(), 100, 98, 1000, "left")
|
||||
drawText("Ver. 2", 550, 435, 1000, "left")
|
||||
if self.input_playback then
|
||||
self:drawSpeedStats(385, 99)
|
||||
self:drawLinesStats(385, 251)
|
||||
self:drawSpeedStats(385, 99)
|
||||
self:drawLinesStats(385, 251)
|
||||
love.graphics.setColor(0,0,0,0.5)
|
||||
love.graphics.rectangle("fill", 385+3, 348+3, 190, 50, 10, 10)
|
||||
love.graphics.setColor(0.05,0.05,0.05,1)
|
||||
@@ -1065,17 +1066,17 @@ function GameMode:drawBackground()
|
||||
if BACKGROUNDS[bg]:tell() >= limit then
|
||||
BACKGROUNDS[bg]:rewind()
|
||||
end
|
||||
if bg == 0 or bg == 8 or bg == 9 or bg == 3 then brightness = 0.7 end
|
||||
love.graphics.setColor(brightness, brightness, brightness, 1)
|
||||
if bg == 0 or bg == 8 or bg == 9 or bg == 3 then brightness = 0.7 end
|
||||
love.graphics.setColor(brightness, brightness, brightness, 1)
|
||||
love.graphics.draw(BACKGROUNDS[bg])
|
||||
end
|
||||
|
||||
function GameMode:drawFrame()
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.line(216,80,216,80+(16*self.grid.height))
|
||||
love.graphics.line(216+(16*self.grid.width),80,216+(16*self.grid.width),80+(16*self.grid.height))
|
||||
love.graphics.line(216,80+(16*self.grid.height),216+(16*self.grid.width),80+(16*self.grid.height))
|
||||
love.graphics.line(216,80,216+(16*self.grid.width),80)
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.line(216,80,216,80+(16*self.grid.height))
|
||||
love.graphics.line(216+(16*self.grid.width),80,216+(16*self.grid.width),80+(16*self.grid.height))
|
||||
love.graphics.line(216,80+(16*self.grid.height),216+(16*self.grid.width),80+(16*self.grid.height))
|
||||
love.graphics.line(216,80,216+(16*self.grid.width),80)
|
||||
love.graphics.setColor(0, 0, 0, 1)
|
||||
love.graphics.rectangle(
|
||||
"fill", 216, 80,
|
||||
|
||||
@@ -64,7 +64,7 @@ function control_type.button:new(data)
|
||||
r=data.r or 80, -- size
|
||||
shape=data.shape or 'circle',
|
||||
key=data.key or 'X',
|
||||
iconSize=data.iconSize or 80,
|
||||
iconSize=data.iconSize or 60,
|
||||
alpha=data.alpha or 0.75,
|
||||
quad=virtual_quad[data.key]
|
||||
},self)
|
||||
@@ -148,6 +148,7 @@ local touches={}
|
||||
local global_toggle=false
|
||||
VCTRL={}
|
||||
VCTRL.focus=nil -- Focusing buttons
|
||||
VCTRL.hasChanged = false
|
||||
|
||||
---@class VCTRL.data
|
||||
---@field type 'button'
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 6.9 KiB |
@@ -1,7 +1,8 @@
|
||||
-- SIMPLE-BUTTON.lua
|
||||
-- A simple module that aims to help you quickly create buttons
|
||||
-- It is can be used as a base class to help you quickly creating button
|
||||
-- This module has type notations so IntelliSense should give you some suggestions
|
||||
-- SIMPLE-BUTTON.lua<br>
|
||||
-- A simple module that aims to help you quickly create buttons<br>
|
||||
-- It is can be used as a base class to help you quickly creating button<br>
|
||||
-- This module has type notations so IntelliSense should give you some suggestions<br>
|
||||
local BUTTON = {}
|
||||
|
||||
-- MIT License
|
||||
|
||||
@@ -174,9 +175,6 @@ function button:release(x, y, touchID)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local BUTTON = {}
|
||||
|
||||
---@param D BUTTON.button|BUTTON.newData
|
||||
---@param safe? boolean @ Creating widget? If not then ignore accept missing important parameters
|
||||
---@return nil
|
||||
|
||||
27
load.lua
27
load.lua
@@ -1,6 +1,12 @@
|
||||
-- Fonts
|
||||
FONT_tromi = love.graphics.newFont('res/fonts/monofonto rg.otf', 28)
|
||||
FONT_big = love.graphics.newFont('res/fonts/monofonto rg.otf', 56)
|
||||
FONT_tromi = love.graphics.newFont('res/fonts/Iosevka-Bold.ttf' , 28)
|
||||
FONT_big = love.graphics.newFont('res/fonts/Iosevka-Heavy.ttf', 56)
|
||||
FONT_bold = love.graphics.newFont('res/fonts/Iosevka-Heavy.ttf', 28)
|
||||
-- Icons
|
||||
FONT_tromi:setFallbacks(love.graphics.newFont('res/fonts/techmino_proportional.otf', 28))
|
||||
FONT_bold :setFallbacks(love.graphics.newFont('res/fonts/techmino_proportional.otf', 28))
|
||||
FONT_big :setFallbacks(love.graphics.newFont('res/fonts/techmino_proportional.otf', 56))
|
||||
CHAR = require("char")
|
||||
|
||||
local font_height = FONT_tromi:getHeight() * 0.5
|
||||
local font_big_height = FONT_big:getHeight() * 0.5
|
||||
@@ -15,7 +21,7 @@ BUTTON = require "libs.simple-button"
|
||||
BUTTON.setDefaultOption{
|
||||
draw = function(self)
|
||||
local need_big_font = (self.font == FONT_big)
|
||||
|
||||
|
||||
love.graphics.setColor(self.backgroundColor)
|
||||
love.graphics.rectangle('fill', self.x, self.y, self.w, self.h, self.r)
|
||||
|
||||
@@ -31,22 +37,19 @@ BUTTON.setDefaultOption{
|
||||
|
||||
local lineAmount
|
||||
do
|
||||
local _, t
|
||||
if need_big_font then
|
||||
_, t = FONT_big:getWrap(text, (self.w - 5) * 2)
|
||||
else
|
||||
_, t = FONT_tromi:getWrap(text, (self.w - 5) * 2)
|
||||
end
|
||||
local _, t = self.font:getWrap(text, (self.w - 5) * 2)
|
||||
lineAmount = #t
|
||||
end
|
||||
|
||||
|
||||
local _font_height = need_big_font and font_big_height or font_height
|
||||
|
||||
|
||||
local textHeight = _font_height * (lineAmount * 0.5)
|
||||
local textPos = self.y + (self.h * 0.5) - textHeight
|
||||
|
||||
if need_big_font then
|
||||
if self.font == FONT_big then
|
||||
drawBigText(text, self.x + 2.5, textPos, self.w - 5, self.textOrientation, self.textColor)
|
||||
elseif self.font == FONT_bold then
|
||||
drawBoldText(text, self.x + 2.5, textPos, self.w - 5, self.textOrientation, self.textColor)
|
||||
else
|
||||
drawText(text, self.x + 2.5, textPos, self.w - 5, self.textOrientation, self.textColor)
|
||||
end
|
||||
|
||||
2
main.lua
2
main.lua
@@ -52,9 +52,11 @@ function love.load()
|
||||
require "game.vctrl" -- VCTRL
|
||||
|
||||
function SCENE.update()
|
||||
SCENE.update = function() end
|
||||
SCENE = SETTINGS.firstTime and InputConfigScene(true) or TitleScene()
|
||||
end
|
||||
function SCENE.render()
|
||||
SCENE.render = function() end
|
||||
love.graphics.draw(LOADING_IMAGE_FILE,0,0,0,0.5)
|
||||
end
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ function SCENE:onInputPress(e) end
|
||||
function SCENE:onInputRelease(e) end
|
||||
|
||||
GameScene = require "scene.game"
|
||||
TrainingScene = require "scene.training"
|
||||
NameEntryScene = require "scene.name_entry"
|
||||
|
||||
KeyConfigScene = require "scene.key_config"
|
||||
@@ -44,7 +45,7 @@ TouchConfigPreviewScene = require "scene.touch_config_preview"
|
||||
InputConfigScene = require "scene.input_config"
|
||||
|
||||
ReplaySelectScene = require "scene.replay"
|
||||
TrainingScene = require "scene.training"
|
||||
ReplayTestScene = require"scene.replay_test"
|
||||
|
||||
FullscreenScene = require "scene.fullscreen"
|
||||
MusicToggleScene = require "scene.music_toggle"
|
||||
|
||||
BIN
res/fonts/Iosevka-Bold.ttf
Normal file
BIN
res/fonts/Iosevka-Bold.ttf
Normal file
Binary file not shown.
BIN
res/fonts/Iosevka-Heavy.ttf
Normal file
BIN
res/fonts/Iosevka-Heavy.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
res/fonts/techmino_proportional.otf
Normal file
BIN
res/fonts/techmino_proportional.otf
Normal file
Binary file not shown.
@@ -45,6 +45,8 @@ local buttonList = {
|
||||
local menuKey -- MENU key used to go main menu XD
|
||||
|
||||
function GameScene:new(player_name, replay_file, replay_grade)
|
||||
VCTRL[9].show = false
|
||||
|
||||
menuKey = BUTTON.new{
|
||||
text = "MENU",
|
||||
x = 265, y = 0, w = 60, h = 25,
|
||||
@@ -130,7 +132,7 @@ end
|
||||
|
||||
function GameScene:onInputPress(e)
|
||||
if e.type == "mouse" or (e.type == "touch" and not VCTRL.press(e.x, e.y, e.id)) then
|
||||
BUTTON.press(buttonList, e.x, e.y, e.id)
|
||||
if self.game.input_playback then BUTTON.press(buttonList, e.x, e.y, e.id) end
|
||||
menuKey:press(e.x, e.y, e.id)
|
||||
elseif (self.game.game_over or self.game.completed) and (e.input == "menu_decide" or e.input == "menu_back" or e.input == "rotate_right") and self.game.game_over_frames > 50 then
|
||||
SCENE = TitleScene()
|
||||
@@ -171,7 +173,7 @@ end
|
||||
|
||||
function GameScene:onInputRelease(e)
|
||||
if e.type == "mouse" or (e.type == "touch" and not VCTRL.release(e.id)) then
|
||||
BUTTON.release(buttonList, e.x, e.y, e.id)
|
||||
if self.game.input_playback then BUTTON.release(buttonList, e.x, e.y, e.id) end
|
||||
menuKey:release(e.x, e.y, e.id)
|
||||
elseif e.input and string.sub(e.input, 1, 5) ~= "menu_" then
|
||||
self.inputs[e.input] = false
|
||||
|
||||
@@ -47,7 +47,7 @@ local function updateButtonList(self)
|
||||
if not SETTINGS.firstTime then
|
||||
menu_screens[4] = TitleScene
|
||||
buttonList[4] = BUTTON.new{
|
||||
text = "⌂", font = FONT_big,
|
||||
text = CHAR.icon.home, font = FONT_big,
|
||||
x = 75, y = 280, w = 40, h = 40,
|
||||
codeWhenReleased = function()
|
||||
if self.menu_state ~= 4 then
|
||||
@@ -70,7 +70,7 @@ function ConfigScene:new(first_time)
|
||||
updateButtonList(self)
|
||||
|
||||
secret_code_used = false
|
||||
secret_code_input = {} -- When it matches 79338732 then we will automatically set the special keybind
|
||||
secret_code_input = {} -- When it matches 88663366 then we will automatically set the special keybind
|
||||
|
||||
self.menu_state = 1
|
||||
if first_time then
|
||||
@@ -88,10 +88,10 @@ function ConfigScene:render()
|
||||
if SETTINGS.tvMode then
|
||||
drawText("TV mode is ON now! Check keybind below", 80, 40, 1000)
|
||||
drawText("Which controls do you want to configure?", 80, 70, 1000)
|
||||
drawText(
|
||||
"2 - Up 1 - Rotate left 5 - Confirm selection\n"..
|
||||
"8 - Right 3 - Rotate right 0 - Back\n"..
|
||||
"4 - Left 7 - Rotate left 2\n"..
|
||||
drawText(
|
||||
"2 - Up 1 - Rotate left 5 - Confirm selection\n"..
|
||||
"8 - Right 3 - Rotate right 0 - Back\n"..
|
||||
"4 - Left 7 - Rotate left 2\n"..
|
||||
"6 - Down 9 - Rotate right 2", 80, 350, 1000
|
||||
)
|
||||
else
|
||||
@@ -128,7 +128,7 @@ function ConfigScene:onInputMove(e)
|
||||
end
|
||||
|
||||
---@param key string
|
||||
local function checkSecretCodeInput(self, key)
|
||||
local function checkSecretCodeInput(key)
|
||||
if secret_code_used then return end
|
||||
if key:sub(1, 2) == "kp" then
|
||||
table.insert(secret_code_input, key:sub(3,3))
|
||||
@@ -160,7 +160,7 @@ local function checkSecretCodeInput(self, key)
|
||||
SETTINGS.firstTime = false
|
||||
SETTINGS.tvMode = true
|
||||
secret_code_used = true
|
||||
updateButtonList(self)
|
||||
updateButtonList(SCENE)
|
||||
elseif current_code == "........" then
|
||||
SETTINGS.input.keys = {}
|
||||
SETTINGS.tvMode = false
|
||||
@@ -183,7 +183,7 @@ function ConfigScene:onInputPress(e)
|
||||
) then
|
||||
SCENE = TitleScene()
|
||||
end
|
||||
checkSecretCodeInput(self, e.key or "")
|
||||
checkSecretCodeInput(e.key or "")
|
||||
end
|
||||
function ConfigScene:onInputRelease(e)
|
||||
if e.type == "touch" or e.type == "mouse" then
|
||||
|
||||
@@ -4,29 +4,41 @@ ReplaySelectScene.title = "Replay"
|
||||
local replay_list
|
||||
local buttonList = {
|
||||
BUTTON.new{
|
||||
text = "↑\nUP", font = FONT_big,
|
||||
text = CHAR.key.up.."\nUP", font = FONT_big,
|
||||
x = 425, y = 80, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {input = "up"} end,
|
||||
codeWhenReleased = function() SCENE:onInputRelease{input = "up"} end
|
||||
},
|
||||
BUTTON.new{
|
||||
text = "↓\nDOWN", font = FONT_big,
|
||||
text = CHAR.key.down.."\nDOWN", font = FONT_big,
|
||||
x = 425, y = 240, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {input = "down"} end,
|
||||
codeWhenReleased = function() SCENE:onInputRelease{input = "down"} end
|
||||
},
|
||||
BUTTON.new{
|
||||
text = "▶\nPLAY", font = FONT_big,
|
||||
text = CHAR.icon.play.."\nPLAY", font = FONT_big,
|
||||
x = 345, y = 160, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {input = "menu_decide"} end,
|
||||
codeWhenReleased = function() SCENE:onInputRelease{input = "menu_decide"} end
|
||||
},
|
||||
BUTTON.new{
|
||||
text = "⌂\nHOME", font = FONT_big,
|
||||
text = CHAR.icon.home.."\nHOME", font = FONT_big,
|
||||
x = 505, y = 160, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {input = "menu_back"} end,
|
||||
codeWhenReleased = function() SCENE:onInputRelease{input = "menu_back"} end
|
||||
},
|
||||
BUTTON.new{
|
||||
text = CHAR.icon.export.."\nEXP.", font = FONT_big,
|
||||
x = 345, y = 320, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {input = "rotate_left"} end,
|
||||
codeWhenReleased = function() SCENE:onInputRelease{input = "rotate_left"} end
|
||||
},
|
||||
BUTTON.new{
|
||||
text = CHAR.icon.import.."\nIMP.", font = FONT_big,
|
||||
x = 505, y = 320, w = 80, h = 80,
|
||||
codeWhenPressed = function() SCENE:onInputPress {input = "rotate_right"} end,
|
||||
codeWhenReleased = function() SCENE:onInputRelease{input = "rotate_right"} end
|
||||
},
|
||||
}
|
||||
|
||||
function ReplaySelectScene:new()
|
||||
@@ -135,7 +147,7 @@ function ReplaySelectScene:onInputPress(e)
|
||||
|
||||
if e.type == "touch" or e.type == "mouse" then
|
||||
BUTTON.press(buttonList, e.x, e.y, e.id)
|
||||
elseif e.input == "menu_decide" or e.input == "rotate_left" or e.scancode == "return" then
|
||||
elseif e.input == "menu_decide" or e.scancode == "return" then
|
||||
if self.replays[1] == nil then SCENE = TitleScene(); return
|
||||
else
|
||||
local line_components = {}
|
||||
@@ -146,15 +158,30 @@ function ReplaySelectScene:onInputPress(e)
|
||||
local player_grade = string.gsub(line_components[2], " ", "")
|
||||
SCENE = GameScene(player_name, selected_replay, player_grade)
|
||||
end
|
||||
-- elseif e.input == "rotate_right" then -- Will add in future, not now
|
||||
-- love.system.setClipboardText(love.data.encode("string", "base64", love.filesystem.read('saves/replays/'..selected_replay)))
|
||||
elseif e.input == "rotate_left" then -- Export
|
||||
local plain_replay_data = love.data.encode("string", "base64", love.filesystem.read(REPLAY_DIR..selected_replay))
|
||||
love.system.setClipboardText(("BEGINNING_OF_TROMI_REPLAY|%s|%s|END_OF_TROMI_REPLAY"):format(selected_replay, plain_replay_data))
|
||||
elseif e.input == "rotate_right" then -- Import
|
||||
local input_data = love.system.getClipboardText()
|
||||
if input_data:find("BEGINNING_OF_TROMI_REPLAY|", 1, true) == 1 and input_data:find("|END_OF_TROMI_REPLAY", 1, true) == #input_data - 19 then
|
||||
local data_part = input_data:sub(27, #input_data - 20)
|
||||
local separator_pos = data_part:find("|", 1, true)
|
||||
local replay_name = data_part:sub(1, separator_pos - 1)
|
||||
local replay_path = REPLAY_DIR..replay_name
|
||||
local replay_data = love.data.decode("string", "base64", data_part:sub(separator_pos + 1))
|
||||
love.filesystem.write(replay_path, replay_data)
|
||||
|
||||
SCENE = ReplayTestScene(replay_name)
|
||||
else
|
||||
SCENE = ReplayTestScene()
|
||||
end
|
||||
elseif e.input == "up" or e.scancode == "up" then
|
||||
if self.replays[1] == nil then SCENE = TitleScene(); return end
|
||||
self.direction = 'up'
|
||||
elseif e.input == "down" or e.scancode == "down" then
|
||||
if self.replays[1] == nil then SCENE = TitleScene(); return end
|
||||
self.direction = 'down'
|
||||
elseif e.input == "menu_back" or e.input == "rotate_right" or e.scancode == "backspace" or e.scancode == "delete" then
|
||||
elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then
|
||||
SCENE = TitleScene()
|
||||
end
|
||||
end
|
||||
|
||||
51
scene/replay_test.lua
Normal file
51
scene/replay_test.lua
Normal file
@@ -0,0 +1,51 @@
|
||||
local ReplayTestScene = SCENE:extend()
|
||||
|
||||
local GAME
|
||||
local error_message
|
||||
local valid_data
|
||||
|
||||
|
||||
function ReplayTestScene:new(input_file)
|
||||
if not input_file then
|
||||
valid_data = false
|
||||
return
|
||||
else
|
||||
valid_data = true
|
||||
end
|
||||
self.input_file = input_file
|
||||
|
||||
GAME = require("game.gamemode")
|
||||
local okay, err = pcall(function()
|
||||
GAME:new("TRO", input_file, "19k")
|
||||
GAME:initialize(require"game.rotation")
|
||||
end)
|
||||
if not okay then
|
||||
-- TODO
|
||||
error_message = err
|
||||
love.filesystem.remove(REPLAY_DIR..self.input_file)
|
||||
end
|
||||
end
|
||||
|
||||
function ReplayTestScene:render()
|
||||
MainBackground()
|
||||
if valid_data then
|
||||
if error_message then
|
||||
drawText("Replay test failed! Data corrupted!", 80, 40, 1000)
|
||||
drawText("Press any key to go back. Anyway here is the error info:", 80, 70, 1000)
|
||||
drawText(error_message, 80, 100, 560)
|
||||
else
|
||||
drawText("Replay test finished!", 80, 40, 1000)
|
||||
drawText("Your replay was imported. Press any key to go back.", 80, 70, 1000)
|
||||
end
|
||||
else
|
||||
drawText("Replay test failed! Not Tromi's replay data", 80, 40, 1000)
|
||||
drawText("Press any key to go back, and check your device's clipboard again!", 80, 100, 1000)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function ReplayTestScene:onInputPress()
|
||||
SCENE = ReplaySelectScene()
|
||||
end
|
||||
|
||||
return ReplayTestScene
|
||||
@@ -15,6 +15,8 @@ local main_menu_screens = {
|
||||
}
|
||||
|
||||
function TitleScene:new()
|
||||
VCTRL.clearAll() -- Reset the RESTART button state
|
||||
VCTRL.new(SETTINGS.input.virtual)
|
||||
if SOUNDS['bgm_firsthalf']:isPlaying() or SOUNDS['bgm_secondhalf']:isPlaying() or not SETTINGS["music"] then
|
||||
love.audio.stop()
|
||||
end
|
||||
|
||||
@@ -5,13 +5,11 @@ TouchConfigScene.title = "Touchscreen config"
|
||||
local Grid = require 'game.grid'
|
||||
|
||||
local buttonList
|
||||
local sliderList
|
||||
local sliderList = {}
|
||||
---@class VCTRL.data
|
||||
local focusingButton
|
||||
---@type number
|
||||
local snapUnit = 1
|
||||
---@type boolean
|
||||
local hasChanged
|
||||
|
||||
---@type function
|
||||
local function exitSceneFunc(saved)
|
||||
@@ -29,37 +27,55 @@ buttonList = {
|
||||
showToggle = BUTTON.new{
|
||||
text = function()
|
||||
if focusingButton then
|
||||
return focusingButton.show and "[SHOW]\nHide" or "Show\n[HIDE]"
|
||||
return focusingButton.show and ">SHOW<\nhide" or "show\n>HIDE<"
|
||||
else
|
||||
return "Show\nHide"
|
||||
return "show\nhide"
|
||||
end
|
||||
end,
|
||||
x = 275, y = 5, w = 50, h = 75,
|
||||
codeWhenReleased = function ()
|
||||
x = 400, y = 110, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
if focusingButton then
|
||||
focusingButton.show = not focusingButton.show
|
||||
hasChanged = true
|
||||
VCTRL.hasChanged = true
|
||||
end
|
||||
end,
|
||||
update = function(self) self.textColor = focusingButton and {1, 1, 1} or {0.5, 0.5, 0.5} end
|
||||
},
|
||||
previewToggle = BUTTON.new{
|
||||
text = "Preview\nON",
|
||||
x = 570, y = 35, w = 60, h = 40,
|
||||
x = 570, y = 60, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
VCTRL.release()
|
||||
BUTTON.release(buttonList)
|
||||
SCENE = TouchConfigPreviewScene()
|
||||
end
|
||||
},
|
||||
resetAll = BUTTON.new{
|
||||
text = "RESET\nALL",
|
||||
x = 500, y = 110, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
local selection = love.window.showMessageBox(
|
||||
"Save config?", "Are you really sure about RESETTING ALL touchscreen configuration?",
|
||||
{"Yes", "No", escapebutton = 2, enterbutton = 1},
|
||||
"info", true
|
||||
)
|
||||
if selection == 1 then
|
||||
VCTRL.focus = nil; focusingButton = nil
|
||||
VCTRL.hasChanged = false
|
||||
VCTRL.clearAll()
|
||||
VCTRL.new(SETTINGS.__default__.input.virtual)
|
||||
SETTINGS.input.virtual = SETTINGS.__default__.input.virtual
|
||||
end
|
||||
end
|
||||
},
|
||||
menuScreen = BUTTON.new{
|
||||
text = "MENU",
|
||||
x = 570, y = 5, w = 60, h = 25,
|
||||
x = 570, y = 10, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
if hasChanged or SETTINGS.firstTime then
|
||||
if VCTRL.hasChanged or SETTINGS.firstTime then
|
||||
local selection = love.window.showMessageBox(
|
||||
"Save config?", "Do you want to save your changes before exiting?",
|
||||
{"Save", "Discard", "Keep editing", escapebutton = 2, enterbutton = 1},
|
||||
{"Save", "Discard", "Keep editing", escapebutton = 3, enterbutton = 1},
|
||||
"info", true
|
||||
)
|
||||
if selection == 1 then
|
||||
@@ -80,45 +96,59 @@ buttonList = {
|
||||
end
|
||||
}
|
||||
}
|
||||
sliderList = {}
|
||||
sliderList.buttonSize = newSlider(
|
||||
200, 30, 120, 0, 0, 120,
|
||||
function(v)
|
||||
if focusingButton then
|
||||
v = math.roundUnit(v, 5)
|
||||
if focusingButton.r ~= v then
|
||||
focusingButton.r = v
|
||||
VCTRL.hasChanged = true
|
||||
end
|
||||
sliderList.buttonSize.value = v / 120
|
||||
end
|
||||
end,
|
||||
{width = 40}
|
||||
)
|
||||
sliderList.iconSize = newSlider(
|
||||
480, 30, 120, 0, 0, 100,
|
||||
function(v)
|
||||
if focusingButton then
|
||||
v = math.roundUnit(v, 5)
|
||||
if focusingButton.iconSize ~= v then
|
||||
focusingButton.iconSize = v
|
||||
VCTRL.hasChanged = true
|
||||
end
|
||||
sliderList.iconSize.value = v / 100
|
||||
end
|
||||
end,
|
||||
{width = 40}
|
||||
)
|
||||
sliderList.opacity = newSlider(
|
||||
155, 20+5, 120, 100, 0, 100,
|
||||
200, 80, 120, 0, 0, 1,
|
||||
function()
|
||||
local v
|
||||
if focusingButton then
|
||||
v = math.roundUnit(sliderList.opacity.value, 0.01)
|
||||
if focusingButton.alpha~=v then
|
||||
focusingButton.alpha = v
|
||||
hasChanged = true
|
||||
VCTRL.hasChanged = true
|
||||
end
|
||||
sliderList.opacity.value = v
|
||||
end
|
||||
end,
|
||||
{width = 30}
|
||||
)
|
||||
sliderList.size = newSlider(
|
||||
155, 60+2.5, 120, 45, 0, 120,
|
||||
function(v)
|
||||
if focusingButton then
|
||||
local v = math.roundUnit(v, 5)
|
||||
if focusingButton.r ~= v then
|
||||
focusingButton.r = v
|
||||
hasChanged = true
|
||||
end
|
||||
sliderList.size.value = v / 120
|
||||
end
|
||||
end,
|
||||
{width = 30}
|
||||
{width = 40}
|
||||
)
|
||||
local gridSizeTable = {1, 2, 5, 10, 20, 50, 100}
|
||||
sliderList.gridSize = newSlider(
|
||||
405, 50, 100, 1, 1, #gridSizeTable - 1,
|
||||
480, 80, 120, 1, 1, #gridSizeTable - 1,
|
||||
function()
|
||||
local v = math.roundUnit(sliderList.gridSize.value, 1 / 6)
|
||||
local f = #gridSizeTable - 1
|
||||
local v = math.roundUnit(sliderList.gridSize.value, 1 / f)
|
||||
sliderList.gridSize.value = v
|
||||
snapUnit = gridSizeTable[math.roundUnit(v * (#gridSizeTable - 1) + 1)]
|
||||
snapUnit = gridSizeTable[math.roundUnit(v * f + 1)]
|
||||
end,
|
||||
{width = 30}
|
||||
{width = 40}
|
||||
); sliderList.gridSize.forceLight = true
|
||||
|
||||
local function sliderList_draw()
|
||||
@@ -145,12 +175,12 @@ local function sliderList_update()
|
||||
end
|
||||
end
|
||||
|
||||
function TouchConfigScene:new(fromPreviewScene)
|
||||
function TouchConfigScene:new()
|
||||
VCTRL.toggle(true)
|
||||
|
||||
VCTRL.focus = nil
|
||||
focusingButton = nil
|
||||
hasChanged = fromPreviewScene
|
||||
|
||||
Grid:new(10, 20)
|
||||
-- TODO
|
||||
end
|
||||
@@ -159,13 +189,15 @@ function TouchConfigScene:update()
|
||||
if VCTRL.focus~=focusingButton then
|
||||
focusingButton = VCTRL.focus
|
||||
sliderList.opacity.value = focusingButton.alpha
|
||||
sliderList.size.value = focusingButton.r / 120
|
||||
sliderList.buttonSize.value = focusingButton.r / 120
|
||||
sliderList.iconSize.value = focusingButton.iconSize / 100
|
||||
end
|
||||
|
||||
BUTTON.update(buttonList)
|
||||
sliderList_update()
|
||||
end
|
||||
|
||||
local string_format = string.format
|
||||
function TouchConfigScene:render()
|
||||
MainBackground()
|
||||
|
||||
@@ -188,19 +220,16 @@ function TouchConfigScene:render()
|
||||
end
|
||||
|
||||
love.graphics.setColor(0, 0, 0, 0.7)
|
||||
-- Opacity and Size
|
||||
love.graphics.rectangle("fill", 10, 5, 267, 75)
|
||||
-- Snap to grid
|
||||
love.graphics.rectangle("fill", 330, 5, 150, 75)
|
||||
love.graphics.rectangle("fill", 5, 5, 560, 100)
|
||||
|
||||
-- Button Size
|
||||
drawText(string_format("Size (buttons)\n%14.1d", focusingButton and focusingButton.r or 0), 10, 13, 100, "left")
|
||||
-- Icon size
|
||||
drawText(string_format("Size (icons)\n%13.1d%%", focusingButton and focusingButton.iconSize or 0), 290, 13, 100, "left")
|
||||
-- Opacity
|
||||
drawText("Opacity", 20, 15, 100, "left")
|
||||
drawText(string.format("%3.1d%%", focusingButton and focusingButton.alpha * 100 or 0), 225, 15, 40, "left")
|
||||
-- Size
|
||||
drawText("Size", 20, 55, 100, "left")
|
||||
drawText(string.format("%3.1dpx", focusingButton and focusingButton.r or 0), 225, 55, 40, "left")
|
||||
drawText(string_format("Opacity\n%13.1d%%", focusingButton and focusingButton.alpha * 100 or 0), 10, 63, 100, "left")
|
||||
-- Snap to grid
|
||||
drawText(string.format("Snap to grid: %3s", snapUnit), 345, 15, 140, "left")
|
||||
drawText(string_format("Snap to grid\n%14.1d", snapUnit), 290, 63, 100, "left")
|
||||
|
||||
for _, v in ipairs(VCTRL) do
|
||||
if v ~= focusingButton then
|
||||
@@ -227,10 +256,8 @@ end
|
||||
---@param e SCENE_onInput
|
||||
function TouchConfigScene:onInputMove(e)
|
||||
if e.type == "touch" or (e.type == "mouse" and love.mouse.isDown(1)) then
|
||||
if VCTRL.drag(e.dx, e.dy, e.id or 1) then hasChanged = true end
|
||||
end
|
||||
|
||||
if e.type == "mouse" then
|
||||
if VCTRL.drag(e.dx, e.dy, e.id or 1) then VCTRL.hasChanged = true end
|
||||
elseif e.type == "mouse" then
|
||||
BUTTON.checkHovering(buttonList, e.x, e.y)
|
||||
end
|
||||
end
|
||||
@@ -240,7 +267,8 @@ function TouchConfigScene:onInputPress(e)
|
||||
if not (
|
||||
VCTRL.press(e.x, e.y, e.id and e.id or 1, true) or
|
||||
BUTTON.press(buttonList, e.x, e.y, e.id) or
|
||||
(e.x >= 80 and e.x <= 230 and e.y >= 10 and e.y <= 77)
|
||||
(e.x >= 120 and e.x <= 280 and e.y >= 10 and e.y <= 100) or
|
||||
(e.x >= 400 and e.x <= 560 and e.y >= 10 and e.y <= 100)
|
||||
) then
|
||||
VCTRL.focus = nil
|
||||
focusingButton = nil
|
||||
|
||||
@@ -8,7 +8,7 @@ local buttonList
|
||||
buttonList = {
|
||||
previewToggle = BUTTON.new{
|
||||
text = "Preview\nOFF",
|
||||
x = 570, y = 35, w = 60, h = 40,
|
||||
x = 570, y = 60, w = 60, h = 40,
|
||||
codeWhenReleased = function()
|
||||
VCTRL.release()
|
||||
BUTTON.release(buttonList)
|
||||
@@ -16,8 +16,6 @@ buttonList = {
|
||||
end
|
||||
},
|
||||
}
|
||||
local sliderList = {}
|
||||
|
||||
local secret_grade_grid = {}
|
||||
do
|
||||
local colour_names = {'R', 'O', 'Y', 'G', 'C', 'B', 'M'}
|
||||
@@ -80,13 +78,17 @@ end
|
||||
function TouchConfigPreviewScene:onInputPress(e)
|
||||
if e.type ~= "virtual" and e.input == 'menu_back' then SCENE = InputConfigScene() end
|
||||
if e.type == "mouse" or e.type == "touch" then
|
||||
BUTTON.press(buttonList, e.x, e.y, e.id)
|
||||
if not BUTTON.press(buttonList, e.x, e.y, e.id) then
|
||||
VCTRL.press(e.x, e.y, e.id or 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
---@param e SCENE_onInput
|
||||
function TouchConfigPreviewScene:onInputRelease(e)
|
||||
if e.type == "mouse" or e.type == "touch" then
|
||||
BUTTON.release(buttonList, e.x, e.y, e.id)
|
||||
if not BUTTON.release(buttonList, e.x, e.y, e.id) then
|
||||
VCTRL.release(e.id or 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ function TrainingScene:onInputPress(e)
|
||||
SCENE = TitleScene()
|
||||
elseif (e.input == "menu_back") then
|
||||
SCENE = TitleScene()
|
||||
elseif e.input == "restart" or e.input == "menu_decide" then
|
||||
SCENE = TrainingScene()
|
||||
elseif e.input and string.sub(e.input, 1, 5) ~= "menu_" then
|
||||
self.inputs[e.input] = true
|
||||
end
|
||||
|
||||
@@ -25,15 +25,14 @@ local _defaultSettings = {
|
||||
{type='button',x=640-145,y=355,key= 'rotate_left2',r=45,iconSize=60,alpha=0.4},
|
||||
{type='button',x=640- 70,y=430,key= 'rotate_right',r=45,iconSize=60,alpha=0.4},
|
||||
{type='button',x=640- 70,y=280,key='rotate_right2',r=45,iconSize=60,alpha=0.4},
|
||||
{type='button',x=320- 40,y=420,key= 'menu_decide',r=35,iconSize=60,alpha=0.4},
|
||||
{type='button',x=320+ 40,y=420,key= 'menu_back',r=35,iconSize=60,alpha=0.4},
|
||||
{type='button',x=320, y=420,key= 'restart',r=35,iconSize=60,alpha=0.4},
|
||||
}
|
||||
},
|
||||
tvMode = false -- 79338732
|
||||
tvMode = false
|
||||
}
|
||||
|
||||
SETTINGS = setmetatable(
|
||||
{},
|
||||
{__default__ = _defaultSettings},
|
||||
{
|
||||
__index = function(_, k)
|
||||
if _settings[k] == nil then
|
||||
|
||||
Reference in New Issue
Block a user