ACF_CustomMod/lua/weapons/gmod_tool/stools/acfarmorprop.lua

354 lines
13 KiB
Lua

TOOL.Category = "Construction"
TOOL.Name = "#Tool.acfarmorprop.name"
TOOL.Command = nil
TOOL.ConfigName = ""
TOOL.ClientConVar["mass"] = "1"
TOOL.ClientConVar["thick"] = "1"
TOOL.ClientConVar["ductility"] = "0"
TOOL.ClientConVar["mhealth"] = "1"
TOOL.ClientConVar["marmor"] = "1"
TOOL.ClientConVar["area"] = "1"
if CLIENT then
language.Add( "Tool.acfarmorprop.name", "ACF Armor Properties" )
language.Add( "Tool.acfarmorprop.desc", "Sets objects armor" )
language.Add( "Tool.acfarmorprop.0", "Left click to apply options. Right click to props properties. Reload to get Total Mass of a Constrained Contraption" )
language.Add( "Tool_acfarmorprop_weight", "Weight:" )
language.Add( "Tool_acfarmorprop_thick" , "Armour Thickness")
language.Add( "Tool_acfarmorprop_thick_desc" , "Set a thickness and the weight will be scaled" )
language.Add( "Tool_acfarmorprop_ductility", "Ductility:" )
language.Add( "Tool_acfarmorprop_ductility_desc" , "Sets ductility of prop. Higher than zero will make prop more resistant to penetration but it will lower its health. Lower than zero will make prop less resistant to penetration but it will endure longer fire" )
language.Add( "Tool_acfarmorprop_zeromass", "Mass must be above 0!" )
end
local function ApplySettings( Player, Entity, Data )
if not SERVER then return end
if Data.Mass then
local physobj = Entity:GetPhysicsObject()
if physobj:IsValid() then physobj:SetMass(Data.Mass) end
duplicator.StoreEntityModifier( Entity, "mass", {Mass = Data.Mass} )
end
if Data.Ductility then
Entity.ACF = Entity.ACF or {}
Entity.ACF.Ductility = (Data.Ductility/100)
duplicator.StoreEntityModifier( Entity, "acfsettings", {Ductility = Data.Ductility} )
end
end
duplicator.RegisterEntityModifier( "acfsettings", ApplySettings )
duplicator.RegisterEntityModifier( "mass", ApplySettings )
local function Recalc(Ply, What)
local Thick, Ductility, Area, Mass
Thick = Ply:GetInfo("acfarmorprop_thick")
Ductility = math.Clamp(Ply:GetInfo("acfarmorprop_ductility")/100,-0.8,0.8)
Area = Ply:GetInfo("acfarmorprop_area") or 1
Mass = (39*Area*Ductility+39*Area)*Thick/50000
if What == "ductility" then
if Mass > 50000 then
Mass = 50000
Ductility = -(39*Area*Thick-50000*Mass)/(39*Area*Thick)
elseif Mass < 0.1 then
Mass = 0.1
Ductility = -(39*Area*Thick-50000*Mass)/(39*Area*Thick)
end
Ply:ConCommand("acfarmorprop_ductility "..(Ductility*100));
end
if What == "thick" then
if Mass > 50000 then
Mass = 50000
Thick = Mass*1000/(Area+Area*Ductility)/0.78
elseif Mass < 0.1 then
Mass = 0.1
Thick = Mass*1000/(Area+Area*Ductility)/0.78
end
Ply:ConCommand("acfarmorprop_thick "..Thick);
end
Ply:ConCommand("acfarmorprop_mass "..Mass);
local MArmour = Mass*1000/(Area+Area*Ductility)/0.78
local MHealth = (Area+Area*Ductility)/ACF.Threshold
Ply:ConCommand("acfarmorprop_mhealth "..MHealth)
Ply:ConCommand("acfarmorprop_marmor "..MArmour)
Ply:ConCommand("acfarmorprop_reloadui")
end
local function IsReallyValid(trace)
if not trace.Entity:IsValid() then return false end
if trace.Entity:IsPlayer() then return false end
if SERVER and not trace.Entity:GetPhysicsObject():IsValid() then return false end
return true
end
function TOOL:LeftClick( trace )
if CLIENT and IsReallyValid(trace) then return true end
if not IsReallyValid(trace) then return false end
self:GetOwner():ConCommand("acfarmorprop_area "..trace.Entity.ACF.Aera);
Recalc(self:GetOwner())
local mass = tonumber(self:GetClientInfo("mass"))
local ductility = tonumber(self:GetClientInfo("ductility"))
ApplySettings( self:GetOwner(), trace.Entity, { Mass = mass, Ductility = ductility } )
self.updateacf = true
return true;
end
function TOOL:RightClick( trace )
if CLIENT and IsReallyValid(trace) then return true end
if not IsReallyValid(trace) then return end
local ent = trace.Entity
local mass = ent:GetPhysicsObject():GetMass()
local ductility = ent.ACF.Ductility
local mhealth = ent.ACF.MaxHealth
local marmor = ent.ACF.MaxArmour
local thick = ent.ACF.MaxArmour
local area = ent.ACF.Aera
self:GetOwner():ConCommand("acfarmorprop_mass "..mass);
self:GetOwner():ConCommand("acfarmorprop_ductility "..(ductility*100));
self:GetOwner():ConCommand("acfarmorprop_mhealth "..mhealth);
self:GetOwner():ConCommand("acfarmorprop_marmor "..marmor);
self:GetOwner():ConCommand("acfarmorprop_thick "..marmor);
self:GetOwner():ConCommand("acfarmorprop_area "..area);
self:GetOwner():ConCommand("acfarmorprop_reloadui");
self.updateacf = true
return true;
end
function TOOL:Reload( trace )
if CLIENT then return false end;
if not IsReallyValid(trace) then return false end
local mass = 0
for ent , v in pairs( constraint.GetAllConstrainedEntities(trace.Entity) ) do
if IsValid(ent) and ent != NULL then
local phys = ent:GetPhysicsObject()
mass = mass + phys:GetMass()
end
end
self:GetOwner():PrintMessage(HUD_PRINTCENTER , "Total Mass is: "..tostring(mass) )
return true
end
function TOOL:Think()
if CLIENT then return end;
local pl = self:GetOwner()
local wep = pl:GetActiveWeapon()
if not wep:IsValid() or wep:GetClass() != "gmod_tool" or pl:GetInfo("gmod_toolmode") != "acfarmorprop" then return end
local trace = pl:GetEyeTrace()
--if IsReallyValid(trace) then pl:SetNetworkedFloat("WeightMass", trace.Entity:GetPhysicsObject():GetMass()) end
local ent = trace.Entity
if ent != self.lastent or self.updateacf then
if( ACF_Check ~= mil ) then
local valid = ACF_Check( ent )
if valid then
local mass = ent:GetPhysicsObject():GetMass()
self:GetOwner():ConCommand("acfarmorprop_mass "..mass);
self:GetOwner():ConCommand("acfarmorprop_area "..ent.ACF.Aera);
self.Weapon:SetNetworkedInt( "WeightMass", mass )
self.Weapon:SetNetworkedInt( "HP", ent.ACF.Health )
self.Weapon:SetNetworkedInt( "Armour", ent.ACF.Armour )
self.Weapon:SetNetworkedInt( "MaxHP", ent.ACF.MaxHealth )
self.Weapon:SetNetworkedInt( "MaxArmour", ent.ACF.MaxArmour )
Recalc(self:GetOwner())
end
end
self.lastent = ent
self.updateacf = false
end
if ent:IsWorld() and !self.updateacf then
self.Weapon:SetNetworkedInt( "WeightMass", 0 )
self.Weapon:SetNetworkedInt( "HP", 0 )
self.Weapon:SetNetworkedInt( "Armour", 0 )
self.Weapon:SetNetworkedInt( "MaxHP", 0 )
self.Weapon:SetNetworkedInt( "MaxArmour", 0 )
self.updateacf = true
end
end
if CLIENT then
function TOOL.BuildCPanel( cp )
cp:AddControl( "Header", { Text = "#Tool.acfarmorprop.name", Description = "#Tool.acfarmorprop.desc" } )
local params = { Label = "#Presets", MenuButton = 1, Folder = "weight", Options = {}, CVars = {} }
params.Options.default = { acf_weight_set = 1 }
table.insert( params.CVars, "acfarmorprop_mass" )
cp:AddControl("ComboBox", params )
cp.mass = cp:AddControl("Header", {Text = "Actual Weight" , Description = "Weight: "..math.floor(GetConVarNumber("acfarmorprop_mass")*10)/10 } )
cp.mhealth = cp:AddControl("Header", {Text = "Actual MaxHealth" , Description = "Max Health: "..math.floor(GetConVarNumber("acfarmorprop_mhealth")*10)/10 } )
cp.marmor = cp:AddControl("Header", {Text = "Actual MaxArmor" , Description = "Max Armor: "..math.floor(GetConVarNumber("acfarmorprop_marmor")*10)/10 } )
cp.thick = cp:AddControl("Slider", { Label = "#Tool_acfarmorprop_thick", Type = "Numeric", Min = "1", Max = "5000", Command = "acfarmorprop_thick" } )
cp:AddControl("Header", {Text = "Armour Thickness Setting" , Description = "#Tool_acfarmorprop_thick_desc" } )
cp.ductility = cp:AddControl("Slider", { Label = "#Tool_acfarmorprop_ductility", Type = "Numeric", Min = "-99", Max = "99", Command = "acfarmorprop_ductility" } )
cp:AddControl("Header", {Text = "Ductility Setting" , Description = "#Tool_acfarmorprop_ductility_desc" } )
end
--local BuildCPanel = TOOL.BuildCPanel
concommand.Add( "acfarmorprop_reloadui", function()
local cp = controlpanel.Get( "acfarmorprop" )
if cp.mass then
cp.mass:SetText("Weight: "..math.floor(GetConVarNumber("acfarmorprop_mass")*10)/10)
end
if cp.mhealth then
cp.mhealth:SetText("Max Health: "..math.floor(GetConVarNumber("acfarmorprop_mhealth")*10)/10)
end
if cp.marmor then
cp.marmor:SetText("Max Armor: "..math.floor(GetConVarNumber("acfarmorprop_marmor")*10)/10)
end
if cp.thick then
local ConVar = GetConVar("acfarmorprop_thick"):GetFloat()
cp.thick:SetValue( ConVar )
end
if cp.ductility then
local ConVar = GetConVar("acfarmorprop_ductility"):GetFloat()
cp.ductility:SetValue( ConVar )
end
--BuildCPanel( CPanel )
end)
/*cvars.AddChangeCallback("acfarmorprop_ductility", function()
if timer.Exists("RecalcTimer") then timer.Remove("RecalcTimer") end
timer.Create("RecalcTimer", 1, 1, function()
Recalc(LocalPlayer(), "ductility")
end)
end)
cvars.AddChangeCallback("acfarmorprop_thick", function()
if timer.Exists("RecalcTimer") then timer.Remove("RecalcTimer") end
timer.Create("RecalcTimer", 1, 1, function()
Recalc(LocalPlayer(), "thick")
end)
end)*/
local TipColor = Color( 250, 250, 200, 255 )
-- surface.CreateFont( "GModWorldtip", {font="coolvetica", size=24, weight=500, antialias=true, additive=false} )
surface.CreateFont("Torchfont", {size=40, weight=1000, antialias=true, additive=false, font="arial"})
local function DrawWeightTip()
local pl = LocalPlayer()
local wep = pl:GetActiveWeapon()
if not wep:IsValid() or wep:GetClass() != "gmod_tool" or pl:GetInfo("gmod_toolmode") != "acfarmorprop" then return end
local trace = pl:GetEyeTrace()
if not IsReallyValid(trace) then return end
local mass = math.floor((wep:GetNetworkedFloat("WeightMass") or 0) *10)/10
local armour = math.floor((wep:GetNetworkedBool("MaxArmour") or 0) *100)/100
local health = math.floor((wep:GetNetworkedBool("MaxHP") or 0) * 10)/10
local mass2 = math.floor((GetConVarNumber("acfarmorprop_mass") or 0)*10)/10
local armour2 = math.floor((GetConVarNumber("acfarmorprop_marmor") or 0)*10)/10
local health2 = math.floor((GetConVarNumber("acfarmorprop_mhealth") or 0)*10)/10
local text = "Current:\nWeight: "..mass.."\nArmour: "..armour.."\nHealth: "..health.."\nAfter:\nWeight: "..mass2.."\nArmour: "..armour2.."\nHealth: "..health2
local pos = (trace.Entity:LocalToWorld(trace.Entity:OBBCenter())):ToScreen()
local black = Color( 0, 0, 0, 255 )
local tipcol = Color( TipColor.r, TipColor.g, TipColor.b, 255 )
local x = 0
local y = 0
local padding = 10
local offset = 50
surface.SetFont( "GModWorldtip" )
local w, h = surface.GetTextSize( text )
x = pos.x - w
y = pos.y - h
x = x - offset
y = y - offset
draw.RoundedBox( 8, x-padding-2, y-padding-2, w+padding*2+4, h+padding*2+4, black )
local verts = {}
verts[1] = { x=x+w/1.5-2, y=y+h+2 }
verts[2] = { x=x+w+2, y=y+h/2-1 }
verts[3] = { x=pos.x-offset/2+2, y=pos.y-offset/2+2 }
draw.NoTexture()
surface.SetDrawColor( 0, 0, 0, tipcol.a )
surface.DrawPoly( verts )
draw.RoundedBox( 8, x-padding, y-padding, w+padding*2, h+padding*2, tipcol )
local verts = {}
verts[1] = { x=x+w/1.5, y=y+h }
verts[2] = { x=x+w, y=y+h/2 }
verts[3] = { x=pos.x-offset/2, y=pos.y-offset/2 }
draw.NoTexture()
surface.SetDrawColor( tipcol.r, tipcol.g, tipcol.b, tipcol.a )
surface.DrawPoly( verts )
draw.DrawText( text, "GModWorldtip", x + w/2, y, black, TEXT_ALIGN_CENTER )
end
hook.Add("HUDPaint", "ACF_WeightWorldTip", DrawWeightTip)
function TOOL:DrawToolScreen(w,h)
local Health = math.floor((self.Weapon:GetNetworkedBool("HP")or 0) *10)/10
local MaxHealth = math.floor((self.Weapon:GetNetworkedBool("MaxHP")or 0) * 10)/10
local Armour = math.floor((self.Weapon:GetNetworkedBool("Armour")or 0) *100)/100
local MaxArmour = math.floor((self.Weapon:GetNetworkedBool("MaxArmour")or 0) *100)/100
local HealthTxt = Health.."/"..MaxHealth.."\n"
local ArmourTxt = Armour.."/"..MaxArmour.."\n"
local HealthPercent = (Health/MaxHealth) * 226
local ArmourPercent = (Armour/MaxArmour) * 226
cam.Start2D()
render.Clear(0,0,0,0)
local Flicker = 255
surface.SetDrawColor(255,255,255,Flicker)
local tex=surface.GetTextureID( "models/props_combine/combine_interface_disp")
surface.SetTexture(tex)
surface.DrawTexturedRect(0, 0, 256, 256)
surface.SetDrawColor(255,255,255,255)
surface.SetFont("Torchfont")
local w, h = surface.GetTextSize(" ")
draw.SimpleTextOutlined("ACF Stats", "Torchfont", 128, 30, Color(224, 224, 255, Flicker), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, Color(0, 0, 0, Flicker))
draw.RoundedBox( 6, 10, 83, 236, 64, Color(200, 200, 200, Flicker))
if Armour != 0 and MaxArmour != 0 then
draw.RoundedBox( 6, 15, 88, ArmourPercent , 54, Color(0, 0, 200, Flicker))
end
draw.RoundedBox( 6, 10, 183, 236, 64, Color(200, 200, 200, Flicker))
if Health != 0 and MaxHealth != 0 then
draw.RoundedBox( 6, 15, 188, HealthPercent , 54, Color(200, 0, 0, Flicker))
end
draw.SimpleTextOutlined("Armour", "Torchfont", 128, 100, Color(224, 224, 255, Flicker), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, Color(0, 0, 0, Flicker))
draw.SimpleTextOutlined(ArmourTxt, "Torchfont", 128, 150, Color(224, 224, 255, Flicker), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, Color(0, 0, 0, Flicker))
draw.SimpleTextOutlined("Health", "Torchfont", 128, 200, Color(224, 224, 255, Flicker), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, Color(0, 0, 0, Flicker))
draw.SimpleTextOutlined(HealthTxt, "Torchfont", 128, 250, Color(224, 224, 255, Flicker), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, Color(0, 0, 0, Flicker))
cam.End2D()
end
end