--[[ | 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/ --]] AddCSLuaFile() DEFINE_BASECLASS "weapon_tttbase" SWEP.HoldType = "physgun" if CLIENT then SWEP.PrintName = "newton_name" SWEP.Slot = 7 SWEP.ViewModelFlip = false SWEP.ViewModelFOV = 54 SWEP.EquipMenuData = { type = "item_weapon", desc = "newton_desc" }; SWEP.Icon = "vgui/ttt/icon_launch" end SWEP.Base = "weapon_tttbase" SWEP.Primary.Ammo = "none" SWEP.Primary.ClipSize = -1 SWEP.Primary.DefaultClip = -1 SWEP.Primary.Automatic = true SWEP.Primary.Delay = 3 SWEP.Primary.Cone = 0.005 SWEP.Primary.Sound = Sound( "weapons/ar2/fire1.wav" ) SWEP.Primary.SoundLevel = 54 SWEP.Secondary.ClipSize = -1 SWEP.Secondary.DefaultClip = -1 SWEP.Secondary.Automatic = false SWEP.Secondary.Ammo = "none" SWEP.Secondary.Delay = 0.5 SWEP.NoSights = true SWEP.Kind = WEAPON_EQUIP2 SWEP.CanBuy = {ROLE_TRAITOR} SWEP.WeaponID = AMMO_PUSH SWEP.UseHands = true SWEP.ViewModel = "models/weapons/c_superphyscannon.mdl" SWEP.WorldModel = "models/weapons/w_physics.mdl" AccessorFuncDT(SWEP, "charge", "Charge") SWEP.IsCharging = false SWEP.NextCharge = 0 local CHARGE_AMOUNT = 0.02 local CHARGE_DELAY = 0.025 local math = math function SWEP:Initialize() if SERVER then self:SetSkin(1) end return self.BaseClass.Initialize(self) end function SWEP:SetupDataTables() self:DTVar("Float", 0, "charge") end function SWEP:PrimaryAttack() if self.IsCharging then return end self:SetNextPrimaryFire( CurTime() + self.Primary.Delay ) self:SetNextSecondaryFire( CurTime() + self.Primary.Delay ) self:FirePulse(600, 300) end function SWEP:SecondaryAttack() if self.IsCharging then return end self:SetNextPrimaryFire( CurTime() + self.Primary.Delay ) self:SetNextSecondaryFire( CurTime() + self.Primary.Delay ) self.IsCharging = true end function SWEP:FirePulse(force_fwd, force_up) if not IsValid(self:GetOwner()) then return end self:GetOwner():SetAnimation( PLAYER_ATTACK1 ) sound.Play(self.Primary.Sound, self:GetPos(), self.Primary.SoundLevel) self:SendWeaponAnim(ACT_VM_IDLE) local cone = self.Primary.Cone or 0.1 local num = 6 local bullet = {} bullet.Num = num bullet.Src = self:GetOwner():GetShootPos() bullet.Dir = self:GetOwner():GetAimVector() bullet.Spread = Vector( cone, cone, 0 ) bullet.Tracer = 1 bullet.Force = force_fwd / 10 bullet.Damage = 1 bullet.TracerName = "AirboatGunHeavyTracer" local owner = self:GetOwner() local fwd = force_fwd / num local up = force_up / num bullet.Callback = function(att, tr, dmginfo) local ply = tr.Entity if SERVER and IsValid(ply) and ply:IsPlayer() and (not ply:IsFrozen()) then local pushvel = tr.Normal * fwd pushvel.z = math.max(pushvel.z, up) ply:SetGroundEntity(nil) ply:SetLocalVelocity(ply:GetVelocity() + pushvel) ply.was_pushed = {att=owner, t=CurTime(), wep=self:GetClass()} end end self:GetOwner():FireBullets( bullet ) end local CHARGE_FORCE_FWD_MIN = 300 local CHARGE_FORCE_FWD_MAX = 700 local CHARGE_FORCE_UP_MIN = 100 local CHARGE_FORCE_UP_MAX = 350 function SWEP:ChargedAttack() local charge = math.Clamp(self:GetCharge(), 0, 1) self.IsCharging = false self:SetCharge(0) if charge <= 0 then return end local max = CHARGE_FORCE_FWD_MAX local diff = max - CHARGE_FORCE_FWD_MIN local force_fwd = ((charge * diff) - diff) + max max = CHARGE_FORCE_UP_MAX diff = max - CHARGE_FORCE_UP_MIN local force_up = ((charge * diff) - diff) + max self:SetNextPrimaryFire( CurTime() + self.Primary.Delay ) self:SetNextSecondaryFire( CurTime() + self.Primary.Delay ) self:FirePulse(force_fwd, force_up) end function SWEP:PreDrop(death_drop) -- allow dropping for now, see if it helps against heisenbug on owner death -- if death_drop then self.IsCharging = false self:SetCharge(0) -- elseif self.IsCharging then -- self:ChargedAttack() -- end end function SWEP:OnRemove() self.IsCharging = false self:SetCharge(0) end function SWEP:Deploy() self.IsCharging = false self:SetCharge(0) return true end function SWEP:Holster() return not self.IsCharging end function SWEP:Think() BaseClass.Think(self) if self.IsCharging and IsValid(self:GetOwner()) and self:GetOwner():IsTerror() then -- on client this is prediction if not self:GetOwner():KeyDown(IN_ATTACK2) then self:ChargedAttack() return true end if SERVER and self:GetCharge() < 1 and self.NextCharge < CurTime() then self:SetCharge(math.min(1, self:GetCharge() + CHARGE_AMOUNT)) self.NextCharge = CurTime() + CHARGE_DELAY end end end if CLIENT then local surface = surface function SWEP:DrawHUD() local x = ScrW() / 2.0 local y = ScrH() / 2.0 local nxt = self:GetNextPrimaryFire() local charge = self.dt.charge if LocalPlayer():IsTraitor() then surface.SetDrawColor(255, 0, 0, 255) else surface.SetDrawColor(0, 255, 0, 255) end if nxt < CurTime() or CurTime() % 0.5 < 0.2 or charge > 0 then local length = 10 local gap = 5 surface.DrawLine( x - length, y, x - gap, y ) surface.DrawLine( x + length, y, x + gap, y ) surface.DrawLine( x, y - length, x, y - gap ) surface.DrawLine( x, y + length, x, y + gap ) end if nxt > CurTime() and charge == 0 then local w = 40 w = (w * ( math.max(0, nxt - CurTime()) / self.Primary.Delay )) / 2 local bx = x + 30 surface.DrawLine(bx, y - w, bx, y + w) bx = x - 30 surface.DrawLine(bx, y - w, bx, y + w) end if charge > 0 then y = y + (y / 3) local w, h = 100, 20 surface.DrawOutlinedRect(x - w/2, y - h, w, h) if LocalPlayer():IsTraitor() then surface.SetDrawColor(255, 0, 0, 155) else surface.SetDrawColor(0, 255, 0, 155) end surface.DrawRect(x - w/2, y - h, w * charge, h) surface.SetFont("TabLarge") surface.SetTextColor(255, 255, 255, 180) surface.SetTextPos( (x - w / 2) + 3, y - h - 15) surface.DrawText("FORCE") end end end