Compare commits

...

43 Commits

Author SHA1 Message Date
MrZ626
441c6f7667 再次修复安全漏洞(嗯 2021-11-17 01:15:03 +08:00
MrZ626
a07d57cf71 版本推进 2021-11-16 20:39:29 +08:00
MrZ626
a467f972f9 调整死亡延迟的称呼 2021-11-16 20:39:19 +08:00
MrZ626
3f455ee360 整理代码 2021-11-16 20:29:55 +08:00
MrZ626
7a0b913768 修复安全漏洞(确信 2021-11-16 14:47:42 +08:00
MrZ626
a7b240ade8 微调符号语言 2021-11-16 14:00:09 +08:00
C₂₉H₂₅N₃O₅
bb64404821 完善字体和符号文本 (#460) 2021-11-15 22:27:40 -06:00
MrZ626
caf92eb3c8 修正几处全半角括号 2021-11-16 11:25:16 +08:00
MrZ626
6a117a0fab 词典添加死亡延迟词条 2021-11-16 11:18:33 +08:00
MrZ626
26682509f7 添加防止死亡延时 close #459 2021-11-16 11:18:32 +08:00
C₂₉H₂₅N₃O₅
d85d92fb43 添加几种语言的赞助说明 (#458) 2021-11-15 17:06:49 -06:00
MrZ626
c412003cb3 调整关于页面信息
词典添加patreon词条
2021-11-16 03:55:57 +08:00
MrZ626
e39b5dbd51 修改中文词典的官网词条 2021-11-16 03:27:46 +08:00
MrZ626
db162ea66f 微调about信息 2021-11-16 03:27:46 +08:00
Not-A-Normal-Robot
f9f9fde368 修改 legals.md 一处拼写错误 (#457) 2021-11-15 10:57:16 -06:00
MrZ626
4b221c2eb5 版本推进 2021-11-15 15:52:16 +08:00
MrZ626
ed45bebfa0 添加转盘模块和实验性每日转盘小程序 2021-11-15 15:47:05 +08:00
MrZ626
fa0bc3805f 整理代码,Zframework添加数学扩展模块 2021-11-15 15:46:57 +08:00
MrZ626
7710f0b70f 修正词典 2021-11-15 02:13:56 +08:00
C₂₉H₂₅N₃O₅
0277ddadb5 微调词典 (#456) 2021-11-14 12:05:00 -06:00
MrZ626
88e23e32f5 piano小程序支持shift/ctrl升降半音,左右alt变调,补充更多键位 2021-11-15 02:00:04 +08:00
MrZ626
8ab5b4a17a SFX模块新增音高获取音名的方法
整理代码
2021-11-15 02:00:04 +08:00
MrZ626
503dfd69ef 再调整SFX.playSample方法,支持用数字代表绝对音高,但是移除最后的音量参数 2021-11-15 01:40:53 +08:00
ParticleG
ae61ec26c0 - Remove upload to server 2021-11-15 01:39:37 +08:00
MrZ626
00bc24bd50 新增piano小程序(目前只支持键盘操作) 2021-11-14 22:19:45 +08:00
MrZ626
abd15d6307 table扩展模块新增一个函数 2021-11-14 22:09:44 +08:00
MrZ626
c01ac546d1 再修正播放采样的超音域问题 2021-11-14 21:48:02 +08:00
MrZ626
af77221ba2 修复换准备音效播放方式后ultra模式倒计时没声 2021-11-14 17:34:41 +08:00
MrZ626
204f0938d3 播放准备音效的函数可调音量 2021-11-14 17:32:10 +08:00
MrZ626
ad39d1408c 音乐室输入首字母自动跳转 2021-11-14 17:31:49 +08:00
MrZ626
ed011173f6 版本推进 2021-11-14 16:53:43 +08:00
MrZ626
491fcb5860 添加缓冲区和消失区两个词条
Co-authored-by: C₂₉H₂₅N₃O₅ <cgu52@wisc.edu>
2021-11-14 16:45:53 +08:00
MrZ626
c2d5537d8d 经典模式添加干旱计数器 close #452 2021-11-14 16:45:50 +08:00
MrZ626
7d5037ae87 竞速-效率显示剩余行数 2021-11-14 12:37:39 +08:00
MrZ626
07d7714317 修正无尽模式标题首字母大小写错误 close #454 2021-11-14 12:19:26 +08:00
MrZ626
2cab97f37d 修复0arr时自动移动时声音特别响 2021-11-14 11:49:41 +08:00
MrZ626
d184778c9a 修正string扩展模块时间转换函数可能出现1分60(截断小数点后两位防止被向上取整) 2021-11-14 11:24:11 +08:00
MrZ626
9fd3b3008d 新增物品数据,每日登录新增加一个zTicket 2021-11-13 22:33:25 +08:00
MrZ626
71aa35b214 修正统计里的日期每次启动都被刷新了导致单日统计时间不对 2021-11-13 17:32:54 +08:00
MrZ626
4443dc9d3e table扩展模块添加一个方法(未来会整理类似数据表更新函数) 2021-11-13 17:29:17 +08:00
MrZ626
839e357301 修改更新历史 2021-11-13 16:31:46 +08:00
MrZ626
ac56c5a415 修改竞速-效率左侧信息栏 2021-11-13 16:23:27 +08:00
MrZ626
36e3343341 TRS的J5和L5新增一个180度踢墙 2021-11-13 16:14:36 +08:00
47 changed files with 562 additions and 284 deletions

View File

@@ -1,54 +0,0 @@
name: "upload artifact"
description: "upload file with webdav"
inputs:
WEBDAV_USERNAME:
required: true
description: "webdav username"
WEBDAV_PASSWORD:
required: true
description: "webdav password"
ARTIFACT_TYPE:
required: true
description: "file build type"
ARTIFACT_PLATFORM:
required: true
description: "file platform"
ARTIFACT_NAME:
required: true
description: "file name"
runs:
using: "composite"
steps:
- uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install Webdav 4
shell: bash
run: |
pip install webdav4
- name: Update release
shell: python
run: |
import re
from webdav4.client import Client
client = Client(
"http://mc.yuhao7370.top:5212/dav",
auth=("${{ inputs.WEBDAV_USERNAME }}", "${{ inputs.WEBDAV_PASSWORD }}"),
timeout=None,
)
if '${{ inputs.ARTIFACT_TYPE }}' == 'release':
print('Removing previous ${{ inputs.ARTIFACT_PLATFORM }} release file...')
for file in client.ls('Techmino distribution'):
if re.search(r'(Techmino_a[0-9]+\.[0-9]+\.[0-9]_${{ inputs.ARTIFACT_PLATFORM }}.*)', file['name']):
client.remove(file['name'])
print('Uploading new ${{ inputs.ARTIFACT_PLATFORM }} release file...')
client.upload_file("${{ inputs.ARTIFACT_NAME }}", 'Techmino distribution/${{ inputs.ARTIFACT_NAME }}')
if '${{ inputs.ARTIFACT_TYPE }}' == 'test':
print('Removing previous ${{ inputs.ARTIFACT_PLATFORM }} test file...')
for file in client.ls('Techmino Snapshot'):
if re.search(r'(Techmino_pre[0-9]+\.[0-9]+\.[0-9]_[0-9a-z]{7}_${{ inputs.ARTIFACT_PLATFORM }}.*)', file['name']):
client.remove(file['name'])
print('Uploading new ${{ inputs.ARTIFACT_PLATFORM }} test file...')
client.upload_file("${{ inputs.ARTIFACT_NAME }}", 'Techmino Snapshot/${{ inputs.ARTIFACT_NAME }}')

View File

@@ -56,14 +56,6 @@ jobs:
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: release
ARTIFACT_PLATFORM: Win64
ARTIFACT_NAME: Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip
build-windows-x86:
runs-on: windows-latest
@@ -85,14 +77,6 @@ jobs:
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: release
ARTIFACT_PLATFORM: Win32
ARTIFACT_NAME: Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip
build-linux:
runs-on: ubuntu-20.04
@@ -109,14 +93,6 @@ jobs:
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: release
ARTIFACT_PLATFORM: Linux
ARTIFACT_NAME: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
build-android:
runs-on: ubuntu-20.04
@@ -139,14 +115,6 @@ jobs:
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: release
ARTIFACT_PLATFORM: Android
ARTIFACT_NAME: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
build-macOS:
runs-on: macos-10.15
@@ -174,14 +142,6 @@ jobs:
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: release
ARTIFACT_PLATFORM: MacOS
ARTIFACT_NAME: Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
build-iOS:
runs-on: macos-latest
@@ -216,14 +176,6 @@ jobs:
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: release
ARTIFACT_PLATFORM: iOS
ARTIFACT_NAME: Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
Add-Release-note:
runs-on: ubuntu-20.04

View File

@@ -49,20 +49,7 @@ jobs:
with:
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Windows
path: love
- name: Pack Techmino
run: 7z a -tzip .\Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Windows.zip .\love
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: test
ARTIFACT_PLATFORM: Windows
ARTIFACT_NAME: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Windows.zip
# - name: Upload artifact to server
# run: |
# curl --user "${{ secrets.WEBDAV_USERNAME }}:${{ secrets.WEBDAV_PASSWORD }}" -T Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Windows.zip http://mc.yuhao7370.top:5212/dav/Techmino%20Snapshots/ -v
build-linux:
runs-on: ubuntu-20.04
needs: get-info
@@ -80,16 +67,6 @@ jobs:
with:
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Linux
path: Techmino.AppImage
- name: Pack Techmino
run: mv Techmino.AppImage Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Linux.AppImage
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: test
ARTIFACT_PLATFORM: Linux
ARTIFACT_NAME: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Linux.AppImage
build-android:
runs-on: ubuntu-20.04
@@ -115,16 +92,6 @@ jobs:
with:
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Android
path: Techmino_Snapshot.apk
- name: Pack Techmino
run: mv Techmino_Snapshot.apk Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Android.apk
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: test
ARTIFACT_PLATFORM: Android
ARTIFACT_NAME: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Android.apk
build-macOS:
runs-on: macos-10.15
@@ -152,16 +119,6 @@ jobs:
with:
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_MacOS
path: Techmino.dmg
- name: Pack Techmino
run: mv Techmino.dmg Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_MacOS.dmg
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: test
ARTIFACT_PLATFORM: MacOS
ARTIFACT_NAME: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_MacOS.dmg
build-iOS:
runs-on: macos-latest
@@ -195,13 +152,3 @@ jobs:
with:
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_iOS
path: Techmino.ipa
- name: Pack Techmino
run: mv Techmino.ipa Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_iOS.ipa
- name: Upload artifact to server
uses: ./.github/actions/upload-artifact
with:
WEBDAV_USERNAME: ${{ secrets.WEBDAV_USERNAME }}
WEBDAV_PASSWORD: ${{ secrets.WEBDAV_PASSWORD }}
ARTIFACT_TYPE: test
ARTIFACT_PLATFORM: iOS
ARTIFACT_NAME: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_iOS.ipa

View File

@@ -4,6 +4,7 @@ LOADED=false
ERRDATA={}
--Pure lua modules (basic)
MATH= require'Zframework.mathExtend'
COLOR= require'Zframework.color'
TABLE= require'Zframework.tableExtend'
STRING= require'Zframework.stringExtend'

23
Zframework/mathExtend.lua Normal file
View File

@@ -0,0 +1,23 @@
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
return MATH

View File

@@ -1,5 +1,5 @@
local type,rem=type,table.remove
local rnd=math.random
local int,rnd=math.floor,math.random
local sfxList={}
local packSetting={}
@@ -7,7 +7,7 @@ local Sources={}
local volume=1
local stereo=1
local noteName={
local noteVal={
C=1,c=1,
D=3,d=3,
E=5,e=5,
@@ -16,10 +16,11 @@ local noteName={
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=noteName[tune:sub(1,1)]
local tuneHeight=noteVal[tune:sub(1,1)]
if tuneHeight then
tuneHeight=tuneHeight+(octave-1)*12
local s=tune:sub(2,2)
@@ -79,21 +80,30 @@ function SFX.setStereo(v)
stereo=v
end
function SFX.playSample(pack,...)--vol-2, sampSet1, vol-3, sampSet2, vol-1
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
if type(arg[#arg])=='number'then vol=rem(arg)end
for i=1,#arg do
if type(arg[i])=='number'then
vol=arg[i]
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=_getTuneHeight(arg[i])--Absolute tune in number
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
if playTune<=base then--Too low notes
playTune=base+1
elseif playTune>top then--Too high notes
playTune=top
end

View File

@@ -63,9 +63,9 @@ function STRING.time(t)
if t<60 then
return format("%.3f\"",t)
elseif t<3600 then
return format("%d'%05.2f\"",int(t/60),t%60)
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),t%60)
return format("%d:%.2d'%05.2f\"",int(t/3600),int(t/60%60),int(t%60*100)/100)
end
end

View File

@@ -46,6 +46,18 @@ function TABLE.cover(new,old)
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
@@ -90,6 +102,11 @@ function TABLE.find(t,val)
for i=1,#t do if t[i]==val then return i end end
end
--Retuen next value of [1~#]
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

View File

@@ -17,7 +17,7 @@ The Apple logo, "Apple Inc.," iOS, iPadOS, macOS, iPhone, and Mac are registered
"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.
Source Han Sans is copyrighted by Adobe Inc. Source Han Sans and Abode 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.
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.
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.

View File

@@ -24,6 +24,7 @@ VERSION=require"version"
TIME=love.timer.getTime
YIELD=coroutine.yield
SYSTEM=love.system.getOS()
FNSF=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()
@@ -205,7 +206,7 @@ Z.setOnQuit(destroyPlayers)
TABLE.cover (FILE.load('conf/user')or{},USER)
TABLE.cover (FILE.load('conf/unlock')or{},RANKS)
TABLE.update(FILE.load('conf/settings')or{},SETTING)
TABLE.update(FILE.load('conf/data')or{},STAT)
TABLE.coverR(FILE.load('conf/data')or{},STAT)
TABLE.cover (FILE.load('conf/key')or{},KEY_MAP)
TABLE.cover (FILE.load('conf/virtualkey')or{},VK_ORG)

View File

@@ -353,8 +353,8 @@ do
[21]={'+0+0','-1+0','-1+1','+0+1','-1+2','+0+2','-1-1','+1+0','+0-2','-1-2'},
[32]={'+0+0','-1+0','-1+1','-1-1','+1+0','+0+2','-1+2','+0-2'},
[23]={'+0+0','+1+0','+1-1','+1+1','-1+0','+0-2','+1-2','+0+2'},
[02]={'+0+0','+0-1','+1-1','-1+0','+2-1'},
[20]={'+0+0','+0+1','-1+1','+1+0','-2+1'},
[02]={'+0+0','+0-1','-1-1','+1-1','-1+0','+2-1'},
[20]={'+0+0','+0+1','+1+1','-1+1','+1+0','-2+1'},
[13]={'+0+0','-1+0','-1-1','+0+1','-1-2'},
[31]={'+0+0','+1+0','+1+1','+0-1','+1+2'},
},--J5

View File

@@ -13,6 +13,7 @@ return{
holdCount=1,
infHold=true,
phyHold=false,
hang=0,
--Visual
bone=false,

View File

@@ -1,3 +1,4 @@
local gc_setColor=love.graphics.setColor
return{
das=16,arr=6,
sddas=6,sdarr=6,
@@ -18,12 +19,24 @@ return{
mStr(r<10 and 9 or r<30 and r or("%02x"):format(r*10-300),63,210)
mText(TEXTOBJ.speedLV,63,290)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
if P.modeData.drought>7 then
if P.modeData.drought<=14 then
gc_setColor(1,1,1,P.modeData.drought/7-1)
else
local gb=P.modeData.drought<=21 and 2-P.modeData.drought/14 or .5
gc_setColor(1,gb,gb)
end
setFont(50)
mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5)
end
end,
task=function(P)
P.modeData.target=10
end,
hook_drop=function(P)
local D=P.modeData
D.drought=P.lastPiece.id==7 and 0 or D.drought+1
if P.stat.row>=D.target then
if D.target==110 then
P.gameEnv.drop,P.gameEnv.lock=5,5

View File

@@ -1,3 +1,4 @@
local gc_setColor=love.graphics.setColor
return{
das=16,arr=6,
sddas=3,sdarr=3,
@@ -15,9 +16,20 @@ return{
mesDisp=function(P)
setFont(75)
local r=P.modeData.target/10
mStr(r<11 and 18 or r<22 and r+8 or("%02x"):format(r*10-220),63,210)
mStr(r<10 and 9 or r<30 and r or("%02x"):format(r*10-300),63,210)
mText(TEXTOBJ.speedLV,63,290)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
if P.modeData.drought>7 then
if P.modeData.drought<=14 then
gc_setColor(1,1,1,P.modeData.drought/7-1)
else
local gb=P.modeData.drought<=21 and 2-P.modeData.drought/14 or .5
gc_setColor(1,gb,gb)
end
setFont(50)
mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5)
end
end,
task=function(P)
P.modeData.target=10

View File

@@ -1,3 +1,4 @@
local gc_setColor=love.graphics.setColor
return{
das=16,arr=6,
sddas=1,sdarr=1,
@@ -15,9 +16,20 @@ return{
mesDisp=function(P)
setFont(75)
local r=P.modeData.target/10
mStr(r==1 and 29 or("%02x"):format(r*10-20),63,210)
mStr(r<10 and 9 or r<30 and r or("%02x"):format(r*10-300),63,210)
mText(TEXTOBJ.speedLV,63,290)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
if P.modeData.drought>7 then
if P.modeData.drought<=14 then
gc_setColor(1,1,1,P.modeData.drought/7-1)
else
local gb=P.modeData.drought<=21 and 2-P.modeData.drought/14 or .5
gc_setColor(1,gb,gb)
end
setFont(50)
mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5)
end
end,
task=function(P)
P.modeData.target=10

View File

@@ -0,0 +1,19 @@
return{
mesDisp=function(P)
setFont(55)
local r=40-P.stat.row
if r<0 then r=0 end
mStr(r,63,170)
PLY.draw.drawTargetLine(P,r)
setFont(45)
mStr(("%.1f"):format(P.stat.atk),63,270)
mText(TEXTOBJ.atk,63,323)
mStr(("%.2f"):format(P.stat.atk/P.stat.row),63,370)
mText(TEXTOBJ.eff,63,423)
end,
hook_drop=function(P)
if P.stat.row>=40 then
P:win('finish')
end
end
}

View File

@@ -16,9 +16,9 @@ return{
if P.stat.frame/60>=warnTime[P.modeData.stage]then
if P.modeData.stage<9 then
P.modeData.stage=P.modeData.stage+1
SFX.play('ready',.7+P.modeData.stage*.03)
playReadySFX(3,.7+P.modeData.stage*.03)
else
SFX.play('start')
playReadySFX(0,.7+P.modeData.stage*.03)
P:win('finish')
return
end

Binary file not shown.

View File

@@ -206,34 +206,30 @@ function playClearSFX(cc)
end
end
end
function playReadySFX(i)
function playReadySFX(i,vol)
if i==3 then
Snd('bass','A3')
Snd('lead','A4')
Snd('bass','A3',vol)
Snd('lead','A4',vol)
elseif i==2 then
Snd('bass','F3')
Snd('lead','A4')
Snd('lead','D5')
Snd('bass','F3',vol)
Snd('lead','A4',vol)
Snd('lead','D5',vol)
elseif i==1 then
Snd('bass','G3')
Snd('lead','B4')
Snd('lead','E5')
Snd('bass','G3',vol)
Snd('lead','B4',vol)
Snd('lead','E5',vol)
elseif i==0 then
Snd('bass','A3')
Snd('lead','A4')
Snd('lead','E5')
Snd('lead','A5')
Snd('bass','A3',vol)
Snd('lead','A4',vol)
Snd('lead','E5',vol)
Snd('lead','A5',vol)
end
end
--Game
function coin(a,b)
if rnd()<.5 then
return a
else
return b
end
function getItem(itemName,amount)
STAT.item[itemName]=STAT.item[itemName]+(amount or 1)
end
function generateLine(hole)
return 1023-2^(hole-1)
@@ -275,9 +271,11 @@ function freshDate(mode)
if STAT.date~=date then
STAT.date=date
STAT.todayTime=0
getItem('zTicket',1)
if not mode:find'q'then
MES.new('info',text.newDay)
end
saveStats()
return true
end
end

View File

@@ -726,6 +726,10 @@ do--Userdata tables
spin=(function()local L={}for i=1,29 do L[i]={0,0,0,0,0,0,0}end return L end)(),
pc=0,hpc=0,b2b=0,b3b=0,score=0,
lastPlay='sprint_10l',--Last played mode ID
item=setmetatable({},{__index=function(self,k)
self[k]=0
return 0
end}),
date=false,
todayTime=0,
}

View File

@@ -4,7 +4,7 @@ return{
{"Translator Note 1",
"",
"help",
"This translation of the TetroDictionary is provided by me, User670 (Discord: User670#9501).\n\nThe translation may not completely reflect the contents of the original Chinese text.\n\nCorrected by C₂₉H₂₅N₃O₅.\n\nTo view the list of contributors or make contributions, feel free to visit the GitHub page.",
"This translation of the TetroDictionary is provided by me, User670 (Discord: User670#9501).\n\nThe translation may not completely reflect the contents of the original Chinese text.\n\nCorrected by C₂₉H₂₅N₃O₅ (Discord: C29H25N3O5#1606).\n\nTo view the list of contributors or make contributions, feel free to visit the GitHub page.",
"https://github.com/26F-Studio/Techmino/blob/main/parts/language/dict_en.lua",
},
{"Official Website",
@@ -16,7 +16,7 @@ return{
{"To New Players",
"guide newbie noob",
"help",
"To new players that want to get better at the game:\n\tTwo principles:\n\t1. find a version with good controls (e.g. Techmino, Tetr.io, Tetris Online, Jstris, Tetr.js). Do not use those version used for programming practice.\n\t2. Build foundations in your skills (stable Techrashes using next queue to aid decisions), don't go for fancy T-Spins from the start.\n\n\tTwo main techniques:\n\t1. familiarize yourself with spawn locations of pieces, and the controls to move the piece into each location\n\t2. Plan ahead of where to put the pieces\nWe recommend that you read this article titled \"Words to newbies from a Tetris Pro\" (Click \"Open URL\". In Simplified Chinese)",
"To new players that want to get better at the game:\n\tTwo principles:\n\t1. find a version with good controls (e.g. Techmino, Tetr.io, Tetris Online, Jstris, Tetr.js). Do not use those version used for programming practice.\n\t2. Build foundations in your skills (stable Techrashes using next queue to aid decisions), don't go for fancy T-Spins from the start.\n\n\tTwo main techniques:\n\t1. familiarize yourself with spawn locations of pieces, and the controls to move the piece into each location\n\t2. Plan ahead of where to put the pieces\nHere is a article written by a well-known player in Chinese Tetris community talking about advices to new players. Click the globe if you can read simplified Chinese.",
"https://bilibili.com/read/cv2352939",
},
{"Learning T-spins",
@@ -55,7 +55,7 @@ return{
"https://tetris.huijiwiki.com",
},
--Organizations
--Webpages / Organizations
{"Github Repository",
"githubrepository sourcecode",
"org",
@@ -65,7 +65,7 @@ return{
{"Communities",
"community communities",
"org",
"Join Tetris communities and talk with other players!\n\nChina: [QQ] Tetris Research: 112897780\nGlobal: [Discord] Hard Drop: discord.gg/harddrop (click \"Open URL\").",
"Join Tetris communities and talk with other players!\n\nChina: [QQ] Tetris Research: 112897780\nGlobal: [Discord] Hard Drop: discord.gg/harddrop (click the globe icon to open).",
"https://discord.gg/harddrop"
},
{"Mew",
@@ -77,10 +77,15 @@ return{
{"Tetris OL Servers",
"tetrisonline servers",
"org",
"Google \"Tetris Online Poland\" for the Poland server.\nClick \"Open URL\" for information about the Tetris Online Study server.",
"Google \"Tetris Online Poland\" for the Poland server.\nClick on the globe icon for information about the Tetris Online Study server.",
"http://teatube.ltd/tos",
},
{"P\97\116\114\111\110",
"p\97\116\114\111\110 support",
"org",
"Techmino's P\97\116\114\111\110 Page",
FNSF and"https://www.youtube.com/watch?v=DVl0IiUKX_g"or"https://www.p\97\116\114\111\110.com/techmino",
},
--Games
{"TTT",
"ttt tetris trainer tres bien",
@@ -256,7 +261,7 @@ return{
"game",
"Another mobile Tetris game by EA. It has two control modes Swipe and One-Touch. It also has a Galaxy Mode besides the Marathon Mode (with gravity mechanism), and the goal of this mode is to clear all Galaxy minoes before the sequence runs out.\n\nThis game is no longer available since April 2020."
},
{"TetrisN3TWORK",
{"Tetris (N3TWORK)",
"tetris n3twork mobile phone",
"game",
"The latest mobile Tetris from N3TWORK Inc. It has a 3-minute ultra mode, a marathon mode and a Royale mode. The UI is great but its controls are not so good.",
@@ -302,7 +307,7 @@ return{
{"BPM",
"bpm blocksperminute piecesperminute speed",
"term",
"Blocks per minute\n\tReflects playing speed of a player.\nAlso MrZ forgot that it can be called PPM to avoid confusing with the music term.",
"Blocks per minute\n\tReflects playing speed of a player.\nAlso called PPM (to avoid confusing with the musical term).",
},
{"KPM",
"kpm keysperminute keypressesperminute",
@@ -582,7 +587,7 @@ return{
"term",
"A terminology used in the Chinese Tetris community. A \"debt\" refers to a situation where one must first finish constructing a specific setup before he or she can perform one or more T-spins with real attacks. When constructing a setup where one or multiple debts are created, it is important to observe the opponent carefully to ensure your safety; otherwise, there is a high probability of topping out before the construction is finished.\n\nThis term is frequently used to describe setups such as TST tower. No real attacks can be made before the setup is constructed completely.",
},
{"Attacking & Defending",
{"Attack & Defend",
"attacking defending",
"term",
"Attacking: send garbage lines to your opponent by clearing lines.\nDefending: after your opponent send you lines, you offset this garbage by clearing lines.\nCounter attack: Send attack back at your opponent after offsetting incoming garbage, or taking the hit then attack back.\nIn most games, garbage offsetting is 1:1, i.e. one attack offsets one incoming garbage.",
@@ -660,7 +665,18 @@ return{
{"Topping out",
"die death topout toppingout",
"term",
"Modern Tetris games have three different conditions in which the player tops out:\n1. Block out: when a piece spawned overlaps with the existing blocks in the field;\n2. Lock out: when a piece locks entirely above the skyline;\n3. Garbage out: when the stack exceeds 40 lines in height (often due to incoming garbage).\nTechmino does not check for locking out and garbage out.",
"Modern Tetris games have three different conditions in which the player tops out:\n1. Block out: when a piece spawned overlaps with the existing blocks in the field;\n2. Lock out: when a piece locks entirely above the skyline;\n3. Top out: when the stack exceeds 40 lines in height (often due to incoming garbage).\nTechmino does not check for locking out and topping out.",
},
{"Buffer zone",
"buffer zone above super invisible disappear",
"term",
"Refers to 21st-40th lines above the visible field. Because the blocks in the field could go over the visible field (this usually happens when multiple garbage lines come in) so the buffer zone was created so those blocks could go back to the field when garbage lines are cleared. Also, the buffer zone is usually located at 21st-40th lines because this is sufficient for most cases. Refer to \"Vanish Zone\" to learn more.",
},
{"Vanish zone",
"vanish zone disappear gone cut die",
"term",
"Refers to the area located above the 40th line. This is usually realised by combining c4w and multiple garbage lines. In many games, when any block reaches the vanish zone, the game is terminated immediately.\nHowever, this area can have different behaviours in different games. Some games are flawed because the game could crash when the blocks enter the vanish zone (e.g. Tetris Online). Wierd behaviours could also happen when the blocks enter the vanish zone (you can refer to this video, click on the globe icon to open the link).\n\nFurthermore, the vanish zone in Jstris is located above the 22nd line, and any blocks locked above the 21st line will disappear. ",
"https://youtu.be/z4WtWISkrdU",
},
{"Falling speed",
"fallingspeed",
@@ -677,11 +693,16 @@ return{
"term",
"Sometimes called the Entry Delay. ARE refers to the delay between the lockdown of one piece and the spawn of another piece.",
},
{"line ARE",
{"Line ARE",
"line are appearance delay",
"term",
"The delay between the start of a line clear animation to the spawn of the next piece.",
},
{"Death ARE",
"death are die delay",
"term",
"(Techmino exclusive) When the spawn location of the next piece is blocked by an existing block in the field, a delay will be added in addition to the spawn ARE, and this delay is referred to as the death ARE. This mechanism can be used along with IHS and IRS to prevent death. \nOriginal idea by Not-A-Normal-Bot",
},
{"Finesse",
"finesse",
"term",

View File

@@ -4,7 +4,7 @@ return{
{"新人须知",
"新人须知 xinren new noob readme",
"help",
"致想深入玩下去的新人:\n\n\t两大根本原则:\n\t\t1. 选手感好的版本Tech/Tetr.io/Jstris/TOP/Tetr.js别用编程练习渣版本\n\t\t2. 踏实打好基础预判next稳定消四等别总想着炫酷T旋对未来发展没好处。\n\t两大主要技巧:\n\t\t1. 熟悉初始位置以及到各个位置的初始操作;\n\t\t2. 提前计算好下一块能放哪。\n\n推荐阅读专栏《给TOP新人的几点建议》\n\n[点击右下角按钮打开链接]",
"致想深入玩下去的新人:\n\n\t两大根本原则:\n\t\t1. 选手感好的版本Tech/Tetr.io/Jstris/TOP/Tetr.js别用编程练习渣版本\n\t\t2. 踏实打好基础预判next稳定消四等别总想着炫酷T旋对未来发展没好处。\n\t两大主要技巧:\n\t\t1. 熟悉初始位置以及到各个位置的初始操作;\n\t\t2. 提前计算好下一块能放哪。\n\n推荐阅读专栏《给TOP新人的几点建议》\n\n[点击右下角地球按钮打开链接]",
"https://bilibili.com/read/cv2352939",
},
{"关于T-spin学习",
@@ -15,7 +15,7 @@ return{
{"游戏官网",
"official website homepage guanwang",
"help",
"Techmino的官网\n可以在上面修改头像个人信息。",
"Techmino的官网\n可以在上面下载游戏本体,或者修改头像以及个人信息。\n\n游戏作者的一些话强烈不建议在任何公开场合提及甚至宣传本游戏更不要随便就对外公布我们的官网链接请务必只在私下里向有基础或真的很有兴趣入坑认真玩的玩家推荐不然很容易拉低社群质量破坏交流氛围非常难处理甚至有可能影响游戏的未来发展。为了保证游戏未来会变得越来越好玩千万慎重考虑您对游戏的推广方式感谢您对Techmino的支持感谢配合",
"http://home.techmino.org",
},
{"灰机Wiki",
@@ -49,7 +49,7 @@ return{
"https://four.lol",
},
--相关组织
--相关网页/组织
{"GitHub仓库",
"源代码 github git sourcecode yuandaima",
"org",
@@ -73,6 +73,12 @@ return{
"TO-S的添加方法、说明等关于茶服的一切",
"http://teatube.ltd/tos",
},
{"P\97\116\114\111\110",
"赞助 p\97\116\114\111\110 support zanzhu daqian",
"org",
"Techmino的P\97\116\114\111\110",
FNSF and"https://www.youtube.com/watch?v=DVl0IiUKX_g"or"https://www.p\97\116\114\111\110.com/techmino",
},
--游戏(题库)
{"TTT",
@@ -217,7 +223,7 @@ return{
{"Tetris Effect",
"效应 tec tetriseffectconnect",
"game",
"简称TE(C)一个Windows/PS/Xbox/Oculus Quest 平台方块, 特效方块游戏,只有单机模式,手感不算太好,想看特效的可以一试, 只是去玩方块的不是很建议。\n\n有一个拓展版本 Tetris Effect: Connected 增加了联网对战, 包含普通对战, Zone 对战经典对战和Boss战四个模式。",
"简称TEC一个Windows/PS/Xbox/Oculus Quest 平台方块, 特效方块游戏,只有单机模式,手感不算太好,想看特效的可以一试, 只是去玩方块的不是很建议。\n\n有一个拓展版本 Tetris Effect: Connected 增加了联网对战, 包含普通对战, Zone 对战经典对战和Boss战四个模式。",
},
{"Cultris II",
"文艺方块 c2 cultris2 cultrisii",
@@ -289,57 +295,57 @@ return{
{"LPM",
"lpm sudu",
"term",
"Line per Minute\n行每分,体现玩家下块速度。\n\n不同游戏中显示的LPM算法可能不一样例如TO中的LPM是用PPS换算的每1PPS=24LPM忽略掉了垃圾行的影响不再是字面意思本游戏中使用L'PM代表这种换算后LPM",
"Line Per Minute\n行每分,体现玩家下块速度。\n\n不同游戏中显示的LPM算法可能不一样例如TO中的LPM是用PPS换算的每1PPS=24LPM忽略掉了垃圾行的影响不再是字面意思本游戏中使用L'PM代表这种换算后LPM",
},
{"PPS",
"pps sudu",
"term",
"Piece per Second\n块每秒,体现玩家下块速度。",
"Piece Per Second\n块每秒,体现玩家下块速度。",
},
{"BPM",
"bpm sudu",
"term",
"Block per Minute\n块每分,体现玩家下块速度\n别问为什么不是PPM问就是不知道",
"Block Per Minute\n块每分,体现玩家下块速度\n又称PPMPiece Per Minute",
},
{"KPM",
"kpm sudu",
"term",
"Key per Minute\n按键每分,体现玩家按键速度。",
"Key Per Minute\n按键每分,体现玩家按键速度。",
},
{"KPP",
"kpp anjian",
"term",
"Key per Piece\n按键每块,体现玩家操作是否繁琐。\n学会极简提升操作效率以减少此数字。",
"Key Per Piece\n按键每块,体现玩家操作是否繁琐。\n学会极简提升操作效率以减少此数字。",
},
{"APM",
"apm attack gongji",
"term",
"Attack per Minute\n攻击每分,即玩家每分钟能打出的垃圾行数。\n一定程度体现玩家攻击力。",
"Attack Per Minute\n攻击每分,即玩家每分钟能打出的垃圾行数。\n一定程度体现玩家攻击力。",
},
{"SPM",
"spm send gongji",
"term",
"Send per Minute\n送出每分,即玩家每分钟实际打出去给对手的垃圾行数。\n一定程度体现玩家给对手实际造成的攻击力。",
"Send Per Minute\n送出每分,即玩家每分钟实际打出去给对手的垃圾行数。\n一定程度体现玩家给对手实际造成的攻击力。",
},
{"DPM",
"dpm dig defend",
"term",
"Dig/Defend per Minute\n挖掘每分,即玩家每分钟向下挖掘的垃圾行数。\n某些时候可以体现玩家生存能力。\n\n或:防御(抵消+挖掘)每分。",
"Dig/Defend Per Minute\n挖掘每分,即玩家每分钟向下挖掘的垃圾行数。\n某些时候可以体现玩家生存能力。\n\n或:防御(抵消+挖掘)每分。",
},
{"RPM",
"rpm receive jieshou",
"term",
"Receive per Minute\n接收每分,即玩家每分钟收到来自对手的垃圾行数。\n一定程度体现玩家被对手施加的压力。",
"Receive Per Minute\n接收每分,即玩家每分钟收到来自对手的垃圾行数。\n一定程度体现玩家被对手施加的压力。",
},
{"ADPM",
"adpm attack defend vs",
"term",
"Atk+Dig per Minute\n攻击+挖掘每分用于在同一局游戏内对比玩家间水平差距比APM更准确一些。在TETR.IO中叫VS的数据就是ADPM调整过比例具体是Atk + Dig per 100s",
"Atk+Dig Per Minute\n攻击+挖掘每分用于在同一局游戏内对比玩家间水平差距比APM更准确一些。在TETR.IO中叫VS的数据就是ADPM调整过比例具体是Atk + Dig per 100s",
},
{"APL",
"apl xiaolv",
"term",
"Attack per Line\n攻击每行,也叫效率,体现玩家攻击的行利用率。",
"Attack Per Line\n攻击每行,也叫效率,体现玩家攻击的行利用率。",
},
--术语(消除名)
@@ -438,7 +444,7 @@ return{
{"方块朝向",
"旋转 朝向 xuanzhuan chaoxiang orientation direction 0r2l 02 20 rl lr",
"term",
"在SRS或者类SRS的旋转系统中需要说明方块朝向的时候“朝下”“竖着”等词描述太模糊。\nSRS中每种方块的初始状态固定所以我们使用0(原位)、R即顺时针转一次、2转两下即180°、L即逆时针转一次四个字符表示方块的四种状态从原位0开始顺时针转一圈四个状态是0R2L。\n最早见于SRS踢墙表的行首0→L表示原位逆时针转一次到L状态0→R表示原位顺时针转一次到R状态2→R代表从180°状态逆时针转一次到R状态。",
"在SRS或者类SRS的旋转系统中需要说明方块朝向的时候“朝下”“竖着”等词描述太模糊。\nSRS中每种方块的初始状态固定所以我们使用0原位、R即顺时针转一次、2转两下即180°、L即逆时针转一次四个字符表示方块的四种状态从原位0开始顺时针转一圈四个状态是0R2L。\n最早见于SRS踢墙表的行首0→L表示原位逆时针转一次到L状态0→R表示原位顺时针转一次到R状态2→R代表从180°状态逆时针转一次到R状态。",
},
{"ARS",
"旋转系统 ars rotate",
@@ -600,7 +606,7 @@ return{
{"欠债",
"欠债 qianzhai",
"term",
"欠债\n指必须完全堆好才能开始转下T旋打出攻击堆完之前T下不去的形状。对战实战中如果要做此类(中局)定式时一定要观察对手情况确保自己安全,不然可能被半途打死\n\n一般只用来描述类似双T3/T3塔的大型组合炮堆完之前完全不能打出攻击。",
"欠债\n指必须完全堆好才能开始转下T旋打出攻击堆完之前T下不去的形状。对战实战中如果要做此类中局定式时一定要观察对手情况确保自己安全,不然可能被半途打死\n\n一般只用来描述类似双T3/T3塔的大型组合炮堆完之前完全不能打出攻击。",
},
{"攻守",
"攻守 gong shou",
@@ -685,7 +691,18 @@ return{
{"死亡判定",
"死亡判定 die death siwang",
"term",
"现代方块普遍使用的死亡判定:\n1. 新出现的方块和场地方块有重叠(窒息,Top Outc4w比s4w强的原因因为被打进18行都不会窒息\n2. 方块锁定时完全在场地的外面(Block Out\n3. 场地内现存方块总高度大于40。部分游戏可能没有这条判定而是会自动“切除”场地内所有高度大于40的部分Vanish Zone\n\n注:本游戏使用的死亡判定不包含上述的第二条和第三条。",
"现代方块普遍使用的死亡判定:\n1. 新出现的方块和场地方块有重叠(窒息,Block Outc4w比s4w强的原因因为被打进18行都不会窒息\n2. 方块锁定时完全在场地的外面(Lock Out\n3. 场地内现存方块总高度大于40。超高Top Out\n\n注:本游戏使用的死亡判定不包含上述的第二条和第三条。",
},
{"缓冲区",
"缓冲区 buffer zone huanchongqu",
"term",
"不是所有游戏都有这个概念指10×20可见场地之上的21~40行。因为垃圾行顶起后两边堆高的方块可能会超出屏幕消行后这些方块要重新回到场地内所以需要保存下来由于程序上要求场地尺寸有限部分游戏可以无限故设定为40一般都够用。\n\n另见“消失区”词条。",
},
{"消失区",
"消失区 vanish zone xiaoshiqu",
"term",
"在缓冲区的基础上指比40行缓冲区还高的区域。\n标准的死亡判定涉及了这个概念在垃圾行升起后如果场地上有任何方块超出了40高的缓冲区也就是达到了消失区时游戏直接结束。\n但事实上这块区域在不同游戏中表现不同甚至有设计者考虑不周导致方块挪到40行以上但是程序没考虑导致方块接触消失区直接报错闪退的游戏。通常出现在玩家堆了c4w然后被打入大量垃圾行时才会考虑这个概念。其他游戏中方块进入消失区可能直接导致游戏结束也有可能会出现一些奇怪的bug附带链接是ppt的复制40行无限ren视频\n\nJstris中22行及以上可以理解为消失区锁定在21行之外的格子会消失。",
"https://www.bilibili.com/video/BV1ZE411Y7GD",
},
{"下落速度",
"下落速度 重力 drop speed zhongli gravity",
@@ -707,6 +724,11 @@ return{
"term",
"方块<锁定完成能消行时的消行动画>占据的时间英文是line ARE。",
},
{"窒息延迟",
"窒息延迟 choke are delay zhixiyanchi",
"term",
"当前方块锁定后如果下一块的生成位置被阻挡,那么下一块的出块延迟会被再额外加上这个延迟的值,方便使用提前系统来避免死亡\n想法来自Not-A-Normal-Bot",
},
{"Finesse",
"极简操作 最简操作 finesse jijiancaozuo zuijiancaozuo",
"term",
@@ -720,7 +742,7 @@ return{
{"手感",
"手感 feel shougan",
"term",
"决定手感的几个主要因素:\n(1) 输入延迟受设备配置或者设备状况影响。可以重启/换设备解决\n(2) 程序运行稳定性程序设计(或者实现)得不好,时不时会卡一下。把设置画面效果拉低可能可以缓解\n(3) 游戏设计故意的。自己适应\n(4) 参数设置设置不当。去改设置\n(5) 游玩姿势姿势不当。不便用力,换个姿势\n(6) 换键位或者换设备后不适应,操作不习惯。多习惯习惯,改改设置\n(7) 肌肉疲劳反应和协调能力下降。睡一觉或者做点体育运动,过段时间(也可能要几天)再来玩",
"决定手感的几个主要因素:\n1 输入延迟受设备配置或者设备状况影响。可以重启/换设备解决\n2 程序运行稳定性程序设计(或者实现)得不好,时不时会卡一下。把设置画面效果拉低可能可以缓解\n3 游戏设计故意的。自己适应\n4 参数设置设置不当。去改设置\n5 游玩姿势姿势不当。不便用力,换个姿势\n6 换键位或者换设备后不适应,操作不习惯。多习惯习惯,改改设置\n7 肌肉疲劳反应和协调能力下降。睡一觉或者做点体育运动,过段时间(也可能要几天)再来玩",
},
{"DAS通俗",
"das arr simple",
@@ -760,7 +782,7 @@ return{
{"His出块",
"his出块 history",
"term",
"一种的出块方式例如His4 Roll6 (h4r6)就是在随机生成新的 Next 的时候随机一个跟最后4次生成的Next中有一样的就重新随机直到已经尝试6次或和那4个都不一样。\n本游戏的His序列模式中最大Roll次数为序列长度的一半向上取整\n\n是纯随机出块的一大改进大大减小了连续出几个SZ洪水的概率。",
"一种的出块方式例如His4 Roll6 h4r6就是在随机生成新的 Next 的时候随机一个跟最后4次生成的Next中有一样的就重新随机直到已经尝试6次或和那4个都不一样。\n本游戏的His序列模式中最大Roll次数为序列长度的一半向上取整\n\n是纯随机出块的一大改进大大减小了连续出几个SZ洪水的概率。",
},
{"HisPool出块",
"hisPool出块 history pool",
@@ -1121,7 +1143,7 @@ return{
{"Jonas",
"jonas",
"name",
"经典块一流玩家曾经的经典块第一CTWC4连冠\n(1981-2021)",
"经典块一流玩家曾经的经典块第一CTWC4连冠\n1981-2021",
},
{"Joseph",
"joseph",
@@ -1131,7 +1153,7 @@ return{
{"Kazu",
"kazu mdking",
"name",
"(也叫“GAMEOVER” “GAMAOVER” “GAME_OVER_RETRY”)\n一流玩家以熟练md转捐赠闻名",
"也叫“GAMEOVER” “GAMAOVER” “GAME_OVER_RETRY”\n一流玩家以熟练md转捐赠闻名",
},
{"Microblizz",
"microblizz",

View File

@@ -194,7 +194,9 @@ return{
"Make sure to get the game only from official sources,",
"as we can't make sure you're safe if you got it elsewhere.",
"The author is not responsible for any modifications.",
"While the game is free, donations are appreciated."
FNSF and"/"or"While the game is free, donations are appreciated.",
FNSF and"/"or"If you are unable to use both WeChat Pay and AliPay,",
FNSF and"/"or"you can go to our P\97\116\114\111\110 page (Link in Zictionary) to support us!",
},
staff={
"Author: MrZ Email: 1046101471@qq.com",
@@ -224,7 +226,6 @@ return{
simple-love-lights [dylhunn]
]],
support="Support the author",
group="Join our Discord: discord.gg/f9pUvkh",
WidgetText={
main={
offline="Single Player",
@@ -476,6 +477,7 @@ return{
lock="Lock Delay",
wait="Entry Delay",
fall="Line Delay",
hang="Death Delay",
bg="Background",
bgm="Music",
@@ -749,7 +751,7 @@ return{
['sprintEff']= {"Sprint", "Efficiency", "Send more attack in 40lines!"},
['zen']= {'Zen', "200", "A 200-line run without a time limit"},
['ultra']= {'Ultra', "EXTRA", "A 2-minute score attack"},
['infinite']= {'infinite', "", "Just a sandbox"},
['infinite']= {"Infinite", "", "Just a sandbox"},
['infinite_dig']= {"Infinite: Dig", "", "Dig-diggin'-dug"},
['marathon_inf']= {"Marathon", "INFINITE", "Infinite marathon."},

View File

@@ -160,7 +160,9 @@ return{
"Descarga disponible únicamente vía el grupo de testeo y discord.gg/f9pUvkh",
"Descargas desde otros sitios pueden contener malware/viruses, y en smartphones sólo requiere permisos de internet y vibración.",
"El autor no se responabiliza por daños ocasionados debido a modificaciones del juego.",
"Por favor descarga las últimas versiones desde los sitios oficiales. El juego es gratuito",
FNSF and"/"or"Por favor descarga las últimas versiones desde los sitios oficiales. El juego es gratuito",
FNSF and"/"or"Si no puede usar WeChat Pay y AliPay,",
FNSF and"/"or"puede ir a nuestra página de P\97\116\114\111\110 para apoyarnos.",
},
staff={
"Autor:MrZ Email: 1046101471@qq.com",
@@ -190,7 +192,6 @@ return{
simple-love-lights [dylhunn]
]],
support="Apoyen al Autor",
group="Grupo Oficial de QQ (si no lo hackean) : 913154753",
WidgetText={
main={
offline="1 Jugador",
@@ -442,6 +443,7 @@ return{
lock="Retraso de Bloqueo",
wait="Retraso de Spawneo",
fall="Retraso de Línea",
-- hang="Death Delay",
bg="Fondo",
bgm="Música",

View File

@@ -160,7 +160,9 @@ return{
"Ce jeu est gratuit et est uniquement disponible via discord.gg/f9pUvkh",
"Ne téléchargez pas ce jeu depuis une autre source au risque d'avoir des virus,",
"et vous n'avez besoin que des permissions de vibration et de communication réseau pour les versions mobiles !",
"Le créateur n'est pas responsable pour n'importe quel type de perte de données suite à une modification du jeu.",
FNSF and"/"or"Le créateur n'est pas responsable pour n'importe quel type de perte de données suite à une modification du jeu.",
FNSF and"/"or"Si vous ne parvenez pas à utiliser à la fois WeChat Pay et AliPay,",
FNSF and"/"or"vous pouvez vous rendre sur notre page P\97\116\114\111\110 pour nous soutenir !",
},
staff={
"Author: MrZ E-mail: 1046101471@qq.com",
@@ -190,7 +192,6 @@ return{
simple-love-lights [dylhunn]
]],
support="Aider le créateur",
group="Groupe QQ officiel : 913154753",
WidgetText={
main={
-- offline="Solo",
@@ -443,6 +444,7 @@ return{
lock="Délai de verrouillage",
wait="Délai d'apparition",
fall="Délai de ligne",
-- hang="Death Delay",
bg="Arrière-plan",
bgm="Musique",

View File

@@ -177,12 +177,14 @@ return{
"Isso é apenas um jogo de blocos, nada de especial.",
"Joga como C2/IO/JS/WWC/KOS e outros.",
"",
"Feito na Love 2D Engine",
"Feito na LÖVE 2D Engine",
"Por favor mande bugs ou sugestões para o autor.",
"certifique-se de pegar o jogo de fontes oficiais;",
"binários obtidos em outros lugares pode conter malware.",
"O autor não é responsável por qualquer binários modificados",
"O jogo é gratis, mas doações são apreciadas."
FNSF and"/"or"O jogo é gratis, mas doações são apreciadas.",
FNSF and"/"or"Se você não conseguir usar o WeChat Pay e o AliPay,",
FNSF and"/"or"pode acessar a página do P\97\116\114\111\110 para nos ajudar!",
},
staff={
"Author: MrZ E-mail: 1046101471@qq.com",
@@ -212,7 +214,6 @@ return{
simple-love-lights [dylhunn]
]],
support="Support author",
group="Junte-se ao nosso Discord: discord.gg/f9pUvkh",
WidgetText={
main={
offline="Solo",
@@ -465,6 +466,7 @@ return{
lock="Delay Trava",
wait="Delay Entrada",
fall="Delay Linha",
-- hang="Death Delay",
bg="Fundo",
bgm="Música",

View File

@@ -1,6 +1,23 @@
return{
fallback='en',
loadText={
loadSFX="#!#",
loadSample="#~#",
loadVoice="#<()==)#",
loadFont="#Aa#",
loadModeIcon="#[ ]#",
loadMode="#[…]#",
loadOther="#…#",
finish="&",
},
sureQuit="X?",
sureReset="R?",
newDay="→→!→→",
playedLong="→→→→!, XX□XX!",
playedTooMuch="→→→→→→→→→→→!, XX□XX!!!!!!!",
atkModeName={"?","( )","!","←→"},
royale_remain="$1 ~",
cmb={nil,"!","!!","!!!","!!!!","!!!!!","!!!!!!","!!!!!!!","!!!!!!!!","!!!!!!!!!","!!!!!!!!!!","!!!!!!!!!!!","!!!!!!!!!!!!","!!!!!!!!!!!!!","!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!!!!",},
@@ -97,12 +114,15 @@ return{
"□!!~~~,□□□□X",
"□!!==*/*/*/*/*~",
"",
"Powered by LÖVE",
"Any suggestions or bug reports are appreciated!",
"Make sure to only obtain the game from official sources;",
"We can't make sure you're safe if you got it elsewhere.",
"The author is not responsible for any modified binaries.",
"While the game is free, donations are appreciated."
"\\LÖVE/",
"(≡≡≡)/(XXX↑↑) : )",
"↓↓[=]↓↓ OK!",
"↓↓……↓↓(!!!)",
"MrZ XXX A→B",
"",
"□$X, ↑$↑ XD!",
"C0, 支 XXX,",
"|^O : )",
},
WidgetText={
main={
@@ -351,6 +371,7 @@ return{
lock="↓_",
wait="→=",
fall="↓=",
hang=":(=",
bg="{~}",
bgm="(~)",

View File

@@ -191,10 +191,12 @@ return{
"",
"使用LÖVE引擎",
"错误或者建议请附带截图发送到内测群或者作者邮箱~",
"仅通过内测qq群/discord群进行免费下载/更新",
"仅通过官网 home.techmino.org 免费下载/更新",
"其他渠道获得游戏皆有被修改/加广告/植入病毒的风险,程序只申请了振动&联网权限!",
"若由于被修改的本游戏产生的各种损失作者不负责(怎么负责啊跟我有啥关系)",
"请从正规途径获得最新版,游戏现为免费,不过有打赏当然感谢啦~记得备注id方便记录",
"若由于被修改的本游戏产生的各种损失作者不负责(怎么负责啊我又没法管)",
FNSF and"/"or"请从正规途径获得最新版,游戏现为免费,不过有打赏当然感谢啦~",
FNSF and"/"or"记得备注id备注id备注id不然可能会没法记录到赞助列表",
FNSF and"/"or"你也可以去我们的P\97\116\114\111\110页面(链接见小Z词典)来支持我们!",
},
staff={
"作者:MrZ 邮箱:1046101471@qq.com",
@@ -224,7 +226,6 @@ return{
simple-love-lights [dylhunn]
]],
support="支持作者",
group="官方QQ群:913154753",
WidgetText={
main={
offline="单机游戏",
@@ -476,6 +477,7 @@ return{
lock="锁定延迟",
wait="出块等待",
fall="消行延迟",
hang="窒息延迟",
bg="背景",
bgm="音乐",

View File

@@ -1,4 +1,3 @@
local C=COLOR
return{
fallback='zh',
loadText={
@@ -194,6 +193,7 @@ return{
"因为如果你在别处找到它,我们无法确保你的安全",
"作者不对任何修改负责",
"虽然游戏是免费的,但我们会感谢捐赠.",
"如果您无法同时使用我们的聊天支付和阿里支付你可以去我们的P\97\116\114\111\110页面(连接到四联词典)支持我们!",
},
staff={
"作者:Z先生 邮箱:1046101471@qq.com",
@@ -223,7 +223,6 @@ return{
simple-love-lights [dylhunn]
]],
support="供养作者!",
group="加入我们的不谐和:不谐和.gg/f9pUvkh",
WidgetText={
main={
offline="单人",
@@ -476,6 +475,7 @@ return{
lock="锁定延迟",
wait="进入延迟",
fall="线路延迟",
hang="毁灭延迟",
bg="背景",
bgm="音乐",

View File

@@ -194,7 +194,8 @@ return{
"僅透過內測QQ群/discord伺服器進行免費下載/更新",
"從其他渠道獲得遊戲皆有被修改/加入廣告/植入病毒的風險,程序只申請了振動&網路權限!",
"若由於被修改的本遊戲產生的各種損失作者概不負責(我怎麼負責啊跟我有什麼關係)",
"請從正規途徑獲得最新版,遊戲現為免費,不過有讚賞當然感謝啦~ 記得備註用戶名,方便記錄!",
FNSF and"/"or"請從正規途徑獲得最新版,遊戲現為免費,不過有讚賞當然感謝啦~ 記得備註用戶名,方便記錄!",
FNSF and"/"or"如果你不使用微信或支付寶你可以前往我們的P\97\116\114\111\110頁面來贊助我們!"
},
staff={
"作者:MrZ 電郵:1046101471@qq.com",
@@ -224,7 +225,6 @@ return{
simple-love-lights [dylhunn]
]],
support="支持作者",
group="官方QQ群:913154753",
WidgetText={
main={
offline="單人遊戲",
@@ -476,6 +476,7 @@ return{
lock="鎖定延遲",
wait="方塊生成等待",
fall="行清除延遲",
hang="死亡延遲",
bg="背景",
bgm="音樂",

View File

@@ -1,7 +1,7 @@
return{
env={
drop=60,lock=60,
eventSet='checkLine_40',
eventSet='sprintEff_40',
bg='bg2',bgm='race',
},
score=function(P)return{P.stat.atk/P.stat.row,P.stat.time}end,

View File

@@ -3,7 +3,7 @@ return{
dascut=0,dropcut=0,
sddas=2,sdarr=2,
ihs=true,irs=true,ims=true,
FTLock=true,
hang=0,FTLock=true,
ghostType='gray',
block=true,ghost=.3,center=1,

View File

@@ -578,7 +578,7 @@ function Player:changeAtk(R)
self.atking=false
end
end
function Player:freshBlock(mode)--string mode: push/move/fresh/newBlock
function Player:freshBlock(mode,ifTele)--string mode: push/move/fresh/newBlock
local ENV=self.gameEnv
--Fresh ghost
if(mode=='move'or mode=='newBlock'or mode=='push')and self.cur then
@@ -643,7 +643,7 @@ function Player:freshBlock(mode)--string mode: push/move/fresh/newBlock
end
--Play sound if touch ground
if mode=='move'then
if mode=='move'and not ifTele then
self:checkTouchSound()
end
end
@@ -1256,6 +1256,7 @@ do
piece.curX,piece.curY,piece.dir=self.curX,self.curY,C.dir
piece.centX,piece.centY=self.curX+sc[2],self.curY+sc[1]
piece.frame,piece.autoLock=self.frameRun,autoLock
self.waiting=ENV.wait
--Tri-corner spin check
@@ -1642,6 +1643,14 @@ do
end
end
--Prevent sudden death if hang>0
if ENV.hang>ENV.wait and self.nextQueue[1]then
local B=self.nextQueue[1]
if self:ifoverlap(B.bk,int(6-#B.bk[1]*.5),int(ENV.fieldH+1-modf(B.RS.centerPos[B.id][B.dir][1]))+ceil(self.fieldBeneath/30))then
self.waiting=self.waiting+ENV.hang
end
end
--Check bot things
if self.bot then
self.bot:checkDest()
@@ -2600,10 +2609,11 @@ function Player:act_insLeft(auto)
while not self:ifoverlap(self.cur.bk,self.curX-1,self.curY)do
self:createMoveFX('left')
self.curX=self.curX-1
self:freshBlock('move')
self:freshBlock('move',true)
end
if self.curX~=x0 then
self.spinLast=false
self:checkTouchSound()
end
if self.gameEnv.shakeFX then
self.swingOffset.vx=-1.5
@@ -2624,10 +2634,11 @@ function Player:act_insRight(auto)
while not self:ifoverlap(self.cur.bk,self.curX+1,self.curY)do
self:createMoveFX('right')
self.curX=self.curX+1
self:freshBlock('move')
self:freshBlock('move',true)
end
if self.curX~=x0 then
self.spinLast=false
self:checkTouchSound()
end
if self.gameEnv.shakeFX then
self.swingOffset.vx=1.5

View File

@@ -31,10 +31,6 @@ function scene.draw()
gc.printf(text.aboutTexts[i],150,35*i+50,1000,'center')
end
--Group
setFont(20)
mStr(text.group,640,480)
--Lib used
setFont(15)
gc.print(text.used,50,325)

View File

@@ -90,7 +90,7 @@ local function newTile()
if nextCD>0 then
nextTile=1
else
nextTile=rnd()>.1 and 2 or rnd()>.1 and 3 or 4
nextTile=MATH.roll(.9)and 2 or MATH.roll(.9)and 3 or 4
nextCD=rnd(8,12)
end

View File

@@ -611,6 +611,16 @@ local commands={}do
scene='app_arithmetic',
description="Arithmetic"
},
{
code="piano",
scene='app_piano',
description="A simple keyboard piano"
},
{
code="spin",
scene='app_spin',
description="???"
},
}
commands.app={
code=function(name)

View File

@@ -7,7 +7,6 @@ local setFont,mStr=FONT.set,GC.mStr
local int,rnd,abs=math.floor,math.random,math.abs
local max,min=math.max,math.min
local ins,rem=table.insert,table.remove
local function sign(a)return a>0 and 1 or a<0 and -1 or 0 end
local levels={
{c=6,r=3,color=3},
@@ -289,7 +288,7 @@ function scene.update(dt)
if state==1 then
time=TIME()-startTime
comboTime=max(comboTime-dt,0)
score1=score1+sign(score-score1)+int((score-score1)*.1+.5)
score1=score1+MATH.sign(score-score1)+int((score-score1)*.1+.5)
end
if sure>0 then sure=sure-dt end

View File

@@ -0,0 +1,53 @@
local gc=love.graphics
local kb=love.keyboard
local instList={'lead','bell','bass'}
local keys={
['1']=61,['2']=63,['3']=65,['4']=66,['5']=68,['6']=70,['7']=72,['8']=73,['9']=75,['0']=77,['-']=78,['=']=80,['backspace']=82,
['q']=49,['w']=51,['e']=53,['r']=54,['t']=56,['y']=58,['u']=60,['i']=61,['o']=63,['p']=65,['[']=66,[']']=68,['\\']=70,
['a']=37,['s']=39,['d']=41,['f']=42,['g']=44,['h']=46,['j']=48,['k']=49,['l']=51,[';']=53,["'"]=54,['return']=56,
['z']=25,['x']=27,['c']=29,['v']=30,['b']=32,['n']=34,['m']=36,[',']=37,['.']=39,['/']=41,
}
local inst
local offset
local scene={}
function scene.sceneInit()
inst='lead'
offset=0
end
function scene.touchDown(x,y,k)
--TODO
end
scene.mouseDown=scene.touchDown
function scene.keyDown(key,isRep)
if not isRep and keys[key]then
local note=keys[key]+offset
if kb.isDown('lshift','rshift')then note=note+1 end
if kb.isDown('lctrl','rctrl')then note=note-1 end
SFX.playSample(inst,note)
TEXT.show(SFX.getNoteName(note),math.random(150,1130),math.random(140,500),60,'score',.8)
elseif key=='tab'then
inst=TABLE.next(instList,inst)
elseif key=='lalt'then
offset=math.max(offset-1,-12)
elseif key=='ralt'then
offset=math.min(offset+1,12)
elseif key=='escape'then
SCN.back()
end
end
function scene.draw()
setFont(30)
gc.print(inst,40,60)
gc.print(offset,40,100)
end
scene.widgetList={
WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,font=60,fText=CHAR.icon.back,code=backScene},
}
return scene

View File

@@ -39,7 +39,7 @@ end
local function start()
state=1
vx=rnd()>.5 and 6 or -6
vx=MATH.coin(6,-6)
vy=rnd()*6-3
end
function scene.keyDown(key,isRep)

48
parts/scenes/app_spin.lua Normal file
View File

@@ -0,0 +1,48 @@
local spinner=require'parts/spinner'.new({
{font=45,disp=CHAR.icon.retry_spin,item='zTicket',amount=1,freq=30},
{font=60,disp=CHAR.mino.Z,item='Zfrag',amount=1,freq=10},
{font=60,disp=CHAR.mino.S,item='Sfrag',amount=1,freq=10},
{font=60,disp=CHAR.mino.J,item='Jfrag',amount=1,freq=10},
{font=60,disp=CHAR.mino.L,item='Lfrag',amount=1,freq=10},
{font=60,disp=CHAR.mino.T,item='Tfrag',amount=1,freq=10},
{font=60,disp=CHAR.mino.O,item='Ofrag',amount=1,freq=10},
{font=60,disp=CHAR.mino.I,item='Ifrag',amount=1,freq=10},
},function(item,amount)
getItem(item,amount)
saveStats()
end)
local scene={}
function scene.keyDown(key,isRep)
if isRep then return end
if key=='space'or key=='return'then
if STAT.item.zTicket>0 then
if spinner:start()then
STAT.item.zTicket=STAT.item.zTicket-1
saveStats()
end
else
MES.new('info',"Not enough zTicket")
end
elseif key=='escape'then
SCN.back()
end
end
function scene.update(dt)
spinner:update(dt)
end
function scene.draw()
setFont(40)
love.graphics.print("zTickets: "..STAT.item.zTicket,90,80)
spinner:draw(640,360)
end
scene.widgetList={
WIDGET.newButton{name="spin", x=1140,y=360,w=120,font=60,fText=CHAR.icon.retry_spin,code=pressKey"space"},
WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,font=60,fText=CHAR.icon.back,code=backScene},
}
return scene

View File

@@ -16,6 +16,7 @@ local sList={
lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99},
wait={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
fall={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
hang={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
eventSet=EVENTSETS,
holdMode={'hold','swap'},
}
@@ -211,6 +212,7 @@ scene.widgetList={
WIDGET.newSelector{name='lock', x=730,y=410,w=260,color='O',list=sList.lock,disp=CUSval('lock'),code=CUSsto('lock')},
WIDGET.newSelector{name='wait', x=730,y=520,w=260,color='G',list=sList.wait,disp=CUSval('wait'),code=CUSsto('wait')},
WIDGET.newSelector{name='fall', x=730,y=600,w=260,color='G',list=sList.fall,disp=CUSval('fall'),code=CUSsto('fall')},
WIDGET.newSelector{name='hang', x=730,y=680,w=260,color='G',list=sList.hang,disp=CUSval('hang'),code=CUSsto('hang')},
--Copy / Paste / Start
WIDGET.newButton{name='copy', x=1070,y=300,w=310,h=70,color='lR',font=25,code=pressKey"cC"},
@@ -220,7 +222,7 @@ scene.widgetList={
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,font=60,fText=CHAR.icon.back,code=pressKey"escape"},
--Rule set
WIDGET.newSelector{name='eventSet', x=930, y=740,w=360,color='H',list=sList.eventSet,disp=CUSval('eventSet'),code=CUSsto('eventSet')},
WIDGET.newSelector{name='eventSet', x=1050,y=740,w=340,color='H',list=sList.eventSet,disp=CUSval('eventSet'),code=CUSsto('eventSet')},
--Special rules
WIDGET.newSwitch{name='ospin', x=850, y=810,lim=210,disp=CUSval('ospin'), code=CUSrev('ospin')},

View File

@@ -29,16 +29,21 @@ local typeColor={
english=COLOR.B,
name=COLOR.lV,
}
local function _filter(word_org)
local word=word_org
word=word:gsub("[Tt]etris",CHAR.zChan.thinking)
if FNSF then word=word:gsub("[Pp]\97\116\114\111\110",CHAR.zChan.qualified)end
return word,word_org
end
local function _scanDict(D)
if not D[1][1]then return end
local c=CHAR.zChan.thinking
local cut=TABLE.cut
for i=1,#D do
local O=D[i]
O.title,O.title_Org=O[1]:gsub("[Tt]etris",c),O[1]
O.title,O.title_Org=_filter(O[1])
O.keywords=O[2]
O.type=O[3]
O.content,O.content_Org=O[4]:gsub("[Tt]etris",c),O[4]
O.content,O.content_Org=_filter(O[4])
O.url=O[5]
cut(O)
end

View File

@@ -14,9 +14,9 @@ local widgetX0={
}
local enterConsole=coroutine.wrap(function()
while true do
Snd('bell',.6,'A4',.7,'E5',1,coin('A5','B5'))YIELD()
Snd('bell',.6,'A4',.7,'F5',1,coin('C6','D6'))YIELD()
Snd('bell',.6,'A4',.7,'G5',1,coin('E6','G6'))YIELD()
Snd('bell',.6,'A4',.7,'E5',1,MATH.coin('A5','B5'))YIELD()
Snd('bell',.6,'A4',.7,'F5',1,MATH.coin('C6','D6'))YIELD()
Snd('bell',.6,'A4',.7,'G5',1,MATH.coin('E6','G6'))YIELD()
Snd('bell',.6,'A4',.7,'A5',1,'A6')SFX.play('ren_mega')SCN.go('app_console')YIELD()
end
end)

View File

@@ -63,6 +63,11 @@ function scene.keyDown(key,isRep)
SCN.swapTo('launchpad','none')
elseif key=="escape"then
SCN.back()
elseif #key==1 and key:find'[0-9a-z]'then
for _=1,#bgmList do
selected=selected%#bgmList+1
if bgmList[selected]:sub(1,1)==key then break end
end
end
end
end

112
parts/spinner.lua Normal file
View File

@@ -0,0 +1,112 @@
local gc=love.graphics
local Spinner={
data={},
totalFreq=0,
spinning=false,
angle=0,
angV=0,
chosen=false,
light=0,
}
Spinner.__index=Spinner
function Spinner:start()
if not self.spinning then
self.spinning=true
self.angle=MATH.tau*math.random()
self.angV=.62+.26*math.random()
return true
end
end
function Spinner:update(dt)
if self.spinning then
self.angle=(self.angle+self.angV*dt*60)%MATH.tau
local dV=
self.angV>.26 and .0026 or
self.angV>.12 and .0012 or
self.angV>.04 and .0004 or
.0001
self.angV=self.angV-dV*dt*60
if self.angV<=0 then
self.angV=0
self.spinning=false
local freq=self.angle%MATH.tau/MATH.tau*self.totalFreq
for i=1,#self.data do
local D=self.data[i]
freq=freq-D.freq
if freq<=0 then
self.chosen=D
self.light=1
if D.item then
self.hook_stop(D.item,D.amount)
end
break
end
end
end
else
if self.light>0 then
self.light=self.light-dt
end
end
end
function Spinner:draw(x,y)
gc.push('transform')
gc.translate(x,y)
--Draw circle
gc.setColor(1,1,1)
gc.setLineWidth(3)
gc.circle('line',0,0,300)
--Draw areas
gc.setLineWidth(1)
local freq=0
for i=1,#self.data do
gc.line(10,0,290,0)
local D=self.data[i]
freq=freq+D.freq
if D==self.chosen then
gc.setColor(1,1,1,.5*self.light)
gc.arc('fill','pie',0,0,300,0,-D.freq*MATH.tau/self.totalFreq)
gc.setColor(1,1,1)
end
local dAng=-MATH.tau*D.freq/self.totalFreq
gc.rotate(dAng*.5)
if D.amount>0 then
setFont(D.font)
if D.amount==1 then
mStr(D.disp,170,-D.font*.7)
else
mStr(D.disp.."x"..D.amount,170,-D.font*.7)
end
end
gc.rotate(dAng*.5)
end
gc.pop()
--Draw target pin
gc.setLineWidth(2)
gc.setColor(1,.3,.3)
gc.line(x,y,x+200*math.cos(self.angle),y-200*math.sin(self.angle))
end
function Spinner.new(data,hook_stop)
local self={}
setmetatable(self,Spinner)
local sum=0
for i=1,#data do
sum=sum+data[i].freq
if not data[i].font then data[i].font=30 end
end
self.data=data
self.totalFreq=sum
self.hook_stop=hook_stop
return self
end
return Spinner

View File

@@ -1,18 +1,15 @@
return[=[
未来模式:
任务树; 大爆炸; 拼方形; 限高无尽挖掘; 连击练习; 极简教程/考试
未来小游戏:
Tetro-1010(四/五连块, 2C2N, 若干回合改变重力方向); Tetra-link(桌游)
噗哟; 泡泡龙; 求合体; 坦克大战; 扫雷; 接水管; 数字记忆; 听声记忆
Tetro-1010(2C2N, 重力); Tetra-link(桌游)
噗哟; 泡泡龙; 求合体; 坦克大战; 扫雷; 接水管; 记忆
其他未来内容:
组队战; 实时统计数据可视化; 教学关; 从录像继续
重做模式选择UI; 重做模组UI; 加速下落; spike相关统计数据
支持更多手柄; 场地格边缘线; 模式数据分析; 高级自定义序列
等级系统; 成就系统; Domain状态; 手势操作; C2连击; 特殊控件(虚拟摇杆等)
方块位移/旋转动画; 更细节的DAS选项; 拓展主题系统; 无用货币
等级系统; 成就系统; 手势操作; C2连击; 特殊控件(虚拟摇杆等)
方块位移/旋转动画; 更细节的DAS选项; 拓展主题系统
可调攻击系统; 更多消除方式; 可调场地宽度; 新联网游戏场景切换逻辑
工程编译到字节码; task-Z(新AI)
收集向抽奖; 自适应UI; 多方块
工程编译到字节码; task-Z(新AI); 自适应UI; 多方块
0.16.5: 新世界 New World
新增:
@@ -23,21 +20,30 @@ return[=[
新BGM:peak(暂未使用)
新BGM:1989(用于经典模式,by C₂₉H₂₅N₃O₅)
删除节奏模式(之后会有全新音游模式)
音乐室输入首字母自动跳转
新增窒息延迟(by Not-A-Normal-Bot) #459
移除模式标题的颜色
改动:
移动音效改为触地音效,在方块因重力或旋转触地时也会播放
新增piano小程序(目前只支持键盘操作)
再调整场地晃动的阻力,看起来更舒服
TRS的J5和L5新增一个180度踢墙
重做全局颜色表(by C₂₉H₂₅N₃O₅)
经典模式添加干旱计数器 #452
重新安排一些模式的BGM
堆积模式移出地图,修改规则可以消超过20行
堆积模式移出地图,修改规则可以消超过20行 #449
只在更新后触发自动转换以旧版本模式名存储的数据
再次更换字体
代码:
播放乐器采样更自然并允许超过音源范围
添加数学扩展模块
添加死亡事件触发器
修复:
堆积模式超级消除有时报错
词典导出词条保留了替换敏感词的特殊字符
修改准备音效后ultra倒计时声音不见了
0arr时自动移动时声音特别响
时间转换函数可能输出1分60 #451
堆积模式超级消除有时报错
0.16.4: 虫洞 Wormhole
新增:

View File

@@ -1,5 +1,5 @@
return{
["apkCode"]=398,
["apkCode"]=401,
["code"]=1605,
["string"]="V0.16.5",
["room"]="ver A-0",