This commit is contained in:
lifestorm
2024-08-04 23:12:27 +03:00
parent 0e770b2b49
commit ba1fc01b16
7084 changed files with 2173495 additions and 14 deletions

View File

@@ -0,0 +1,60 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
local ix = ix
include('shared.lua')
netstream.Hook("OpenComputer", function(activeComputer, activeComputerUsers, activeComputerNotes, groupmessages, hasDiskInserted)
LocalPlayer().activeComputer = activeComputer
LocalPlayer().activeComputer.hasDiskInserted = hasDiskInserted
LocalPlayer().activeComputerUsers = activeComputerUsers
LocalPlayer().activeComputerNotes = activeComputerNotes
netstream.Start("SyncStoredNewspapers")
local base = vgui.Create("CitizenComputer")
ix.gui.medicalComputer.groupMessages = groupmessages or {}
end)
-- function ENT:Draw()
-- self:DrawModel()
-- local ang = self:GetAngles()
-- local pos = self:GetPos() + ang:Up() * 12 + ang:Right() * 10 + ang:Forward() * 11.75
-- ang:RotateAroundAxis(ang:Right(), -85.6)
-- ang:RotateAroundAxis(ang:Up(), 90)
-- local width, height = 200, 170
-- local display = self.Displays[self:GetDisplay()] or self.Displays[6]
-- cam.Start3D2D( pos, ang, 0.1 )
-- render.PushFilterMin(TEXFILTER.NONE)
-- render.PushFilterMag(TEXFILTER.NONE)
-- surface.SetDrawColor( Color( 16, 16, 16, 240 ) )
-- surface.DrawRect( 0, 0, width, height )
-- surface.SetDrawColor( Color( 255, 255, 255, 16 ) )
-- surface.DrawRect( 10, height / 2 + math.sin( CurTime() * 4 ) * height / 2.5, width - 22, 1 )
-- local alpha = 191 + 64 * math.sin( CurTime() * 4 )
-- local color = ColorAlpha(display[2], alpha)
-- draw.SimpleText( "Computer", "MenuFont", width / 2, 25, Color( 255, 255, 255, alpha ), TEXT_ALIGN_CENTER )
-- draw.SimpleText( display[1], "MenuFont", width / 2, height - 35, Color( 255, 255, 180, alpha ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
-- render.PopFilterMin()
-- render.PopFilterMag()
-- cam.End3D2D()
-- end

View File

@@ -0,0 +1,73 @@
--[[
| 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/
--]]
local timer = timer
local IsValid = IsValid
AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside
AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent.
include("shared.lua")
function ENT:SetProperSkin()
self:SetSkin(0)
end
function ENT:SaveMedicalComputers()
ix.saveEnts:SaveEntity(self)
end
function ENT:Use(client)
if (client.CantPlace) then
client:NotifyLocalized("Musisz poczekać, zanim będziesz mógł tego użyć!")
return false
end
client.CantPlace = true
timer.Simple(3, function()
if (client) then
client.CantPlace = false
end
end)
if (self:GetNWInt("owner") == nil) then
self:SetNWInt("owner", client:GetCharacter():GetID())
end
if (!self.canUse) then
return
end
self:EmitSound( "buttons/button1.wav" )
self.canUse = false
if (client:GetCharacter():GetGroup()) then
self:GetGroupInformation(client, client:GetCharacter(), true)
else
netstream.Start(client, "OpenComputer", self, self.users, self.notes, false, self.hasDiskInserted)
end
self:SetDisplay(2)
local uniqueID = "computer_"..self:EntIndex().."_charcheck"
timer.Create(uniqueID, 10, 0, function()
if (!IsValid(self)) then
timer.Remove(uniqueID)
return
elseif (!IsValid(client) or !client:GetCharacter()) then
self.canUse = true
self:SetDisplay(1)
timer.Remove(uniqueID)
end
end)
end

View File

@@ -0,0 +1,22 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
ENT.Type = "anim"
ENT.Author = "Fruity"
ENT.Base = "ix_medical_computer"
ENT.PrintName = "Computer"
ENT.Category = "HL2 RP"
ENT.Spawnable = true
ENT.AdminOnly = true
ENT.PhysgunDisable = true
ENT.bNoPersist = true

View File

@@ -0,0 +1,43 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
include('shared.lua')
function ENT:Draw()
self:DrawModel() -- Draw the model
local ang = self:GetAngles()
local pos = self:GetPos() + ang:Up() * 48 + ang:Right() * 9.8 + ang:Forward() * -2.38
ang:RotateAroundAxis(ang:Right(), -90)
ang:RotateAroundAxis(ang:Up(), 90)
ang:RotateAroundAxis( ang:Forward(), -48 )
cam.Start3D2D( pos, ang, 0.1 )
local width, height = 155, 80
surface.SetDrawColor( Color( 255, 255, 255, 16 ) )
surface.DrawRect( 0, height / 2 + math.sin( CurTime() * 4 ) * height / 2, width, 1 )
local alpha = 191 + 64 * math.sin( CurTime() * 4 )
draw.SimpleText( "Konsola poleceń", "MenuFont", width / 2, 15, Color( 255, 255, 255, alpha ), TEXT_ALIGN_CENTER )
draw.SimpleText( "Oczekiwanie na użytkownika", "MenuFont", width / 2, height - 25, Color( 255, 255, 180, alpha ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
cam.End3D2D()
end
netstream.Hook("OpenConsoleGUI", function(entity)
ix.gui.consolePanel = vgui.Create("ConsolePanel")
ix.gui.consolePanel.entity = entity
end)

View File

@@ -0,0 +1,156 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside
AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent.
include('shared.lua')
function ENT:Initialize()
self:SetModel( "models/props_combine/combine_interface001.mdl" )
self:SetSubMaterial(1, "phoenix_storms/black_chrome")
self:SetSolid(SOLID_VPHYSICS)
self:SetMoveType(MOVETYPE_VPHYSICS)
self:PhysicsInit( SOLID_VPHYSICS )
self:SetUseType(SIMPLE_USE)
self.canUse = true
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:EnableMotion(false)
physObj:Wake()
end
if table.Count(ents.FindByClass("ix_console")) == 1 then
self:SetName("ix_console_master")
end
ix.saveEnts:SaveEntity(self)
end
function ENT:Use(client)
if (self.canUse) then
if ((!IsValid(self.user) or self.user == client) and client:GetActiveCombineSuit()) then
self.user = client
client.ixConsole = self
self:EmitSound("buttons/button19.wav", 75)
netstream.Start(client, "OpenConsoleGUI", self)
ix.combineNotify:AddNotification("LOG:// Konsola poleceń została użyta przez " .. client:GetCombineTag(), nil, client)
else
self.canUse = false
self:EmitSound("buttons/button8.wav", 75)
timer.Simple(1, function()
self.canUse = true
end)
end
end
end
function ENT:AcceptInput(input, activator, caller, data)
if (!caller.lastTarget or caller.lastTarget != activator) then
caller.lastTarget = activator
end
if (input == "Alert" and self:GetName() == "ix_console_master") then
local character = activator:GetCharacter()
if (activator:IsPlayer() and character and character:GetGenericdata() and !isnumber(character:GetGenericdata())) then
local genericData = character:GetGenericdata()
local cid = character:GetCid() or "N/A"
local name = string.utf8upper(character:GetName()) or "N/A"
if (genericData.anticitizen) then
if (genericData.anticitizen == true) then
caller:Fire("SetAngry", 0, 0)
ix.combineNotify:AddImportantNotification("WRN:// Wizja na Antyobywatelu " .. name .. ", #" .. cid, nil, activator, activator:GetPos())
end
end
if (genericData.bol) then
if (genericData.bol == true) then
caller:Fire("SetAngry", 0, 0)
ix.combineNotify:AddImportantNotification("WRN:// Wizja na BOLu " .. name .. ", #" .. cid, Color(255, 255, 0, 255), activator, activator:GetPos())
end
end
if (activator:Team() == FACTION_VORT and character:GetBackground() != "Biotyk" and character:GetBackground() != "Kolaborator") then
local items = character:GetInventory():GetItems()
local shackles = false
local hooks = false
local collar = false
for itemID, itemData in pairs(items) do
if (ix.item.instances[itemID]:GetData("equip")) then
if (ix.item.instances[itemID].uniqueID == "vortigaunt_slave_shackles_fake") then
shackles = true
elseif (ix.item.instances[itemID].uniqueID == "vortigaunt_slave_hooks_fake") then
hooks = true
elseif (ix.item.instances[itemID].uniqueID == "vortigaunt_slave_collar_fake") then
collar = true
end
end
end
if (!shackles or !hooks or !collar) then
caller:Fire("SetAngry", 0, 0)
ix.combineNotify:AddImportantNotification("WRN:// Wizja na niezarejestrowanym Biotyku #" .. cid, Color(255, 0, 0, 255), activator, activator:GetPos())
end
end
end
if (activator:IsPlayer() and activator:IsRunning()) then
caller:Fire("SetAngry", 0, 0)
end
end
end
function ENT:OnRemove()
if IsValid(self.user) then
self.user.currentCamera = nil
end
self.user = nil
end
function ENT:CloseConsole()
if (IsValid(self.user)) then
self.user.currentCamera = nil
end
self.user = nil
end
-- Hooks
local function SetupCameraVis(client, entity)
if IsValid(client.currentCamera) then
AddOriginToPVS(client.currentCamera:GetPos())
end
end
hook.Add("SetupPlayerVisibility", "ConsoleCameraVisual", SetupCameraVis)
local function OnCameraCreated(entity)
if !entity or entity and !IsValid(entity) then return end
if (entity:GetClass() == "npc_combine_camera") then
timer.Simple(1, function()
if !entity or entity and !IsValid(entity) then return end
entity:SetHealth(100)
end)
entity:Fire("AddOutput", "OnFoundEnemy ix_console:Alert")
--ix.saveEnts:SaveEntity(entity)
end
end
hook.Add("OnEntityCreated", "OnCameraCreated", OnCameraCreated)

View File

@@ -0,0 +1,28 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
ENT.Type = "anim"
ENT.Base = "base_gmodentity"
ENT.PrintName = "Console"
ENT.Author = "Fruity"
ENT.Contact = ""
ENT.Purpose = ""
ENT.Instructions = "Fruitybooty"
ENT.Category = "HL2 RP"
ENT.Spawnable = true
ENT.AdminOnly = true
ENT.PhysgunDisable = true
ENT.bNoPersist = true

View File

@@ -0,0 +1,91 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
include('shared.lua')
netstream.Hook("OpenMedicalComputer", function(activeComputer, activeComputerUsers, activeComputerNotes, groupmessages, hasDiskInserted)
LocalPlayer().activeComputer = activeComputer
LocalPlayer().activeComputer.hasDiskInserted = hasDiskInserted
LocalPlayer().activeComputerUsers = activeComputerUsers
LocalPlayer().activeComputerNotes = activeComputerNotes
netstream.Start("SyncStoredNewspapers")
ix.gui.medicalComputer = vgui.Create("MedicalComputerBase")
ix.gui.medicalComputer.groupMessages = groupmessages or {}
end)
netstream.Hook("SyncStoredNewspapersClient", function(stored)
local writingPlugin = ix.plugin.list["writing"]
writingPlugin.storedNewspapers = stored
end)
netstream.Hook("createMedicalRecords", function(table, resultName, searchname, resultID)
LocalPlayer().activeComputerRecords = table
LocalPlayer().activeComputerResultName = resultName
LocalPlayer().activeComputerSearchName = searchname
LocalPlayer().activeComputerResultID = resultID
end)
function ENT:Initialize()
self:StartShittyComputerSound()
end
function ENT:StartShittyComputerSound()
local uniqueID = "MedicalAmbientSound_"..self:EntIndex()
local time = 1
timer.Simple(1, function()
timer.Adjust(uniqueID, 8)
end)
timer.Create(uniqueID, time, 0, function()
if (IsValid(self)) then
self:EmitSound( "willardnetworks/datapad/computerloop.wav", 65, 100, 0.15)
else
timer.Remove(uniqueID)
end
end)
end
-- function ENT:Draw()
-- self:DrawModel()
-- local ang = self:GetAngles()
-- local pos = self:GetPos() + ang:Up() * 12 + ang:Right() * 10 + ang:Forward() * 11.75
-- ang:RotateAroundAxis(ang:Right(), -85.6)
-- ang:RotateAroundAxis(ang:Up(), 90)
-- local width, height = 200, 170
-- local display = self.Displays[self:GetDisplay()] or self.Displays[6]
-- cam.Start3D2D( pos, ang, 0.1 )
-- render.PushFilterMin(TEXFILTER.NONE)
-- render.PushFilterMag(TEXFILTER.NONE)
-- surface.SetDrawColor( Color( 16, 16, 16, 240 ) )
-- surface.DrawRect( 0, 0, width, height )
-- surface.SetDrawColor( Color( 255, 255, 255, 16 ) )
-- surface.DrawRect( 10, height / 2 + math.sin( CurTime() * 4 ) * height / 2.5, width - 22, 1 )
-- local alpha = 191 + 64 * math.sin( CurTime() * 4 )
-- draw.SimpleText( "Medical Computer", "MenuFont", width / 2, 25, Color( 255, 255, 255, alpha ), TEXT_ALIGN_CENTER )
-- draw.SimpleText( display[1], "MenuFont", width / 2, height - 35, Color( 255, 255, 180, alpha ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
-- render.PopFilterMin()
-- render.PopFilterMag()
-- cam.End3D2D()
-- end

View File

@@ -0,0 +1,395 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside
AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent.
include('shared.lua')
util.AddNetworkString( "TypeSound" )
util.AddNetworkString( "ClickSound" )
function ENT:Initialize()
self:SetModel("models/willardnetworks/props/willard_computer.mdl")
self:SetSolid(SOLID_VPHYSICS)
self:SetMoveType(MOVETYPE_VPHYSICS)
self:PhysicsInit( SOLID_VPHYSICS )
self:DrawShadow(false)
self:SetUseType(SIMPLE_USE)
self:SetDisplay(1)
local physics = self:GetPhysicsObject()
physics:EnableMotion(true)
physics:Wake()
timer.Simple(1, function()
if IsValid(self) and physics then
physics:EnableMotion(false)
end
end)
self.canUse = true
self.users = {}
self.notes = {}
self:SaveMedicalComputers()
-- self:SpawnProps()
self:SetProperSkin()
self.hasDiskInserted = false
end
function ENT:SetProperSkin()
self:SetSkin(1)
end
function ENT:SaveMedicalComputers()
ix.saveEnts:SaveEntity(self)
end
function ENT:CloseMedicalComputer()
self:SetDisplay(3)
self:EmitSound("ambient/machines/combine_terminal_idle1.wav")
timer.Remove("computer_"..self:EntIndex().."_charcheck")
timer.Simple(2, function()
if IsValid(self) then
self:SetDisplay(1)
self.canUse = true
end
end)
end
-- function ENT:SpawnProps()
-- local rightFrom = Vector(-20 * self:GetRight(), 0, 0)
-- local leftFrom = Vector(20 * self:GetRight(), 0, 0)
-- local forwardFrom = Vector(20 * self:GetForward(), 0, 0)
-- local aBitDown = Vector(0, 0, 3)
-- local cabinet = ents.Create("prop_dynamic")
-- cabinet:SetPos(self:GetPos() + leftFrom - aBitDown)
-- cabinet:SetAngles(self:GetAngles())
-- cabinet:SetModel("models/props_lab/harddrive02.mdl")
-- cabinet:Activate()
-- cabinet:SetParent(self)
-- cabinet:Spawn()
-- cabinet:DeleteOnRemove(self)
-- local keyboard = ents.Create("prop_dynamic")
-- keyboard:SetPos(self:GetPos() + forwardFrom - (aBitDown * 4.5))
-- keyboard:SetAngles(self:GetAngles())
-- keyboard:SetModel("models/props_c17/computer01_keyboard.mdl")
-- keyboard:Activate()
-- keyboard:SetParent(self)
-- keyboard:Spawn()
-- keyboard:DeleteOnRemove(self)
-- local mouse = ents.Create("prop_dynamic")
-- mouse:SetPos(self:GetPos() + forwardFrom + rightFrom - (aBitDown * 4.3))
-- mouse:SetAngles(self:GetAngles() + Angle(20, -80, 0))
-- mouse:SetModel("models/gibs/shield_scanner_gib1.mdl")
-- mouse:SetMaterial("phoenix_storms/dome")
-- mouse:Activate()
-- mouse:SetParent(self)
-- mouse:Spawn()
-- mouse:DeleteOnRemove(self)
-- end
function ENT:GetGroupInformation(client, character, bNormal)
self.groupmessages = {}
self.groupmessages["messages"] = {}
self.groupmessages["replies"] = {}
local messageQuery = mysql:Select("ix_comgroupmessages")
messageQuery:Select("message_id")
messageQuery:Select("message_text")
messageQuery:Select("message_date")
messageQuery:Select("message_poster")
messageQuery:Select("message_groupid")
messageQuery:Where("message_groupid", character:GetGroupID())
messageQuery:Callback(function(result)
self.groupmessages["messages"] = result or {}
local replyQuery = mysql:Select("ix_comgroupreplies")
replyQuery:Select("reply_id")
replyQuery:Select("reply_text")
replyQuery:Select("reply_date")
replyQuery:Select("reply_poster")
replyQuery:Select("reply_parent")
replyQuery:Select("reply_groupid")
replyQuery:Where("reply_groupid", character:GetGroupID())
replyQuery:Callback(function(result2)
self.groupmessages["replies"] = result2 or {}
if !bNormal then
netstream.Start(client, "OpenMedicalComputer", self, self.users, self.notes, self.groupmessages, self.hasDiskInserted)
else
netstream.Start(client, "OpenComputer", self, self.users, self.notes, self.groupmessages, self.hasDiskInserted)
end
end)
replyQuery:Execute()
end)
messageQuery:Execute()
end
function ENT:Use(client)
if (client.CantPlace) then
client:NotifyLocalized("Musisz poczekać, zanim będziesz mógł tego użyć!")
return false
end
client.CantPlace = true
timer.Simple(3, function()
if (client) then
client.CantPlace = false
end
end)
local character = client:GetCharacter()
if (self:GetNWInt("owner") == nil) then
self:SetNWInt("owner", character:GetID())
end
if !self.canUse then
return
end
self:EmitSound( "buttons/button1.wav" )
self.canUse = false
if (character:GetGroup()) then
self:GetGroupInformation(client, character, false)
else
netstream.Start(client, "OpenMedicalComputer", self, self.users, self.notes, false, self.hasDiskInserted)
end
self:SetDisplay(2)
local uniqueID = "computer_"..self:EntIndex().."_charcheck"
timer.Create(uniqueID, 10, 0, function()
if (!IsValid(self)) then
timer.Remove(uniqueID)
return
elseif (!IsValid(client) or !client:GetCharacter()) then
self.canUse = true
self:SetDisplay(1)
timer.Remove(uniqueID)
end
end)
end
function ENT:AddUser(cid)
if (self.users) then
if (istable(self.users)) then
table.insert(self.users, cid)
end
end
end
function ENT:AddNote(name, text, headline)
self.notes[#self.notes + 1] = {
text = text,
headline = headline,
date = ix.date.GetFormatted("%d/%m/%Y"),
poster = name
}
end
function ENT:UpdateNote(name, text, headline, key)
if !text then self.notes[key] = nil return end
self.notes[key] = {
text = text,
headline = headline,
date = ix.date.GetFormatted("%d/%m/%Y"),
poster = name
}
end
function ENT:OnRemove()
if timer.Exists("MedicalAmbientSound_"..self:EntIndex()) then
timer.Remove("MedicalAmbientSound_"..self:EntIndex())
end
end
function ENT:CheckIfUserHasAccess(client)
if client:HasActiveCombineSuit() then return true end
local character = client:GetCharacter()
local inventory = character:GetInventory()
local invItems = inventory:GetItems()
for _, v in pairs(self.users) do
for _, v2 in pairs(invItems) do
if v2.uniqueID != "id_card" then
continue
end
if tostring(v) == tostring(v2:GetData("cid")) then
return true
end
end
end
client:Notify("You do not have access or you are not wearing a combine suit.")
return false
end
netstream.Hook("AddComputerUser", function(client, activeComputer, cid)
if table.IsEmpty(activeComputer.users) then activeComputer:AddUser(cid) return end
if activeComputer:CheckIfUserHasAccess(client) then
activeComputer:AddUser(cid)
else
return false
end
end)
netstream.Hook("searchMedicalFile", function(client, searchname, activeComputer)
if !activeComputer:CheckIfUserHasAccess(client) then
return false
end
local curTime = CurTime()
if (client.nextSearchMedicalFile and client.nextSearchMedicalFile > curTime) then
return
end
client.nextSearchMedicalFile = curTime + 2
local query = mysql:Select("ix_characters")
query:Select("id")
query:Select("name")
query:Select("cid")
query:WhereLike(((tonumber(searchname) != nil and string.utf8len( searchname ) <= 5) and "cid" or "name"), searchname)
query:Where("schema", Schema and Schema.folder or "helix")
query:Limit(1)
query:Callback(function(result)
if (!istable(result)) then
netstream.Start(client, "createMedicalRecords", false, false, false, false)
return
end
if not result[1] then
netstream.Start(client, "createMedicalRecords", false, false, false, false)
return
end
local dataQuery = mysql:Select("ix_characters_data")
dataQuery:Select("data")
dataQuery:Where("id", result[1].id)
dataQuery:Where("key", "datafilemedicalrecords")
dataQuery:Callback(function(dataResult)
if (!istable(dataResult)) then
netstream.Start(client, "createMedicalRecords", false, false, false, false)
return
end
if not dataResult[1] then
netstream.Start(client, "createMedicalRecords", false, false, false, false)
return
end
local medicalrecords = util.JSONToTable(dataResult[1].data or "")
timer.Simple(0.05, function()
netstream.Start(client, "createMedicalRecords", medicalrecords, result[1].name, searchname, result[1].id)
end)
end)
dataQuery:Execute()
end)
query:Execute()
end)
netstream.Hook("MedicalComputerAddRecord", function(client, id, posterName, text, activeComputer)
if !activeComputer:CheckIfUserHasAccess(client) then
return false
end
id = tonumber(id)
local dataQuery = mysql:Select("ix_characters_data")
dataQuery:Select("data")
dataQuery:Where("id", id)
dataQuery:Where("key", "datafilemedicalrecords")
dataQuery:Callback(function(dataResult)
if (!istable(dataResult)) then
return
end
if not dataResult[1] then
return
end
local medicalrecords = util.JSONToTable(dataResult[1].data or "")
medicalrecords[#medicalrecords + 1] = {
text = text,
date = os.date("%d/%m/%Y"),
poster = posterName
}
if (ix.char.loaded[id]) then
ix.char.loaded[id]:SetDatafilemedicalrecords(medicalrecords)
ix.char.loaded[id]:Save()
else
local updateQuery = mysql:Update("ix_characters_data")
updateQuery:Update("data", util.TableToJSON(medicalrecords))
updateQuery:Where("id", id)
updateQuery:Where("key", "datafilemedicalrecords")
updateQuery:Execute()
end
end)
dataQuery:Execute()
end)
netstream.Hook("MedicalComputerAddNote", function(client, activeComputer, posterName, text, headline)
if !activeComputer:CheckIfUserHasAccess(client) then
return false
end
activeComputer:AddNote(posterName, text, headline)
end)
netstream.Hook("MedicalComputerUpdateNote", function(client, activeComputer, posterName, text, headline, key)
if !activeComputer:CheckIfUserHasAccess(client) then
return false
end
activeComputer:UpdateNote(posterName, text, headline, key)
end)
net.Receive( "TypeSound", function( length, client )
client:EmitSound(string.format( "ambient/machines/keyboard%d_clicks.wav", math.random( 6 ) ),75)
end )
net.Receive( "ClickSound", function( length, client )
client:EmitSound("willardnetworks/datapad/mouseclick.wav", 75)
end )
netstream.Hook("CloseMedicalComputer", function(client, activeComputer)
if activeComputer then
activeComputer:CloseMedicalComputer()
end
end)
netstream.Hook("SyncStoredNewspapers", function(client)
local writingPlugin = ix.plugin.list["writing"]
local storedNewspapers = writingPlugin.storedNewspapers
netstream.Start(client, "SyncStoredNewspapersClient", storedNewspapers)
end)

View File

@@ -0,0 +1,32 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
ENT.Type = "anim"
ENT.Author = "Fruity"
ENT.PrintName = "Medical Computer"
ENT.Category = "HL2 RP"
ENT.Spawnable = true
ENT.AdminOnly = true
ENT.PhysgunDisable = true
ENT.bNoPersist = true
ENT.Displays = {
[1] = {"OCZEKIWANIE", Color( 255, 255, 180 ), true},
[2] = {"POBIERANIE INFORMACJI", Color(0, 255, 0)},
[3] = {"PRZEŁADOWYWANIE", Color(255, 200, 0)},
[4] = {"OFFLINE", Color(255, 0, 0), true}
}
function ENT:SetupDataTables()
self:NetworkVar("Int", 0, "Display")
end

View File

@@ -0,0 +1,82 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
include('shared.lua')
netstream.Hook("OpenTerminal", function(idCardId, genericData, activeCID, credits, entity, messages)
LocalPlayer().idCardId = idCardId
LocalPlayer().idCardCredits = credits
LocalPlayer().activeTerminal = entity
LocalPlayer().genericData = genericData
LocalPlayer().activeCID = activeCID
if istable(messages) then
LocalPlayer().messageList = messages
else
messages = {}
LocalPlayer().messageList = messages
end
vgui.Create("ixTerminal")
end)
netstream.Hook("OpenCIDSelectorTerminal", function(entity)
LocalPlayer().activeTerminal = entity
local cidSelector = vgui.Create("CIDSelector")
cidSelector.activeEntity = entity
cidSelector.ExitCallback = function()
netstream.Start("ClosePanelsTerminal", LocalPlayer().activeTerminal)
LocalPlayer().activeTerminal = nil
LocalPlayer().genericData = nil
LocalPlayer().activeCID = nil
LocalPlayer().messageList = nil
end
cidSelector.SelectCallback = function(idCardID, cid, cidName, entity)
netstream.Start("SelectCIDTerminal", idCardID, cid, cidName, entity)
end
end)
function ENT:Draw()
self:DrawModel()
local width, height = 200, 120
local ang = self:GetAngles()
local pos = self:GetPos() + ang:Up() * 31.2 + ang:Right() * 13 + ang:Forward() * 3.1
ang:RotateAroundAxis(ang:Right(), 94)
ang:RotateAroundAxis(ang:Up(), 90)
ang:RotateAroundAxis(ang:Forward(), 180)
local display = self.Displays[self:GetDisplay()] or self.Displays[6]
cam.Start3D2D( pos, ang, 0.1 )
render.PushFilterMin(TEXFILTER.NONE)
render.PushFilterMag(TEXFILTER.NONE)
surface.SetDrawColor( Color( 16, 16, 16, 140 ) )
surface.DrawRect( 0, 0, width, height )
surface.SetDrawColor( Color( 255, 255, 255, 16 ) )
surface.DrawRect( 0, height / 2 + math.sin( CurTime() * 4 ) * height / 2, width, 1 )
local alpha = 191 + 64 * math.sin( CurTime() * 4 )
local color = ColorAlpha(display[2], alpha)
draw.SimpleText( "Terminal Obywatelski", "MenuFont", width / 2, 25, Color( 255, 255, 255, alpha ), TEXT_ALIGN_CENTER )
draw.SimpleText(display[1], "MenuFont", width / 2, height * 0.5, color, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
render.PopFilterMin()
render.PopFilterMag()
cam.End3D2D()
end

View File

@@ -0,0 +1,452 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
AddCSLuaFile( "cl_init.lua" ) -- Make sure clientside
AddCSLuaFile( "shared.lua" ) -- and shared scripts are sent.
include('shared.lua')
function ENT:Initialize()
self:SetModel(self.model)
self:SetSolid(SOLID_VPHYSICS)
self:SetMoveType(MOVETYPE_VPHYSICS)
self:PhysicsInit( SOLID_VPHYSICS )
self:DrawShadow(false)
self:SetUseType(SIMPLE_USE)
self:SetDisplay(1)
local physics = self:GetPhysicsObject()
if (physics) then
physics:EnableMotion(false)
physics:Wake()
end
self.canUse = true
self:SaveTerminalLocations()
self:OnInitialize()
end
function ENT:OnInitialize()
end
function ENT:SaveTerminalLocations()
ix.saveEnts:SaveEntity(self)
end
function ENT:CheckGlobalUse(client)
if client.CantPlace then
client:NotifyLocalized("Musisz poczekać, zanim będziesz mógł tego użyć!")
return false
end
client.CantPlace = true
timer.Simple(3, function()
if client then
client.CantPlace = false
end
end)
return true
end
function ENT:CheckLocalUse(client)
if (!self.canUse and IsValid(self.activePlayer) and self.activePlayer:GetCharacter() == self.activeCharacter) then
return false
else
self.canUse = false
self.activePlayer = client
self.activeCharacter = client:GetCharacter()
return true
end
end
function ENT:Use(client)
if !self:CheckGlobalUse(client) then
return false
end
if !self:CheckLocalUse(client) then
return false
end
self:OnUse(client)
end
function ENT:OnUse(client)
self:CheckForCID(client)
end
function ENT:SetGroups(bUse)
if bUse then
self:SetBodygroup(2, 1)
self:SetSkin(1)
else
self:SetBodygroup(2, 0)
self:SetSkin(0)
end
end
function ENT:CheckForCID(client)
if (ix.config.Get("creditsNoConnection")) then
self.canUse = false
self:SetGroups(true)
self:SetDisplay(2)
self:EmitSound("buttons/button4.wav")
timer.Simple(10, function()
if (!IsValid(self)) then return end
self:SetDisplay(5)
self:EmitSound("hl1/fvox/buzz.wav", 60, 100, 0.5)
timer.Simple(5, function()
if (!IsValid(self)) then return end
self.canUse = true
self:SetDisplay(1)
self:SetGroups(false)
end)
end)
return
end
local idCards = self.activeCharacter:GetInventory():GetItemsByUniqueID("id_card")
if (#idCards > 1) then
self:OpenCIDSelector(client)
return
end
if (#idCards == 1) then
self:SetGroups(true)
idCards[1]:LoadOwnerGenericData(self.OpenTerminal, self.OpenTerminalFail, client, self)
else
self.canUse = false
self:EmitSound("buttons/button2.wav")
timer.Simple(1, function()
if (IsValid(self)) then
self.canUse = true
end
end)
end
end
function ENT:OpenCIDSelector(client)
netstream.Start(client, "OpenCIDSelectorTerminal", self)
end
netstream.Hook("SelectCIDTerminal", function(client, idCardID, _, _, activeTerminal)
if (IsValid(activeTerminal)) then
local idCard = ix.item.instances[idCardID]
if (!idCard) then
activeTerminal.OpenTerminalFail(nil, client, activeTerminal)
else
idCard:LoadOwnerGenericData(activeTerminal.OpenTerminal, activeTerminal.OpenTerminalFail, client, activeTerminal)
end
end
end)
netstream.Hook("ClosePanelsTerminal", function(client, activeTerminal)
if (IsValid(activeTerminal)) then
activeTerminal.OpenTerminalFail(nil, client, activeTerminal)
end
activeTerminal.genericDataCredits = nil
activeTerminal.genericDataCommunion = nil
activeTerminal.activeCID = nil
end)
function ENT.OpenTerminalFail(idCard, client, activeTerminal)
if (!IsValid(activeTerminal)) then return end
activeTerminal:SetDisplay(4)
activeTerminal:EmitSound("ambient/machines/combine_terminal_idle1.wav")
activeTerminal:SetGroups(false)
timer.Simple(2, function()
if IsValid(activeTerminal) then
activeTerminal:SetDisplay(1)
activeTerminal.canUse = true
end
end)
end
function ENT.OpenTerminal(idCard, genericData, client, activeTerminal)
if (!IsValid(activeTerminal)) then return end
activeTerminal:SetGroups(true)
activeTerminal:EmitSound("buttons/button4.wav")
activeTerminal:SetDisplay(2)
if (activeTerminal:CheckForVerdicts(client, idCard, genericData)) then
timer.Simple(2, function()
if table.IsEmpty(genericData) then
activeTerminal:SetDisplay(8)
activeTerminal:EmitSound("buttons/button2.wav")
timer.Simple(2, function()
if IsValid(activeTerminal) then
activeTerminal:SetDisplay(1)
activeTerminal.canUse = true
end
end)
else
activeTerminal:OnSuccess(idCard, genericData, client)
end
end)
end
end
function ENT:IsSocialOrCohesion(character, genericData)
if (character:IsVortigaunt()) then
if (genericData.cohesionPoints) then
return genericData.cohesionPoints
else
return genericData.socialCredits
end
else
return genericData.socialCredits
end
end
function ENT:OnSuccess(idCard, genericData, client)
local character = client:GetCharacter()
self:SetDisplay(7)
self:EmitSound("ambient/machines/combine_terminal_idle3.wav")
self.genericDataCommunion = genericData.bypassCommunion
self.activeCID = idCard:GetData("cid")
genericData.socialCredits = !genericData.combine and math.Clamp(tonumber(self:IsSocialOrCohesion(character, genericData)), 0, 200) or tonumber(self:IsSocialOrCohesion(character, genericData))
self.genericDataCredits = genericData.socialCredits
local query = mysql:Select("ix_camessaging")
query:Select("message_cid")
query:Select("message_text")
query:Select("message_date")
query:Select("message_poster")
query:Select("message_reply")
query:Where("message_cid", idCard:GetData("cid"))
query:Callback(function(result)
if (character:IsVortigaunt()) then
if (genericData.cid or character:GetBackground() == "Kolaborator") then
ix.combineNotify:AddNotification("LOG:// Podmiot " .. string.upper("identyfikator zasobu biotyczynego:") .. " #" .. genericData.cid .. " użył Terminala Obywatelskiego", nil, client)
else
ix.combineNotify:AddNotification("LOG:// Podmiot " .. string.upper("obroża zasobu biotycznego:") .. " #" .. character:GetCollarID() .. " użył Terminala Obywatelskiego", nil, client)
end
else
ix.combineNotify:AddNotification("LOG:// Podmiot '" .. genericData.name .. "' użył Terminala Obywatelskiego", nil, client)
end
if (!istable(result)) then
netstream.Start(client, "OpenTerminal", idCard:GetID(), genericData, idCard:GetData("cid"), idCard:GetCredits(), self)
return
end
netstream.Start(client, "OpenTerminal", idCard:GetID(), genericData, idCard:GetData("cid"), idCard:GetCredits(), self, result)
end)
query:Execute()
end
function ENT:CheckForVerdicts(client, idCard, genericData)
if (idCard:GetData("active", false) == false) then
self:CreateCombineAlert(client, "WRN:// Wykryto próbę użycia nieaktywnego CID #" .. idCard:GetData("cid", 00000))
self:SetDisplay(8)
timer.Simple(1.5, function()
if self then
self.OpenTerminalFail(nil, client, self)
end
end)
return
end
local isBOL = genericData.bol
local isAC = genericData.anticitizen
if (isBOL or isAC) then
local text = isBOL and "Podejrzanego BOL" or "Antyobywatela"
self:CreateCombineAlert(client, "WRN:// Wykryto aktywność identyfikatora " .. text)
if isAC then
self:SetDisplay(8)
timer.Simple(1.5, function()
if self then
self.OpenTerminalFail(nil, client, self)
end
end)
end
return !isAC -- stop if isAC, continue for isBOL
end
return true
end
function ENT:CreateCombineAlert(client, message)
ix.combineNotify:AddImportantNotification(message, nil, client, self:GetPos())
end
function ENT.CheckIdCardCoupon(idCard, genericData, client, entity, couponAmount)
local character = client:GetCharacter()
if entity:IDCardCheck(idCard, genericData, client, entity) then
entity:EmitSound("ambient/levels/labs/coinslot1.wav")
if (ix.config.Get("creditsNoConnection")) then
entity:SetDisplay(2)
entity.canUse = false
timer.Simple(10, function()
if (!IsValid(entity)) then return end
entity:SetDisplay(5)
entity:EmitSound("buttons/combine_button_locked.wav")
timer.Simple(5, function()
if (!IsValid(entity)) then return end
entity:SetDisplay(1)
entity.canUse = true
end)
timer.Simple(2, function()
if (!IsValid(entity)) then return end
entity:EmitSound("ambient/levels/labs/coinslot1.wav")
end)
end)
return
end
timer.Simple(1, function()
if IsValid(entity) then
entity:EmitSound("Friends/friend_online.wav")
end
end)
entity:SetDisplay(2)
entity.canUse = false
timer.Simple(2, function()
if IsValid(entity) then
if ix.city.main:HasCredits(couponAmount) then
entity:EmitSound("Friends/friend_join.wav")
entity:SetDisplay(4)
idCard:GiveCredits(couponAmount, "Rations", "Ration Coupon")
ix.city.main:TakeCredits(couponAmount)
else
entity:SetDisplay(2)
entity.canUse = false
timer.Simple(10, function()
if (!IsValid(entity)) then return end
entity:SetDisplay(5)
entity:EmitSound("buttons/combine_button_locked.wav")
timer.Simple(5, function()
if (!IsValid(entity)) then return end
entity:SetDisplay(1)
entity.canUse = true
end)
timer.Simple(2, function()
if (!IsValid(entity)) then return end
entity:EmitSound("ambient/levels/labs/coinslot1.wav")
end)
end)
return
end
if ix.item.instances[client.ixCouponUsed] then
ix.item.instances[client.ixCouponUsed]:Remove()
end
client.ixCouponUsed = nil
ix.log.Add(client, "rationsCoupon", couponAmount)
timer.Simple(2, function()
if IsValid(entity) then
entity:SetDisplay(1)
entity.canUse = true
end
end)
end
end)
end
end
function ENT.CheckIdError(idCard, client, entity)
entity:DisplayError(INVALID_CID)
client.ixCouponUsed = nil
end
function ENT:IDCardCheck(idCard, genericData, client, entity)
if (idCard:GetData("active", false) == false) then
entity:CreateCombineAlert(client, "WRN:// Wykryto próbę użycia nieaktywnego CID #" .. idCard:GetData("cid", 00000), FREQ_LIMIT)
return false
end
local isBOL = genericData.bol
local isAC = genericData.anticitizen
if (isBOL or isAC) then
local text = isBOL and "Podejrzanego BOL" or "Antyobywatela"
entity:CreateCombineAlert(client, "WRN:// Wykryto aktywność identyfikatora " .. text, isAC and FREQ_LIMIT)
-- only halt if isAC, allow it to continue for BOL
if (isAC) then
return false
end
end
return true
end
netstream.Hook("AddCAMessage", function(client, name, cid, text, activeTerminal)
if !text or !name or !cid then return false end
if cid != activeTerminal.activeCID then
return false
end
if activeTerminal.genericDataCredits < ix.config.Get("communionSCRequirement", 150) and !activeTerminal.genericDataCommunion then
return false
end
local timestamp = os.date( "%d.%m.%Y" )
local queryObj = mysql:Insert("ix_camessaging")
queryObj:Insert("message_poster", name)
queryObj:Insert("message_text", text)
queryObj:Insert("message_date", timestamp)
queryObj:Insert("message_cid", cid)
queryObj:Execute()
ix.combineNotify:AddNotification("LOG:// Podmiot '" .. name .. "' wysłał wiadomość za pomocą terminala komunikacyjnego", nil, client)
for _, v in pairs(player.GetAll()) do
if !IsValid(v) then continue end
local character = v:GetCharacter()
if !character then continue end
local inventory = character:GetInventory()
if !inventory:HasItem("capda") then continue end
v:Notify("Ktoś właśnie wysłał wiadomość przez terminal komunikacyjny!")
end
end)
netstream.Hook("RemoveCAMessage", function(client, id)
if !id then return false end
if !client:GetCharacter():GetFaction() != FACTION_ADMIN then return false end
local queryObj = mysql:Delete("ix_camessaging")
queryObj:Where("message_id", id)
queryObj:Execute()
end)
netstream.Hook("BreakAttemptSpottedTerminal", function(client, name, cid, activeTerminal)
if cid != activeTerminal.activeCID then
return false
end
ix.combineNotify:AddImportantNotification("WRN:// Próba 51b; Uszkodzenie mienia publicznego", nil, client, client:GetPos())
end)

View File

@@ -0,0 +1,43 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
ENT.Type = "anim"
ENT.PrintName = "Terminal Obywatelski"
ENT.Author = "Fruity"
ENT.Contact = "Willard Networks"
ENT.Purpose = "View datafile info and more via entity."
ENT.Instructions = "Press E"
ENT.Category = "HL2 RP"
ENT.Spawnable = true
ENT.AdminOnly = true
ENT.PhysgunDisable = true
ENT.bNoPersist = true
ENT.model = "models/willardnetworks/props/civilterminal7.mdl"
ENT.canMalfunction = true
ENT.Displays = {
[1] = {"OCZEKIWANIE NA CID", Color( 255, 255, 180 ), true},
[2] = {"WERYFIKOWANIE", Color(255, 200, 0)},
[3] = {"POBIERANIE INFORMACJI", Color(0, 255, 0)},
[4] = {"PRZEŁADOWYWANIE", Color(255, 200, 0)},
[5] = {"OFFLINE", Color(255, 0, 0), true},
[6] = {"OCZEKIWANIE NA CID", Color( 255, 255, 180 )},
[7] = {"PRZYGOTOWYWANIE", Color(0, 255, 0)},
[8] = {"BRAK INFORMACJI", Color(0, 255, 0)}
}
function ENT:SetupDataTables()
self:NetworkVar("Int", 0, "Display")
end

View File

@@ -0,0 +1,606 @@
--[[
| 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/
--]]
local PLUGIN = PLUGIN
if (SERVER) then
AddCSLuaFile("shared.lua")
end
SWEP.PrintName = "Datapad Kombinatu"
SWEP.Category = "Half-Life 2"
SWEP.Spawnable= true
SWEP.AdminSpawnable= true
SWEP.AdminOnly = false
SWEP.ViewModelFOV = 70
SWEP.ViewModel = "models/weapons/c_slam.mdl"
SWEP.WorldModel = "models/weapons/w_slam.mdl"
SWEP.ShowViewModel = false
SWEP.ShowWorldModel = false
SWEP.ViewModelFlip = false
SWEP.BobScale = 1
SWEP.SwayScale = 0
SWEP.AutoSwitchTo = false
SWEP.AutoSwitchFrom = false
SWEP.Weight = 0
SWEP.Slot = 0
SWEP.SlotPos = 1
SWEP.UseHands = true
SWEP.FireWhenLowered = true
SWEP.FiresUnderwater = true
SWEP.DrawAmmo = false
SWEP.CSMuzzleFlashes = 1
SWEP.Base = "weapon_base"
SWEP.IsAlwaysRaised = true
SWEP.HoldType = "knife"
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = ""
SWEP.Primary.Damage = 5
SWEP.Primary.Delay = 0.75
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = 0
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = ""
SWEP.Secondary.Delay = 0.5
SWEP.MaxOffFlat = 80 -- Maximum degrees off of flat to be.
SWEP.LastFire = 0
SWEP.IronSightsPos = Vector(0, 0, 0)
SWEP.IronSightsAng = Vector(0, 0, 0)
SWEP.ViewModelBoneMods = {
["Slam_base"] = { scale = Vector(0.001, 0.001, 0.001), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) },
["Detonator"] = { scale = Vector(0.001, 0.001, 0.001), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) }
}
SWEP.VElements = {
["v_element"] = { type = "Model", model = "models/fruity/tablet/tablet_sfm.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(7.068, 2.714, -1.198), angle = Angle(75.973, -119.392, 180), size = Vector(1, 1, 2), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 3, bodygroup = {} }
}
SWEP.WElements = {
["w_element"] = { type = "Model", model = "models/fruity/tablet/tablet_sfm.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(3.901, 5.111, -0.477), angle = Angle(36.905, -180, -178.631), size = Vector(0.8, 0.8, 0.8), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 3, bodygroup = {} }
}
function SWEP:Initialize()
self:SetHoldType( self.HoldType )
if CLIENT then
-- Create a new table for every weapon instance
self.VElements = table.FullCopy( self.VElements )
self.WElements = table.FullCopy( self.WElements )
self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
self:SetHoldType( self.HoldType )
self:CreateModels(self.VElements) -- create viewmodels
self:CreateModels(self.WElements) -- create worldmodels
-- init view model bone build function
if IsValid(self.Owner) then
local vm = self.Owner:GetViewModel()
if IsValid(vm) then
self:ResetBonePositions(vm)
-- Init viewmodel visibility
if (self.ShowViewModel == nil or self.ShowViewModel) then
vm:SetColor(Color(255,255,255,255))
else
-- we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
vm:SetColor(Color(255,255,255,1))
-- ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
-- however for some reason the view model resets to render mode 0 every frame so we just apply a debug material to prevent it from drawing
vm:SetMaterial("Debug/hsv")
end
end
end
end
end
----------------------------------------------------
if CLIENT then
SWEP.vRenderOrder = nil
function SWEP:ViewModelDrawn()
local vm = self.Owner:GetViewModel()
if !IsValid(vm) then return end
if (!self.VElements) then return end
self:UpdateBonePositions(vm)
if (!self.vRenderOrder) then
-- we build a render order because sprites need to be drawn after models
self.vRenderOrder = {}
for k, v in pairs( self.VElements ) do
if (v.type == "Model") then
table.insert(self.vRenderOrder, 1, k)
elseif (v.type == "Sprite" or v.type == "Quad") then
table.insert(self.vRenderOrder, k)
end
end
end
for _, name in ipairs( self.vRenderOrder ) do
local v = self.VElements[name]
if (!v) then self.vRenderOrder = nil break end
if (v.hide) then continue end
local model = v.modelEnt
local sprite = v.spriteMaterial
if (!v.bone) then continue end
local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
if (!pos) then continue end
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 IsValid(PLUGIN.updates) and PLUGIN.updates:IsVisible() then
model:SetSkin(3)
elseif IsValid(PLUGIN.viewLogs) and PLUGIN.viewLogs:IsVisible() then
model:SetSkin(5)
elseif IsValid(PLUGIN.viewLog) and PLUGIN.viewLog:IsVisible() then
model:SetSkin(6)
elseif IsValid(PLUGIN.editupdates) and PLUGIN.editupdates:IsVisible() then
model:SetSkin(7)
elseif (IsValid(PLUGIN.editUpdate) and PLUGIN.editUpdate:IsVisible()) or (IsValid(PLUGIN.newUpdate) and PLUGIN.newUpdate:IsVisible()) then
model:SetSkin(10)
elseif IsValid(PLUGIN.verdictCodes) and PLUGIN.verdictCodes:IsVisible() then
model:SetSkin(11)
elseif IsValid(PLUGIN.communicationCodes) and PLUGIN.communicationCodes:IsVisible() then
model:SetSkin(12)
elseif IsValid(PLUGIN.datafileInfo) and PLUGIN.datafileInfo:IsVisible() then
model:SetSkin(4)
elseif IsValid(PLUGIN.viewEntryLogs) and PLUGIN.viewEntryLogs:IsVisible() then
model:SetSkin(13)
elseif IsValid(PLUGIN.violationsTitleSubframe) and PLUGIN.violationsTitleSubframe:IsVisible() then
model:SetSkin(16)
else
model:SetSkin(0)
end
if (v.bodygroup) then
for k, v1 in pairs( v.bodygroup ) do
if (model:GetBodygroup(k) != v1) then
model:SetBodygroup(k, v1)
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
SWEP.wRenderOrder = nil
function SWEP:DrawWorldModel()
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
local bone_ent
if (IsValid(self.Owner)) then
bone_ent = self.Owner
else
-- when the weapon is dropped
bone_ent = self
end
for _, 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
if (v.bone) then
pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
else
pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
end
if (!pos) then continue 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 IsValid(PLUGIN.updates) and PLUGIN.updates:IsVisible() then
model:SetSkin(3)
elseif IsValid(PLUGIN.viewLogs) and PLUGIN.viewLogs:IsVisible() then
model:SetSkin(5)
elseif IsValid(PLUGIN.viewLog) and PLUGIN.viewLog:IsVisible() then
model:SetSkin(6)
elseif IsValid(PLUGIN.editupdates) and PLUGIN.editupdates:IsVisible() then
model:SetSkin(7)
elseif (IsValid(PLUGIN.editUpdate) and PLUGIN.editUpdate:IsVisible()) or (IsValid(PLUGIN.newUpdate) and PLUGIN.newUpdate:IsVisible()) then
model:SetSkin(10)
elseif IsValid(PLUGIN.verdictCodes) and PLUGIN.verdictCodes:IsVisible() then
model:SetSkin(11)
elseif IsValid(PLUGIN.communicationCodes) and PLUGIN.communicationCodes:IsVisible() then
model:SetSkin(12)
elseif IsValid(PLUGIN.datafileInfo) and PLUGIN.datafileInfo:IsVisible() then
model:SetSkin(4)
elseif IsValid(PLUGIN.viewEntryLogs) and PLUGIN.viewEntryLogs:IsVisible() then
model:SetSkin(13)
elseif IsValid(PLUGIN.violationsTitleSubframe) and PLUGIN.violationsTitleSubframe:IsVisible() then
model:SetSkin(16)
else
model:SetSkin(0)
end
if (v.bodygroup) then
for k, v1 in pairs( v.bodygroup ) do
if (model:GetBodygroup(k) != v1) then
model:SetBodygroup(k, v1)
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 SWEP: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
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
if (IsValid(self.Owner) and self.Owner:IsPlayer() and
ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
ang.r = -ang.r -- Fixes mirrored models
end
end
return pos, ang
end
function SWEP:CreateModels( tab )
if (!tab) then return end
for _, 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 _, 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
local allbones
local hasGarryFixedBoneScalingYet = false
function SWEP:UpdateBonePositions(vm)
if self.ViewModelBoneMods then
if (!vm:GetBoneCount()) then return end
-- !! WORKAROUND !! --
-- We need to check all model names :/
local loopthrough = self.ViewModelBoneMods
if (!hasGarryFixedBoneScalingYet) then
allbones = {}
for i=0, vm:GetBoneCount() do
local bonename = vm:GetBoneName(i)
if (self.ViewModelBoneMods[bonename]) then
allbones[bonename] = self.ViewModelBoneMods[bonename]
else
allbones[bonename] = {
scale = Vector(1,1,1),
pos = Vector(0,0,0),
angle = Angle(0,0,0)
}
end
end
loopthrough = allbones
end
-- !! ----------- !! --
for k, v in pairs( loopthrough ) do
local bone = vm:LookupBone(k)
if (!bone) then continue end
-- !! WORKAROUND !! --
local s = Vector(v.scale.x,v.scale.y,v.scale.z)
local p = Vector(v.pos.x,v.pos.y,v.pos.z)
local ms = Vector(1,1,1)
if (!hasGarryFixedBoneScalingYet) then
local cur = vm:GetBoneParent(bone)
while(cur >= 0) do
local pscale = loopthrough[vm:GetBoneName(cur)].scale
ms = ms * pscale
cur = vm:GetBoneParent(cur)
end
end
s = s * ms
-- !! ----------- !! --
if vm:GetManipulateBoneScale(bone) != s then
vm:ManipulateBoneScale( bone, s )
end
if vm:GetManipulateBoneAngles(bone) != v.angle then
vm:ManipulateBoneAngles( bone, v.angle )
end
if vm:GetManipulateBonePosition(bone) != p then
vm:ManipulateBonePosition( bone, p )
end
end
else
self:ResetBonePositions(vm)
end
end
function SWEP:ResetBonePositions(vm)
if (!vm:GetBoneCount()) then return end
for i=0, vm:GetBoneCount() do
vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
end
end
--luacheck: ignore 122
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)
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
end
----------------------------------------------------
function SWEP:OnRemove()
end
function SWEP:Deploy()
--if !IsValid(self.Owner.C4s) then self.Owner.C4s = {} end
self.Weapon:SendWeaponAnim(ACT_SLAM_TRIPMINE_DRAW)
end
function SWEP:PrimaryAttack()
self:EmitSound( "UI/buttonclick.wav" )
self:SetNextPrimaryFire( CurTime()+2 )
if SERVER and IsFirstTimePredicted() then
if (PLUGIN:HasAccessToDatafile(self.Owner)) then
PLUGIN:Refresh(self.Owner)
else
self.Owner:NotifyLocalized("You do not have access to the datapad")
end
end
end
function SWEP:SecondaryAttack()
end
function SWEP:Holster()
if CLIENT and IsValid(self.Owner) then
local vm = self.Owner:GetViewModel()
if IsValid(vm) then
self:ResetBonePositions(vm)
end
end
return true
end
function SWEP:OnRemove()
self:Holster()
end