Skip to content

Commit d5c0475

Browse files
authored
Add buoyancy controller (#3456)
* Add buoyancy controller * Critical fixes * Small cleanups * Make sure that self.Marks always contains only valid entities * Add to sents_registry * Less code duplication * Fix typo * Small cleanups * Small cleanups
1 parent 208bb44 commit d5c0475

File tree

3 files changed

+188
-1
lines changed

3 files changed

+188
-1
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
AddCSLuaFile()
2+
3+
DEFINE_BASECLASS("base_wire_entity")
4+
ENT.PrintName = "Wire Buoyancy"
5+
ENT.RenderGroup = RENDERGROUP_BOTH
6+
ENT.WireDebugName = "Buoyancy"
7+
8+
if CLIENT then return end
9+
10+
function ENT:Initialize()
11+
self:PhysicsInit(SOLID_VPHYSICS)
12+
self.Marks = {}
13+
14+
WireLib.CreateInputs(self, { "Percent" })
15+
end
16+
17+
function ENT:UpdateOverlay()
18+
self:SetOverlayText(string.format("Buoyancy ratio: %.2f\nNumber of entities linked: %i", self.Percent, #self.Marks))
19+
end
20+
21+
function ENT:UpdateOutputs()
22+
self:UpdateOverlay()
23+
WireLib.SendMarks(self)
24+
end
25+
26+
local function SetBuoyancy(ent, controller)
27+
local phys = ent:GetPhysicsObject()
28+
29+
if phys:IsValid() then
30+
phys:SetBuoyancyRatio(controller.Percent)
31+
phys:Wake()
32+
end
33+
end
34+
35+
function ENT:Setup(percent)
36+
self.Percent = math.Clamp(percent, -10, 10)
37+
38+
for _, ent in ipairs(self.Marks) do
39+
SetBuoyancy(ent, self)
40+
end
41+
42+
self:UpdateOverlay()
43+
end
44+
45+
function ENT:TriggerInput(name, value)
46+
if name == "Percent" then
47+
self.Percent = math.Clamp(value, -10, 10)
48+
49+
for _, ent in ipairs(self.Marks) do
50+
SetBuoyancy(ent, self)
51+
end
52+
53+
self:UpdateOverlay()
54+
end
55+
end
56+
57+
-- Buoyancy is reset by the physgun and gravgun
58+
local function RestoreBuoyancy(ply, ent)
59+
if ent.WireBuoyancyController then
60+
timer.Simple(0 , function()
61+
if not ent:IsValid() or not ent.WireBuoyancyController then return end
62+
SetBuoyancy(ent, ent.WireBuoyancyController)
63+
end)
64+
end
65+
end
66+
67+
hook.Add("PhysgunDrop", "WireBuoyancy", RestoreBuoyancy)
68+
hook.Add("GravGunOnDropped", "WireBuoyancy", RestoreBuoyancy)
69+
70+
function ENT:CheckEnt(checkent)
71+
for index, ent in ipairs(self.Marks) do
72+
if checkent == ent then
73+
return true, index
74+
end
75+
end
76+
77+
return false, 0
78+
end
79+
80+
function ENT:LinkEnt(ent)
81+
if self:CheckEnt(ent) then return false end
82+
83+
table.insert(self.Marks, ent)
84+
SetBuoyancy(ent, self)
85+
86+
ent:CallOnRemove("Buoyancy.Unlink" .. self:EntIndex(), function(ent)
87+
self:UnlinkEnt(ent)
88+
end)
89+
90+
ent.WireBuoyancyController = self
91+
self:UpdateOutputs()
92+
93+
return true
94+
end
95+
96+
function ENT:UnlinkEnt(ent)
97+
local bool, index = self:CheckEnt(ent)
98+
99+
if bool then
100+
table.remove(self.Marks, index)
101+
ent:RemoveCallOnRemove("Buoyancy.Unlink" .. self:EntIndex())
102+
ent.WireBuoyancyController = nil
103+
self:UpdateOutputs()
104+
end
105+
106+
return bool
107+
end
108+
109+
function ENT:ClearEntities()
110+
for index, ent in ipairs(self.Marks) do
111+
ent:RemoveCallOnRemove("Buoyancy.Unlink" .. self:EntIndex())
112+
ent.WireBuoyancyController = nil
113+
end
114+
115+
self.Marks = {}
116+
self:UpdateOutputs()
117+
end
118+
119+
function ENT:OnRemove()
120+
self:ClearEntities()
121+
end
122+
123+
function ENT:BuildDupeInfo()
124+
local info = BaseClass.BuildDupeInfo(self)
125+
126+
if #self.Marks > 0 then
127+
local tab = {}
128+
129+
for index, ent in ipairs(self.Marks) do
130+
tab[index] = ent:EntIndex()
131+
end
132+
133+
info.marks = tab
134+
end
135+
136+
return info
137+
end
138+
139+
function ENT:ApplyDupeInfo(ply, ent, info, GetEntByID)
140+
BaseClass.ApplyDupeInfo(self, ply, ent, info, GetEntByID)
141+
142+
if info.marks then
143+
for index, entid in ipairs(info.marks) do
144+
local ent = GetEntByID(entid)
145+
146+
if ent:IsValid() then
147+
self:LinkEnt(ent)
148+
end
149+
end
150+
end
151+
end
152+
153+
duplicator.RegisterEntityClass("gmod_wire_buoyancy", WireLib.MakeWireEnt, "Data", "Percent")

lua/wire/server/sents_registry.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
-- TIP: To return a strict-only error in _preFactory, or _postFactory, just return a string, which contains the error message.
4545
-- (If you return a string to non-strict E2, obv it will also stop spawning the entity)
4646

47-
-- Supported types (to which can WireLib.castE2ValueToLuaValue cast E2 values):
47+
-- Supported types (to which can WireLib.castE2ValueToLuaValue cast E2 values):
4848
-- TYPE_STRING, TYPE_NUMBER, TYPE_BOOL, TYPE_ENTITY, TYPE_VECTOR,
4949
-- TYPE_COLOR, TYPE_TABLE, TYPE_USERDATA, TYPE_ANGLE, TYPE_DAMAGEINFO,
5050
-- TYPE_MATERIAL, TYPE_EFFECTDATA, TYPE_MATRIX
@@ -1317,3 +1317,8 @@ register("gmod_wire_materializer", {
13171317
["Material"] = {TYPE_STRING, "debug/env_cubemap_model", "Default material"},
13181318
["Range"] = {TYPE_NUMBER, 2048, "Length of the materializer beam"},
13191319
})
1320+
1321+
register("gmod_wire_buoyancy", {
1322+
["Model"] = {TYPE_STRING, "models/jaanus/wiretool/wiretool_siren.mdl", "Path to model"},
1323+
["Percent"] = {TYPE_NUMBER, 1, "Buoyancy coefficient"},
1324+
})

lua/wire/stools/buoyancy.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
WireToolSetup.setCategory("Physics/Force")
2+
WireToolSetup.open("buoyancy", "Buoyancy", "gmod_wire_buoyancy", nil, "Buoyancys")
3+
4+
if CLIENT then
5+
language.Add("tool.wire_buoyancy.name", "Buoyancy Tool (Wire)")
6+
language.Add("tool.wire_buoyancy.desc", "Spawns a Buoyancy Controller for use with the wire system.")
7+
end
8+
9+
WireToolSetup.BaseLang()
10+
WireToolSetup.SetupMax(10)
11+
12+
if SERVER then
13+
function TOOL:GetConVars()
14+
return self:GetClientNumber("percent"), self:GetClientInfo("model")
15+
end
16+
end
17+
18+
TOOL.ClientConVar = {
19+
percent = 1,
20+
model = "models/jaanus/wiretool/wiretool_siren.mdl"
21+
}
22+
23+
WireToolSetup.SetupLinking()
24+
25+
function TOOL.BuildCPanel(panel)
26+
WireToolHelpers.MakePresetControl(panel, "wire_buoyancy")
27+
WireDermaExts.ModelSelect(panel, "wire_buoyancy_model", list.Get("Wire_Laser_Tools_Models"), 1, true)
28+
panel:NumSlider("Percent", "wire_buoyancy_percent", -10, 10)
29+
end

0 commit comments

Comments
 (0)