方块对象里不再存旋转中心了,直接存旋转系统

修复玩家初始化时cc的初始几块中心位置不正确导致崩溃(好像是超级远古bug,终于修了)
This commit is contained in:
MrZ626
2021-08-23 03:33:37 +08:00
parent acb29c33d3
commit 9b28cdbcd2
4 changed files with 64 additions and 50 deletions

View File

@@ -193,7 +193,7 @@ do
C.id=id C.id=id
C.bk=bk C.bk=bk
P.curX,P.curY=x,y P.curX,P.curY=x,y
P.cur.dir,P.cur.sc=dir,defaultCenterPos[id][dir] P.cur.dir=dir
P.spinLast=2 P.spinLast=2
P.stat.rotate=P.stat.rotate+1 P.stat.rotate=P.stat.rotate+1
P:freshBlock('move') P:freshBlock('move')
@@ -631,8 +631,11 @@ do
local idir=(C.dir+d)%4 local idir=(C.dir+d)%4
local kickList=list[C.id][C.dir*10+idir] local kickList=list[C.id][C.dir*10+idir]
local icb=BLOCKS[C.id][idir] local icb=BLOCKS[C.id][idir]
local isc=defaultCenterPos[C.id][idir] local ix,iy do
local ix,iy=P.curX+C.sc[2]-isc[2],P.curY+C.sc[1]-isc[1] local oldSC=C.RS.centerPos[C.id][C.dir]
local newSC=defaultCenterPos[C.id][idir]
ix,iy=P.curX+oldSC[2]-newSC[2],P.curY+oldSC[1]-newSC[1]
end
local dx,dy=0,0 do local dx,dy=0,0 do
local pressing=P.keyPressing local pressing=P.keyPressing
if pressing[1]and P:ifoverlap(C.bk,P.curX-1,P.curY)then dx=dx-1 end if pressing[1]and P:ifoverlap(C.bk,P.curX-1,P.curY)then dx=dx-1 end
@@ -653,7 +656,7 @@ do
P:createMoveFX() P:createMoveFX()
end end
P.curX,P.curY,C.dir=x,y,idir P.curX,P.curY,C.dir=x,y,idir
C.sc,C.bk=isc,icb C.bk=icb
P.spinLast=test==2 and 0 or 1 P.spinLast=test==2 and 0 or 1
local t=P.freshTime local t=P.freshTime

View File

@@ -94,8 +94,9 @@ if type(_CC)=='table'then
TABLE.cut(P.holdQueue) TABLE.cut(P.holdQueue)
P.holdTime=P.gameEnv.holdCount P.holdTime=P.gameEnv.holdCount
P.cur=rem(P.nextQueue,1) local C=rem(P.nextQueue,1)
P.curX,P.curY=blockPos[P.cur.id],int(P.gameEnv.fieldH+1-modf(P.cur.sc[1]))+ceil(P.fieldBeneath/30) P.cur=C
P.curX,P.curY=blockPos[C.id],int(P.gameEnv.fieldH+1-modf(C.centerPos[C.id][C.dir][1]))+ceil(P.fieldBeneath/30)
P.newNext() P.newNext()
local id=CCblockID[P.nextQueue[P.AIdata.next].id] local id=CCblockID[P.nextQueue[P.AIdata.next].id]

View File

