--Made by Prisima --Ported by Sylve local function P_CollidedNoZ(mobj1, mobj2) --Collision, not taking Z into account if not mobj1 or not mobj2 then return end if (mobj1 == mobj2) then return end local blockdist = mobj1.radius + mobj2.radius if (abs(mobj1.x - mobj2.x) >= blockdist) or (abs(mobj1.y - mobj2.y) >= blockdist) return false -- didn't hit it end --This is Z stuff --if (mobj2.z > mobj1.z + mobj1.height) -- return false -- overhead --end --if (mobj2.z + mobj2.height < mobj1.z) -- return false -- underneath --end return true end local function P_DoMultiCarry(s, t, dist) if not (s or t) then return end if P_AproxDistance(s.mo.x-t.mo.x, s.mo.y-t.mo.y) > dist --X, Y distance check return end if t.mo.state == S_PLAY_RIDE and s.jumptimer <= 0 --Jumptimer prevents players from instantly latching on after an event such as: jumping, spinning, or getting hurt and ((P_MobjFlip(s.mo) == 1 and not ( (t.mo.z > s.mo.z + s.mo.height + (s.mo.height/3)) or (t.mo.z < s.mo.z + ((s.mo.height/3)*2)) )) or (P_MobjFlip(s.mo) == -1 and not ( (t.mo.z < s.mo.z - s.mo.height - (s.mo.height/3)) or (t.mo.z > s.mo.z - ((s.mo.height/3)*2)) ))) and ((t.iscarrying == nil) or (t.iscarrying == s)) if t.mo.tracer and t.mo.tracer.player t.rootplayer = t.mo.tracer.player --If your tracer is a player and you are in a carrying state, that other player is your carrier end if s.mo.tracer and s.grabbingon s.mo.tracer = nil --This breaks the interference with the original Tails pickup end if s.grabbingon == nil -- If you aren't grabbing on anyone yet S_StartSound(s.mo, sfx_s3k4a) -- Start the "clink" sound s.grabbingon = t -- You are now set to grab on "T" t.iscarrying = s if t.rootplayer t.rootplayer.carriedplayers = $1+1 t.rootplayer.camchange = true end end if t.rootplayer --rootplayer is the original Tails that's carrying everyone s.rootplayer = t.rootplayer --your root is my root end --S movement P_ResetPlayer(s) s.grabbingon = t P_TryMove(s.mo, t.mo.x, t.mo.y) s.mo.momx = t.mo.momx s.mo.momy = t.mo.momy s.mo.momz = t.mo.momz --s.pflags = $1|PF_CARRIED s.mo.state = S_PLAY_RIDE if (P_MobjFlip(s.mo) == 1) P_MoveOrigin(s.mo, s.mo.x, s.mo.y, t.mo.z-(P_GetPlayerHeight(s)-(P_GetPlayerHeight(s)*10/48))) else P_MoveOrigin(s.mo, s.mo.x, s.mo.y, t.mo.z+(P_GetPlayerHeight(s)-(P_GetPlayerHeight(s)*10/48))) end --Abandon Ship! if (s.cmd.buttons & BT_JUMP) s.jumptimer = 15 P_DoJump(s, true) s.grabbingon = nil t.iscarrying = nil if t.rootplayer t.rootplayer.carriedplayers = $1-1 t.rootplayer.camchange = true s.jumptimer = 15 end end if (s.cmd.buttons & BT_SPIN) s.jumptimer = 10 s.mo.state = S_PLAY_ROLL s.pflags = $1|PF_SPINNING s.grabbingon = nil t.iscarrying = nil if t.rootplayer t.rootplayer.carriedplayers = $1-1 t.rootplayer.camchange = true end end end end addHook("PlayerSpawn", function(player) player.carriedplayers = 0 player.jumptimer = 1 end) addHook("ThinkFrame", do for player in players.iterate if player and player.mo and player.valid if not (player and player.mo and player.mo.valid) then return end if not player.initiated player.carriedplayers = 0 player.mocamera = 1 player.jumptimer = 1 player.camchange = false player.initiated = true end if player.camchange == true and player.mocamera == 1 if player.carriedplayers >= 1 COM_BufInsertText(player, "cam_dist "..(((player.carriedplayers+1)*42)+128)) --This changes the player's camera to fit the carried players COM_BufInsertText(player, "cam_height "..(20-((player.carriedplayers+1)*8))) else COM_BufInsertText(player, "cam_dist "..((player.carriedplayers*42)+128)) COM_BufInsertText(player, "cam_height "..(20-((player.carriedplayers)*8))) end player.camchange = false end if (player.mo.state == S_PLAY_RIDE) and player.mo.tracer and player.mo.tracer.player and player.mo.tracer.player.mocamera and (player.mo.tracer.player.mocamera == 1) and player.iscarrying == nil COM_BufInsertText(player.mo.tracer.player, "cam_dist 170") --This changes the player's camera to fit only ME! (Since I'm the only player.) COM_BufInsertText(player.mo.tracer.player, "cam_height 20") end if player.jumptimer > 0 player.jumptimer = $1-1 --It depletes every tic end if P_IsObjectOnGround(player.mo) player.carriedplayers = 0 --You can't carry players when you're on the ground! player.camchange = true --Update the player's camera player.iscarrying = nil --You can't carry players when you're on the ground! end if player.grabbingon --Check to see if multicarry is valid. if P_CollidedNoZ(player.mo, player.grabbingon.mo) == false or ((P_MobjFlip(player.mo) == 1 and ( (player.grabbingon.mo.z > player.mo.z + player.mo.height + (player.mo.height/3)) or (player.grabbingon.mo.z < player.mo.z + ((player.mo.height/3)*2)) )) or (P_MobjFlip(player.mo) == -1 and ( (player.grabbingon.mo.z < player.mo.z - player.mo.height - (player.mo.height/3)) or (player.grabbingon.mo.z > player.mo.z - ((player.mo.height/3)*2)) ))) if player.rootplayer player.rootplayer.carriedplayers = $1-1 --Minus one player that the root Tails is carrying. player.rootplayer.camchange = true player.rootplayer = nil end player.grabbed = nil player.grabbingon.iscarrying = nil player.grabbingon = nil end if not (player.mo.state == S_PLAY_RIDE) and player.grabbingon player.grabbingon.iscarrying = nil player.grabbingon = nil --If you aren't in a carrying state, there's no reason you should be grabbing on anybody. if player.rootplayer player.rootplayer.carriedplayers = $1-1 --Minus one player that the root Tails is carrying. player.rootplayer.camchange = true player.rootplayer = nil player.grabbed = nil end end end if player.grabbed != nil if ((P_MobjFlip(player.mo) == 1 and ( (player.grabbed.mo.z > player.mo.z + player.mo.height + (player.mo.height/3)) or (player.grabbed.mo.z < player.mo.z + ((player.mo.height/3)*2)) )) or (P_MobjFlip(player.mo) == -1 and ( (player.grabbed.mo.z < player.mo.z - player.mo.height - (player.mo.height/3)) or (player.grabbed.mo.z > player.mo.z - ((player.mo.height/3)*2)) )) or (P_CollidedNoZ(player.mo, player.grabbed.mo) == false)) player.grabbed = nil else P_DoMultiCarry(player, player.grabbed, 35*FRACUNIT) end end end end end) -- Main collision hook addHook("MobjMoveCollide", function(collider, mobj) if (collider and mobj) and collider.player and mobj.player and collider.player.mo and mobj.player.mo and collider.player.mo.valid and mobj.player.mo.valid local s = collider.player local t = mobj.player if P_CollidedNoZ(s.mo, t.mo) and ((P_MobjFlip(s.mo) == 1 and not ( (t.mo.z > s.mo.z + s.mo.height + (s.mo.height/3)) or (t.mo.z < s.mo.z + ((s.mo.height/3)*2)) )) or (P_MobjFlip(s.mo) == -1 and not ( (t.mo.z < s.mo.z - s.mo.height - (s.mo.height/3)) or (t.mo.z > s.mo.z - ((s.mo.height/3)*2)) ))) collider.player.grabbed = mobj.player --Player.grabbed is a variable that is mainly set here to determine collision end end end, MT_PLAYER) -- Get off of that carried player if you are damaged addHook("MobjDamage", function(target) if target.player and target.player.mo and target.player.mo.valid local player = target.player player.jumptimer = 5 if player.grabbingon and player.rootplayer player.rootplayer.carriedplayers = $1-1 player.rootplayer.camchange = true player.grabbingon.iscarrying = nil end end end, MT_PLAYER) -- Enhanced camera COM_AddCommand("mc_cam", function(p, val) if not p.mo CONS_Printf(p, "MC_CAM: You can't use this right now.") return end if not val CONS_Printf(p, "MC_CAM : Enable/disable the multi-carry enhanced camera.") if p.mocamera if p.mocamera == 1 CONS_Printf(p, "Current mode is: On") elseif p.mocamera == 0 CONS_Printf(p, "Current mode is: Off") end end return end if val == "on" p.mocamera = 1 elseif val == "off" p.mocamera = 0 else CONS_Printf(p, "MC_CAM: Invalid argument. Supported arguments are \"On\" and \"Off\".") end end)