重构玩家交互事件系统,尝试支持可通过网络传递的自定义事件
This commit is contained in:
@@ -570,6 +570,16 @@ function applyCustomGame()-- Apply CUSTOMENV, BAG, MISSION
|
|||||||
GAME.modeEnv.mission=nil
|
GAME.modeEnv.mission=nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
local defaultAttackRule={
|
||||||
|
extraEvent={
|
||||||
|
{'attack',4},
|
||||||
|
},
|
||||||
|
extraEventHandler={
|
||||||
|
attack=function(P,P2,...)
|
||||||
|
P:beAttacked(P2,...)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
function loadGame(mode,ifQuickPlay,ifNet)-- Load a mode and go to game scene
|
function loadGame(mode,ifQuickPlay,ifNet)-- Load a mode and go to game scene
|
||||||
freshDate()
|
freshDate()
|
||||||
if legalGameTime() then
|
if legalGameTime() then
|
||||||
@@ -577,6 +587,7 @@ function loadGame(mode,ifQuickPlay,ifNet)-- Load a mode and go to game scene
|
|||||||
MODES[mode]=require('parts.modes.'..mode)
|
MODES[mode]=require('parts.modes.'..mode)
|
||||||
MODES[mode].name=mode
|
MODES[mode].name=mode
|
||||||
end
|
end
|
||||||
|
TABLE.complete(defaultAttackRule,MODES[mode])
|
||||||
if MODES[mode].score then
|
if MODES[mode].score then
|
||||||
STAT.lastPlay=mode
|
STAT.lastPlay=mode
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -701,6 +701,37 @@ function Player:_triggerEvent(eventName)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
function Player:extraEvent(eventName,...)
|
||||||
|
if not (GAME.curMode.extraEvent and GAME.curMode.extraEventHandler) then return end
|
||||||
|
local list=GAME.curMode.extraEvent
|
||||||
|
local eventID
|
||||||
|
for i=1,#list do
|
||||||
|
if list[i][1]==eventName then
|
||||||
|
eventID=i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not eventID then
|
||||||
|
MES.new('warn',"Extra event '"..eventName.."' doesn't exist in this mode")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Write to stream
|
||||||
|
if self.type=='human' then
|
||||||
|
ins(GAME.rep,self.frameRun)
|
||||||
|
ins(GAME.rep,eventID)
|
||||||
|
local data={...}
|
||||||
|
for i=1,#data do
|
||||||
|
ins(GAME.rep,data[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Trigger for everyone
|
||||||
|
for i=1,#PLAYERS do
|
||||||
|
local R=PLAYERS[i]
|
||||||
|
GAME.curMode.extraEventHandler[eventName](R,self,...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Player:getHolePos()-- Get a good garbage-line hole position
|
function Player:getHolePos()-- Get a good garbage-line hole position
|
||||||
if self.garbageBeneath==0 then
|
if self.garbageBeneath==0 then
|
||||||
@@ -833,34 +864,13 @@ function Player:ifoverlap(bk,x,y)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function Player:attack(R,send,time,line,fromStream)
|
function Player:attack(R,send,time,line)
|
||||||
if GAME.net then
|
self:extraEvent('attack',R.sid,send,time,line)
|
||||||
if self.type=='human' then-- Local player attack others
|
end
|
||||||
ins(GAME.rep,self.frameRun)
|
function Player:beAttacked(P2,sid,send,time,line)
|
||||||
ins(GAME.rep,
|
if self==P2 or self.sid~=sid then return end
|
||||||
R.sid+
|
self:receive(P2,send,time,line)
|
||||||
send*0x100+
|
P2:createBeam(self,send)
|
||||||
time*0x10000+
|
|
||||||
line*0x100000000+
|
|
||||||
0x2000000000000
|
|
||||||
)
|
|
||||||
self:createBeam(R,send)
|
|
||||||
end
|
|
||||||
if fromStream and R.type=='human' then-- Local player receiving lines
|
|
||||||
ins(GAME.rep,R.frameRun)
|
|
||||||
ins(GAME.rep,
|
|
||||||
self.sid+
|
|
||||||
send*0x100+
|
|
||||||
time*0x10000+
|
|
||||||
line*0x100000000+
|
|
||||||
0x1000000000000
|
|
||||||
)
|
|
||||||
R:receive(self,send,time,line)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
R:receive(self,send,time,line)
|
|
||||||
self:createBeam(R,send)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
function Player:receive(A,send,time,line)
|
function Player:receive(A,send,time,line)
|
||||||
self.lastRecv=A
|
self.lastRecv=A
|
||||||
@@ -2708,38 +2718,15 @@ local function update_streaming(P)
|
|||||||
P:pressKey(event)
|
P:pressKey(event)
|
||||||
elseif event<=64 then-- Release key
|
elseif event<=64 then-- Release key
|
||||||
P:releaseKey(event-32)
|
P:releaseKey(event-32)
|
||||||
elseif event>0x2000000000000 then-- Sending lines
|
elseif event<=128 then-- Custom Event
|
||||||
local sid=event%0x100
|
local eventName=P.gameEnv.extraEvent[event-64][1]
|
||||||
local amount=floor(event/0x100)%0x100
|
local eventParamCount=P.gameEnv.extraEvent[event-64][2]
|
||||||
local time=floor(event/0x10000)%0x10000
|
local paramList={}
|
||||||
local line=floor(event/0x100000000)%0x10000
|
for i=1,eventParamCount do
|
||||||
for _,p in next,PLY_ALIVE do
|
ins(paramList,P.stream[P.streamProgress+1+i])
|
||||||
if p.sid==sid then
|
|
||||||
P.netAtk=P.netAtk+amount
|
|
||||||
if P.netAtk~=P.stat.send then-- He cheated or just desynchronized to death
|
|
||||||
MES.new('warn',"#"..P.uid.." desynchronized")
|
|
||||||
NET.player_finish({reason='desync'})
|
|
||||||
P:lose(true)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
P:attack(p,amount,time,line,true)
|
|
||||||
P:createBeam(p,amount)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif event>0x1000000000000 then-- Receiving lines
|
|
||||||
local sid=event%0x100
|
|
||||||
for _,p in next,PLY_ALIVE do
|
|
||||||
if p.sid==sid then
|
|
||||||
P:receive(
|
|
||||||
p,
|
|
||||||
floor(event/0x100)%0x100,-- amount
|
|
||||||
floor(event/0x10000)%0x10000,-- time
|
|
||||||
floor(event/0x100000000)%0x10000-- line
|
|
||||||
)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
P.streamProgress=P.streamProgress+eventParamCount
|
||||||
|
P:extraEvent(eventName,unpack(paramList))
|
||||||
end
|
end
|
||||||
P.streamProgress=P.streamProgress+2
|
P.streamProgress=P.streamProgress+2
|
||||||
eventTime=P.stream[P.streamProgress]
|
eventTime=P.stream[P.streamProgress]
|
||||||
|
|||||||
Reference in New Issue
Block a user