@@ -303,7 +303,7 @@ local function drawBlock(CB,curX,curY,texture)
end end
local function drawNextPreview(B,fieldH,fieldBeneath) local function drawNextPreview(B,fieldH,fieldBeneath)
gc_setColor(1,1,1,.8) gc_setColor(1,1,1,.8)
local y=int(fieldH+1-modf(B.sc[1]))+ceil(fieldBeneath/30) local y=int(fieldH+1-modf(B.rs.centerPos[B.id][B.dir][1]))+ceil(fieldBeneath/30)
B=B.bk B=B.bk
local x=int(6-#B[1]*.5) local x=int(6-#B[1]*.5)
local cross=TEXTURE.puzzleMark[-1] local cross=TEXTURE.puzzleMark[-1]
@@ -763,15 +763,16 @@ function draw.norm(P,repMode)
local curColor=C.color local curColor=C.color
local trans=P.lockDelay/ENV.lock local trans=P.lockDelay/ENV.lock
local centerX=30*(P.curX+C.sc[2])-20 local centerPos=C.rs.centerPos[C.id][C.dir]
local centerX=30*(P.curX+centerPos[2])-20
--Draw ghost & rotation center --Draw ghost & rotation center
local centerDisp=ENV.center and P.RS.centerDisp[C.id] local centerDisp=ENV.center and C.rs.centerDisp[C.id]
if ENV.ghost then if ENV.ghost then
drawGhost[ENV.ghostType](P.cur.bk,P.curX,P.ghoY,ENV.ghost,P.skinLib,curColor) drawGhost[ENV.ghostType](P.cur.bk,P.curX,P.ghoY,ENV.ghost,P.skinLib,curColor)
if centerDisp then if centerDisp then
gc_setColor(1,1,1,ENV.center) gc_setColor(1,1,1,ENV.center)
gc_draw(P.RS.centerTex,centerX,-30*(P.ghoY+C.sc[1])+10) gc_draw(C.rs.centerTex,centerX,-30*(P.ghoY+centerPos[1])+10)
end end
elseif repMode then elseif repMode then
drawGhost.grayCell(P.cur.bk,P.curX,P.ghoY,.15,nil,nil) drawGhost.grayCell(P.cur.bk,P.curX,P.ghoY,.15,nil,nil)
@@ -785,7 +786,7 @@ function draw.norm(P,repMode)
drawBlock(P.cur.bk,P.curX,P.curY,P.skinLib[curColor]) drawBlock(P.cur.bk,P.curX,P.curY,P.skinLib[curColor])
if centerDisp then if centerDisp then
gc_setColor(1,1,1,ENV.center) gc_setColor(1,1,1,ENV.center)
gc_draw(P.RS.centerTex,centerX,-30*(P.curY+C.sc[1])+10) gc_draw(C.rs.centerTex,centerX,-30*(P.curY+centerPos[1])+10)
end end
elseif repMode then elseif repMode then
drawBlockShade(P.cur.bk,P.curX,P.curY,trans*.3) drawBlockShade(P.cur.bk,P.curX,P.curY,trans*.3)

View File

@@ -111,8 +111,12 @@ function Player:createClearingFX(y,spd)
end end
function Player:createBeam(R,send,power,color) function Player:createBeam(R,send,power,color)
local x1,y1,x2,y2 local x1,y1,x2,y2
if self.miniMode then x1,y1=self.centerX,self.centerY if self.miniMode then
else x1,y1=self.x+(30*(self.curX+self.cur.sc[2])-30+15+150)*self.size,self.y+(600-30*(self.curY+self.cur.sc[1])+15)*self.size x1,y1=self.centerX,self.centerY
else
local C=self.cur
local sc=C.rs.centerPos[C.id][C.dir]
x1,y1=self.x+(30*(self.curX+sc[2])-30+15+150)*self.size,self.y+(600-30*(self.curY+sc[1])+15)*self.size
end end
if R.small then x2,y2=R.centerX,R.centerY if R.small then x2,y2=R.centerX,R.centerY
else x2,y2=R.x+308*R.size,R.y+450*R.size else x2,y2=R.x+308*R.size,R.y+450*R.size
@@ -228,7 +232,13 @@ function Player:setInvisible(time)--Time in frames
end end
end end
function Player:setRS(RSname) function Player:setRS(RSname)
self.RS=RSlist[RSname]or RSlist.TRS local rs=RSlist[RSname]or RSlist.TRS
self.RS=rs
--Reset all player's blocks' RSs
for i=1,#self.nextQueue do self.nextQueue[i].rs=rs end
for i=1,#self.holdQueue do self.holdQueue[i].rs=rs end
if self.cur then self.cur.rs=rs end
end end
function Player:destroyBot() function Player:destroyBot()
if self.AI_mode=='CC'then if self.AI_mode=='CC'then
@@ -326,10 +336,12 @@ function Player:pushNextList(L,mir)--Push some nexts to nextQueue
end end
function Player:getCenterX() function Player:getCenterX()
return self.curX+self.cur.sc[2]-5.5 local C=self.cur
return self.curX+C.rs.centerPos[C.id][C.dir][2]-5.5
end end
function Player:getCenterY() function Player:getCenterY()
return self.curY-self.cur.sc[1] local C=self.cur
return self.curY-C.rs.centerPos[C.id][C.dir][1]
end end
function Player:solid(x,y) function Player:solid(x,y)
if x<1 or x>10 or y<1 then return true end if x<1 or x>10 or y<1 then return true end
@@ -498,6 +510,8 @@ function Player:freshBlock(mode)--string mode: push/move/fresh/newBlock
--Fresh delays --Fresh delays
if mode=='move'or mode=='newBlock'or mode=='fresh'then if mode=='move'or mode=='newBlock'or mode=='fresh'then
local d0,l0=ENV.drop,ENV.lock local d0,l0=ENV.drop,ENV.lock
local C=self.cur
local sc=C.rs.centerPos[C.id][C.dir]
if ENV.easyFresh then if ENV.easyFresh then
if self.lockDelay<l0 and self.freshTime>0 then if self.lockDelay<l0 and self.freshTime>0 then
if mode~='newBlock'then if mode~='newBlock'then
@@ -506,14 +520,14 @@ function Player:freshBlock(mode)--string mode: push/move/fresh/newBlock
self.lockDelay=l0 self.lockDelay=l0
self.dropDelay=d0 self.dropDelay=d0
end end
if self.curY+self.cur.sc[1]<self.minY then if self.curY+sc[1]<self.minY then
self.minY=self.curY+self.cur.sc[1] self.minY=self.curY+sc[1]
self.dropDelay=d0 self.dropDelay=d0
self.lockDelay=l0 self.lockDelay=l0
end end
else else
if self.curY+self.cur.sc[1]<self.minY then if self.curY+sc[1]<self.minY then
self.minY=self.curY+self.cur.sc[1] self.minY=self.curY+sc[1]
if self.lockDelay<l0 and self.freshTime>0 then if self.lockDelay<l0 and self.freshTime>0 then
self.freshTime=self.freshTime-1 self.freshTime=self.freshTime-1
self.dropDelay=d0 self.dropDelay=d0
@@ -628,17 +642,19 @@ end
local spawnSFX_name={}for i=1,7 do spawnSFX_name[i]='spawn_'..i end local spawnSFX_name={}for i=1,7 do spawnSFX_name[i]='spawn_'..i end
function Player:resetBlock()--Reset Block's position and execute I*S function Player:resetBlock()--Reset Block's position and execute I*S
local B=self.cur.bk local C=self.cur
self.curX=int(6-#B[1]*.5) local sc=C.rs.centerPos[C.id][C.dir]
local y=int(self.gameEnv.fieldH+1-modf(self.cur.sc[1]))+ceil(self.fieldBeneath/30)
self.curX=int(6-#C.bk[1]*.5)
local y=int(self.gameEnv.fieldH+1-modf(sc[1]))+ceil(self.fieldBeneath/30)
self.curY=y self.curY=y
self.minY=y+self.cur.sc[1] self.minY=y+sc[1]
local pressing=self.keyPressing local pressing=self.keyPressing
--IMS --IMS
if self.gameEnv.ims and(pressing[1]and self.movDir==-1 or pressing[2]and self.movDir==1)and self.moving>=self.gameEnv.das then if self.gameEnv.ims and(pressing[1]and self.movDir==-1 or pressing[2]and self.movDir==1)and self.moving>=self.gameEnv.das then
local x=self.curX+self.movDir local x=self.curX+self.movDir
if not self:ifoverlap(B,x,y)then if not self:ifoverlap(C.bk,x,y)then
self.curX=x self.curX=x
end end
end end
@@ -665,25 +681,26 @@ function Player:resetBlock()--Reset Block's position and execute I*S
end end
--Spawn SFX --Spawn SFX
if self.sound and self.cur.id<8 then if self.sound and C.id<8 then
SFX.fplay(spawnSFX_name[self.cur.id],SETTING.sfx_spawn) SFX.fplay(spawnSFX_name[C.id],SETTING.sfx_spawn)
end end
end end
function Player:spin(d,ifpre) function Player:spin(d,ifpre)
local cur=self.cur local C=self.cur
local kickData=self.RS.kickTable[cur.id] local sc=C.rs.centerPos[C.id][C.dir]
local kickData=C.rs.kickTable[C.id]
if type(kickData)=='table'then if type(kickData)=='table'then
local idir=(cur.dir+d)%4 local idir=(C.dir+d)%4
kickData=kickData[cur.dir*10+idir] kickData=kickData[C.dir*10+idir]
if not kickData then if not kickData then
self:freshBlock('move') self:freshBlock('move')
SFX.play(ifpre and'prerotate'or'rotate',nil,self:getCenterX()*.15) SFX.play(ifpre and'prerotate'or'rotate',nil,self:getCenterX()*.15)
return return
end end
local icb=BLOCKS[cur.id][idir] local icb=BLOCKS[C.id][idir]
local isc=self.RS.centerPos[cur.id][idir] local isc=C.rs.centerPos[C.id][idir]
local baseX,baseY=self.curX+cur.sc[2]-isc[2],self.curY+cur.sc[1]-isc[1] local baseX,baseY=self.curX+sc[2]-isc[2],self.curY+sc[1]-isc[1]
for test=1,#kickData do for test=1,#kickData do
local ix,iy=baseX+kickData[test][1],baseY+kickData[test][2] local ix,iy=baseX+kickData[test][1],baseY+kickData[test][2]
if (self.freshTime>0 or kickData[test][2]<=0)and not self:ifoverlap(icb,ix,iy)then if (self.freshTime>0 or kickData[test][2]<=0)and not self:ifoverlap(icb,ix,iy)then
@@ -691,7 +708,7 @@ function Player:spin(d,ifpre)
if self.gameEnv.moveFX and self.gameEnv.block then self:createMoveFX()end if self.gameEnv.moveFX and self.gameEnv.block then self:createMoveFX()end
--Change block position --Change block position
cur.sc,cur.bk,cur.dir=isc,icb,idir sc,C.bk,C.dir=isc,icb,idir
self.curX,self.curY=ix,iy self.curX,self.curY=ix,iy
self.spinLast=test==2 and 0 or 1 self.spinLast=test==2 and 0 or 1
@@ -828,29 +845,20 @@ function Player:hold(ifpre)
end end
end end
function Player:getBlock(id,name,color)--Get a block(id=n) object function Player:getBlock(id,name,color)--Get a block object
local E=self.gameEnv local E=self.gameEnv
local dir=E.face[id] local dir=E.face[id]
return{ return{
id=id, id=id,
dir=dir, dir=dir,
bk=BLOCKS[id][dir], bk=BLOCKS[id][dir],
sc=self.RS.centerPos[id][dir], rs=self.RS,
name=name or id, name=name or id,
color=E.bone and 17 or color or E.skin[id], color=E.bone and 17 or color or E.skin[id],
} }
end end
function Player:getNext(n)--Push a block(id=n) to nextQueue function Player:getNext(id)--Push a block to nextQueue
local E=self.gameEnv ins(self.nextQueue,self:getBlock(id))
local dir=E.face[n]
ins(self.nextQueue,{
id=n,
bk=BLOCKS[n][dir],
sc=self.RS.centerPos[n][dir],
dir=dir,
name=n,
color=E.bone and 17 or E.skin[n],
})
end end
function Player:popNext(ifhold)--Pop nextQueue to hand function Player:popNext(ifhold)--Pop nextQueue to hand
if not ifhold then if not ifhold then
@@ -1058,6 +1066,7 @@ do--Player.drop(self)--Place piece
local finish local finish
local cmb=self.combo local cmb=self.combo
local C,CB,CX,CY=self.cur,self.cur.bk,self.curX,self.curY local C,CB,CX,CY=self.cur,self.cur.bk,self.curX,self.curY
local sc=C.rs.centerPos[C.id][C.dir]
local clear--If clear with no line fall local clear--If clear with no line fall
local cc,gbcc=0,0--Row/garbage-row cleared,full-part local cc,gbcc=0,0--Row/garbage-row cleared,full-part
local atk,exblock=0,0--Attack & extra defense local atk,exblock=0,0--Attack & extra defense
@@ -1067,14 +1076,14 @@ do--Player.drop(self)--Place piece
piece.id,piece.name=C.id,C.name piece.id,piece.name=C.id,C.name
piece.curX,piece.curY,piece.dir=self.curX,self.curY,C.dir piece.curX,piece.curY,piece.dir=self.curX,self.curY,C.dir
piece.centX,piece.centY=self.curX+C.sc[2],self.curY+C.sc[1] piece.centX,piece.centY=self.curX+sc[2],self.curY+sc[1]
piece.frame,piece.autoLock=self.frameRun,autoLock piece.frame,piece.autoLock=self.frameRun,autoLock
self.waiting=ENV.wait self.waiting=ENV.wait
--Tri-corner spin check --Tri-corner spin check
if self.spinLast then if self.spinLast then
if C.id<6 then if C.id<6 then
local x,y=CX+C.sc[2],CY+C.sc[1] local x,y=CX+sc[2],CY+sc[1]
local c=0 local c=0
if self:solid(x-1,y+1)then c=c+1 end if self:solid(x-1,y+1)then c=c+1 end
if self:solid(x+1,y+1)then c=c+1 end if self:solid(x+1,y+1)then c=c+1 end