diff --git a/parts/player/gameEnv0.lua b/parts/player/gameEnv0.lua index 5ecace2cf..4e03416d7 100644 --- a/parts/player/gameEnv0.lua +++ b/parts/player/gameEnv0.lua @@ -65,11 +65,11 @@ return { -- Some Events are registered in player/init.lua, see "tableNeedMerge" extraEvent={ - {'attack',4}, + {'attack',5}, }, extraEventHandler={ - attack=function(P,P2,...) - P:beAttacked(P2,...) + attack=function(P,source,...) + P:beAttacked(source,...) end, }, diff --git a/parts/player/init.lua b/parts/player/init.lua index cafd04ec2..3df3eda4b 100644 --- a/parts/player/init.lua +++ b/parts/player/init.lua @@ -250,9 +250,9 @@ local tableNeedMerge={ 'hook_spawn', 'hook_hold', 'hook_die', - 'extraEvent', + 'hook_atk_calculation', + 'task', } -for _,k in next,tableNeedMerge do gameEnv0[k]={} end local function _mergeFuncTable(f,L) if type(f)=='function' then ins(L,f) @@ -266,16 +266,14 @@ end local function _applyGameEnv(P)-- Finish gameEnv processing local ENV=P.gameEnv - -- Create event tables + -- Apply events for i=1,#tableNeedMerge do ENV[tableNeedMerge[i]]=_mergeFuncTable(ENV[tableNeedMerge[i]],{}) end -- Apply eventSet - while true do - if not (ENV.eventSet and ENV.eventSet~="X") then - break - end + repeat + if not (ENV.eventSet and ENV.eventSet~="X") then break end if type(ENV.eventSet)~='string' then MES.new('warn',"Wrong event set type: "..type(ENV.eventSet)) break @@ -286,7 +284,11 @@ local function _applyGameEnv(P)-- Finish gameEnv processing break end for k,v in next,eventSet do - if k=='extraEventHandler' then + if k=='extraEvent' then + for _,ev in ipairs(v) do + table.insert(ENV.extraEvent, ev) + end + elseif k=='extraEventHandler' then for ev,handler in next,v do if ENV.extraEventHandler[ev] then local prevHandler=ENV.extraEventHandler[ev] @@ -306,8 +308,7 @@ local function _applyGameEnv(P)-- Finish gameEnv processing ENV[k]=v end end - break - end + until true P._20G=ENV.drop==0 P.dropDelay=ENV.drop diff --git a/parts/player/player.lua b/parts/player/player.lua index aa58531af..02d18d0c4 100644 --- a/parts/player/player.lua +++ b/parts/player/player.lua @@ -909,12 +909,45 @@ function Player:ifoverlap(bk,x,y) end end function Player:attack(R,send,time,line) - self:extraEvent('attack',R.sid,send,time,line) -end -function Player:beAttacked(P2,sid,send,time,line) - if self==P2 or self.sid~=sid then return end - self:receive(P2,send,time,line) - P2:createBeam(self,send) + local sid=R.sid + -- Add the attack to the list of in-transit attacks. + -- These attacks will be able to cancel with incoming attacks that cross them. + if not self.inTransitAttacks then + self.inTransitAttacks={} + end + if not self.inTransitAttacks[sid] then + self.inTransitAttacks[sid]={seenAttacks=0} + end + table.insert(self.inTransitAttacks[sid], {send=send, time=time, line=line}) + -- Send the attack + -- We also send the number of seen attacks from this player. + -- This allows that player to know which attacks are still in transit, and which have already arrived. + -- This is because... if a player already saw an attack before sending this one, the attacks did not cross. + -- But if they didn't see the attack, then the attacks must have crossed (and should cancel each other) + self:extraEvent('attack',sid,send,time,line,self.inTransitAttacks[sid].seenAttacks) +end +function Player:beAttacked(source,target_sid,send,time,line,seenCount) + -- Only recieve the attack if you are the target. + if self==source or self.sid~=target_sid then return end + + if not self.inTransitAttacks then + self.inTransitAttacks={} + end + if not self.inTransitAttacks[source.sid] then + self.inTransitAttacks[source.sid]={seenAttacks=0} + end + -- Increment the number of seen attacks from that player. + self.inTransitAttacks[source.sid].seenAttacks=self.inTransitAttacks[source.sid].seenAttacks + 1 + -- Block against any in-transit attacks before recieving (this prevents passhtrough) + for i=seenCount+1,#self.inTransitAttacks[source.sid] do + local atk=self.inTransitAttacks[source.sid][i] + local cancel=MATH.min(atk.send, send) + atk.send=atk.send-cancel + send=send-cancel + end + + self:receive(source,send,time,line) + source:createBeam(self,send) end function Player:receive(A,send,time,line) self.lastRecv=A diff --git a/version.lua b/version.lua index 5dca7c19d..a3be5749b 100644 --- a/version.lua +++ b/version.lua @@ -2,6 +2,6 @@ return { ["apkCode"]=1722, ["code"]=1722, ["string"]="V0.17.22", - ["room"]="ver A-14", + ["room"]="ver A-15", ["name"]="暂停 Break", }