diff --git a/addons/llb_ball/lua/entities/llb_baseball.lua b/addons/llb_ball/lua/entities/llb_baseball.lua deleted file mode 100644 index de41b3e..0000000 --- a/addons/llb_ball/lua/entities/llb_baseball.lua +++ /dev/null @@ -1,263 +0,0 @@ -AddCSLuaFile() - -DEFINE_BASECLASS("base_anim") - -ENT.PrintName = "Lethal League Baseball" -ENT.Author = "Lua coding: Chev\nBaseball model: Team Reptile" -ENT.Purpose = "The baseball from LL/LLB. Hit it to make it go faster!" -ENT.Category = "Lethal League" - -ENT.AutomaticFrameAdvance = true -ENT.Editable = true -ENT.Spawnable = true -ENT.AdminOnly = false -ENT.RenderGroup = RENDERGROUP_OPAQUE - -ENT.BallSize = 18 -ENT.ServingPitch = false - -ENT.BounceSound = Sound("llb/wall_bounce.ogg") -ENT.HitSound = Sound("llb/medium_hit.ogg") -ENT.StrongHitSound = Sound("llb/strong_hit.ogg") -ENT.KnockoutSound = Sound("llb/knockout.ogg") - -ENT.BallOwner = nil - -function ENT:SetupDataTables() - self:NetworkVar("Bool", 0, "LockXAxis", {KeyName = "lockx", Edit = {type="Boolean", order=1}}) - self:NetworkVar("Bool", 1, "LockYAxis", {KeyName = "locky", Edit = {type="Boolean", order=2}}) - self:NetworkVar("Bool", 2, "LockZAxis", {KeyName = "lockz", Edit = {type="Boolean", order=3}}) - self:NetworkVar("Bool", 3, "DamagePlayers", {KeyName = "dmgply", Edit = {type="Boolean", order=4}}) -end - -function ENT:SpawnFunction(ply, tr, ClassName) - if (!tr.Hit) then return end - - local ent = ents.Create(ClassName) - ent:SetPos(tr.HitPos + tr.HitNormal * self.BallSize * 2) - ent:Spawn() - ent:Activate() - - local phys = ent:GetPhysicsObject() - phys:SetVelocity(Vector(0, 0, 0)) - phys:SetAngles(Angle(0, 0, 0)) - phys:AddAngleVelocity(Vector(256, 0, 0)) - - return ent -end - -function ENT:Think() - if CLIENT then return end - local phys = self:GetPhysicsObject() - local vel = self:GetVelocity() - if !IsValid(phys) then return end - - vel.x = self:GetLockXAxis() and 0 or vel.x - vel.y = self:GetLockYAxis() and 0 or vel.y - vel.z = self:GetLockZAxis() and 0 or vel.z - - phys:SetVelocity(Vector(vel.x, vel.y, vel.z)) - self:NextThink(CurTime()) - return true -end - -function ENT:Initialize() - if CLIENT then - //local matname = "LLBBaseball_"..math.Round(SysTime(), 2) * 100 - local matname = "LLBBaseball_"..self:EntIndex() - - self.BallMaterial = CreateMaterial(matname, "VertexLitGeneric", { - ["$basetexture"] = "models/llb/baseball/baseball", - ["$surfaceprop"] = "Rubber", - - ["$selfillumtint"] = "[0 1 0]", - ["$selfillum"] = "1", - ["$selfillummask"] = "models/llb/baseball/baseball_i", - - ["$phong"] = "1", - ["$phongboost"] = "0.2", - ["$phongexponent"] = "5", - ["$phongfresnelranges"] = "[0.2 0.8 0.1]", - ["$lightwarptexture"] = "models/llb/baseball/lightwarp", - ["$nocull"] = "1", - - ["$rimlight"] = "1", - ["$rimlightexponent"] = "5", - ["$rimlightboost"] = "3", - - ["$blendtintbybasealpha"] = "0", - ["$blendtintcoloroverbase"] = "0", - - ["$model"] = "1" - }) - self:SetMaterial("!"..matname) - - self.BallMaterial:SetVector("$selfillumtint", Vector(1, 0, 0)) - end - - hook.Add("RenderScreenspaceEffects", "LLBInvertColorsHit", function() - if self.IsInverted then - DrawColorModify({ - ["$pp_colour_brightness"] = 0, - ["$pp_colour_contrast"] = 1, - ["$pp_colour_colour"] = -1, - ["$pp_colour_addr"] = 0.04 - }) - end - end) - - if CLIENT then return end - self:SetModel("models/llb/baseball.mdl") - self:SetModelScale(0.55) - self:SetCollisionGroup(COLLISION_GROUP_PASSABLE_DOOR) - self:PhysicsInit(SOLID_VPHYSICS) - self:SetMoveType(MOVETYPE_VPHYSICS) - self:SetSolid(SOLID_VPHYSICS) - self:SetTrigger(true) - self.ServingPitch = true - - local size = self.BallSize / 2.1 - self:PhysicsInitSphere(size, "metal_bouncy") - self:SetCollisionBounds(Vector(-size, -size, -size), Vector(size, size, size)) - - self.BallTrail = util.SpriteTrail(self, 0, Color(255, 0, 0), false, 17, 17, 0.03, 1/17, "effects/beam_generic01") - - local phys = self:GetPhysicsObject() - if phys:IsValid() then - phys:Wake() - phys:EnableGravity(false) - end - - hook.Add("KeyPress", "LLBCheckPlayerHitBall", function(ply, key) - if !IsValid(ply) or !IsValid(self) or !IsFirstTimePredicted then return end - if key == IN_ATTACK and ply:GetPos():Distance(self:GetPos()) < 120 then --player will hit the ball if they're within 120 hammer units - local dmginfo = DamageInfo() - dmginfo:SetAttacker(ply) - self:OnTakeDamage(dmginfo) - end - end) - - util.AddNetworkString("LLBDrawInvertedColors") - util.AddNetworkString("LLBChangeBallColor") -end - -net.Receive("LLBDrawInvertedColors", function() - local ent = net.ReadEntity() - local time = net.ReadFloat() - if !ent:IsDormant() then - ent.IsInverted = true - RunConsoleCommand("pp_texturize", "pp/texturize/invert.png") - timer.Simple(time, function() - ent.IsInverted = false - RunConsoleCommand("pp_texturize", "") - end) - end -end) - -net.Receive("LLBChangeBallColor", function() - local ent = net.ReadEntity() - local entowner = net.ReadEntity() - ent.BallOwner = entowner - ent.BallMaterial:SetVector("$selfillumtint", ent.BallOwner:GetPlayerColor()) -end) - -function ENT:OnRemove() - if SERVER then - hook.Remove("KeyPress", "LLBCheckPlayerHitBall") - else - hook.Remove("RenderScreenspaceEffects", "LLBInvertColorsHit") - end -end - -function ENT:PhysicsCollide(data, physobj) - -- Play sound on bounce - if data.DeltaTime > 0.02 then - sound.Play(self.BounceSound, self:GetPos(), 80, 100, 1) - end -end - -function ENT:StartTouch(ent) - local speed = self:GetVelocity():Length() ^ 0.8 - if ent:IsPlayer() and self.BallOwner != ent and speed > 16 then --damage a player if they touch the ball - if !self:GetDamagePlayers() then return end - local dmginf = DamageInfo() - dmginf:SetDamage(speed/8) - dmginf:SetDamageType(DMG_GENERIC) - dmginf:SetAttacker(self) - dmginf:SetInflictor(self) - dmginf:SetDamageForce(Vector(0, 0, 1)) - ent:TakeDamageInfo(dmginf) - - util.ScreenShake(self:GetPos(), 2, 30, 0.5, 300) - if ent:Health() > 0 then - sound.Play("llb/takedmg_"..math.random(1, 4)..".ogg", self:GetPos(), 80, 100, 1) - else - local phys = self:GetPhysicsObject() --reset ball speed when a player dies - phys:SetVelocity(Vector(0, 0, 0)) - phys:SetAngles(Angle(90, 0, 0)) - phys:AddAngleVelocity(-phys:GetAngleVelocity() + Vector(256, 0, 0)) - self.ServingPitch = true - - sound.Play(self.KnockoutSound, self:GetPos(), 80, 100, 1) - end - end -end - -function ENT:OnTakeDamage(dmginfo) - local phys = self:GetPhysicsObject() - local newvel = self:GetVelocity()*1.5 - local speed = newvel:Length() ^ 0.8 - - local att = dmginfo:GetAttacker() - if att:IsPlayer() and att:Alive() then --set the ball owner and ball color on hit - self.BallOwner = att - local plycol = att:GetPlayerColor():ToColor() - local newplycol = math.Round(plycol.r).." "..math.Round(plycol.g).." "..math.Round(plycol.b) - self.BallTrail:Fire("Color", newplycol) - net.Start("LLBChangeBallColor") - net.WriteEntity(self) - net.WriteEntity(self.BallOwner) - net.Broadcast() - end - - if att:IsPlayer() and !att:Alive() then return end - local aimvec = att:GetAimVector() - - if self:GetVelocity() == Vector(0, 0, 0) and !self.ServingPitch then return end - phys:EnableMotion(false) - - if speed > 1000 then --play different sounds based on ball speed - net.Start("LLBDrawInvertedColors") - net.WriteEntity(self) - net.WriteFloat((math.Clamp(0.00205*speed, 0, 1.2))) - net.Broadcast() - sound.Play(self.StrongHitSound, self:GetPos(), 80, 100, 1) - util.ScreenShake(self:GetPos(), 25, 4, 1.3, 300) - elseif speed > 500 then - sound.Play(self.StrongHitSound, self:GetPos(), 80, 100, 1) - util.ScreenShake(self:GetPos(), 20, 4, 1.3, 300) - else - sound.Play(self.HitSound, self:GetPos(), 80, (speed*0.0295+100), 1) - util.ScreenShake(self:GetPos(), 2, 4, 1, 300) - end - - timer.Simple((math.Clamp(0.00205*speed, 0, 1.2)), function() --temporarily stop the ball after being hit. - if !IsValid(self) then return end - phys:EnableMotion(true) - if self.ServingPitch then - phys:SetVelocity(aimvec*50*3.4) - self.ServingPitch = false - else - if speed == 0 then return end - phys:SetVelocity(aimvec*speed*3.8) --may need some more testing - end - - phys:AddAngleVelocity(Vector(-512, 0, 0)) - end) -end - -if CLIENT then - function ENT:Draw() - self:DrawModel() - end -end \ No newline at end of file diff --git a/addons/llb_ball/lua/entities/llb_baseball/cl_init.lua b/addons/llb_ball/lua/entities/llb_baseball/cl_init.lua new file mode 100644 index 0000000..1a98e0d --- /dev/null +++ b/addons/llb_ball/lua/entities/llb_baseball/cl_init.lua @@ -0,0 +1,82 @@ +include("shared.lua") + +function ENT:Initialize() + -- Create an individual material for every ball instance + -- This allows each ball to be colored individually + local matname = "LLBBaseball_" .. self:EntIndex() + + self.BallMaterial = CreateMaterial(matname, "VertexLitGeneric", { + ["$basetexture"] = "models/llb/baseball/baseball", + ["$surfaceprop"] = "Rubber", + + ["$selfillumtint"] = "[0 1 0]", + ["$selfillum"] = "1", + ["$selfillummask"] = "models/llb/baseball/baseball_i", + + ["$phong"] = "1", + ["$phongboost"] = "0.2", + ["$phongexponent"] = "5", + ["$phongfresnelranges"] = "[0.2 0.8 0.1]", + ["$lightwarptexture"] = "models/llb/baseball/lightwarp", + ["$nocull"] = "1", + + ["$rimlight"] = "1", + ["$rimlightexponent"] = "5", + ["$rimlightboost"] = "3", + + ["$blendtintbybasealpha"] = "0", + ["$blendtintcoloroverbase"] = "0", + + ["$model"] = "1" + }) + self:SetMaterial("!" .. matname) + + self.BallMaterial:SetVector("$selfillumtint", Vector(1, 0, 0)) + + hook.Add("RenderScreenspaceEffects", self, function(ent) + if ent.IsInverted then + DrawColorModify({ + ["$pp_colour_addr"] = 0, + ["$pp_colour_addg"] = 0, + ["$pp_colour_addb"] = 0, + ["$pp_colour_brightness"] = 0, + ["$pp_colour_colour"] = 1, + ["$pp_colour_contrast"] = 1, + ["$pp_colour_mulr"] = 0, + ["$pp_colour_mulg"] = 0, + ["$pp_colour_mulb"] = 0, + ["$pp_colour_inv"] = 1, + }) + end + end) +end + +function ENT:Draw() + self:DrawModel() +end + +net.Receive("llb_baseball.ChangeBallColor", function() + local ent = net.ReadEntity() + local entowner = net.ReadEntity() + ent.BallOwner = entowner + ent.BallMaterial:SetVector("$selfillumtint", ent.BallOwner:GetPlayerColor()) +end) + +net.Receive("llb_baseball.DrawInvertedColors", function() + local ent = net.ReadEntity() + local time = net.ReadFloat() + + if not ent:IsDormant() then + ent.IsInverted = true + + --RunConsoleCommand("pp_texturize", "pp/texturize/invert.png") + + timer.Simple(time, function() + --RunConsoleCommand("pp_texturize", "") + + if IsValid(ent) then + ent.IsInverted = false + end + end) + end +end) diff --git a/addons/llb_ball/lua/entities/llb_baseball/init.lua b/addons/llb_ball/lua/entities/llb_baseball/init.lua new file mode 100644 index 0000000..cf66c6b --- /dev/null +++ b/addons/llb_ball/lua/entities/llb_baseball/init.lua @@ -0,0 +1,234 @@ +AddCSLuaFile("cl_init.lua") +AddCSLuaFile("shared.lua") + +include("shared.lua") + +-- Internal size of the ball--do not touch this +ENT.BallSize = 18 + +-- If ball is being initially served or not +ENT.ServingPitch = false + +util.AddNetworkString("llb_baseball.DrawInvertedColors") +util.AddNetworkString("llb_baseball.ChangeBallColor") + +local NEW_VEL_VECTOR = Vector() + +function ENT:Initialize() + self:SetModel("models/llb/baseball.mdl") + self:SetModelScale(0.55) + + self:SetCollisionGroup(COLLISION_GROUP_PASSABLE_DOOR) + self:PhysicsInit(SOLID_VPHYSICS) + self:SetMoveType(MOVETYPE_VPHYSICS) + self:SetSolid(SOLID_VPHYSICS) + + self:SetTrigger(true) + + self.ServingPitch = true + + local size = self.BallSize / 2.1 + self:PhysicsInitSphere(size, "metal_bouncy") + self:SetCollisionBounds(Vector(-size, -size, -size), Vector(size, size, size)) + + local trailTexture = "trails/smoke" + if IsMounted("tf") then trailTexture = "effects/beam_generic01" end + self.BallTrail = util.SpriteTrail(self, 0, Color(255, 0, 0), false, 17, 17, 0.03, 1 / 17, trailTexture) + + local phys = self:GetPhysicsObject() + if phys:IsValid() then + phys:Wake() + phys:EnableGravity(false) + end + + hook.Add("KeyPress", self, function(ent, ply, key) + if not IsValid(ply) or not IsValid(ent) or not IsFirstTimePredicted() then return end + + local plyPos = ply:GetPos() + local entPos = ent:GetPos() + + -- The player will hit the ball if they're within 120 hammer units. + -- They don't need to look directly at the ball + if key == IN_ATTACK and plyPos:Distance(entPos) < 120 then + local dmginfo = DamageInfo() + dmginfo:SetAttacker(ply) + ent:OnTakeDamage(dmginfo) + end + end) +end + +function ENT:Think() + local phys = self:GetPhysicsObject() + if not IsValid(phys) then return end + + local vel = self:GetVelocity() + vel.x = self:GetLockXAxis() and 0 or vel.x + vel.y = self:GetLockYAxis() and 0 or vel.y + vel.z = self:GetLockZAxis() and 0 or vel.z + + -- Use a preinitialized vector so we don't create a vector every frame + NEW_VEL_VECTOR:SetUnpacked(vel.x, vel.y, vel.z) + phys:SetVelocity(NEW_VEL_VECTOR) + + self:NextThink(CurTime()) + + return true +end + +function ENT:PhysicsCollide(data, physobj) + -- Play sound and screen shake on bounce + if data.DeltaTime > 0.02 then + sound.Play(self.BounceSound, self:GetPos(), 80, 100, 1) + + util.ScreenShake(self:GetPos(), 2, 4, 0.2, 1500) + end +end + +function ENT:SpawnFunction(ply, tr, ClassName) + if not tr.Hit then return end + + local ent = ents.Create(ClassName) + ent:SetPos(tr.HitPos + tr.HitNormal * self.BallSize * 2) + ent:Spawn() + ent:Activate() + + local phys = ent:GetPhysicsObject() + phys:SetVelocity(Vector(0, 0, 0)) + phys:SetAngles(Angle(0, 0, 0)) + phys:AddAngleVelocity(Vector(256, 0, 0)) + + return ent +end + +function ENT:OnTakeDamage(dmginfo) + -- Prevents multiple damage events from overlapping and causing issues + if self.IsPaused then return end + + -- Attacker must be an alive player + local att = dmginfo:GetAttacker() + if not att:IsPlayer() or not att:Alive() then return end + + -- Ball needs valid physics, otherwise we can't temporarily freeze it + local phys = self:GetPhysicsObject() + if not IsValid(phys) then return end + + local newvel = self:GetVelocity() * 1.5 + local speed = newvel:Length() ^ 0.8 + + -- Freeze the ball + phys:EnableMotion(false) + self.IsPaused = true + + -- Set new ball owner + self.BallOwner = att + + -- Set the color of the ball trail + local plycol = att:GetPlayerColor():ToColor() + local newplycol = math.Round(plycol.r) .. " " .. math.Round(plycol.g) .. " " .. math.Round(plycol.b) + self.BallTrail:Fire("Color", newplycol) + + -- Let clients know about the ball's new color + net.Start("llb_baseball.ChangeBallColor") + net.WriteEntity(self) + net.WriteEntity(self.BallOwner) + net.Broadcast() + + -- Fixes issues where velocity gets nulled out if ball is locked to an axis and player fires perpendicular to it + local aimAng = att:GetAimVector():Angle() + aimAng:Normalize() + + if self:GetLockXAxis() then + aimAng.y = aimAng.y > 0 and 90 or -90 + end + + if self:GetLockYAxis() then + aimAng.y = math.abs(aimAng.y) > 90 and 180 or 0 + end + + if self:GetLockZAxis() then + aimAng.p = 0 + end + + local aimVecFixed = aimAng:Forward() + + local ballPauseTime = math.Clamp(0.00205 * speed, 0, 1.2) + + -- Play different sounds based on ball speed + if speed > 1000 then + -- Tell clients in PVS to invert their screen colors + net.Start("llb_baseball.DrawInvertedColors") + net.WriteEntity(self) + net.WriteFloat(math.Clamp(0.00205 * speed, 0, 1.2)) + net.SendPVS(self:GetPos()) + + sound.Play(self.StrongHitSound, self:GetPos(), 80, 100, 1) + util.ScreenShake(self:GetPos(), 25, 4, ballPauseTime, 300) + elseif speed > 500 then + sound.Play(self.StrongHitSound, self:GetPos(), 80, 100, 1) + util.ScreenShake(self:GetPos(), 20, 4, ballPauseTime, 300) + else + sound.Play(self.HitSound, self:GetPos(), 80, speed * 0.0295 + 100, 1) + util.ScreenShake(self:GetPos(), 2, 4, ballPauseTime, 300) + end + + -- Lock the player until ball unfreezes. + att:Lock() + timer.Simple(ballPauseTime, function() + if not IsValid(att) then return end + + att:UnLock() + end) + + -- Unfreeze the ball after it was temporarily frozen. + timer.Simple(ballPauseTime, function() + if not IsValid(self) or not IsValid(phys) then return end + self.IsPaused = false + + phys:EnableMotion(true) + + if self.ServingPitch then + phys:SetVelocity(aimVecFixed * 50 * 3.4) + + self.ServingPitch = false + else + if speed == 0 then return end + + -- *May need some more testing + phys:SetVelocity(aimVecFixed * speed * 3.8) + end + + phys:AddAngleVelocity(Vector(-512, 0, 0)) + end) +end + +function ENT:StartTouch(ent) + local speed = self:GetVelocity():Length() ^ 0.8 + -- Damage a player if they touch the ball + if ent:IsPlayer() and self.BallOwner != ent and speed > 16 then + if not self:GetDamagePlayers() then return end + local dmginf = DamageInfo() + dmginf:SetDamage(speed / 8) + dmginf:SetDamageType(DMG_GENERIC) + dmginf:SetAttacker(self) + dmginf:SetInflictor(self) + dmginf:SetDamageForce(Vector(0, 0, 1)) + ent:TakeDamageInfo(dmginf) + + util.ScreenShake(self:GetPos(), 2, 30, 0.5, 300) + + -- If player is still alive after taking damage + if ent:Health() > 0 then + sound.Play("llb/takedmg_" .. math.random(1, 4) .. ".ogg", self:GetPos(), 80, 100, 1) + -- Reset ball speed when a player dies + else + local phys = self:GetPhysicsObject() + phys:SetVelocity(Vector(0, 0, 0)) + phys:SetAngles(Angle(90, 0, 0)) + phys:AddAngleVelocity(-phys:GetAngleVelocity() + Vector(256, 0, 0)) + + self.ServingPitch = true + + sound.Play(self.KnockoutSound, self:GetPos(), 80, 100, 1) + end + end +end diff --git a/addons/llb_ball/lua/entities/llb_baseball/shared.lua b/addons/llb_ball/lua/entities/llb_baseball/shared.lua new file mode 100644 index 0000000..4a39bb8 --- /dev/null +++ b/addons/llb_ball/lua/entities/llb_baseball/shared.lua @@ -0,0 +1,26 @@ +DEFINE_BASECLASS("base_anim") + +ENT.PrintName = "Lethal League Baseball" +ENT.Author = "Lua coding & model port: Chev\nBaseball model: Team Reptile" +ENT.Purpose = "The baseball from LL/LLB. Hit it to make it go faster!" +ENT.Category = "Lethal League" + +ENT.AutomaticFrameAdvance = true +ENT.Editable = true +ENT.Spawnable = true +ENT.AdminOnly = false +ENT.RenderGroup = RENDERGROUP_OPAQUE + +ENT.BounceSound = Sound("llb/wall_bounce.ogg") +ENT.HitSound = Sound("llb/medium_hit.ogg") +ENT.StrongHitSound = Sound("llb/strong_hit.ogg") +ENT.KnockoutSound = Sound("llb/knockout.ogg") + +ENT.BallOwner = nil + +function ENT:SetupDataTables() + self:NetworkVar("Bool", 0, "LockXAxis", {KeyName = "lockx", Edit = {type = "Boolean", order = 1}}) + self:NetworkVar("Bool", 1, "LockYAxis", {KeyName = "locky", Edit = {type = "Boolean", order = 2}}) + self:NetworkVar("Bool", 2, "LockZAxis", {KeyName = "lockz", Edit = {type = "Boolean", order = 3}}) + self:NetworkVar("Bool", 3, "DamagePlayers", {KeyName = "dmgply", Edit = {type = "Boolean", order = 4}}) +end diff --git a/addons/llb_ball/materials/pp/texturize/invert.png b/addons/llb_ball/materials/pp/texturize/invert.png deleted file mode 100644 index de7bc2f..0000000 Binary files a/addons/llb_ball/materials/pp/texturize/invert.png and /dev/null differ