Files
wnsrc/gamemodes/ixhl2rp/plugins/combineutilities/sv_plugin.lua

510 lines
18 KiB
Lua
Raw Normal View History

2024-08-04 23:12:27 +03:00
--[[
| 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
function PLUGIN:GetHookCallPriority(hook)
if (hook == "HandlePlayerDeath") then
return 1100
end
end
function PLUGIN:PlayerLoadedCharacter(client, character)
-- Datafile
local bHasDatafile = character:GetHasDatafile()
if (!bHasDatafile) then
PLUGIN:CreateDatafile(client)
end
-- Teams
if (client:IsCombine()) then
self:LeaveTeam(client)
net.Start("ixPTSync")
net.WriteBool(true)
net.WriteTable(self.teams)
net.Send(client)
else
if (client:GetNetVar("ProtectionTeam")) then
self:LeaveTeam(client)
end
net.Start("ixPTSync")
net.WriteBool(false)
net.Send(client)
end
end
function PLUGIN:PostCalculatePlayerDamage(victim, damage, hitgroup)
if (victim.beingAmputated and victim.beingAmputatedEnd > CurTime() and damage:GetAttacker() == victim.beingAmputated) then
damage:ScaleDamage(hitgroup == HITGROUP_HEAD and 10 or 5)
end
end
function PLUGIN:HandlePlayerDeath(victim, damage)
if (victim.beingAmputated and victim.beingAmputatedEnd > CurTime() and damage:GetAttacker() == victim.beingAmputated) then
for _, v in ipairs(player.GetAll()) do
if (CAMI.PlayerHasAccess(v, "Helix - Ban Character")) then
v:ChatNotify(victim.beingAmputated:Name().." has amputated "..victim:Name().." for: "..(victim.beingAmputatedReason or "no reason given"))
end
end
victim.beingAmputated:Notify("Verdict delivered!")
victim.beingAmputated = nil
victim.beingAmputatedEnd = nil
victim.beingAmputatedReason = nil
return true --Do not let medical plugin interfere and put player in bleedout
end
end
-- Entity related functions
function PLUGIN:PlayerButtonDown( client, key )
if (IsFirstTimePredicted() and key == KEY_LALT) then
local entity = client:GetEyeTraceNoCursor().Entity
if !IsValid(entity) then
return false
end
if !entity.canUse then
return false
end
if (client:GetShootPos():Distance(entity:GetPos()) > 100) then
return false
end
if entity:GetNWInt("owner") and client:GetCharacter():GetID() != entity:GetNWInt("owner") then
return false
end
if entity.hasDiskInserted then client:NotifyLocalized("This computer has a disk inserted!") return false end
if (entity:GetClass() == "ix_medical_computer" or entity:GetClass() == "ix_computer") then
local getUsers = entity.users
local getNotes = entity.notes
local activeClass = "med_computer"
if entity:GetClass() == "ix_computer" then
activeClass = "cit_computer"
end
local pos = entity:GetPos()
ix.item.Spawn(activeClass, pos + Vector( 0, 0, 2 ), function(item, entityCreated) item:SetData("users", getUsers) item:SetData("notes", getNotes) end, entity:GetAngles())
entity:Remove()
end
end
end
function PLUGIN:RegisterSaveEnts()
ix.saveEnts:RegisterEntity("ix_medical_computer", true, true, true, {
OnSave = function(entity, data) --OnSave
data.motion = false
data.users = entity.users
data.notes = entity.notes
data.owner = entity:GetNWInt("owner")
end,
OnRestore = function(entity, data)
entity.users = data.users
entity.notes = data.notes
entity:SetNWInt("owner", data.owner)
end
})
ix.saveEnts:RegisterEntity("ix_computer", true, true, true, {
OnSave = function(entity, data) --OnSave
data.motion = false
data.users = entity.users
data.notes = entity.notes
data.owner = entity:GetNWInt("owner")
end,
OnRestore = function(entity, data)
entity.users = data.users
entity.notes = data.notes
entity:SetNWInt("owner", data.owner)
end
})
ix.saveEnts:RegisterEntity("ix_terminal", true, true, true, {
OnSave = function(entity, data) --OnSave
return {pos = data.pos, angles = data.angles, motion = false}
end,
})
ix.saveEnts:RegisterEntity("ix_console", true, true, true, {
OnSave = function(entity, data) --OnSave
return {pos = data.pos, angles = data.angles, motion = false}
end,
})
ix.saveEnts:RegisterEntity("npc_combine_camera", true, true, true, {
OnSave = function(entity, data) --OnSave
return {pos = data.pos, angles = data.angles, motion = false}
end,
OnRestore = function(entity, data)
entity:SetOwner(nil)
end,
})
ix.saveEnts:RegisterEntity("ix_workshiftterminal", true, true, true, {
OnSave = function(entity, data) --OnSave
return {pos = data.pos, angles = data.angles, motion = false}
end,
})
end
function PLUGIN:CanInsertDisk(client, item)
if !client then return false end
if !client:Alive() then return false end
local targetEnt = client:GetEyeTraceNoCursor().Entity
if !targetEnt then client:Notify("You are not looking at a computer!") return false end
if !IsValid(targetEnt) then client:Notify("You are not looking at a computer!") return false end
local entClass = targetEnt:GetClass()
if (entClass != "ix_medical_computer" and entClass != "ix_computer") then client:Notify("You are not looking at a computer!") return false end
if targetEnt.hasDiskInserted then client:Notify("There is already a disk in this computer!") return false end
return targetEnt
end
function PLUGIN:InsertDisk(client, item)
local computerEnt = self:CanInsertDisk(client, item)
if !computerEnt or (computerEnt and !IsValid(computerEnt)) then return false end
local bSuccess, error = item:Transfer(nil, nil, nil, item.player)
if (!bSuccess and isstring(error)) then
client:Notify("Could not drop the disk and insert it.")
return
end
local disk = bSuccess
local rotation = Vector(0, 0, 0)
local angle = computerEnt:GetAngles()
angle:RotateAroundAxis(angle:Up(), rotation.x)
disk:SetAngles(angle)
disk:SetPos(computerEnt:GetPos() + computerEnt:GetUp() * -1.5 + computerEnt:GetForward() * -15)
constraint.Weld( disk, computerEnt, 0, 0, 0, true, false )
local physObj = disk:GetPhysicsObject()
if !physObj then return end
physObj:EnableMotion(false)
computerEnt.hasDiskInserted = item:GetID()
item.computer = computerEnt
end
netstream.Hook("RequestFloppyDiskData", function(client, computerEnt, password)
if !computerEnt then return false end
if !IsValid(computerEnt) then return false end
if !IsEntity(computerEnt) then return false end
local diskItem = ix.item.instances[computerEnt.hasDiskInserted]
if !diskItem then return false end
local diskPassword = diskItem:GetData("password", false)
local diskData = diskItem:GetData("content", false)
if !diskPassword then
netstream.Start(client, "ReplyFloppyDiskData", true, false, diskData)
return
end
if (diskPassword and !password) or !password then
netstream.Start(client, "ReplyFloppyDiskData", false)
return
end
if (diskPassword != password) then
netstream.Start(client, "ReplyFloppyDiskData", false, true)
return
end
if (diskPassword == password) then
netstream.Start(client, "ReplyFloppyDiskData", true, false, diskData)
return
end
end)
netstream.Hook("FloppyDiskSetPassword", function(client, newPass, computerEnt)
if !computerEnt then return false end
if !IsValid(computerEnt) then return false end
if !IsEntity(computerEnt) then return false end
local diskItem = ix.item.instances[computerEnt.hasDiskInserted]
if !diskItem then return false end
diskItem:SetData("password", newPass)
end)
netstream.Hook("FloppyDiskSetData", function(client, newContent, computerEnt)
if !computerEnt then return false end
if !IsValid(computerEnt) then return false end
if !IsEntity(computerEnt) then return false end
local diskItem = ix.item.instances[computerEnt.hasDiskInserted]
if !diskItem then return false end
diskItem:SetData("content", newContent)
end)
netstream.Hook("SetFloppyDiskName", function(client, text, itemID, password)
local character = client:GetCharacter()
if !character then return false end
local inventory = character:GetInventory()
if !inventory then return false end
local item = ix.item.instances[itemID]
if !item then return end
local password2 = item:GetData("password", false)
if password2 and !password then return end
if password2 != password then
client:NotifyLocalized("Wrong password.")
return
end
if !inventory.GetItemByID then return false end
if !inventory:GetItemByID(itemID) then
local targetEnt = client:GetEyeTraceNoCursor().Entity
if !IsValid(targetEnt) then return false end
if targetEnt:GetClass() != "ix_item" then return false end
if (targetEnt.ixItemID and targetEnt.ixItemID != itemID) then return false end
end
item:SetData("customName", Schema:FirstToUpper(text))
client:NotifyLocalized("Set the disk name to "..Schema:FirstToUpper(text))
end)
netstream.Hook("FindLetterRecepient", function(client, text, itemID)
local character = client:GetCharacter()
if !character then return end
local inventory = character:GetInventory()
if !inventory then return end
if !inventory:GetItemByID(itemID) then return end
if inventory:GetItemByID(itemID).name != "Paper" then return end
if string.len(text) == 5 and isnumber(tonumber(text)) then
text = Schema:ZeroNumber(tonumber(text), 5)
end
local id = false
local name = false
local cid = false
for _, v in pairs(ix.char.loaded) do
if !isnumber(text) and string.len(tostring(text)) != 5 then
if (ix.util.StringMatches(v:GetName(), text)) then
id = v:GetID()
name = v:GetName()
cid = v:GetCid()
break
end
else
if ix.util.StringMatches(tostring(v:GetCid()), tostring(text)) then
id = v:GetID()
name = v:GetName()
cid = v:GetCid()
break
end
end
end
if !id or !name or !cid then
local receiverQuery = mysql:Select("ix_characters")
receiverQuery:Select("id")
receiverQuery:Select("name")
receiverQuery:Select("cid")
if !isnumber(text) and string.len(tostring(text)) != 5 then
receiverQuery:WhereLike("name", text)
else
receiverQuery:WhereLike("cid", text)
end
receiverQuery:Callback(function(result)
if (!result or !istable(result) or #result == 0) then
return
end
local first = result[1]
id = first.id
name = first.name
cid = first.cid
end)
receiverQuery:Execute()
end
timer.Simple(3, function()
if !id or !name or !cid then client:Notify("Could not find the person you were trying to send a letter to.") return end
cid = cid or "00000"
netstream.Start(client, "ReplyLetterRecepient", id, name, cid, itemID)
end)
end)
function PLUGIN:AddLogToDatafile(client, toCharID, fromCID, fromName)
local whomData = {
fromGenericData = false,
fromLogsTable = false,
toGenericData = false,
toLogsTable = false
}
for _, v in pairs(ix.char.loaded) do
if ix.util.StringMatches(tostring(v:GetCid()), tostring(fromCID)) then
whomData.fromGenericData = v:GetGenericdata()
whomData.fromLogsTable = v:GetDatafilelogs()
break
end
end
if ix.char.loaded[tonumber(toCharID)] then
whomData.toGenericData = ix.char.loaded[tonumber(toCharID)]:GetGenericdata()
whomData.toLogsTable = ix.char.loaded[tonumber(toCharID)]:GetDatafilelogs()
end
local addLogsTo = {["to"] = toCharID, ["from"] = fromCID}
if whomData.fromGenericData and whomData.fromLogsTable then addLogsTo["from"] = nil end
if whomData.toGenericData and whomData.toLogsTable then addLogsTo["to"] = nil end
if !whomData.fromGenericData or !whomData.fromLogsTable or !whomData.toGenericData or !whomData.toLogsTable then
for whom, id in pairs(addLogsTo) do
local query = mysql:Select("ix_characters")
query:Select("name")
query:Select("faction")
query:Select("id")
query:Select("cid")
if whom != "to" then
query:Where("cid", id)
else
query:Where("id", id)
end
query:Where("schema", Schema and Schema.folder or "helix")
query:Callback(function(result)
if (!istable(result) or #result == 0) then
return
end
local dataSelect = mysql:Select("ix_characters_data")
dataSelect:Where("id", result[1].id)
dataSelect:WhereIn("key", {"genericdata", "datafilelogs"})
dataSelect:Callback(function(dataSelectResult)
if (!istable(dataSelectResult) or #dataSelectResult == 0) then
return
end
for _, v in ipairs(dataSelectResult) do
if whom == "to" then
if v.key == "genericdata" then
whomData.toGenericData = util.JSONToTable(v.data or "")
elseif v.key == "datafilelogs" then
whomData.toLogsTable = util.JSONToTable(v.data or "")
end
else
if v.key == "genericdata" then
whomData.fromGenericData = util.JSONToTable(v.data or "")
elseif v.key == "datafilelogs" then
whomData.fromLogsTable = util.JSONToTable(v.data or "")
end
end
end
end)
dataSelect:Execute()
end)
query:Execute()
end
end
timer.Simple(4, function()
if whomData.fromGenericData and whomData.fromLogsTable and whomData.toGenericData and whomData.toLogsTable then
local combineutilities = ix.plugin.list["combineutilities"]
if combineutilities and combineutilities.AddLog then
for i = 1, 2 do
local logsT = (i == 1 and whomData.fromLogsTable or whomData.toLogsTable)
local genericT = (i == 1 and whomData.fromGenericData or whomData.toGenericData)
local fromName1 = whomData.fromGenericData.name or ""
local fromCID1 = whomData.fromGenericData.cid or ""
local toName = whomData.toGenericData.name or ""
local toCID = whomData.toGenericData.cid or ""
if (i == 1) then -- Only need the notification once
ix.combineNotify:AddNotification("LOG:// Subject '" .. fromName1 .. "' sent a letter to '" .. toName .. "'", nil, client)
end
combineutilities:AddLog(client, logsT, genericT, "TERMINAL", nil, "LETTER SENT/RECEIVED - "..fromName1.." | "..fromCID1.." -> "..toName.." | "..toCID, true, true)
end
end
end
end)
end
netstream.Hook("SendLetterToID", function(client, charID, itemID, fromCID, fromName)
local character = client:GetCharacter()
if !character then return end
local inventory = character:GetInventory()
if !inventory then return end
if !inventory:GetItemByID(itemID) then return end
if inventory:GetItemByID(itemID).name != "Paper" then return end
local paperInstance = ix.item.instances[tonumber(itemID)]
if !paperInstance then return end
local paperWritingID = paperInstance:GetData("writingID")
if !paperWritingID then return end
local paperTitle = paperInstance:GetData("title", "Paper")
local currentOwner = paperInstance:GetData("owner", false)
if ix.char.loaded[tonumber(charID)] then
ix.char.loaded[tonumber(charID)]:SetPurchasedItems("letter_"..itemID, {title = paperTitle, fromCID = fromCID, fromName = fromName, writingID = paperWritingID, owner = currentOwner})
client:Notify("Letter has been successfully sent.")
PLUGIN:AddLogToDatafile(client, charID, fromCID, fromName)
ix.item.instances[tonumber(itemID)]:Remove()
else
local dataSelect = mysql:Select("ix_characters_data")
dataSelect:Where("id", tonumber(charID))
dataSelect:WhereIn("key", "purchasedItems")
dataSelect:Callback(function(dataSelectResult)
if (!istable(dataSelectResult) or #dataSelectResult == 0) then
return
end
local purchasedItems = util.JSONToTable(dataSelectResult[1].data)
if !purchasedItems then return end
purchasedItems["letter_"..itemID] = {title = paperTitle, fromCID = fromCID, fromName = fromName, writingID = paperWritingID, owner = currentOwner}
local updateQuery = mysql:Update("ix_characters_data")
updateQuery:Update("data", util.TableToJSON(purchasedItems))
updateQuery:Where("id", tonumber(charID))
updateQuery:Where("key", "purchasedItems")
updateQuery:Execute()
ix.item.instances[tonumber(itemID)]:Remove()
PLUGIN:AddLogToDatafile(client, charID, fromCID, fromName)
end)
dataSelect:Execute()
client:Notify("Letter has been successfully sent.")
end
end)