This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 8064ba84d8
commit 73479cff9e
7338 changed files with 1718883 additions and 14 deletions

View File

@@ -0,0 +1,350 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
-- traitor equipment: teleporter
AddCSLuaFile()
SWEP.HoldType = "normal"
if CLIENT then
SWEP.PrintName = "tele_name"
SWEP.Slot = 7
SWEP.ViewModelFlip = false
SWEP.ViewModelFOV = 10
SWEP.DrawCrosshair = false
SWEP.CSMuzzleFlashes = false
SWEP.EquipMenuData = {
type = "item_weapon",
desc = "tele_desc"
};
SWEP.Icon = "vgui/ttt/icon_tport"
end
SWEP.Base = "weapon_tttbase"
SWEP.ViewModel = "models/weapons/v_crowbar.mdl"
SWEP.WorldModel = "models/weapons/w_slam.mdl"
SWEP.Primary.ClipSize = 16
SWEP.Primary.DefaultClip = 16
SWEP.Primary.ClipMax = 16
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "GaussEnergy"
SWEP.Primary.Delay = 0.5
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
SWEP.Secondary.Delay = 1.0
SWEP.Kind = WEAPON_EQUIP2
SWEP.CanBuy = {ROLE_TRAITOR, ROLE_DETECTIVE}
SWEP.WeaponID = AMMO_TELEPORT
SWEP.AllowDrop = true
SWEP.NoSights = true
local delay_beamup = 1
local delay_beamdown = 1
local ttt_telefrags = CreateConVar("ttt_teleport_telefrags", "1")
function SWEP:SetTeleportMark(pos, ang)
self.teleport = {pos = pos, ang = ang}
end
function SWEP:GetTeleportMark() return self.teleport end
function SWEP:PrimaryAttack()
self:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
if self:Clip1() <= 0 then
self:DryFire(self.SetNextSecondaryFire)
return
end
-- Disallow initiating teleports during post, as it will occur across the
-- restart and allow the user an advantage during prep
if GetRoundState() == ROUND_POST then return end
if SERVER then
self:TeleportRecall()
else
surface.PlaySound("buttons/combine_button7.wav")
end
end
function SWEP:SecondaryAttack()
self:SetNextSecondaryFire( CurTime() + self.Secondary.Delay )
if SERVER then
self:TeleportStore()
else
surface.PlaySound("ui/buttonrollover.wav")
end
end
local zap = Sound("ambient/levels/labs/electric_explosion4.wav")
local unzap = Sound("ambient/levels/labs/electric_explosion2.wav")
local function Telefrag(victim, attacker, weapon)
if not IsValid(victim) then return end
local dmginfo = DamageInfo()
dmginfo:SetDamage(5000)
dmginfo:SetDamageType(DMG_SONIC)
dmginfo:SetAttacker(attacker)
dmginfo:SetInflictor(weapon)
dmginfo:SetDamageForce(Vector(0,0,10))
dmginfo:SetDamagePosition(attacker:GetPos())
victim:TakeDamageInfo(dmginfo)
end
local function ShouldCollide(ent)
local g = ent:GetCollisionGroup()
return (g != COLLISION_GROUP_WEAPON and
g != COLLISION_GROUP_DEBRIS and
g != COLLISION_GROUP_DEBRIS_TRIGGER and
g != COLLISION_GROUP_INTERACTIVE_DEBRIS)
end
-- Teleport a player to a {pos, ang}
local function TeleportPlayer(ply, teleport)
local oldpos = ply:GetPos()
local pos = teleport.pos
local ang = teleport.ang
-- print decal on destination
util.PaintDown(pos + Vector(0,0,25), "GlassBreak", ply)
-- perform teleport
ply:SetPos(pos)
ply:SetEyeAngles(ang) -- ineffective due to freeze...
timer.Simple(delay_beamdown, function ()
if IsValid(ply) then
ply:Freeze(false)
end
end)
sound.Play(zap, oldpos, 65, 100)
sound.Play(unzap, pos, 55, 100)
-- print decal on source now that we're gone, because else it will refuse
-- to draw for some reason
util.PaintDown(oldpos + Vector(0,0,25), "GlassBreak", ply)
end
-- Checks teleport destination. Returns bool and table, if bool is true then
-- location is blocked by world or prop. If table is non-nil it contains a list
-- of blocking players.
local function CanTeleportToPos(ply, pos)
-- first check if we can teleport here at all, because any solid object or
-- brush will make us stuck and therefore kills/blocks us instead, so the
-- trace checks for anything solid to players that isn't a player
local tr = nil
local tres = {start=pos, endpos=pos, mask=MASK_PLAYERSOLID, filter=player.GetAll()}
local collide = false
-- This thing is unnecessary if we can supply a collision group to trace
-- functions, like we can in source and sanity suggests we should be able
-- to do so, but I have not found a way to do so yet. Until then, re-trace
-- while extending our filter whenever we hit something we don't want to
-- hit (like weapons or ragdolls).
repeat
tr = util.TraceEntity(tres, ply)
if tr.HitWorld then
collide = true
elseif IsValid(tr.Entity) then
if ShouldCollide(tr.Entity) then
collide = true
else
table.insert(tres.filter, tr.Entity)
end
end
until (not tr.Hit) or collide
if collide then
--Telefrag(ply, ply)
return true, nil
else
-- find all players in the place where we will be and telefrag them
local blockers = ents.FindInBox(pos + Vector(-16, -16, 0),
pos + Vector(16, 16, 64))
local blocking_plys = {}
for _, block in ipairs(blockers) do
if IsValid(block) then
if block:IsPlayer() and block != ply then
if block:IsTerror() and block:Alive() then
table.insert(blocking_plys, block)
-- telefrag blocker
--Telefrag(block, ply)
end
end
end
end
return false, blocking_plys
end
return false, nil
end
local function DoTeleport(ply, teleport, weapon)
if IsValid(ply) and ply:IsTerror() and teleport then
local fail = false
local block_world, block_plys = CanTeleportToPos(ply, teleport.pos)
if block_world then
-- if blocked by prop/world, always fail
fail = true
elseif block_plys and #block_plys > 0 then
-- if blocked by player, maybe telefrag
if ttt_telefrags:GetBool() then
for _, p in ipairs(block_plys) do
Telefrag(p, ply, weapon)
end
else
fail = true
end
end
if not fail then
TeleportPlayer(ply, teleport)
else
ply:Freeze(false)
LANG.Msg(ply, "tele_failed")
end
elseif IsValid(ply) then
-- should never happen, but at least unfreeze
ply:Freeze(false)
LANG.Msg(ply, "tele_failed")
end
end
local function StartTeleport(ply, teleport, weapon)
if (not IsValid(ply)) or (not ply:IsTerror()) or (not teleport) then
return end
teleport.ang = ply:EyeAngles()
timer.Simple(delay_beamup, function() DoTeleport(ply, teleport, weapon) end)
local ang = ply:GetAngles()
local edata_up = EffectData()
edata_up:SetOrigin(ply:GetPos())
ang = Angle(0, ang.y, ang.r) -- deep copy
edata_up:SetAngles(ang)
edata_up:SetEntity(ply)
edata_up:SetMagnitude(delay_beamup)
edata_up:SetRadius(delay_beamdown)
util.Effect("teleport_beamup", edata_up)
local edata_dn = EffectData()
edata_dn:SetOrigin(teleport.pos)
ang = Angle(0, ang.y, ang.r) -- deep copy
edata_dn:SetAngles(ang)
edata_dn:SetEntity(ply)
edata_dn:SetMagnitude(delay_beamup)
edata_dn:SetRadius(delay_beamdown)
util.Effect("teleport_beamdown", edata_dn)
end
function SWEP:TeleportRecall()
local ply = self:GetOwner()
if IsValid(ply) and ply:IsTerror() then
local mark = self:GetTeleportMark()
if mark then
local g = ply:GetGroundEntity()
if g != game.GetWorld() and not IsValid(g) then
LANG.Msg(ply, "tele_no_ground")
return
end
if ply:Crouching() then
LANG.Msg(ply, "tele_no_crouch")
return
end
ply:Freeze(true)
self:TakePrimaryAmmo(1)
timer.Simple(0.2, function() StartTeleport(ply, mark, self) end)
else
LANG.Msg(ply, "tele_no_mark")
end
end
end
local function CanStoreTeleportPos(ply, pos)
local g = ply:GetGroundEntity()
if g != game.GetWorld() or (IsValid(g) and g:GetMoveType() != MOVETYPE_NONE) then
return false, "tele_no_mark_ground"
elseif ply:Crouching() then
return false, "tele_no_mark_crouch"
end
return true, nil
end
function SWEP:TeleportStore()
local ply = self:GetOwner()
if IsValid(ply) and ply:IsTerror() then
local allow, msg = CanStoreTeleportPos(ply, self:GetPos())
if not allow then
LANG.Msg(ply, msg)
return
end
self:SetTeleportMark(ply:GetPos(), ply:EyeAngles())
LANG.Msg(ply, "tele_marked")
end
end
function SWEP:Reload()
return false
end
if CLIENT then
function SWEP:Initialize()
self:AddHUDHelp("tele_help_pri", "tele_help_sec", true)
return self.BaseClass.Initialize(self)
end
end
function SWEP:Deploy()
if SERVER and IsValid(self:GetOwner()) then
self:GetOwner():DrawViewModel(false)
end
return true
end
function SWEP:ShootEffects() end