Created
April 14, 2019 18:48
-
-
Save Donkie/4852487cabe7d18e20e0e591ba9a65f4 to your computer and use it in GitHub Desktop.
SWEP Constructor for entities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ENT.ShowWorldModel = false | |
ENT.SWEPKitWElements = { | |
["element_name"] = { type = "Model", model = "models/goldengun.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(-12.855, 1.567, 0.054), angle = Angle(-3.962, 0, 173.091), size = Vector(0.935, 0.935, 0.935), color = Color(255, 255, 255, 255), surpresslightning = false, material = "models/player/shared/gold_player", skin = 0, bodygroup = {} } | |
} | |
function ENT:GetEntityByName(name) | |
if self.WElements[name] then | |
return self.WElements[name].modelEnt | |
end | |
end | |
function ENT:SWEPKitInit() | |
self.WElements = table.FullCopy( self.SWEPKitWElements ) | |
self:CreateModels(self.WElements) | |
end | |
ENT.wRenderOrder = nil | |
function ENT:Draw() | |
if not self.hasswepkitinit then | |
self:SWEPKitInit() | |
self.hasswepkitinit = true | |
end | |
if (self.ShowWorldModel == nil or self.ShowWorldModel) then | |
self:DrawModel() | |
end | |
if (!self.WElements) then return end | |
if (!self.wRenderOrder) then | |
self.wRenderOrder = {} | |
for k, v in pairs( self.WElements ) do | |
if (v.type == "Model") then | |
table.insert(self.wRenderOrder, 1, k) | |
elseif (v.type == "Sprite" or v.type == "Quad") then | |
table.insert(self.wRenderOrder, k) | |
end | |
end | |
end | |
for k, name in pairs( self.wRenderOrder ) do | |
local v = self.WElements[name] | |
if (!v) then self.wRenderOrder = nil break end | |
if (v.hide) then continue end | |
local pos, ang = self:GetBoneOrientation( self.WElements, v, self, "ValveBiped.Bip01_R_Hand" ) | |
if (!pos) then | |
pos = self:GetPos() | |
ang = self:GetAngles() | |
end | |
local model = v.modelEnt | |
local sprite = v.spriteMaterial | |
if (v.type == "Model" and IsValid(model)) then | |
model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z ) | |
ang:RotateAroundAxis(ang:Up(), v.angle.y) | |
ang:RotateAroundAxis(ang:Right(), v.angle.p) | |
ang:RotateAroundAxis(ang:Forward(), v.angle.r) | |
model:SetAngles(ang) | |
--model:SetModelScale(v.size) | |
local matrix = Matrix() | |
matrix:Scale(v.size) | |
model:EnableMatrix( "RenderMultiply", matrix ) | |
if (v.material == "") then | |
model:SetMaterial("") | |
elseif (model:GetMaterial() != v.material) then | |
model:SetMaterial( v.material ) | |
end | |
if (v.skin and v.skin != model:GetSkin()) then | |
model:SetSkin(v.skin) | |
end | |
if (v.bodygroup) then | |
for k, v in pairs( v.bodygroup ) do | |
if (model:GetBodygroup(k) != v) then | |
model:SetBodygroup(k, v) | |
end | |
end | |
end | |
if (v.surpresslightning) then | |
render.SuppressEngineLighting(true) | |
end | |
render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255) | |
render.SetBlend(v.color.a/255) | |
model:DrawModel() | |
render.SetBlend(1) | |
render.SetColorModulation(1, 1, 1) | |
if (v.surpresslightning) then | |
render.SuppressEngineLighting(false) | |
end | |
elseif (v.type == "Sprite" and sprite) then | |
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z | |
render.SetMaterial(sprite) | |
render.DrawSprite(drawpos, v.size.x, v.size.y, v.color) | |
elseif (v.type == "Quad" and v.draw_func) then | |
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z | |
ang:RotateAroundAxis(ang:Up(), v.angle.y) | |
ang:RotateAroundAxis(ang:Right(), v.angle.p) | |
ang:RotateAroundAxis(ang:Forward(), v.angle.r) | |
cam.Start3D2D(drawpos, ang, v.size) | |
v.draw_func( self ) | |
cam.End3D2D() | |
end | |
end | |
end | |
function ENT:GetBoneOrientation( basetab, tab, ent, bone_override ) | |
local bone, pos, ang | |
if (tab.rel and tab.rel != "") then | |
local v = basetab[tab.rel] | |
if (!v) then return end | |
-- Technically, if there exists an element with the same name as a bone | |
-- you can get in an infinite loop. Let's just hope nobody's that stupid. | |
pos, ang = self:GetBoneOrientation( basetab, v, ent ) | |
if (!pos) then return end | |
pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z | |
ang:RotateAroundAxis(ang:Up(), v.angle.y) | |
ang:RotateAroundAxis(ang:Right(), v.angle.p) | |
ang:RotateAroundAxis(ang:Forward(), v.angle.r) | |
else | |
bone = ent:LookupBone(bone_override or tab.bone) | |
if (!bone) then return end | |
pos, ang = Vector(0,0,0), Angle(0,0,0) | |
local m = ent:GetBoneMatrix(bone) | |
if (m) then | |
pos, ang = m:GetTranslation(), m:GetAngles() | |
end | |
end | |
return pos, ang | |
end | |
function ENT:CreateModels( tab ) | |
if (!tab) then return end | |
-- Create the clientside models here because Garry says we can't do it in the render hook | |
for k, v in pairs( tab ) do | |
if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and | |
string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then | |
v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE) | |
if (IsValid(v.modelEnt)) then | |
v.modelEnt:SetPos(self:GetPos()) | |
v.modelEnt:SetAngles(self:GetAngles()) | |
v.modelEnt:SetParent(self) | |
v.modelEnt:SetNoDraw(true) | |
v.createdModel = v.model | |
else | |
v.modelEnt = nil | |
end | |
elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite) | |
and file.Exists ("materials/" .. v.sprite .. ".vmt", "GAME")) then | |
local name = v.sprite .. "-" | |
local params = { ["$basetexture"] = v.sprite } | |
-- make sure we create a unique name based on the selected options | |
local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" } | |
for i, j in pairs( tocheck ) do | |
if (v[j]) then | |
params["$" .. j] = 1 | |
name = name .. "1" | |
else | |
name = name .. "0" | |
end | |
end | |
v.createdSprite = v.sprite | |
v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params) | |
end | |
end | |
end | |
--[[************************* | |
Global utility code | |
*************************]] | |
-- Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference). | |
-- Does not copy entities of course, only copies their reference. | |
-- WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop | |
function table.FullCopy( tab ) | |
if (!tab) then return nil end | |
local res = {} | |
for k, v in pairs( tab ) do | |
if (type(v) == "table") then | |
res[k] = table.FullCopy(v)-- recursion ho! | |
elseif (type(v) == "Vector") then | |
res[k] = Vector(v.x, v.y, v.z) | |
elseif (type(v) == "Angle") then | |
res[k] = Angle(v.p, v.y, v.r) | |
else | |
res[k] = v | |
end | |
end | |
return res | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment