mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
126
gamemodes/ixhl2rp/plugins/cid/cl_plugin.lua
Normal file
126
gamemodes/ixhl2rp/plugins/cid/cl_plugin.lua
Normal file
@@ -0,0 +1,126 @@
|
||||
--[[
|
||||
| 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 netstream = netstream
|
||||
local vgui = vgui
|
||||
local hook = hook
|
||||
local IsValid = IsValid
|
||||
local pairs = pairs
|
||||
local LocalPlayer = LocalPlayer
|
||||
local Derma_Select = Derma_Select
|
||||
local timer = timer
|
||||
local Derma_Query = Derma_Query
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
netstream.Hook("ixCreditTransactionLog", function(data, bShowReadButton)
|
||||
local transactionUI = vgui.Create("ixCIDTransactionLog")
|
||||
transactionUI:CreateContent(data, bShowReadButton)
|
||||
end)
|
||||
|
||||
netstream.Hook("ixRequestCredits", function(client, amount, reason)
|
||||
local clientName = hook.Run("GetCharacterName", client, "ic") or client:GetName()
|
||||
if (IsValid(PLUGIN.posTransactionPanel)) then
|
||||
client:NotifyLocalized("posTransOngoing")
|
||||
netstream.Start("ixDenyCreditOperation")
|
||||
return
|
||||
end
|
||||
|
||||
local cards = {}
|
||||
for _, v in pairs(LocalPlayer():GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
|
||||
cards[#cards + 1] = {
|
||||
text = v:GetName(),
|
||||
value = v
|
||||
}
|
||||
end
|
||||
|
||||
local amountPercent = amount / 100
|
||||
local vat = math.Round(amountPercent * ix.config.Get("transactionVatPercent", 2))
|
||||
|
||||
local cardsCount = #cards
|
||||
if (cardsCount > 1) then
|
||||
PLUGIN.posTransactionPanel = Derma_Select("Credits Requested", clientName.." requests "..amount.." credit(s) from you for '"..reason.."'. Transaction vat: " .. vat .. " credit(s). What card will you choose to pay?",
|
||||
cards, "Select ID Card",
|
||||
"Confirm Operation", function(value, name)
|
||||
netstream.Start("ixConfirmCreditOperation", value:GetID())
|
||||
timer.Remove("ixPosTransactionQuery")
|
||||
end, "Refuse Request", function()
|
||||
netstream.Start("ixDenyCreditOperation")
|
||||
timer.Remove("ixPosTransactionQuery")
|
||||
end)
|
||||
elseif (cardsCount == 1) then
|
||||
PLUGIN.posTransactionPanel = Derma_Query(clientName.." requests "..amount.." credit(s) from you for '"..reason.."'. Transaction vat: " .. vat .. " credit(s). Are you confirming this transaction?", "Credits Requested",
|
||||
"Confirm Operation", function()
|
||||
netstream.Start("ixConfirmCreditOperation", cards[1].value:GetID())
|
||||
timer.Remove("ixPosTransactionQuery")
|
||||
end, "Refuse Request", function()
|
||||
netstream.Start("ixDenyCreditOperation")
|
||||
timer.Remove("ixPosTransactionQuery")
|
||||
end)
|
||||
else
|
||||
LocalPlayer():NotifyLocalized("You have received a credits request, but you do not have an ID card to perform it.")
|
||||
netstream.Start("ixDenyCreditOperation")
|
||||
return
|
||||
end
|
||||
|
||||
timer.Create("ixPosTransactionQuery", 14, 1, function()
|
||||
client:NotifyLocalized("posTransExpired")
|
||||
PLUGIN.posTransactionPanel:Remove()
|
||||
netstream.Start("ixDenyCreditOperation")
|
||||
end)
|
||||
end)
|
||||
|
||||
netstream.Hook("ixSelectCID", function(hasFail)
|
||||
local cidSelector = vgui.Create("CIDSelector")
|
||||
|
||||
if (hasFail) then
|
||||
cidSelector.ExitCallback = function()
|
||||
netstream.Start("ixSelectCIDFail")
|
||||
end
|
||||
end
|
||||
|
||||
cidSelector.SelectCallback = function(cardID)
|
||||
netstream.Start("ixSelectCIDSuccess", cardID)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("changeLockAccess", function()
|
||||
local entity = net.ReadEntity()
|
||||
|
||||
ix.menu.Open({["Set Member Access"] = true, ["Set Management Access"] = true}, entity)
|
||||
end)
|
||||
|
||||
net.Receive("changeLockAccessCmru", function()
|
||||
local entity = net.ReadEntity()
|
||||
|
||||
local accessLevels = {}
|
||||
for i=1, 5 do
|
||||
accessLevels["Set Level "..tostring(i).." Access"] = true
|
||||
end
|
||||
ix.menu.Open(accessLevels, entity)
|
||||
end)
|
||||
|
||||
net.Receive("changeLockAccessCon", function()
|
||||
local entity = net.ReadEntity()
|
||||
|
||||
local accessLevels = {}
|
||||
for i=1, 5 do
|
||||
accessLevels["Set Level "..tostring(i).." Access"] = true
|
||||
end
|
||||
ix.menu.Open(accessLevels, entity)
|
||||
end)
|
||||
|
||||
function PLUGIN:CreateExtraCharacterTabInfo(character, informationSubframe, CreatePart)
|
||||
local citizenID = LocalPlayer():GetCharacter():GetCid() or "N/A"
|
||||
|
||||
local cidPanel = informationSubframe:Add("Panel")
|
||||
CreatePart(cidPanel, "Citizen ID:", citizenID, "cid")
|
||||
end
|
||||
129
gamemodes/ixhl2rp/plugins/cid/derma/cl_cidselector.lua
Normal file
129
gamemodes/ixhl2rp/plugins/cid/derma/cl_cidselector.lua
Normal file
@@ -0,0 +1,129 @@
|
||||
--[[
|
||||
| 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 PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
if ix.gui.cidSelector then
|
||||
ix.gui.cidSelector:Remove()
|
||||
end
|
||||
|
||||
ix.gui.cidSelector = self
|
||||
|
||||
self:SetSize(ScrW(), ScrH())
|
||||
self:SetAlpha(0)
|
||||
self:AlphaTo(255, 0.5, 0)
|
||||
self.Paint = function(self, w, h)
|
||||
surface.SetDrawColor(Color(63, 58, 115, 220))
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
Derma_DrawBackgroundBlur( self, 1 )
|
||||
end
|
||||
|
||||
self.innerContent = self:Add("Panel")
|
||||
self.innerContent:SetSize(SScaleMin(500 / 3), SScaleMin(50 / 3))
|
||||
self.innerContent:Center()
|
||||
self.innerContent:MakePopup()
|
||||
self.innerContent.Paint = function(self, w, h)
|
||||
surface.SetDrawColor(0, 0, 0, 130)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
Schema:AllowMessage(self.innerContent)
|
||||
|
||||
self:CreateTopBar()
|
||||
self:CreateSelector()
|
||||
end
|
||||
|
||||
function PANEL:CreateTopBar()
|
||||
local topbar = self.innerContent:Add("Panel")
|
||||
topbar:SetSize(self.innerContent:GetWide(), SScaleMin(50 / 3))
|
||||
topbar:Dock(TOP)
|
||||
topbar.Paint = function( self, w, h )
|
||||
surface.SetDrawColor(0, 0, 0, 130)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
local titleText = topbar:Add("DLabel")
|
||||
titleText:SetFont("CharCreationBoldTitleNoClamp")
|
||||
titleText:Dock(LEFT)
|
||||
titleText:SetText("Which CID do you want to use?")
|
||||
titleText:DockMargin(SScaleMin(10 / 3), 0, 0, 0)
|
||||
titleText:SetContentAlignment(4)
|
||||
titleText:SizeToContents()
|
||||
|
||||
local exit = topbar:Add("DImageButton")
|
||||
exit:SetImage("willardnetworks/tabmenu/navicons/exit.png")
|
||||
exit:SetSize(SScaleMin(20 / 3), SScaleMin(20 / 3))
|
||||
exit:DockMargin(0, SScaleMin(15 / 3), SScaleMin(10 / 3), SScaleMin(15 / 3))
|
||||
exit:Dock(RIGHT)
|
||||
exit.DoClick = function()
|
||||
if self.ExitCallback then
|
||||
self.ExitCallback()
|
||||
end
|
||||
|
||||
self:Remove()
|
||||
surface.PlaySound("helix/ui/press.wav")
|
||||
end
|
||||
|
||||
local function createDivider(parent)
|
||||
parent:SetSize(1, topbar:GetTall())
|
||||
parent:Dock(RIGHT)
|
||||
parent:DockMargin(0, SScaleMin(10 / 3), SScaleMin(10 / 3), SScaleMin(10 / 3))
|
||||
parent.Paint = function(self, w, h)
|
||||
surface.SetDrawColor(Color(111, 111, 136, (255 / 100 * 30)))
|
||||
surface.DrawLine(0, 0, 0, h)
|
||||
end
|
||||
end
|
||||
|
||||
local divider = topbar:Add("Panel")
|
||||
createDivider(divider)
|
||||
end
|
||||
|
||||
function PANEL:CreateSelector()
|
||||
local selectorPanel = self.innerContent:Add("DScrollPanel")
|
||||
selectorPanel:Dock(FILL)
|
||||
|
||||
local character = LocalPlayer():GetCharacter()
|
||||
local inventoryItems = character:GetInventory():GetItemsByUniqueID("id_card")
|
||||
|
||||
for k, v in pairs(inventoryItems) do
|
||||
local cidButton = selectorPanel:Add("DButton")
|
||||
local cidName = v:GetData("name") or ""
|
||||
local cid = v:GetData("cid") or ""
|
||||
|
||||
cidButton:Dock(TOP)
|
||||
cidButton:SetTall(SScaleMin(50 / 3))
|
||||
cidButton:DockMargin(SScaleMin(50 / 3), k == 1 and SScaleMin(10 / 3) or 0, SScaleMin(50 / 3), SScaleMin(10 / 3))
|
||||
cidButton:SetFont("MenuFontNoClamp")
|
||||
cidButton:SetText(cidName.." | "..cid.." | "..v:GetData("cardNumber"))
|
||||
cidButton.Paint = function( self, w, h )
|
||||
surface.SetDrawColor(0, 0, 0, 130)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
cidButton.DoClick = function()
|
||||
self:AlphaTo(0, 0.5, 0)
|
||||
timer.Simple(0.5, function()
|
||||
if self.SelectCallback then
|
||||
self.SelectCallback(v:GetID(), cid, cidName, self.activeEntity)
|
||||
end
|
||||
|
||||
self:Remove()
|
||||
end)
|
||||
end
|
||||
|
||||
self.innerContent:SetTall(math.Clamp(self.innerContent:GetTall() + cidButton:GetTall() + (k == 1 and SScaleMin(10 / 3) or 0) + SScaleMin(10 / 3), 0, SScaleMin(600 / 3)))
|
||||
self.innerContent:Center()
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register("CIDSelector", PANEL, "EditablePanel")
|
||||
182
gamemodes/ixhl2rp/plugins/cid/derma/cl_transactionlog.lua
Normal file
182
gamemodes/ixhl2rp/plugins/cid/derma/cl_transactionlog.lua
Normal file
@@ -0,0 +1,182 @@
|
||||
--[[
|
||||
| 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 PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetSize(SScaleMin(1179 / 3), SScaleMin(1116 / 3))
|
||||
self:MakePopup()
|
||||
self:Center()
|
||||
|
||||
Schema:AllowMessage(self)
|
||||
|
||||
self.content = self:Add("DScrollPanel")
|
||||
self.content:SetSize(SScaleMin(800 / 3), SScaleMin(740 / 3))
|
||||
self.content:Center()
|
||||
|
||||
self.contentPanels = {}
|
||||
|
||||
local topPanel = self.content:Add("Panel")
|
||||
topPanel:Dock(TOP)
|
||||
topPanel:SetTall(SScaleMin(32 / 3))
|
||||
topPanel.Paint = function(this, w, h)
|
||||
self:DrawBottomLine(w, h)
|
||||
end
|
||||
|
||||
local title = topPanel:Add("DLabel")
|
||||
title:Dock(LEFT)
|
||||
title:SetText("GENERIC TRANSACTION LOG")
|
||||
title:SetFont("LargerTitlesFontNoClamp")
|
||||
title:SizeToContents()
|
||||
|
||||
local exit = topPanel:Add("DButton")
|
||||
exit:Dock(RIGHT)
|
||||
exit:SetWide(SScaleMin(24 / 3))
|
||||
exit:DockMargin(0, SScaleMin(4 / 3), 0, SScaleMin(4 / 3))
|
||||
exit:SetText("")
|
||||
exit.Paint = function(this, w, h)
|
||||
surface.SetDrawColor(color_white)
|
||||
surface.SetMaterial(ix.util.GetMaterial("willardnetworks/tabmenu/navicons/exit.png"))
|
||||
surface.DrawTexturedRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
exit.DoClick = function()
|
||||
self:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:DrawBottomLine(w, h)
|
||||
surface.SetDrawColor(color_white)
|
||||
surface.DrawLine(0, h - 1, w, h - 1)
|
||||
end
|
||||
|
||||
function PANEL:CreateContentPanel(height, bShouldCreateBottomLine)
|
||||
local contentPanel = self.content:Add("Panel")
|
||||
contentPanel:Dock(TOP)
|
||||
contentPanel:SetTall(height)
|
||||
|
||||
if bShouldCreateBottomLine then
|
||||
contentPanel.Paint = function(this, w, h)
|
||||
self:DrawBottomLine(w, h)
|
||||
end
|
||||
end
|
||||
|
||||
self.contentPanels[#self.contentPanels + 1] = contentPanel
|
||||
|
||||
return contentPanel
|
||||
end
|
||||
|
||||
function PANEL:CreateContent(data, bShowReadButton)
|
||||
if (data and !table.IsEmpty(data)) then
|
||||
for _, tData in pairs(data) do
|
||||
local transPanel = self:CreateContentPanel(SScaleMin(140 / 3), true)
|
||||
|
||||
-- LEFT SIDE
|
||||
local leftPanel = transPanel:Add("Panel")
|
||||
transPanel.leftPanel = leftPanel
|
||||
leftPanel:SetTall(transPanel:GetTall())
|
||||
leftPanel:Dock(LEFT)
|
||||
leftPanel.Paint = function(this, w, h)
|
||||
surface.SetDrawColor(color_white)
|
||||
surface.DrawLine(w, 1, w, h - 1)
|
||||
end
|
||||
|
||||
leftPanel.datePanel = self:CreateText(leftPanel, os.date("%d/%m/%y", tData.datetime), TOP, 4)
|
||||
leftPanel.datePanel:SetTall(SScaleMin(50 / 3))
|
||||
leftPanel.timePanel = self:CreateText(leftPanel, os.date("%H:%M:%S", tData.datetime), TOP, 4)
|
||||
|
||||
if (bShowReadButton) then
|
||||
leftPanel.readUnRead = leftPanel:Add("DButton")
|
||||
leftPanel.readUnRead:Dock(FILL)
|
||||
leftPanel.readUnRead:SetText(tonumber(tData.read) == 1 and "READ" or "UNREAD")
|
||||
leftPanel.readUnRead:SetFont("TitlesFontNoClamp")
|
||||
leftPanel.readUnRead:SizeToContents()
|
||||
leftPanel.readUnRead:SetContentAlignment(4)
|
||||
leftPanel.readUnRead.Paint = nil
|
||||
leftPanel.readUnRead.DoClick = function()
|
||||
if (tData.read == 1) then
|
||||
tData.read = 0
|
||||
else
|
||||
tData.read = 1
|
||||
end
|
||||
leftPanel.readUnRead:SetText(tonumber(tData.read) == 1 and "READ" or "UNREAD")
|
||||
netstream.Start("ixTransactionSetRead", tData.id, false, tData.read == 1, tData.pos)
|
||||
end
|
||||
end
|
||||
leftPanel:SetWidth(SScaleMin(90 / 3))
|
||||
|
||||
-- RIGHT SIDE
|
||||
local rightPanel = transPanel:Add("Panel")
|
||||
transPanel.rightPanel = rightPanel
|
||||
rightPanel:Dock(FILL)
|
||||
-- INFO ROW
|
||||
rightPanel.transInfoPanel = rightPanel:Add("Panel")
|
||||
rightPanel.transInfoPanel:Dock(TOP)
|
||||
rightPanel.transInfoPanel:SetTall(SScaleMin(50 / 3))
|
||||
self:CreateText(rightPanel.transInfoPanel, tData.sender_name.." | CID: "..tData.sender_cid, LEFT, 4, Color(171, 27, 27, 255))
|
||||
self:CreateText(rightPanel.transInfoPanel, "➔", FILL, 5, Color(169, 171, 27, 255))
|
||||
self:CreateText(rightPanel.transInfoPanel, tData.receiver_name.." | CID: "..tData.receiver_cid, RIGHT, 6, Color(63, 171, 27, 255))
|
||||
-- AMOUNT ROW
|
||||
rightPanel.descPanel = rightPanel:Add("Panel")
|
||||
rightPanel.descPanel:Dock(TOP)
|
||||
rightPanel.descPanel.amountLabel = self:CreateText(rightPanel.descPanel, "AMOUNT: "..tData.amount.." ", RIGHT, 6, Color(169, 171, 27, 255))
|
||||
rightPanel.descPanel.amountLabel:DockMargin(0, 0, 0, SScaleMin(5 / 3))
|
||||
rightPanel.descPanel.reasonLabel = self:CreateText(rightPanel.descPanel, "REASON: ", LEFT, 5, Color(169, 171, 27, 255))
|
||||
rightPanel.descPanel.reasonLabel:DockMargin(0, 0, 0, SScaleMin(5 / 3))
|
||||
rightPanel.descPanel:SetTall(rightPanel.descPanel.amountLabel:GetTall())
|
||||
|
||||
rightPanel.reasonPanel = rightPanel:Add("Panel")
|
||||
rightPanel.reasonPanel:Dock(TOP)
|
||||
rightPanel.reasonPanel:SetTall(SScaleMin(50 / 3))
|
||||
rightPanel.reasonPanel:DockMargin(0, SScaleMin(10 / 3), 0, 0)
|
||||
rightPanel.reasonPanel.reasonTextEntry = rightPanel.reasonPanel:Add("DTextEntry")
|
||||
rightPanel.reasonPanel.reasonTextEntry:Dock(FILL)
|
||||
rightPanel.reasonPanel.reasonTextEntry:SetText(tData.reason)
|
||||
rightPanel.reasonPanel.reasonTextEntry:SetEditable(true)
|
||||
rightPanel.reasonPanel.reasonTextEntry:SetVerticalScrollbarEnabled(true)
|
||||
rightPanel.reasonPanel.reasonTextEntry:SetMultiline(true)
|
||||
rightPanel.reasonPanel.reasonTextEntry:SetFont("MenuFontNoClamp")
|
||||
rightPanel.reasonPanel.reasonTextEntry:SetTextColor( color_white )
|
||||
rightPanel.reasonPanel.reasonTextEntry:SetCursorColor( color_white )
|
||||
rightPanel.reasonPanel.reasonTextEntry.Paint = function(this, w, h)
|
||||
surface.SetDrawColor(20, 20, 20, 75)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
this:DrawTextEntryText( this:GetTextColor(), this:GetHighlightColor(), this:GetCursorColor() )
|
||||
end
|
||||
|
||||
-- Because scrollbar won't be useable unless textentry is editable thanks derma
|
||||
local coverForTextEntry = rightPanel.reasonPanel:Add("Panel")
|
||||
coverForTextEntry:Dock(FILL)
|
||||
coverForTextEntry:DockMargin(0, 0, 19, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:CreateText(parent, text, dock, contentAlignment, color)
|
||||
local label = parent:Add("DLabel")
|
||||
label:Dock(dock)
|
||||
label:SetText(text or "")
|
||||
label:SetFont("TitlesFontNoClamp")
|
||||
label:SetTextColor(color or color_white)
|
||||
label:SetContentAlignment(contentAlignment)
|
||||
label:SizeToContents()
|
||||
|
||||
return label
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
surface.SetDrawColor(color_white)
|
||||
surface.SetMaterial(Material("willardnetworks/posterminal.png"))
|
||||
surface.DrawTexturedRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
vgui.Register("ixCIDTransactionLog", PANEL, "EditablePanel")
|
||||
106
gamemodes/ixhl2rp/plugins/cid/items/sh_cmru_card.lua
Normal file
106
gamemodes/ixhl2rp/plugins/cid/items/sh_cmru_card.lua
Normal file
@@ -0,0 +1,106 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
ITEM.name = "CMRU Access Card"
|
||||
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
|
||||
ITEM.description = "A Civil Medical & Research Union Keycard."
|
||||
ITEM.category = "Combine"
|
||||
ITEM.skin = 2
|
||||
ITEM.iconCam = {
|
||||
pos = Vector(-509.64, -427.61, 310.24),
|
||||
ang = Angle(25, 400, 0),
|
||||
fov = 0.59
|
||||
}
|
||||
|
||||
function ITEM:GetName()
|
||||
local accessLevel = self:GetData("accessLevel", 1)
|
||||
|
||||
return "CMRU Level " .. accessLevel .. " Access Keycard"
|
||||
end
|
||||
|
||||
function ITEM:GetDescription()
|
||||
local idCard = ix.item.instances[self:GetData("cardID")]
|
||||
return idCard and string.format(self.description.."\n\nCurrently bound to identity card #%s.", idCard:GetData("cardNumber")) or
|
||||
(self:GetData("cardID") and self.description.."\n\nCurrently bound." or self.description)
|
||||
end
|
||||
|
||||
ITEM.functions.Bind = {
|
||||
name = "Bind ID Card",
|
||||
icon = "icon16/vcard_edit.png",
|
||||
OnClick = function(itemTable)
|
||||
local cards = {}
|
||||
|
||||
for _, v in pairs(LocalPlayer():GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
|
||||
table.insert(cards, {
|
||||
text = v:GetName(),
|
||||
value = v
|
||||
})
|
||||
end
|
||||
|
||||
local cardsCount = table.Count(cards)
|
||||
if (cardsCount > 1) then
|
||||
Derma_Select("Bind ID Card to CMRU Card", "Please select a ID card to bind to this CMRU Card:",
|
||||
cards, "Select ID card",
|
||||
"Confirm Operation", function(value, name)
|
||||
netstream.Start("ixBindCMRUCard", itemTable:GetID(), value:GetID())
|
||||
end, "Cancel")
|
||||
elseif (cardsCount == 1) then
|
||||
Derma_Query("Are you sure you wish to bind your ID to this CMRU Card?", "Bind ID Card to CMRU Card",
|
||||
"Confirm Operation", function()
|
||||
netstream.Start("ixBindCMRUCard", itemTable:GetID(), cards[1].value:GetID())
|
||||
end, "Cancel")
|
||||
else
|
||||
LocalPlayer():NotifyLocalized("You do not have ID card to bind to this CMRU Card.")
|
||||
end
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!IsValid(itemTable.player)) then
|
||||
return false
|
||||
end
|
||||
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
|
||||
if (!inventory:HasItem("id_card")) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (itemTable:GetData("cardID")) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.SetAccessLevel = {
|
||||
name = "Toggle Card Access Level",
|
||||
icon = "icon16/vcard_add.png",
|
||||
OnRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
local accessLevel = itemTable:GetData("accessLevel", 1)
|
||||
|
||||
accessLevel = accessLevel != 5 and accessLevel + 1 or 1
|
||||
itemTable:SetData("accessLevel", accessLevel)
|
||||
client:NotifyLocalized("You have set this card's Access Level to Access Level " .. accessLevel .. ".")
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
|
||||
end
|
||||
}
|
||||
106
gamemodes/ixhl2rp/plugins/cid/items/sh_con_card.lua
Normal file
106
gamemodes/ixhl2rp/plugins/cid/items/sh_con_card.lua
Normal file
@@ -0,0 +1,106 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
ITEM.name = "Conscript Access Card"
|
||||
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
|
||||
ITEM.description = "A Conscript Access Keycard."
|
||||
ITEM.category = "Combine"
|
||||
ITEM.skin = 2
|
||||
ITEM.iconCam = {
|
||||
pos = Vector(-509.64, -427.61, 310.24),
|
||||
ang = Angle(25, 400, 0),
|
||||
fov = 0.59
|
||||
}
|
||||
|
||||
function ITEM:GetName()
|
||||
local accessLevel = self:GetData("accessLevel", 1)
|
||||
|
||||
return "Conscript Level " .. accessLevel .. " Access Keycard"
|
||||
end
|
||||
|
||||
function ITEM:GetDescription()
|
||||
local idCard = ix.item.instances[self:GetData("cardID")]
|
||||
return idCard and string.format(self.description.."\n\nCurrently bound to identity card #%s.", idCard:GetData("cardNumber")) or
|
||||
(self:GetData("cardID") and self.description.."\n\nCurrently bound." or self.description)
|
||||
end
|
||||
|
||||
ITEM.functions.Bind = {
|
||||
name = "Bind ID Card",
|
||||
icon = "icon16/vcard_edit.png",
|
||||
OnClick = function(itemTable)
|
||||
local cards = {}
|
||||
|
||||
for _, v in pairs(LocalPlayer():GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
|
||||
table.insert(cards, {
|
||||
text = v:GetName(),
|
||||
value = v
|
||||
})
|
||||
end
|
||||
|
||||
local cardsCount = table.Count(cards)
|
||||
if (cardsCount > 1) then
|
||||
Derma_Select("Bind ID Card to Conscript Card", "Please select a ID card to bind to this Conscript Card:",
|
||||
cards, "Select ID card",
|
||||
"Confirm Operation", function(value, name)
|
||||
netstream.Start("ixBindConCard", itemTable:GetID(), value:GetID())
|
||||
end, "Cancel")
|
||||
elseif (cardsCount == 1) then
|
||||
Derma_Query("Are you sure you wish to bind your ID to this Conscript Card?", "Bind ID Card to Conscript Card",
|
||||
"Confirm Operation", function()
|
||||
netstream.Start("ixBindConCard", itemTable:GetID(), cards[1].value:GetID())
|
||||
end, "Cancel")
|
||||
else
|
||||
LocalPlayer():NotifyLocalized("You do not have ID card to bind to this Conscript Card.")
|
||||
end
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!IsValid(itemTable.player)) then
|
||||
return false
|
||||
end
|
||||
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
|
||||
if (!inventory:HasItem("id_card")) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (itemTable:GetData("cardID")) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.SetAccessLevel = {
|
||||
name = "Toggle Card Access Level",
|
||||
icon = "icon16/vcard_add.png",
|
||||
OnRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
local accessLevel = itemTable:GetData("accessLevel", 1)
|
||||
|
||||
accessLevel = accessLevel != 5 and accessLevel + 1 or 1
|
||||
itemTable:SetData("accessLevel", accessLevel)
|
||||
client:NotifyLocalized("You have set this card's Access Level to Access Level " .. accessLevel .. ".")
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
|
||||
end
|
||||
}
|
||||
181
gamemodes/ixhl2rp/plugins/cid/items/sh_cwu_card.lua
Normal file
181
gamemodes/ixhl2rp/plugins/cid/items/sh_cwu_card.lua
Normal file
@@ -0,0 +1,181 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
ITEM.name = "CWU Access Card"
|
||||
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
|
||||
ITEM.description = "A Civil Workers' Union Access Keycard."
|
||||
ITEM.category = "Combine"
|
||||
ITEM.skin = 2
|
||||
ITEM.iconCam = {
|
||||
pos = Vector(-509.64, -427.61, 310.24),
|
||||
ang = Angle(25, 400, 0),
|
||||
fov = 0.59
|
||||
}
|
||||
|
||||
function ITEM:GetName()
|
||||
local accessLevel = self:GetData("accessLevel", "Member Access")
|
||||
|
||||
return "CWU " .. accessLevel .. " Keycard"
|
||||
end
|
||||
|
||||
function ITEM:GetFactionInfo()
|
||||
return self:GetData("faction", false) and ix.factionBudget.list[self:GetData("faction")] and "Binded to: " .. ix.factionBudget.list[self:GetData("faction")].name or "This card is not binded to any faction."
|
||||
end
|
||||
|
||||
function ITEM:GetColorAppendix()
|
||||
local info = {["green"] = self:GetFactionInfo()}
|
||||
|
||||
return info
|
||||
end
|
||||
|
||||
function ITEM:GetDescription()
|
||||
local idCard = ix.item.instances[self:GetData("cardID")]
|
||||
return idCard and string.format(self.description.."\n\nCurrently bound to identity card #%s.", idCard:GetData("cardNumber")) or
|
||||
(self:GetData("cardID") and self.description.."\n\nCurrently bound." or self.description)
|
||||
end
|
||||
|
||||
ITEM.functions.Bind = {
|
||||
name = "Bind ID Card",
|
||||
icon = "icon16/vcard_edit.png",
|
||||
OnClick = function(itemTable)
|
||||
local cards = {}
|
||||
|
||||
for _, v in pairs(LocalPlayer():GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
|
||||
table.insert(cards, {
|
||||
text = v:GetName(),
|
||||
value = v
|
||||
})
|
||||
end
|
||||
|
||||
local cardsCount = table.Count(cards)
|
||||
if (cardsCount > 1) then
|
||||
Derma_Select("Bind ID Card to CWU Card", "Please select a ID card to bind to this CWU Card:",
|
||||
cards, "Select ID card",
|
||||
"Confirm Operation", function(value, name)
|
||||
netstream.Start("ixBindCWUCard", itemTable:GetID(), value:GetID())
|
||||
end, "Cancel")
|
||||
elseif (cardsCount == 1) then
|
||||
Derma_Query("Are you sure you wish to bind your ID to this CWU Card?", "Bind ID Card to CWU Card",
|
||||
"Confirm Operation", function()
|
||||
netstream.Start("ixBindCWUCard", itemTable:GetID(), cards[1].value:GetID())
|
||||
end, "Cancel")
|
||||
else
|
||||
LocalPlayer():NotifyLocalized("You do not have ID card to bind to this CWU Card.")
|
||||
end
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!IsValid(itemTable.player)) then
|
||||
return false
|
||||
end
|
||||
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
|
||||
if (!inventory:HasItem("id_card")) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (itemTable:GetData("cardID")) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.SetAccessLevel = {
|
||||
name = "Toggle Card Access Level",
|
||||
icon = "icon16/vcard_add.png",
|
||||
isMulti = true,
|
||||
multiOptions = function(item, player)
|
||||
local keys = table.GetKeys(ix.city.cwuAccess)
|
||||
local accessLevels = {}
|
||||
for _, accessLevel in pairs(keys) do
|
||||
accessLevels[#accessLevels + 1] = {name = accessLevel, data = {aLevel = accessLevel .. " Access"}}
|
||||
end
|
||||
|
||||
return accessLevels
|
||||
end,
|
||||
OnRun = function(itemTable, accessLevel)
|
||||
local client = itemTable.player
|
||||
|
||||
itemTable:SetData("accessLevel", accessLevel.aLevel)
|
||||
client:NotifyLocalized("You have set this card's Access Level to " .. accessLevel.aLevel .. ".")
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.SetFaction = {
|
||||
name = "Set Card Faction",
|
||||
icon = "icon16/vcard_add.png",
|
||||
isMulti = true,
|
||||
multiOptions = function(item, player)
|
||||
local factions = {}
|
||||
for id, faction in pairs(ix.factionBudget.list) do
|
||||
factions[#factions + 1] = {name = faction.name, data = faction}
|
||||
end
|
||||
|
||||
return factions
|
||||
end,
|
||||
OnRun = function(item, data)
|
||||
item:SetData("faction", data.id)
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.insert = {
|
||||
name = "Insert card",
|
||||
icon = "icon16/add.png",
|
||||
OnRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
local ent = client:GetEyeTrace().Entity
|
||||
if (!ent.CWUInsert) or client:EyePos():DistToSqr(ent:GetPos()) > 62500 then
|
||||
return false
|
||||
end
|
||||
|
||||
local bSuccess, error = itemTable:Transfer(nil, nil, nil, client)
|
||||
if (!bSuccess and isstring(error)) then
|
||||
client:NotifyLocalized(error)
|
||||
return false
|
||||
else
|
||||
client:EmitSound("npc/zombie/foot_slide" .. math.random(1, 3) .. ".wav", 75, math.random(90, 120), 1)
|
||||
end
|
||||
|
||||
if bSuccess and IsEntity(bSuccess) then
|
||||
ent:CWUInsert(bSuccess)
|
||||
end
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
|
||||
if (!client:GetEyeTrace().Entity.CWUInsert) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
106
gamemodes/ixhl2rp/plugins/cid/items/sh_dob_card.lua
Normal file
106
gamemodes/ixhl2rp/plugins/cid/items/sh_dob_card.lua
Normal file
@@ -0,0 +1,106 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
ITEM.name = "DOB Access Card"
|
||||
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
|
||||
ITEM.description = "A Department of Business Access Keycard."
|
||||
ITEM.category = "Combine"
|
||||
ITEM.skin = 2
|
||||
ITEM.iconCam = {
|
||||
pos = Vector(-509.64, -427.61, 310.24),
|
||||
ang = Angle(25, 400, 0),
|
||||
fov = 0.59
|
||||
}
|
||||
|
||||
function ITEM:GetName()
|
||||
local accessLevel = self:GetData("accessLevel", "Member Access")
|
||||
|
||||
return "DOB " .. accessLevel .. " Keycard"
|
||||
end
|
||||
|
||||
function ITEM:GetDescription()
|
||||
local idCard = ix.item.instances[self:GetData("cardID")]
|
||||
return idCard and string.format(self.description.."\n\nCurrently bound to identity card #%s.", idCard:GetData("cardNumber")) or
|
||||
(self:GetData("cardID") and self.description.."\n\nCurrently bound." or self.description)
|
||||
end
|
||||
|
||||
ITEM.functions.Bind = {
|
||||
name = "Bind ID Card",
|
||||
icon = "icon16/vcard_edit.png",
|
||||
OnClick = function(itemTable)
|
||||
local cards = {}
|
||||
|
||||
for _, v in pairs(LocalPlayer():GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
|
||||
table.insert(cards, {
|
||||
text = v:GetName(),
|
||||
value = v
|
||||
})
|
||||
end
|
||||
|
||||
local cardsCount = table.Count(cards)
|
||||
if (cardsCount > 1) then
|
||||
Derma_Select("Bind ID Card to DOB Card", "Please select a ID card to bind to this DOB Card:",
|
||||
cards, "Select ID card",
|
||||
"Confirm Operation", function(value, name)
|
||||
netstream.Start("ixBindDOBCard", itemTable:GetID(), value:GetID())
|
||||
end, "Cancel")
|
||||
elseif (cardsCount == 1) then
|
||||
Derma_Query("Are you sure you wish to bind your ID to this DOB Card?", "Bind ID Card to DOB Card",
|
||||
"Confirm Operation", function()
|
||||
netstream.Start("ixBindDOBCard", itemTable:GetID(), cards[1].value:GetID())
|
||||
end, "Cancel")
|
||||
else
|
||||
LocalPlayer():NotifyLocalized("You do not have ID card to bind to this DOB Card.")
|
||||
end
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!IsValid(itemTable.player)) then
|
||||
return false
|
||||
end
|
||||
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
|
||||
if (!inventory:HasItem("id_card")) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (itemTable:GetData("cardID")) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.SetAccessLevel = {
|
||||
name = "Toggle Card Access Level",
|
||||
icon = "icon16/vcard_add.png",
|
||||
OnRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
local accessLevel = itemTable:GetData("accessLevel", "Member Access")
|
||||
local target = accessLevel == "Member Access" and "Management Access" or "Member Access"
|
||||
|
||||
itemTable:SetData("accessLevel", target)
|
||||
client:NotifyLocalized("You have set this card's Access Level to " .. target .. ".")
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
|
||||
end
|
||||
}
|
||||
66
gamemodes/ixhl2rp/plugins/cid/items/sh_fake_id_card.lua
Normal file
66
gamemodes/ixhl2rp/plugins/cid/items/sh_fake_id_card.lua
Normal file
@@ -0,0 +1,66 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
ITEM.name = "#00000's Identity Card"
|
||||
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
|
||||
ITEM.description = "A citizen identification card assigned to %s, CID #%s.\n\nCard Number: %s\nGenetic description:\n%s.\n\nThis card is property of the Combine Civil Administration. Illegal possession and identity fraud are punishable by law and will result in prosecution by Civil Protection. If found, please return this card immediately to the nearest Civil Protection team."
|
||||
ITEM.category = "Combine"
|
||||
ITEM.iconCam = {
|
||||
pos = Vector(0, 0, 10),
|
||||
ang = Angle(90, 90, 0),
|
||||
fov = 45,
|
||||
}
|
||||
|
||||
if (CLIENT) then
|
||||
function ITEM:PaintOver(item, w, h)
|
||||
surface.SetDrawColor(110, 255, 110, 100)
|
||||
surface.DrawRect(w - 14, h - 14, 8, 8)
|
||||
end
|
||||
end
|
||||
|
||||
function ITEM:GetName()
|
||||
return "#" .. self:GetData("cid", "00000") .. "'s Identity Card"
|
||||
end
|
||||
|
||||
function ITEM:GetDescription()
|
||||
return string.format(self.description,
|
||||
self:GetData("name", "Nobody"),
|
||||
self:GetData("cid", "00000"),
|
||||
self:GetData("cardNumber", "00-0000-0000-00"),
|
||||
self:GetData("geneticDesc", "N/A | N/A | N/A EYES | N/A HAIR"))
|
||||
end
|
||||
|
||||
local prime = 9999999787 -- prime % 4 = 3! DO NOT CHANGE EVER
|
||||
local offset = 100000 -- slightly larger than sqrt(prime) is ok. DO NOT CHANGE EVER
|
||||
local block = 100000000
|
||||
local function generateCardNumber(id)
|
||||
id = (id + offset) % prime
|
||||
|
||||
local cardNum = 0
|
||||
|
||||
for _ = 1, math.floor(id/block) do
|
||||
cardNum = (cardNum + (id * block) % prime) % prime
|
||||
end
|
||||
|
||||
cardNum = (cardNum + (id * (id % block) % prime)) % prime
|
||||
|
||||
if (2 * id < prime) then
|
||||
return cardNum
|
||||
else
|
||||
return prime - cardNum
|
||||
end
|
||||
end
|
||||
|
||||
function ITEM:OnInstanced()
|
||||
local cardNum = Schema:ZeroNumber(generateCardNumber(self:GetID()), 10)
|
||||
|
||||
self:SetData("cardNumber", string.utf8sub(cardNum, 1, 2) .. "-" .. string.utf8sub(cardNum, 3, 6) .. "-" .. string.utf8sub(cardNum, 7, 10) .. "-" .. Schema:ZeroNumber(cardNum % 97, 2))
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
ITEM.name = "Counterfeit Identity Card Creation Device"
|
||||
ITEM.model = Model("models/props_lab/reciever01a.mdl")
|
||||
ITEM.description = "A device used to modify blank Identity Cards to look like real, functional ones."
|
||||
ITEM.category = "Tools"
|
||||
|
||||
ITEM.functions.CreateID = {
|
||||
name = "Create Counterfeit ID",
|
||||
icon = "icon16/vcard.png",
|
||||
OnRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
|
||||
client:RequestString("Name", "Enter the name of the person that this counterfeit ID will be for", function(name)
|
||||
client:RequestString("CID", "Enter the CID of the person that this counterfeit ID will be for", function(cid)
|
||||
client:RequestString("Generic Description", "Enter the generic description of the person that this counterfeit ID will be for", function(desc)
|
||||
local inventory = client:GetCharacter():GetInventory()
|
||||
local card = inventory:HasItem("id_card_blank")
|
||||
|
||||
if (!card) then
|
||||
client:Notify("You need a Blank Identity Card to turn into a counterfeit one!")
|
||||
client:EmitSound("buttons/combine_button_locked.wav")
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
card:Remove()
|
||||
|
||||
inventory:Add("fake_id_card", 1, {
|
||||
name = name,
|
||||
cid = cid,
|
||||
geneticDesc = desc
|
||||
})
|
||||
|
||||
client:Notify("Counterfeit Identity Card created.")
|
||||
client:EmitSound("ambient/machines/combine_terminal_idle2.wav")
|
||||
end, "YOUNG ADULT/ADULT/MIDDLE-AGED/ELDERLY | 0\'00\" | [COLOR] EYES | [COLOR] HAIR")
|
||||
end, "00000")
|
||||
end, "")
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
289
gamemodes/ixhl2rp/plugins/cid/items/sh_id_card.lua
Normal file
289
gamemodes/ixhl2rp/plugins/cid/items/sh_id_card.lua
Normal file
@@ -0,0 +1,289 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
ITEM.name = "#00000's Identity Card"
|
||||
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
|
||||
ITEM.description = "A citizen identification card assigned to %s, CID #%s.\n\nCard Number: %s\nGenetic description:\n%s.\n\nThis card is property of the Combine Civil Administration. Illegal possession and identity fraud are punishable by law and will result in prosecution by Civil Protection. If found, please return this card immediately to the nearest Civil Protection team."
|
||||
ITEM.category = "Combine"
|
||||
ITEM.iconCam = {
|
||||
pos = Vector(0, 0, 10),
|
||||
ang = Angle(90, 90, 0),
|
||||
fov = 45,
|
||||
}
|
||||
|
||||
if (CLIENT) then
|
||||
function ITEM:PaintOver(item, w, h)
|
||||
if (item:GetData("active")) then
|
||||
surface.SetDrawColor(110, 255, 110, 100)
|
||||
surface.DrawRect(w - 14, h - 14, 8, 8)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ITEM:GetName()
|
||||
return "#" .. self:GetData("cid", "00000") .. "'s Identity Card"
|
||||
end
|
||||
|
||||
-- It's also possible to use ITEM.KeepOnDeath = true
|
||||
function ITEM:KeepOnDeath(client)
|
||||
return self:GetData("owner") == client:GetCharacter():GetID() and self:GetData("active")
|
||||
end
|
||||
|
||||
function ITEM:GetDescription()
|
||||
return string.format(self.description,
|
||||
self:GetData("name", "Nobody"),
|
||||
self:GetData("cid", "00000"),
|
||||
self:GetData("cardNumber", "00-0000-0000-00"),
|
||||
self:GetData("geneticDesc", "N/A | N/A | N/A EYES | N/A HAIR"))
|
||||
end
|
||||
|
||||
local prime = 9999999787 -- prime % 4 = 3! DO NOT CHANGE EVER
|
||||
local offset = 100000 -- slightly larger than sqrt(prime) is ok. DO NOT CHANGE EVER
|
||||
local block = 100000000
|
||||
local function generateCardNumber(id)
|
||||
id = (id + offset) % prime
|
||||
|
||||
local cardNum = 0
|
||||
|
||||
for _ = 1, math.floor(id/block) do
|
||||
cardNum = (cardNum + (id * block) % prime) % prime
|
||||
end
|
||||
|
||||
cardNum = (cardNum + (id * (id % block) % prime)) % prime
|
||||
|
||||
if (2 * id < prime) then
|
||||
return cardNum
|
||||
else
|
||||
return prime - cardNum
|
||||
end
|
||||
end
|
||||
|
||||
function ITEM:GetCredits()
|
||||
return self:GetData("credits", 0)
|
||||
end
|
||||
|
||||
function ITEM:HasCredits(amount)
|
||||
return amount <= self:GetData("credits", 0)
|
||||
end
|
||||
|
||||
if (SERVER) then
|
||||
function ITEM:SetCredits(amount)
|
||||
self:SetData("credits", math.floor(amount))
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ITEM:GiveCredits(amount, sender, reason)
|
||||
if (amount < 0 and !self:HasCredits(math.abs(amount))) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (amount == 0) then
|
||||
return true
|
||||
end
|
||||
|
||||
if (sender) then
|
||||
local insert = mysql:Insert("ix_cid_transactions")
|
||||
insert:Insert("datetime", os.time())
|
||||
insert:Insert("sender_name", sender)
|
||||
insert:Insert("sender_cid", "00000")
|
||||
insert:Insert("sender_cardid", 0)
|
||||
insert:Insert("receiver_name", self:GetData("name", "UNKNOWN"))
|
||||
insert:Insert("receiver_cid", self:GetData("cid", "INVALID"))
|
||||
insert:Insert("receiver_cardid", self:GetID())
|
||||
insert:Insert("amount", amount)
|
||||
if (reason and reason != "") then
|
||||
insert:Insert("reason", string.len(reason) > 250 and string.sub(reason, 1, 250) or reason)
|
||||
else
|
||||
insert:Insert("reason", "no reason given")
|
||||
end
|
||||
|
||||
insert:Insert("pos", 0)
|
||||
insert:Insert("read", 1)
|
||||
insert:Execute()
|
||||
end
|
||||
|
||||
return self:SetCredits(amount + self:GetCredits())
|
||||
end
|
||||
|
||||
function ITEM:TakeCredits(amount, receiver, reason)
|
||||
if (amount > 0 and !self:HasCredits(amount)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (amount == 0) then
|
||||
return true
|
||||
end
|
||||
|
||||
if (receiver) then
|
||||
local insert = mysql:Insert("ix_cid_transactions")
|
||||
insert:Insert("datetime", os.time())
|
||||
insert:Insert("sender_name", self:GetData("name", "UNKNOWN"))
|
||||
insert:Insert("sender_cid", self:GetData("cid", "INVALID"))
|
||||
insert:Insert("sender_cardid", self:GetID())
|
||||
insert:Insert("receiver_name", receiver)
|
||||
insert:Insert("receiver_cid", "00000")
|
||||
insert:Insert("receiver_cardid", 0)
|
||||
insert:Insert("amount", amount)
|
||||
if (reason and reason != "") then
|
||||
insert:Insert("reason", string.len(reason) > 250 and string.sub(reason, 1, 250) or reason)
|
||||
else
|
||||
insert:Insert("reason", "no reason given")
|
||||
end
|
||||
|
||||
insert:Insert("pos", 0)
|
||||
insert:Insert("read", 1)
|
||||
insert:Execute()
|
||||
end
|
||||
|
||||
return self:SetCredits(self:GetCredits() - amount)
|
||||
end
|
||||
|
||||
function ITEM:OnInstanced()
|
||||
local cardNum = Schema:ZeroNumber(generateCardNumber(self:GetID()), 10)
|
||||
self:SetData("cardNumber", string.utf8sub(cardNum, 1, 2).."-"..string.utf8sub(cardNum, 3, 6).."-"..string.utf8sub(cardNum, 7, 10)..
|
||||
"-"..Schema:ZeroNumber(cardNum % 97, 2))
|
||||
end
|
||||
|
||||
function ITEM:TransferData(newCard, wipe)
|
||||
newCard:SetData("credits", self:GetData("credits", 0))
|
||||
newCard:SetData("nextRationTime", self:GetData("nextRationTime", 0))
|
||||
|
||||
if (wipe) then
|
||||
self:SetData("active", false)
|
||||
self:SetData("credits", 0)
|
||||
self:SetData("nextRationTime", 0)
|
||||
end
|
||||
end
|
||||
|
||||
function ITEM:OnRemoved()
|
||||
if (self:GetData("active") != false) then
|
||||
local ownerId = self:GetData("owner")
|
||||
local data = {credits = self:GetData("credits", 0), ration = self:GetData("nextRationTime", 0)}
|
||||
if (ix.char.loaded[ownerId]) then
|
||||
ix.char.loaded[ownerId]:SetIdCardBackup(data)
|
||||
ix.char.loaded[ownerId]:SetIdCard(nil)
|
||||
end
|
||||
|
||||
local updateQuery = mysql:Update("ix_characters_data")
|
||||
updateQuery:Update("data", util.TableToJSON(data))
|
||||
updateQuery:Where("id", ownerId)
|
||||
updateQuery:Where("key", "idCardBackup")
|
||||
updateQuery:Execute()
|
||||
|
||||
local idCardQuery = mysql:Update("ix_characters")
|
||||
idCardQuery.updateList[#idCardQuery.updateList + 1] = {"`idcard`", "NULL"}
|
||||
idCardQuery:Where("id", ownerId)
|
||||
idCardQuery:Where("schema", Schema and Schema.folder or "helix")
|
||||
idCardQuery:Execute()
|
||||
|
||||
self:SetData("active", false)
|
||||
end
|
||||
end
|
||||
|
||||
function ITEM:LoadOwnerGenericData(callback, error, ...)
|
||||
if (!callback) then return end
|
||||
|
||||
local arg = {...}
|
||||
local queryObj = mysql:Select("ix_characters_data")
|
||||
queryObj:Where("id", self:GetData("owner", 0))
|
||||
queryObj:Where("key", "genericdata")
|
||||
queryObj:Select("data")
|
||||
queryObj:Callback(function(result)
|
||||
if (!istable(result) or !result[1]) then
|
||||
if (error) then
|
||||
error(self, unpack(arg))
|
||||
end
|
||||
else
|
||||
callback(self, util.JSONToTable(result[1].data or ""), unpack(arg))
|
||||
end
|
||||
end)
|
||||
queryObj:Execute()
|
||||
end
|
||||
|
||||
netstream.Hook("ixSetIDCardCredits", function(client, itemID, amount)
|
||||
ix.item.instances[itemID]:SetCredits(amount)
|
||||
end)
|
||||
end
|
||||
|
||||
ITEM.functions.SetCredits = {
|
||||
name = "Set Credits",
|
||||
icon = "icon16/money_add.png",
|
||||
OnClick = function(itemTable)
|
||||
local client = itemTable.player
|
||||
Derma_StringRequest("Set Credits", "What do you want to set the credits to?", itemTable:GetData("credits", 0), function(text)
|
||||
local amount = tonumber(text)
|
||||
|
||||
if (amount and amount >= 0) then
|
||||
netstream.Start("ixSetIDCardCredits", itemTable:GetID(), math.floor(amount))
|
||||
else
|
||||
client:NotifyLocalized("numNotValid")
|
||||
end
|
||||
end)
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!CAMI.PlayerHasAccess(itemTable.player, "Helix - Set Credits")) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!itemTable:GetData("active", false)) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.insert = {
|
||||
name = "Insert CID",
|
||||
icon = "icon16/add.png",
|
||||
OnRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
local ent = client:GetEyeTrace().Entity
|
||||
if (!ent.CIDInsert) or client:EyePos():DistToSqr(ent:GetPos()) > 62500 then
|
||||
return false
|
||||
end
|
||||
|
||||
local bSuccess, error = itemTable:Transfer(nil, nil, nil, client)
|
||||
if (!bSuccess and isstring(error)) then
|
||||
client:NotifyLocalized(error)
|
||||
return false
|
||||
else
|
||||
client:EmitSound("npc/zombie/foot_slide" .. math.random(1, 3) .. ".wav", 75, math.random(90, 120), 1)
|
||||
end
|
||||
|
||||
if bSuccess and IsEntity(bSuccess) then
|
||||
ent:CIDInsert(bSuccess)
|
||||
end
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
|
||||
if (!client:GetEyeTrace().Entity.CIDInsert) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!itemTable:GetData("active", false)) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
19
gamemodes/ixhl2rp/plugins/cid/items/sh_id_card_blank.lua
Normal file
19
gamemodes/ixhl2rp/plugins/cid/items/sh_id_card_blank.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
ITEM.name = "Blank CID card"
|
||||
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
|
||||
ITEM.description = "A blank citizen identification card without any data."
|
||||
ITEM.category = "Combine"
|
||||
ITEM.iconCam = {
|
||||
pos = Vector(-509.64, -427.61, 310.24),
|
||||
ang = Angle(25, 400, 0),
|
||||
fov = 0.59
|
||||
}
|
||||
114
gamemodes/ixhl2rp/plugins/cid/items/sh_id_card_creator.lua
Normal file
114
gamemodes/ixhl2rp/plugins/cid/items/sh_id_card_creator.lua
Normal file
@@ -0,0 +1,114 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
ITEM.name = "Identity Card Creation Device"
|
||||
ITEM.model = Model("models/props_lab/reciever01d.mdl")
|
||||
ITEM.description = "A device used to bind blank Identity Cards to a specific person."
|
||||
ITEM.category = "Combine"
|
||||
ITEM.functions.CreateIDTarget = {
|
||||
name = "Create Identity Card for target",
|
||||
icon = "icon16/vcard_add.png",
|
||||
OnRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
|
||||
if (ix.config.Get("creditsNoConnection")) then
|
||||
client:EmitSound("hl1/fvox/buzz.wav", 60, 100, 0.5)
|
||||
return false
|
||||
end
|
||||
|
||||
if (itemTable:CheckAccess(client, itemTable) == false) then
|
||||
client:EmitSound("buttons/combine_button_locked.wav", 60, 100, 0.5)
|
||||
return false
|
||||
end
|
||||
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local target = util.TraceLine(data).Entity
|
||||
|
||||
if (IsValid(target) and target:IsPlayer() and target:GetCharacter()) then
|
||||
client:SetAction("@scanning", 5)
|
||||
client:EmitSound("buttons/button18.wav", 60, 100, 0.5)
|
||||
client:DoStaredAction(target, function()
|
||||
itemTable:CreateIDCard(client, target)
|
||||
end, 5, function()
|
||||
client:SetAction()
|
||||
client:EmitSound("buttons/combine_button_locked.wav", 60, 100, 0.5)
|
||||
end)
|
||||
else
|
||||
client:NotifyLocalized("plyNotValid")
|
||||
end
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
return !IsValid(itemTable.entity)
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.CreateIDSelf = {
|
||||
name = "Create Identity Card for yourself",
|
||||
icon = "icon16/vcard.png",
|
||||
OnRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
|
||||
if (ix.config.Get("creditsNoConnection")) then
|
||||
client:EmitSound("hl1/fvox/buzz.wav", 60, 100, 0.5)
|
||||
return false
|
||||
end
|
||||
|
||||
if (itemTable:CheckAccess(client, itemTable) == false) then
|
||||
client:EmitSound("buttons/combine_button_locked.wav", 60, 100, 0.5)
|
||||
return false
|
||||
end
|
||||
|
||||
client:SetAction("@scanning", 5, function()
|
||||
itemTable:CreateIDCard(client, client)
|
||||
end)
|
||||
client:EmitSound("buttons/button18.wav", 60, 100, 0.5)
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
function ITEM:CreateIDCard(client, target)
|
||||
local character = target:GetCharacter()
|
||||
local cid = character:GetCid()
|
||||
|
||||
if (!cid) then
|
||||
client:NotifyLocalized("idNotFound")
|
||||
client:EmitSound("buttons/combine_button_locked.wav", 60, 100, 0.5)
|
||||
return
|
||||
end
|
||||
|
||||
local inventory = client:GetCharacter():GetInventory()
|
||||
local blankCard = inventory:HasItem("id_card_blank")
|
||||
|
||||
if (!blankCard) then
|
||||
client:NotifyLocalized("idNoBlank")
|
||||
client:EmitSound("buttons/combine_button_locked.wav", 60, 100, 0.5)
|
||||
return
|
||||
end
|
||||
|
||||
blankCard:Remove()
|
||||
character:CreateIDCard()
|
||||
client:EmitSound("buttons/button4.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("idCardAdded")
|
||||
|
||||
ix.combineNotify:AddNotification("NTC:// Identification Card #" .. character:GetCid() .. " created by " .. client:GetCombineTag())
|
||||
end
|
||||
|
||||
function ITEM:CheckAccess(client, itemTable)
|
||||
if (!client:HasActiveCombineSuit() and !ix.faction.Get(client:Team()).allowCIDCreator) then
|
||||
client:NotifyLocalized("idNotAllowed")
|
||||
return false
|
||||
end
|
||||
end
|
||||
106
gamemodes/ixhl2rp/plugins/cid/items/sh_moe_card.lua
Normal file
106
gamemodes/ixhl2rp/plugins/cid/items/sh_moe_card.lua
Normal file
@@ -0,0 +1,106 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
ITEM.name = "MOE Access Card"
|
||||
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
|
||||
ITEM.description = "A Ministry of Enlightenment Access Keycard."
|
||||
ITEM.category = "Combine"
|
||||
ITEM.skin = 2
|
||||
ITEM.iconCam = {
|
||||
pos = Vector(-509.64, -427.61, 310.24),
|
||||
ang = Angle(25, 400, 0),
|
||||
fov = 0.59
|
||||
}
|
||||
|
||||
function ITEM:GetName()
|
||||
local accessLevel = self:GetData("accessLevel", "Member Access")
|
||||
|
||||
return "MOE " .. accessLevel .. " Keycard"
|
||||
end
|
||||
|
||||
function ITEM:GetDescription()
|
||||
local idCard = ix.item.instances[self:GetData("cardID")]
|
||||
return idCard and string.format(self.description.."\n\nCurrently bound to identity card #%s.", idCard:GetData("cardNumber")) or
|
||||
(self:GetData("cardID") and self.description.."\n\nCurrently bound." or self.description)
|
||||
end
|
||||
|
||||
ITEM.functions.Bind = {
|
||||
name = "Bind ID Card",
|
||||
icon = "icon16/vcard_edit.png",
|
||||
OnClick = function(itemTable)
|
||||
local cards = {}
|
||||
|
||||
for _, v in pairs(LocalPlayer():GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
|
||||
table.insert(cards, {
|
||||
text = v:GetName(),
|
||||
value = v
|
||||
})
|
||||
end
|
||||
|
||||
local cardsCount = table.Count(cards)
|
||||
if (cardsCount > 1) then
|
||||
Derma_Select("Bind ID Card to MOE Card", "Please select a ID card to bind to this MOE Card:",
|
||||
cards, "Select ID card",
|
||||
"Confirm Operation", function(value, name)
|
||||
netstream.Start("ixBindMOECard", itemTable:GetID(), value:GetID())
|
||||
end, "Cancel")
|
||||
elseif (cardsCount == 1) then
|
||||
Derma_Query("Are you sure you wish to bind your ID to this MOE Card?", "Bind ID Card to MOE Card",
|
||||
"Confirm Operation", function()
|
||||
netstream.Start("ixBindMOECard", itemTable:GetID(), cards[1].value:GetID())
|
||||
end, "Cancel")
|
||||
else
|
||||
LocalPlayer():NotifyLocalized("You do not have ID card to bind to this MOE Card.")
|
||||
end
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!IsValid(itemTable.player)) then
|
||||
return false
|
||||
end
|
||||
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
|
||||
if (!inventory:HasItem("id_card")) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (itemTable:GetData("cardID")) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.SetAccessLevel = {
|
||||
name = "Toggle Card Access Level",
|
||||
icon = "icon16/vcard_add.png",
|
||||
OnRun = function(itemTable)
|
||||
local client = itemTable.player
|
||||
local accessLevel = itemTable:GetData("accessLevel", "Member Access")
|
||||
local target = accessLevel == "Member Access" and "Management Access" or "Member Access"
|
||||
|
||||
itemTable:SetData("accessLevel", target)
|
||||
client:NotifyLocalized("You have set this card's Access Level to " .. target .. ".")
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
|
||||
end
|
||||
}
|
||||
226
gamemodes/ixhl2rp/plugins/cid/items/sh_pos_terminal.lua
Normal file
226
gamemodes/ixhl2rp/plugins/cid/items/sh_pos_terminal.lua
Normal file
@@ -0,0 +1,226 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
ITEM.name = "POS Terminal"
|
||||
ITEM.model = Model("models/willardnetworks/props/posterminal.mdl")
|
||||
ITEM.description = "A device that allows someone to request money from another person to be deposited upon another card."
|
||||
ITEM.category = "Combine"
|
||||
|
||||
function ITEM:GetDescription()
|
||||
local idCard = ix.item.instances[self:GetData("cardID")]
|
||||
return idCard and string.format(self.description.."\n\nCurrently bound to identity card #%s.", idCard:GetData("cardNumber")) or self.description
|
||||
end
|
||||
|
||||
if (SERVER) then
|
||||
function ITEM:AddTransactionID(id)
|
||||
local ids = self:GetData("transactionIDs", {})
|
||||
ids[#ids + 1] = id
|
||||
self:SetData("transactionIDs", ids, false, false, true)
|
||||
end
|
||||
end
|
||||
|
||||
ITEM.functions.RequestCredits = {
|
||||
name = "Request credits",
|
||||
icon = "icon16/money.png",
|
||||
OnClick = function(itemTable)
|
||||
local client = itemTable.player
|
||||
|
||||
if (ix.config.Get("creditsNoConnection")) then
|
||||
client:EmitSound("hl1/fvox/buzz.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("errorNoConnection")
|
||||
return false
|
||||
end
|
||||
|
||||
Derma_StringRequest("Request credits", "How many credits do you want to request?", itemTable:GetData("lastAmount", 0), function(text)
|
||||
local amount = tonumber(text)
|
||||
|
||||
if (amount) then
|
||||
Derma_StringRequest("Request credits - COMMENT", "Please state the reason for the transaction:", "", function(reason)
|
||||
if (text == "") then
|
||||
client:NotifyLocalized("reasonNotValid")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
netstream.Start("ixRequestCredits", itemTable:GetID(), math.floor(amount), reason)
|
||||
end)
|
||||
else
|
||||
client:NotifyLocalized("numNotValid")
|
||||
end
|
||||
end)
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!itemTable:GetData("cardID", false)) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.Bind = {
|
||||
name = "Bind ID Card",
|
||||
icon = "icon16/vcard_edit.png",
|
||||
OnClick = function(itemTable)
|
||||
local client = itemTable.player
|
||||
|
||||
if (ix.config.Get("creditsNoConnection")) then
|
||||
client:EmitSound("hl1/fvox/buzz.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("errorNoConnection")
|
||||
return false
|
||||
end
|
||||
|
||||
local cards = {}
|
||||
|
||||
for _, v in pairs(client:GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
|
||||
table.insert(cards, {
|
||||
text = v:GetName(),
|
||||
value = v
|
||||
})
|
||||
end
|
||||
|
||||
local cardsCount = table.Count(cards)
|
||||
if (cardsCount > 1) then
|
||||
Derma_Select("Bind ID Card to POS", "Please select a ID card to bind to this POS terminal:",
|
||||
cards, "Select ID card",
|
||||
"Confirm Operation", function(value, name)
|
||||
netstream.Start("ixBindTerminal", itemTable:GetID(), value:GetID())
|
||||
end, "Cancel")
|
||||
elseif (cardsCount == 1) then
|
||||
Derma_Query("Are you sure you wish to bind your ID to this POS terminal?", "Bind ID Card to POS",
|
||||
"Confirm Operation", function()
|
||||
netstream.Start("ixBindTerminal", itemTable:GetID(), cards[1].value:GetID())
|
||||
end, "Cancel")
|
||||
else
|
||||
client:NotifyLocalized("You do not have ID card to bind to this terminal.")
|
||||
end
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then return false end
|
||||
if (!IsValid(itemTable.player)) then return false end
|
||||
|
||||
if (itemTable:GetData("cardIDLock", false)) then return false end
|
||||
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
if (!inventory:HasItem("id_card")) then return false end
|
||||
if (!itemTable:GetData("cardID", false)) then return true end
|
||||
|
||||
if (inventory:GetItemCount("id_card") == 1 and inventory:GetItemByID(itemTable:GetData("cardID"))) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.ShowLog = {
|
||||
name = "Show Transactions",
|
||||
icon = "icon16/eye.png",
|
||||
OnRun = function(itemTable, data)
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
PLUGIN:SelectTransactions(itemTable.player, "pos", itemTable:GetID(), data and data[1], itemTable:GetData("cardIDLock", false) and !inventory:GetItemByID(itemTable:GetData("cardID")))
|
||||
|
||||
return false
|
||||
end,
|
||||
isMulti = true,
|
||||
multiOptions = function(item, player)
|
||||
local options = {{name = "1 day", data = {1}}}
|
||||
|
||||
for i = 2, 6 do
|
||||
options[#options + 1] = {name = i.." days", data = {i}}
|
||||
end
|
||||
options[#options + 1] = {name = "1 week", data = {7}}
|
||||
options[#options + 1] = {name = "2 week", data = {14}}
|
||||
options[#options + 1] = {name = "1 month", data = {30}}
|
||||
|
||||
options[#options + 1] = {name = "other", data = {-1}, OnClick = function(itemTable)
|
||||
Derma_StringRequest("Transaction Log Days", "How many days of transaction logs do you wish to see?", "7", function(text)
|
||||
local amount = tonumber(text)
|
||||
if (!amount or amount <= 0) then return end
|
||||
|
||||
net.Start("ixInventoryAction")
|
||||
net.WriteString("ShowLog")
|
||||
net.WriteUInt(itemTable.id, 32)
|
||||
net.WriteUInt(itemTable.invID, 32)
|
||||
net.WriteTable({amount})
|
||||
net.SendToServer()
|
||||
end)
|
||||
|
||||
return false
|
||||
end}
|
||||
|
||||
return options
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then return false end
|
||||
if (!IsValid(itemTable.player)) then return false end
|
||||
if (!itemTable:GetData("cardID", false)) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
ITEM.functions.Lock = {
|
||||
name = "Lock ID Card",
|
||||
icon = "icon16/lock.png",
|
||||
OnRun = function(itemTable)
|
||||
itemTable:SetData("cardIDLock", true)
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then return false end
|
||||
if (!IsValid(itemTable.player)) then return false end
|
||||
|
||||
if (itemTable:GetData("cardIDLock", false)) then return false end
|
||||
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
if (!itemTable:GetData("cardID", false)) then return false end
|
||||
if (!inventory:GetItemByID(itemTable:GetData("cardID"))) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.LockUn = {
|
||||
name = "UnLock ID Card",
|
||||
icon = "icon16/lock_open.png",
|
||||
OnRun = function(itemTable)
|
||||
itemTable:SetData("cardIDLock", false)
|
||||
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then return false end
|
||||
if (!IsValid(itemTable.player)) then return false end
|
||||
|
||||
if (!itemTable:GetData("cardIDLock", false)) then return false end
|
||||
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
if (!itemTable:GetData("cardID", false)) then return false end
|
||||
if (!inventory:GetItemByID(itemTable:GetData("cardID"))) then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
157
gamemodes/ixhl2rp/plugins/cid/items/sh_request_device.lua
Normal file
157
gamemodes/ixhl2rp/plugins/cid/items/sh_request_device.lua
Normal file
@@ -0,0 +1,157 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
REQUEST_CP = 0
|
||||
REQUEST_MED = 1
|
||||
REQUEST_WORK = 2
|
||||
|
||||
ITEM.name = "Request Device"
|
||||
ITEM.model = Model("models/gibs/shield_scanner_gib1.mdl")
|
||||
ITEM.description = "A small device with rounded corners, housing one button. A small combine logo is visible.\n\nThe instructions read: please first register this device by holding your ID card against this device. Once registration is completed, you can request assistance from Civil Protection by pressing the button and stating your request. Your name and CID is automatically included with the request.\nPlease be aware the misuse of the request device, making false statements to Civil Protection and identity fraud are punishable by law and will result in prosecution by Civil Protection."
|
||||
ITEM.price = 20
|
||||
ITEM.category = "Combine"
|
||||
function ITEM:GetDescription()
|
||||
local idCard = ix.item.instances[self:GetData("cardID")]
|
||||
return idCard and string.format(self.description.."\n\nCurrently bound to identity card #%s.", idCard:GetData("cardNumber")) or self.description
|
||||
end
|
||||
|
||||
local function GetRequestTable(data)
|
||||
return {
|
||||
name = data.actionName,
|
||||
icon = "icon16/help.png",
|
||||
OnClick = function(itemTable)
|
||||
if (ix.config.Get("creditsNoConnection")) then
|
||||
itemTable.player:EmitSound("hl1/fvox/buzz.wav", 60, 100, 0.5)
|
||||
return
|
||||
end
|
||||
|
||||
Derma_StringRequest(data.requestTitle, data.requestMessage, PLUGIN.text,
|
||||
function(text)
|
||||
if (text and string.utf8len(text) > 0) then
|
||||
netstream.Start("ixRequest", itemTable:GetID(), text, data.requestType)
|
||||
end
|
||||
|
||||
PLUGIN.text = nil
|
||||
end,
|
||||
function(text)
|
||||
if (text == PLUGIN.text) then
|
||||
PLUGIN.text = text
|
||||
elseif (text and string.utf8len(text) > 0)then
|
||||
PLUGIN.text = text
|
||||
else
|
||||
PLUGIN.text = nil
|
||||
end
|
||||
end, "MAKE REQUEST", "CANCEL"
|
||||
)
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!itemTable:GetData("cardID", false)) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
ITEM.functions.RequestCp = GetRequestTable({
|
||||
actionName = "Make CP Request",
|
||||
requestTitle = "Request Civil Protection Assistance",
|
||||
requestMessage = "Please enter your assistance request for Civil Protection. Your name and CID will automatically be included in the request.",
|
||||
requestType = REQUEST_CP
|
||||
})
|
||||
|
||||
ITEM.functions.RequestMed = GetRequestTable({
|
||||
actionName = "Make CMRU Request",
|
||||
requestTitle = "Request Civil Medical & Research Union Assistance",
|
||||
requestMessage = "Please enter your assistance request for Civil Medical Research Union. Your name and CID will automatically be included in the request. Do not forget to tell your location!",
|
||||
requestType = REQUEST_MED
|
||||
})
|
||||
|
||||
ITEM.functions.RequestCwu = GetRequestTable({
|
||||
actionName = "Make CWU Request",
|
||||
requestTitle = "Request Civil Workers Union Assistance",
|
||||
requestMessage = "Please enter your assistance request for Civil Workers Union. Your name and CID will automatically be included in the request.",
|
||||
requestType = REQUEST_WORK
|
||||
})
|
||||
|
||||
ITEM.functions.Bind = {
|
||||
name = "Bind ID Card",
|
||||
icon = "icon16/vcard_edit.png",
|
||||
OnClick = function(itemTable)
|
||||
local cards = {}
|
||||
|
||||
for _, v in pairs(LocalPlayer():GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
|
||||
table.insert(cards, {
|
||||
text = v:GetName(),
|
||||
value = v
|
||||
})
|
||||
end
|
||||
|
||||
local cardsCount = table.Count(cards)
|
||||
if (cardsCount > 1) then
|
||||
Derma_Select("Bind ID Card to RD", "Please select a ID card to bind to this Request Device:",
|
||||
cards, "Select ID card",
|
||||
"Confirm Operation", function(value, name)
|
||||
netstream.Start("ixBindRequestDevice", itemTable:GetID(), value:GetID())
|
||||
end, "Cancel")
|
||||
elseif (cardsCount == 1) then
|
||||
Derma_Query("Are you sure you wish to bind your ID to this Request Device?", "Bind ID Card to RD",
|
||||
"Confirm Operation", function()
|
||||
netstream.Start("ixBindRequestDevice", itemTable:GetID(), cards[1].value:GetID())
|
||||
end, "Cancel")
|
||||
else
|
||||
LocalPlayer():NotifyLocalized("You do not have ID card to bind to this request device.")
|
||||
end
|
||||
end,
|
||||
OnRun = function(itemTable)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(itemTable)
|
||||
if (IsValid(itemTable.entity)) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!IsValid(itemTable.player)) then
|
||||
return false
|
||||
end
|
||||
|
||||
local inventory = itemTable.player:GetCharacter():GetInventory()
|
||||
if (!inventory:HasItem("id_card")) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (!itemTable:GetData("cardID", false)) then
|
||||
return true
|
||||
end
|
||||
|
||||
if (inventory:GetItemCount("id_card") == 1 and inventory:GetItemByID(itemTable:GetData("cardID"))) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
if (CLIENT) then
|
||||
netstream.Hook("rdMoreThanOneText", function(text)
|
||||
PLUGIN.rdText = text
|
||||
end)
|
||||
end
|
||||
281
gamemodes/ixhl2rp/plugins/cid/sh_commands.lua
Normal file
281
gamemodes/ixhl2rp/plugins/cid/sh_commands.lua
Normal file
@@ -0,0 +1,281 @@
|
||||
--[[
|
||||
| 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 ix = ix
|
||||
local math = math
|
||||
local tostring = tostring
|
||||
local pairs = pairs
|
||||
local netstream = netstream
|
||||
local CurTime = CurTime
|
||||
local IsValid = IsValid
|
||||
local util = util
|
||||
local hook = hook
|
||||
local ipairs = ipairs
|
||||
local table = table
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
ix.command.Add("CharSetCredits", {
|
||||
description = "@cmdCharSetMoney",
|
||||
privilege = "Set Credits",
|
||||
arguments = {
|
||||
ix.type.character,
|
||||
ix.type.number
|
||||
},
|
||||
OnRun = function(self, client, target, amount)
|
||||
amount = math.Round(amount)
|
||||
|
||||
if (amount <= 0) then
|
||||
return "@invalidArg", 2
|
||||
end
|
||||
|
||||
target:SetCredits(amount)
|
||||
client:NotifyLocalized("setCredits", target:GetName(), tostring(amount))
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("CharGiveCredits", {
|
||||
description = "@cmdCharGiveCredits",
|
||||
privilege = "Set Credits",
|
||||
arguments = {
|
||||
ix.type.character,
|
||||
ix.type.number
|
||||
},
|
||||
OnRun = function(self, client, target, amount)
|
||||
amount = math.Round(amount)
|
||||
|
||||
target:GiveCredits(amount)
|
||||
client:NotifyLocalized("giveCredits", target:GetName(), tostring(amount))
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("Request", {
|
||||
description = "@cmdRequest",
|
||||
arguments = {
|
||||
ix.type.text
|
||||
},
|
||||
combineBeep = true,
|
||||
OnRun = function(self, client, text)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
|
||||
local items = character:GetInventory():GetItems()
|
||||
local requestDevices = {}
|
||||
|
||||
for _, item in pairs(items) do
|
||||
if (item.uniqueID == "request_device" and item:GetData("cardID")) then
|
||||
requestDevices[#requestDevices + 1] = item
|
||||
end
|
||||
end
|
||||
|
||||
if (#requestDevices > 1) then
|
||||
client:NotifyLocalized("rdMoreThanOne")
|
||||
netstream.Start(client, "rdMoreThanOneText", text)
|
||||
return
|
||||
elseif (#requestDevices == 0) then
|
||||
client:NotifyLocalized("rdNoRD")
|
||||
return
|
||||
end
|
||||
|
||||
if (ix.config.Get("creditsNoConnection")) then
|
||||
client:EmitSound("hl1/fvox/buzz.wav", 60, 100, 0.5)
|
||||
return
|
||||
end
|
||||
|
||||
local idCard = ix.item.instances[requestDevices[1]:GetData("cardID")]
|
||||
if (!idCard) then
|
||||
client:NotifyLocalized("rdError")
|
||||
return
|
||||
end
|
||||
|
||||
if (client.ixNextRequest and client.ixNextRequest > CurTime()) then
|
||||
client:NotifyLocalized("rdFreqLimit")
|
||||
return
|
||||
else
|
||||
client.ixNextRequest = CurTime() + 10
|
||||
end
|
||||
|
||||
idCard:LoadOwnerGenericData(PLUGIN.RequestSuccess, PLUGIN.RequestError, client, text)
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("WithdrawCredit", {
|
||||
description = "Withdraws credits from the specified character's active CID card.",
|
||||
OnCheckAccess = function(self, client)
|
||||
return client:GetCharacter() and (client:GetCharacter():GetFaction() == FACTION_ADMIN or client:GetCharacter():HasFlags("U"))
|
||||
end,
|
||||
arguments = {
|
||||
ix.type.character,
|
||||
ix.type.number
|
||||
},
|
||||
OnRun = function(self, client, target, amount)
|
||||
amount = math.Round(amount)
|
||||
|
||||
if (amount <= 0) then
|
||||
return "@invalidArg", 2
|
||||
end
|
||||
|
||||
if (target:HasCredits(amount)) then
|
||||
local receiverCardId = client:GetCharacter():GetIdCard()
|
||||
local senderCardId = target:GetIdCard()
|
||||
|
||||
PLUGIN:CreditTransaction(receiverCardId, senderCardId, amount, target, client, nil, "CCA Withdraw")
|
||||
|
||||
target:GetPlayer():Notify("The Combine Civil Administration withdrew "..amount.." credits from your card.")
|
||||
else
|
||||
client:Notify("Character do not have this amount of credits.")
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("CreateCid", {
|
||||
description = "Creates new CID card for the specified character.",
|
||||
adminOnly = true,
|
||||
arguments = {
|
||||
ix.type.player
|
||||
},
|
||||
OnRun = function(self, client, target)
|
||||
if (IsValid(target) and target:IsPlayer() and target:GetCharacter()) then
|
||||
local character = target:GetCharacter()
|
||||
local cid = character:GetCid()
|
||||
|
||||
if (!cid) then
|
||||
client:NotifyLocalized("idNotFound")
|
||||
return
|
||||
end
|
||||
|
||||
character:CreateIDCard()
|
||||
client:EmitSound("buttons/button4.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("idCardAdded")
|
||||
|
||||
if (target != client) then
|
||||
target:NotifyLocalized("idCardRecreated")
|
||||
end
|
||||
else
|
||||
client:NotifyLocalized("plyNotValid")
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
if (ix.plugin.list.doors) then
|
||||
-- Overriding Helix door plugin command to use credits instead
|
||||
ix.command.Add("DoorBuy", {
|
||||
description = "@cmdDoorBuy",
|
||||
OnRun = function(self, client, arguments)
|
||||
-- Get the entity 96 units infront of the player.
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local trace = util.TraceLine(data)
|
||||
local entity = trace.Entity
|
||||
|
||||
-- Check if the entity is a valid door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
if (!entity:GetNetVar("ownable") or entity:GetNetVar("faction") or entity:GetNetVar("class")) then
|
||||
return "@dNotAllowedToOwn"
|
||||
end
|
||||
|
||||
if (IsValid(entity:GetDTEntity(0))) then
|
||||
return "@dOwnedBy", entity:GetDTEntity(0):Name()
|
||||
end
|
||||
|
||||
entity = IsValid(entity.ixParent) and entity.ixParent or entity
|
||||
|
||||
-- Get the price that the door is bought for.
|
||||
local price = entity:GetNetVar("price", ix.config.Get("doorCost"))
|
||||
local character = client:GetCharacter()
|
||||
|
||||
-- Check if the player can actually afford it.
|
||||
if (character:HasCredits(price)) then
|
||||
-- Set the door to be owned by this player.
|
||||
entity:SetDTEntity(0, client)
|
||||
entity.ixAccess = {
|
||||
[client] = DOOR_OWNER
|
||||
}
|
||||
|
||||
ix.plugin.list.doors:CallOnDoorChildren(entity, function(child)
|
||||
child:SetDTEntity(0, client)
|
||||
end)
|
||||
|
||||
local doors = character:GetVar("doors") or {}
|
||||
doors[#doors + 1] = entity
|
||||
character:SetVar("doors", doors, true)
|
||||
|
||||
-- Take their money and notify them.
|
||||
character:TakeCredits(price, "Housing", "Door purchased")
|
||||
ix.city.main:AddCredits(price)
|
||||
hook.Run("OnPlayerPurchaseDoor", client, entity, true, ix.plugin.list.doors.CallOnDoorChildren)
|
||||
|
||||
ix.log.Add(client, "buydoor")
|
||||
return "@dPurchased", price..(price == 1 and " credit" or " credits")
|
||||
else
|
||||
-- Otherwise tell them they can not.
|
||||
return "@canNotAfford"
|
||||
end
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("DoorSell", {
|
||||
description = "@cmdDoorSell",
|
||||
OnRun = function(self, client, arguments)
|
||||
-- Get the entity 96 units infront of the player.
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local trace = util.TraceLine(data)
|
||||
local entity = trace.Entity
|
||||
|
||||
-- Check if the entity is a valid door.
|
||||
if (IsValid(entity) and entity:IsDoor() and !entity:GetNetVar("disabled")) then
|
||||
-- Check if the player owners the door.
|
||||
if (client == entity:GetDTEntity(0)) then
|
||||
entity = IsValid(entity.ixParent) and entity.ixParent or entity
|
||||
|
||||
-- Get the price that the door is sold for.
|
||||
local price = math.Round(entity:GetNetVar("price", ix.config.Get("doorCost")) * ix.config.Get("doorSellRatio"))
|
||||
local character = client:GetCharacter()
|
||||
|
||||
-- Remove old door information.
|
||||
entity:RemoveDoorAccessData()
|
||||
|
||||
local doors = character:GetVar("doors") or {}
|
||||
|
||||
for k, v in ipairs(doors) do
|
||||
if (v == entity) then
|
||||
table.remove(doors, k)
|
||||
end
|
||||
end
|
||||
|
||||
character:SetVar("doors", doors, true)
|
||||
|
||||
-- Take their money and notify them.
|
||||
character:GiveCredits(price, "Housing", "Door sold")
|
||||
hook.Run("OnPlayerPurchaseDoor", client, entity, false, PLUGIN.CallOnDoorChildren)
|
||||
|
||||
ix.log.Add(client, "selldoor")
|
||||
return "@dSold", price..(price == 1 and " credit" or " credits")
|
||||
else
|
||||
-- Otherwise tell them they can not.
|
||||
return "@notOwner"
|
||||
end
|
||||
else
|
||||
-- Tell the player the door isn't valid.
|
||||
return "@dNotValid"
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
210
gamemodes/ixhl2rp/plugins/cid/sh_plugin.lua
Normal file
210
gamemodes/ixhl2rp/plugins/cid/sh_plugin.lua
Normal file
@@ -0,0 +1,210 @@
|
||||
--[[
|
||||
| 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 CAMI = CAMI
|
||||
local ix = ix
|
||||
local IsValid = IsValid
|
||||
local net = net
|
||||
local tonumber = tonumber
|
||||
local Color = Color
|
||||
local chat = chat
|
||||
local string = string
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
PLUGIN.name = "CID"
|
||||
PLUGIN.author = "Gr4Ss"
|
||||
PLUGIN.description = "Adds identification cards and credits as digital currency."
|
||||
|
||||
CAMI.RegisterPrivilege({
|
||||
Name = "Helix - Set Credits",
|
||||
MinAccess = "superadmin"
|
||||
})
|
||||
|
||||
ix.config.Add("creditsNoConnection", false, "Disable the use of credits in some situations, simulating the connection to the Combine network being down.", nil, {
|
||||
category = "Miscellaneous"
|
||||
})
|
||||
|
||||
ix.config.Add("requestDeviceAction", "just used request device.", "The action that should be sent after someone uses request device.", nil, {
|
||||
category = "Miscellaneous"
|
||||
})
|
||||
|
||||
ix.char.RegisterVar("cid", {
|
||||
field = "cid",
|
||||
fieldType = ix.type.string,
|
||||
default = nil,
|
||||
bNoDisplay = true
|
||||
})
|
||||
|
||||
ix.char.RegisterVar("idCardBackup", {
|
||||
field = "idCardBackup",
|
||||
default = {},
|
||||
bNoDisplay = true,
|
||||
bNoNetworking = true
|
||||
})
|
||||
|
||||
ix.char.RegisterVar("idCard", {
|
||||
field = "idcard",
|
||||
fieldType = ix.type.number,
|
||||
default = nil,
|
||||
bNoDisplay = true,
|
||||
OnSet = function(self, value)
|
||||
local client = self:GetPlayer()
|
||||
|
||||
if (IsValid(client)) then
|
||||
self.vars.idCard = value
|
||||
|
||||
net.Start("ixCharacterVarChanged")
|
||||
net.WriteUInt(self:GetID(), 32)
|
||||
net.WriteString("idCard")
|
||||
net.WriteType(self.vars.idCard)
|
||||
net.Broadcast()
|
||||
end
|
||||
end,
|
||||
OnGet = function(self, default)
|
||||
local idCard = self.vars.idCard
|
||||
|
||||
return tonumber(idCard) or 0
|
||||
end,
|
||||
OnAdjust = function(self, client, data, value, newData)
|
||||
newData.idCard = value
|
||||
end
|
||||
})
|
||||
|
||||
ix.util.Include("cl_plugin.lua")
|
||||
ix.util.Include("sh_commands.lua")
|
||||
ix.util.Include("sv_hooks.lua")
|
||||
ix.util.Include("sv_net.lua")
|
||||
ix.util.Include("sv_plugin.lua")
|
||||
|
||||
ix.lang.AddTable("english", {
|
||||
cmdCharSetCredits = "Set a character's Credits.",
|
||||
cmdCharGiveCredits = "Give a character Credits.",
|
||||
cmdRequest = "Make a request for assistance to Civil Protection. Will use a ID card-bound request device from your inventory.",
|
||||
|
||||
setCredits = "You have set %s's credits to %s.",
|
||||
giveCredits = "You have given %s %s credits.",
|
||||
|
||||
scanning = "Scanning...",
|
||||
idNotFound = "ERROR: Biological signature not found.",
|
||||
idNoBlank = "ERROR: No blank card inserted.",
|
||||
idCardAdded = "SUCCESS: ID Card created.",
|
||||
idCardRecreated = "SUCCESS: ID Card recreated.",
|
||||
idNotAllowed = "Device does not respond when you try to use it.",
|
||||
|
||||
posBound = "SUCCESS: POS terminal bound to the specified ID Card.",
|
||||
posBoundInactiveCard = "ERROR: ID Card is no longer active. Please dispose of inactive card immediately.",
|
||||
|
||||
posRequestSent = "INFO: Performing credit transaction...",
|
||||
posRequestExecuting = "INFO: Executing transaction... please wait...",
|
||||
posTransactionSuccess = "SUCCESS: Transaction complete.",
|
||||
posError = "ERROR: Unexpected error occurred. Transaction was terminated.",
|
||||
posBoundCardNotActive = "ERROR: Bound ID Card no longer active. Please dispose of inactive card immediately.",
|
||||
posCardNotActive = "ERROR: Used ID Card no longer active. Please dispose of inactive card immediately.",
|
||||
posTransOngoing = "%s tried to start a new transaction, but you are still finishing another transaction.",
|
||||
posTransExpired = "Your transaction has expired.",
|
||||
posTransactionRefused = "Your POS transaction was refused or timed out.",
|
||||
|
||||
numNotValid = "You specified invalid amount of credits!",
|
||||
reasonNotValid = "You specified an invalid reason for the transaction!",
|
||||
transactionNoMoney = "ERROR: Insufficient credits.",
|
||||
transactionOwnChars = "ERROR: You cannot transfer credits between your own characters!",
|
||||
transactionSelf = "ERROR: You cannot transfer credits to yourself!",
|
||||
|
||||
rdBound = "SUCCESS: Request Device successfully bound to the specified ID Card.",
|
||||
rdError = "ERROR: Unexpected error occurred. Please find a Civil Protection officer to file your request manually.",
|
||||
rdMoreThanOne = "You have more than one bound request device, please select in your inventory which one you want to use.",
|
||||
rdNoRD = "You do not have a request device, or it is not bound to an ID card!",
|
||||
rdFreqLimit = "Please wait at least 10 seconds between requests.",
|
||||
|
||||
cwuBound = "SUCCESS: CWU Card successfully bound to the specified ID Card.",
|
||||
dobBound = "SUCCESS: DOB Card successfully bound to the specified ID Card.",
|
||||
cmruBound = "SUCCESS: CMRU Card successfully bound to the specified ID Card.",
|
||||
conBound = "SUCCESS: CCR Card successfully bound to the specified ID Card.",
|
||||
|
||||
targetTransactionInProgress = "This person already has a transaction in progress!",
|
||||
|
||||
idCardIssued = "New identity card issued for %s by %s",
|
||||
|
||||
errorNoConnection = "ERROR: NO CONNECTION"
|
||||
})
|
||||
|
||||
ix.lang.AddTable("spanish", {
|
||||
posBoundCardNotActive = "ERROR: La tarjeta ID vinculada ya no está activa. Por favor, deshágase de la tarjeta inactiva inmediatamente.",
|
||||
posTransExpired = "Tu transacción ha caducado.",
|
||||
posTransactionSuccess = "ÉXITO: Transacción completada.",
|
||||
posTransOngoing = "%s ha intentado iniciar una nueva transacción, pero todavía estás terminando otra transacción.",
|
||||
posRequestExecuting = "INFO: Ejecutando la transacción... por favor espere...",
|
||||
numNotValid = "¡Has especificado una cantidad de créditos inválida!",
|
||||
posError = "ERROR: Se ha producido un error inesperado. La transacción ha finalizado.",
|
||||
posCardNotActive = "ERROR: La tarjeta ID vinculada ya no está activa. Por favor, deshágase de la tarjeta inactiva inmediatamente.",
|
||||
reasonNotValid = "¡Has especificado un motivo no válido para la transacción!",
|
||||
transactionOwnChars = "ERROR: ¡No puedes transferir créditos entre tus propios personajes!",
|
||||
transactionNoMoney = "ERROR: Créditos insuficientes.",
|
||||
targetTransactionInProgress = "¡Esta persona ya tiene una transacción en curso!",
|
||||
transactionSelf = "ERROR: ¡No puedes transferirte créditos a ti mismo!",
|
||||
rdError = "ERROR: Se ha producido un error inesperado. Por favor, busque a un agente de Protección Civil para presentar tu solicitud manualmente.",
|
||||
giveCredits = "Has dado %s %s créditos.",
|
||||
scanning = "Escaneando...",
|
||||
cmdCharSetCredits = "Establecer los créditos de un personaje.",
|
||||
cmdCharGiveCredits = "Dar créditos a un personaje.",
|
||||
posTransactionRefused = "Su transacción en del datafono ha sido rechazada o ha expirado.",
|
||||
idNoBlank = "ERROR: No se ha insertado ninguna tarjeta en blanco.",
|
||||
posBoundInactiveCard = "ERROR: La tarjeta de identificación ya no está activa. Por favor, deshágase de la tarjeta inactiva inmediatamente.",
|
||||
rdNoRD = "¡No tiene un dispositivo de socorro, o no está vinculado a una tarjeta de identificación!",
|
||||
idCardAdded = "ÉXITO: Tarjeta de identificación creada.",
|
||||
posRequestSent = "INFO: Realizando una transacción de crédito...",
|
||||
idCardRecreated = "ÉXITO: Tarjeta de identificación recreada.",
|
||||
posBound = "ÉXITO: El datafono está vinculado a la tarjeta de identificación especificada.",
|
||||
idNotAllowed = "El dispositivo no responde cuando intentas utilizarlo.",
|
||||
idNotFound = "ERROR: Señal Biológica no encontrada.",
|
||||
rdMoreThanOne = "Tienes más de un dispositivo de socorro vinculado, por favor selecciona en tu inventario cuál quieres usar.",
|
||||
rdFreqLimit = "Por favor, espere al menos 10 segundos entre peticiones.",
|
||||
cmdRequest = "Realiza una solicitud de ayuda a Protección Civil. Utilizará un dispositivo de socorro vinculado a una tarjeta de identificación de tu inventario.",
|
||||
rdBound = "ÉXITO: El dispositivo de socorro se ha vinculado con éxito a la tarjeta de identificación especificada.",
|
||||
setCredits = "Los créditos de %s han sido establecidos a %s.",
|
||||
cwuBound = "ÉXITO: Tarjeta UTC vinculada con éxito a la tarjeta ID especificada.",
|
||||
idCardIssued = "Nuevo documento de identidad emitido para %s por %s"
|
||||
})
|
||||
|
||||
do
|
||||
local CLASS = {}
|
||||
CLASS.color = Color(175, 125, 100)
|
||||
CLASS.format = "%s, #%s requests %s\"%s\""
|
||||
CLASS.formatCP = "%s requests %s\"%s\""
|
||||
|
||||
function CLASS:CanHear(speaker, listener, data)
|
||||
if data.otherListeners and data.otherListeners[listener] then return true end
|
||||
return listener == speaker or listener:HasActiveCombineSuit() or ix.faction.Get(listener:Team()).canHearRequests == true
|
||||
end
|
||||
|
||||
local requestTypes = {
|
||||
[REQUEST_CP] = "CP",
|
||||
[REQUEST_MED] = "CMRU",
|
||||
[REQUEST_WORK] = "CWU"
|
||||
}
|
||||
|
||||
function CLASS:OnChatAdd(speaker, text, aonymous, data)
|
||||
local requestType = ""
|
||||
|
||||
if (data.requestType) then
|
||||
requestType = requestTypes[data.requestType].." "
|
||||
end
|
||||
|
||||
if (speaker:IsCombine()) then
|
||||
chat.AddText(self.color, string.format(self.formatCP, "Protection Unit", requestType, text))
|
||||
else
|
||||
chat.AddText(self.color, string.format(self.format, data.name, data.cid, requestType, text))
|
||||
end
|
||||
end
|
||||
|
||||
ix.chat.Register("request", CLASS)
|
||||
end
|
||||
65
gamemodes/ixhl2rp/plugins/cid/sv_hooks.lua
Normal file
65
gamemodes/ixhl2rp/plugins/cid/sv_hooks.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
--[[
|
||||
| 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 ix = ix
|
||||
local pairs = pairs
|
||||
local math = math
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
-- Always ensure the character's current CID item is loaded
|
||||
function PLUGIN:CharacterLoaded(character)
|
||||
local idCardID = character:GetIdCard()
|
||||
local inventory = character:GetInventory()
|
||||
if (idCardID and (!inventory or !inventory:GetItemByID(idCardID)) and !ix.item.instances[idCardID]) then
|
||||
ix.item.LoadItemByID(idCardID)
|
||||
end
|
||||
|
||||
if (inventory) then
|
||||
for _, v in pairs(inventory:GetItems()) do
|
||||
if (v:GetData("cardID") and !ix.item.instances[v:GetData("cardID")]) then
|
||||
ix.item.LoadItemByID(v:GetData("cardID"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:OnCharacterCreated(client, character)
|
||||
local charID = character.id
|
||||
local id = self:GenerateCid(charID)
|
||||
|
||||
character:SetCid(id)
|
||||
end
|
||||
|
||||
function PLUGIN:InventoryItemAdded(oldInv, inventory, newItem)
|
||||
if (oldInv != nil) then return end
|
||||
|
||||
if (newItem.uniqueID == "id_card" and
|
||||
newItem:GetData("owner") == inventory.owner and
|
||||
newItem:GetData("active") != false) then
|
||||
|
||||
local character = ix.char.loaded[inventory.owner]
|
||||
local oldCardId = character:GetIdCard()
|
||||
if (oldCardId) then
|
||||
local oldCard = ix.item.instances[oldCardId]
|
||||
if (oldCard) then
|
||||
oldCard:TransferData(newItem, true)
|
||||
end
|
||||
else
|
||||
local dataBackup = character:GetIdCardBackup({})
|
||||
for k, v in pairs(dataBackup) do
|
||||
newItem:SetData(k, v)
|
||||
end
|
||||
end
|
||||
|
||||
character:SetIdCard(newItem:GetID())
|
||||
end
|
||||
end
|
||||
485
gamemodes/ixhl2rp/plugins/cid/sv_net.lua
Normal file
485
gamemodes/ixhl2rp/plugins/cid/sv_net.lua
Normal file
@@ -0,0 +1,485 @@
|
||||
--[[
|
||||
| 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 netstream = netstream
|
||||
local CAMI = CAMI
|
||||
local ix = ix
|
||||
local math = math
|
||||
local util = util
|
||||
local IsValid = IsValid
|
||||
local CurTime = CurTime
|
||||
local istable = istable
|
||||
local Color = Color
|
||||
local string = string
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
--Honeypot netstream hook, overwrite unsecure hook in sh_id_card.lua
|
||||
netstream.Hook("ixSetIDCardCredits", function(client, itemID, amount)
|
||||
local bNoAccess = !CAMI.PlayerHasAccess(client, "Helix - Set Credits")
|
||||
if (bNoAccess) then
|
||||
ix.log.Add(client, "netstreamHoneypot", "ixSetIDCardCredits", bNoAccess)
|
||||
return
|
||||
end
|
||||
|
||||
if (!ix.item.instances[itemID] or amount < 0) then
|
||||
return
|
||||
end
|
||||
|
||||
ix.item.instances[itemID]:SetCredits(math.floor(amount))
|
||||
ix.log.Add(client, "creditIDCardSetCredits", itemID, amount)
|
||||
end)
|
||||
|
||||
-- Request credits
|
||||
netstream.Hook("ixRequestCredits", function(client, posTerminalID, amount, reason)
|
||||
if (!client:GetCharacter():GetInventory():GetItemByID(posTerminalID)) then
|
||||
return
|
||||
end
|
||||
|
||||
if (reason == "") then
|
||||
client:NotifyLocalized("reasonNotValid")
|
||||
return
|
||||
end
|
||||
|
||||
local posTerminal = ix.item.instances[posTerminalID]
|
||||
if (!posTerminal) then
|
||||
return
|
||||
end
|
||||
|
||||
local receiverCard = ix.item.instances[posTerminal:GetData("cardID", -1)]
|
||||
if (!receiverCard) then
|
||||
client:NotifyLocalized("posError")
|
||||
return
|
||||
end
|
||||
|
||||
if (receiverCard:GetData("active") == false) then
|
||||
client:NotifyLocalized("posBoundCardNotActive")
|
||||
return
|
||||
end
|
||||
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local target = util.TraceLine(data).Entity
|
||||
|
||||
if (IsValid(target) and target:IsPlayer() and target:GetCharacter()) then
|
||||
if (IsValid(target.ixSendCreditsTo) and target.ixSendCreditsToTime > CurTime()) then
|
||||
client:NotifyLocalized("targetTransactionInProgress")
|
||||
return
|
||||
end
|
||||
|
||||
posTerminal:SetData("lastAmount", amount, nil, nil, true)
|
||||
|
||||
target.ixSendCreditsTo = client
|
||||
target.ixSendCreditsToTime = CurTime() + 15
|
||||
target.ixSendCreditsReason = reason
|
||||
target.ixReceiverCardID = receiverCard:GetID()
|
||||
target.ixSendCreditsAmount = amount
|
||||
target.ixSendCreditsPosTerminal = posTerminal
|
||||
|
||||
netstream.Start(target, "ixRequestCredits", client, amount, reason)
|
||||
client:NotifyLocalized("posRequestSent")
|
||||
else
|
||||
client:NotifyLocalized("plyNotValid")
|
||||
end
|
||||
end)
|
||||
|
||||
netstream.Hook("ixConfirmCreditOperation", function(sender, senderCardID)
|
||||
if (!IsValid(sender.ixSendCreditsTo)) then
|
||||
return
|
||||
end
|
||||
|
||||
local receiver = sender.ixSendCreditsTo
|
||||
local receiverCardID = sender.ixReceiverCardID
|
||||
local reason = sender.ixSendCreditsReason
|
||||
local amount = sender.ixSendCreditsAmount
|
||||
local posTerminal = sender.ixSendCreditsPosTerminal
|
||||
|
||||
sender.ixSendCreditsTo = nil
|
||||
sender.ixSendCreditsToTime = nil
|
||||
sender.ixSendCreditsReason = nil
|
||||
sender.ixReceiverCardID = nil
|
||||
sender.ixSendCreditsAmount = nil
|
||||
|
||||
if (!sender:GetCharacter():GetInventory():GetItemByID(senderCardID)) then
|
||||
if (IsValid(receiver)) then
|
||||
receiver:NotifyLocalized("posError")
|
||||
end
|
||||
sender:NotifyLocalized("posError")
|
||||
return
|
||||
end
|
||||
|
||||
local senderCard = ix.item.instances[senderCardID]
|
||||
if (senderCard:GetData("active") == false) then
|
||||
if (IsValid(receiver)) then
|
||||
receiver:NotifyLocalized("posCardNotActive")
|
||||
end
|
||||
sender:NotifyLocalized("posCardNotActive")
|
||||
return
|
||||
end
|
||||
|
||||
if (!senderCard:HasCredits(amount)) then
|
||||
if (IsValid(receiver)) then
|
||||
receiver:NotifyLocalized("transactionNoMoney")
|
||||
end
|
||||
sender:NotifyLocalized("transactionNoMoney")
|
||||
return
|
||||
end
|
||||
|
||||
PLUGIN:CreditTransaction(receiverCardID, senderCardID, amount, sender, receiver, posTerminal, reason)
|
||||
end)
|
||||
|
||||
netstream.Hook("ixDenyCreditOperation", function(sender)
|
||||
if (IsValid(sender.ixSendCreditsTo)) then
|
||||
sender.ixSendCreditsTo:NotifyLocalized("posTransactionRefused")
|
||||
end
|
||||
|
||||
sender.ixSendCreditsTo = nil
|
||||
sender.ixSendCreditsToTime = nil
|
||||
sender.ixSendCreditsReason = nil
|
||||
sender.ixReceiverCardID = nil
|
||||
sender.ixSendCreditsAmount = nil
|
||||
end)
|
||||
|
||||
netstream.Hook("ixBindTerminal", function(client, itemID, cardID)
|
||||
if (!client:GetCharacter():GetInventory():GetItemByID(cardID) or !client:GetCharacter():GetInventory():GetItemByID(itemID)) then
|
||||
return
|
||||
end
|
||||
|
||||
local itemTable = ix.item.instances[itemID]
|
||||
if (itemTable:GetData("active") == false) then
|
||||
client:NotifyLocalized("posBoundInactiveCard")
|
||||
return
|
||||
end
|
||||
|
||||
if (itemTable:GetData("cardIDLock", false)) then return end
|
||||
|
||||
itemTable:SetData("cardID", cardID)
|
||||
|
||||
client:EmitSound("buttons/combine_button1.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("posBound")
|
||||
end)
|
||||
|
||||
|
||||
-- Send Credits
|
||||
netstream.Hook("ixSendCredits", function(client, senderCardID, receiverCid, amount, senderCid)
|
||||
if (!client:GetCharacter():GetInventory():GetItemByID(senderCardID)) then
|
||||
client:NotifyLocalized("posError")
|
||||
return
|
||||
end
|
||||
|
||||
local senderCard = ix.item.instances[senderCardID]
|
||||
if (!senderCard) then
|
||||
client:NotifyLocalized("posError")
|
||||
return
|
||||
end
|
||||
|
||||
amount = math.floor(amount)
|
||||
if (amount <= 0) then
|
||||
client:NotifyLocalized("numNotValid")
|
||||
return
|
||||
end
|
||||
|
||||
if (!senderCard:HasCredits(amount)) then
|
||||
client:NotifyLocalized("transactionNoMoney")
|
||||
return
|
||||
end
|
||||
|
||||
if (senderCard:GetData("cid", "00000") == receiverCid) then
|
||||
client:NotifyLocalized("transactionSelf")
|
||||
return
|
||||
end
|
||||
|
||||
local receiverQuery = mysql:Select("ix_characters")
|
||||
receiverQuery:Select("id")
|
||||
receiverQuery:Select("idcard")
|
||||
receiverQuery:Select("steamid")
|
||||
receiverQuery:Where("cid", receiverCid)
|
||||
receiverQuery:Limit(1)
|
||||
receiverQuery:Callback(function(result)
|
||||
if (!result or !istable(result) or #result == 0) then
|
||||
client:NotifyLocalized("posError")
|
||||
return
|
||||
end
|
||||
|
||||
local first = result[1]
|
||||
if (client:SteamID64() == first.steamid and result[1].id != client:GetCharacter():GetID()) then
|
||||
client:NotifyLocalized("transactionOwnChars")
|
||||
-- return
|
||||
end
|
||||
|
||||
local receiver = ix.char.loaded[first.id]
|
||||
|
||||
ix.combineNotify:AddNotification("LOG:// Subject ID #" .. senderCid .. " sent " .. amount .. " Credits to #" .. receiverCid, nil, client)
|
||||
PLUGIN:CreditTransaction(result[1].idcard, senderCardID, amount, client, receiver, nil, "Terminal Transfer", senderCid, receiverCid)
|
||||
end)
|
||||
receiverQuery:Execute()
|
||||
end)
|
||||
|
||||
|
||||
-- Request stuff
|
||||
local red = Color(255, 0, 0, 255)
|
||||
local orange = Color(255, 165, 0, 255)
|
||||
local yellow = Color(255, 255, 0, 255)
|
||||
local function createCombineAlert(client, text, color)
|
||||
ix.combineNotify:AddImportantNotification(text, color, client)
|
||||
end
|
||||
|
||||
function PLUGIN.RequestSuccess(idCard, genericData, client, text, requestType)
|
||||
local isBOL = genericData.bol
|
||||
local isAC = genericData.anticitizen
|
||||
|
||||
local alertText, color = "%s, #%s (SC: %d) requesting assistance", yellow
|
||||
|
||||
if (client:IsCombine()) then
|
||||
alertText = "%s (SC: %d) requesting assistance"
|
||||
elseif (isAC) then
|
||||
alertText, color = "Anti-Citizen %s, #%s requesting assistance", red
|
||||
elseif (isBOL) then
|
||||
alertText, color = "BOL Suspect %s, #%s requesting assistance", orange
|
||||
elseif (genericData.loyaltyStatus and genericData.loyaltyStatus != "NONE") then
|
||||
if (genericData.loyaltyStatus == "CCA MEMBER") then
|
||||
alertText, color = "CCA Member "..alertText, red
|
||||
else
|
||||
alertText, color = string.utf8sub(genericData.loyaltyStatus, 1, 7).." Conformist "..alertText, orange
|
||||
end
|
||||
elseif (genericData.socialCredits > 90) then
|
||||
if (genericData.socialCredits >= 175) then
|
||||
alertText = "Tier 3 Conformist "..alertText
|
||||
elseif (genericData.socialCredits >= 125) then
|
||||
alertText = "Tier 2 Conformist "..alertText
|
||||
else
|
||||
alertText = "Tier 1 Conformist "..alertText
|
||||
end
|
||||
end
|
||||
|
||||
if (idCard:GetData("active", false) == false) then
|
||||
alertText, color = alertText.." with inactive Identification Card", color != red and orange or red
|
||||
end
|
||||
|
||||
alertText = "WRN:// " .. alertText
|
||||
|
||||
if (client:IsCombine()) then
|
||||
createCombineAlert(client, string.format(alertText, genericData.name, math.Clamp(tonumber(genericData.socialCredits), 0, 200)), color)
|
||||
else
|
||||
createCombineAlert(client, string.format(alertText, genericData.name, genericData.cid, math.Clamp(tonumber(genericData.socialCredits), 0, 200)), color)
|
||||
end
|
||||
|
||||
local otherListeners = {}
|
||||
if (requestType == REQUEST_MED or requestType == REQUEST_WORK) then
|
||||
for _, ply in pairs(player.GetAll()) do
|
||||
if (ply == client) then continue end
|
||||
|
||||
local character = ply:GetCharacter()
|
||||
if !character then continue end
|
||||
|
||||
local inventory = character:GetInventory()
|
||||
if !inventory then continue end
|
||||
|
||||
local radio = nil
|
||||
if (requestType == REQUEST_MED) then
|
||||
radio = inventory:HasItem("cmru_radio")
|
||||
elseif (requestType == REQUEST_WORK) then
|
||||
radio = inventory:HasItem("cwu_radio")
|
||||
end
|
||||
|
||||
if (radio and radio:GetData("enabled")) then
|
||||
otherListeners[ply] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
client:EmitSound("buttons/button3.wav")
|
||||
ix.chat.Send(client, "me", ix.config.Get("requestDeviceAction", "used request device."), false)
|
||||
ix.chat.Send(client, "request", text, false, nil, {name = genericData.name, cid = genericData.cid, requestType = requestType, otherListeners = otherListeners})
|
||||
end
|
||||
|
||||
function PLUGIN.RequestError(idCard, client, text)
|
||||
client:NotifyLocalized("rdError")
|
||||
end
|
||||
|
||||
netstream.Hook("ixRequest", function(client, itemID, text, requestType)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
local inventory = character:GetInventory()
|
||||
if (!inventory) then return end
|
||||
|
||||
local items = inventory:GetItems()
|
||||
|
||||
local itemTable = items[itemID]
|
||||
local idCard = items[itemTable:GetData("cardID")]
|
||||
if (!itemTable or !idCard or itemTable.uniqueID != "request_device" or idCard.uniqueID != "id_card") then
|
||||
client:NotifyLocalized("rdError")
|
||||
return
|
||||
end
|
||||
|
||||
if (client.ixNextRequest and client.ixNextRequest > CurTime()) then
|
||||
client:NotifyLocalized("rdFreqLimit")
|
||||
|
||||
return
|
||||
else
|
||||
client.ixNextRequest = CurTime() + 10
|
||||
end
|
||||
|
||||
idCard:LoadOwnerGenericData(PLUGIN.RequestSuccess, PLUGIN.RequestError, client, text, requestType)
|
||||
end)
|
||||
|
||||
netstream.Hook("ixBindRequestDevice", function(client, itemID, cardID)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
local inventory = character:GetInventory()
|
||||
if (!inventory) then return end
|
||||
|
||||
local items = inventory:GetItems()
|
||||
local itemTable = items[itemID]
|
||||
if (!itemTable or itemTable.uniqueID != "request_device" or itemTable:GetData("active") == false or itemTable:GetData("cardID") or !items[cardID] or items[cardID].uniqueID != "id_card") then
|
||||
client:NotifyLocalized("posBoundInactiveCard")
|
||||
return
|
||||
end
|
||||
|
||||
itemTable:SetData("cardID", cardID)
|
||||
|
||||
client:EmitSound("buttons/combine_button1.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("rdBound")
|
||||
end)
|
||||
|
||||
netstream.Hook("ixBindCWUCard", function(client, itemID, cardID)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
local inventory = character:GetInventory()
|
||||
if (!inventory) then return end
|
||||
|
||||
local items = inventory:GetItems()
|
||||
local itemTable = items[itemID]
|
||||
if (!itemTable or itemTable.uniqueID != "cwu_card" or itemTable:GetData("cardID") or !items[cardID] or items[cardID].uniqueID != "id_card") then
|
||||
client:NotifyLocalized("posBoundInactiveCard")
|
||||
return
|
||||
end
|
||||
|
||||
itemTable:SetData("cardID", cardID)
|
||||
|
||||
client:EmitSound("buttons/combine_button1.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("cwuBound")
|
||||
end)
|
||||
|
||||
netstream.Hook("ixBindCONCard", function(client, itemID, cardID)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
local inventory = character:GetInventory()
|
||||
if (!inventory) then return end
|
||||
|
||||
local items = inventory:GetItems()
|
||||
local itemTable = items[itemID]
|
||||
if (!itemTable or itemTable.uniqueID != "con_card" or itemTable:GetData("cardID") or !items[cardID] or items[cardID].uniqueID != "id_card") then
|
||||
client:NotifyLocalized("posBoundInactiveCard")
|
||||
return
|
||||
end
|
||||
|
||||
itemTable:SetData("cardID", cardID)
|
||||
|
||||
client:EmitSound("buttons/combine_button1.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("conBound")
|
||||
end)
|
||||
|
||||
netstream.Hook("ixBindDOBCard", function(client, itemID, cardID)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
local inventory = character:GetInventory()
|
||||
if (!inventory) then return end
|
||||
|
||||
local items = inventory:GetItems()
|
||||
local itemTable = items[itemID]
|
||||
if (!itemTable or itemTable.uniqueID != "dob_card" or itemTable:GetData("cardID") or !items[cardID] or items[cardID].uniqueID != "id_card") then
|
||||
client:NotifyLocalized("posBoundInactiveCard")
|
||||
return
|
||||
end
|
||||
|
||||
itemTable:SetData("cardID", cardID)
|
||||
|
||||
client:EmitSound("buttons/combine_button1.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("dobBound")
|
||||
end)
|
||||
|
||||
netstream.Hook("ixBindCMRUCard", function(client, itemID, cardID)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
local inventory = character:GetInventory()
|
||||
if (!inventory) then return end
|
||||
|
||||
local items = inventory:GetItems()
|
||||
local itemTable = items[itemID]
|
||||
if (!itemTable or itemTable.uniqueID != "cmru_card" or itemTable:GetData("cardID") or !items[cardID] or items[cardID].uniqueID != "id_card") then
|
||||
client:NotifyLocalized("posBoundInactiveCard")
|
||||
return
|
||||
end
|
||||
|
||||
itemTable:SetData("cardID", cardID)
|
||||
|
||||
client:EmitSound("buttons/combine_button1.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("cmruBound")
|
||||
end)
|
||||
|
||||
netstream.Hook("ixBindConCard", function(client, itemID, cardID)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
local inventory = character:GetInventory()
|
||||
if (!inventory) then return end
|
||||
|
||||
local items = inventory:GetItems()
|
||||
local itemTable = items[itemID]
|
||||
if (!itemTable or itemTable.uniqueID != "con_card" or itemTable:GetData("cardID") or !items[cardID] or items[cardID].uniqueID != "id_card") then
|
||||
client:NotifyLocalized("posBoundInactiveCard")
|
||||
return
|
||||
end
|
||||
|
||||
itemTable:SetData("cardID", cardID)
|
||||
|
||||
client:EmitSound("buttons/combine_button1.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("conBound")
|
||||
end)
|
||||
|
||||
netstream.Hook("ixBindMOECard", function(client, itemID, cardID)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
local inventory = character:GetInventory()
|
||||
if (!inventory) then return end
|
||||
|
||||
local items = inventory:GetItems()
|
||||
local itemTable = items[itemID]
|
||||
if (!itemTable or itemTable.uniqueID != "moe_card" or itemTable:GetData("cardID") or !items[cardID] or items[cardID].uniqueID != "id_card") then
|
||||
client:NotifyLocalized("posBoundInactiveCard")
|
||||
return
|
||||
end
|
||||
|
||||
itemTable:SetData("cardID", cardID)
|
||||
|
||||
client:EmitSound("buttons/combine_button1.wav", 60, 100, 0.5)
|
||||
client:NotifyLocalized("moeBound")
|
||||
end)
|
||||
|
||||
netstream.Hook("ixSelectCIDSuccess", function(client, cardID)
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
local inventory = character:GetInventory()
|
||||
if (!inventory) then return end
|
||||
|
||||
local items = inventory:GetItems()
|
||||
local cardItem = items[cardID]
|
||||
|
||||
if (cardItem and cardItem.uniqueID == "id_card") then
|
||||
client.ixSelectCIDSuccess(cardItem)
|
||||
end
|
||||
end)
|
||||
|
||||
netstream.Hook("ixSelectCIDFail", function(client)
|
||||
client.ixSelectCIDFail()
|
||||
end)
|
||||
390
gamemodes/ixhl2rp/plugins/cid/sv_plugin.lua
Normal file
390
gamemodes/ixhl2rp/plugins/cid/sv_plugin.lua
Normal file
@@ -0,0 +1,390 @@
|
||||
--[[
|
||||
| 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 ix = ix
|
||||
local string = string
|
||||
local os = os
|
||||
local CurTime = CurTime
|
||||
local IsValid = IsValid
|
||||
local netstream = netstream
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
util.AddNetworkString("changeLockAccess")
|
||||
util.AddNetworkString("changeLockAccessCmru")
|
||||
util.AddNetworkString("changeLockAccessCon")
|
||||
|
||||
ix.log.AddType("creditIDCardSetCredits", function(client, itemId, amount)
|
||||
return string.format("%s has set card #%d's credits to %d.", client:SteamName(), itemId, amount)
|
||||
end)
|
||||
|
||||
-- CID GENERATION
|
||||
local prime = 99787 -- prime % 4 = 3! DO NOT CHANGE EVER
|
||||
local offset = 320 -- slightly larger than sqrt(prime) is ok. DO NOT CHANGE EVER
|
||||
local block = 1000
|
||||
function PLUGIN:GenerateCid(id)
|
||||
id = (id + offset) % prime
|
||||
|
||||
local cid = 0
|
||||
|
||||
for _ = 1, math.floor(id/block) do
|
||||
cid = (cid + (id * block) % prime) % prime
|
||||
end
|
||||
|
||||
cid = (cid + (id * (id % block) % prime)) % prime
|
||||
|
||||
if (2 * id < prime) then
|
||||
return Schema:ZeroNumber(cid, 5)
|
||||
else
|
||||
return Schema:ZeroNumber(prime - cid, 5)
|
||||
end
|
||||
end
|
||||
|
||||
ix.log.AddType("creditTransaction", function(client, senderCard, receiverCard, amount, posDevice, reason, senderCID, receiverCID)
|
||||
local senderCardCid
|
||||
local receiverCardCid
|
||||
|
||||
if !senderCID then
|
||||
senderCardCid = senderCard:GetData("cid", "INVALID")
|
||||
else
|
||||
senderCardCid = (tostring(senderCard:GetData("cid", "00000")) == "00000" and senderCID or senderCard:GetData("cid", "INVALID"))
|
||||
end
|
||||
|
||||
if !receiverCID then
|
||||
receiverCardCid = receiverCard:GetData("cid", "INVALID")
|
||||
else
|
||||
receiverCardCid = (tostring(receiverCard:GetData("cid", "00000") ) == "00000" and receiverCID or receiverCard:GetData("cid", "INVALID"))
|
||||
end
|
||||
|
||||
local senderName = senderCard:GetData("name", "UNKNOWN")
|
||||
|
||||
if (IsValid(client) and client:HasActiveCombineMask()) then
|
||||
senderName = "IDENTITY REDACTED"
|
||||
senderCardCid = "REDACTED"
|
||||
end
|
||||
|
||||
local insert = mysql:Insert("ix_cid_transactions")
|
||||
insert:Insert("datetime", os.time())
|
||||
insert:Insert("sender_name", senderName)
|
||||
insert:Insert("sender_cid", senderCardCid)
|
||||
insert:Insert("sender_cardid", senderCard:GetID())
|
||||
insert:Insert("receiver_name", receiverCard:GetData("name", "UNKNOWN"))
|
||||
insert:Insert("receiver_cid", receiverCardCid)
|
||||
insert:Insert("receiver_cardid", receiverCard:GetID())
|
||||
insert:Insert("amount", amount)
|
||||
if (reason and reason != "") then
|
||||
insert:Insert("reason", string.len(reason) > 250 and string.sub(reason, 1, 250) or reason)
|
||||
else
|
||||
insert:Insert("reason", "no reason given")
|
||||
end
|
||||
|
||||
if (posDevice) then
|
||||
insert:Insert("pos", posDevice:GetID())
|
||||
insert:Insert("read", 0)
|
||||
insert:Callback(function(result, _, insertID)
|
||||
posDevice:AddTransactionID(insertID)
|
||||
end)
|
||||
else
|
||||
insert:Insert("pos", 0)
|
||||
insert:Insert("read", 1)
|
||||
end
|
||||
insert:Execute()
|
||||
|
||||
return string.format("%s (CID: %s, item: %s) has send %d credits to %s (CID: %s, item: %s) via %s.",
|
||||
senderCard:GetData("name"),
|
||||
senderCardCid,
|
||||
senderCard:GetID(),
|
||||
amount,
|
||||
receiverCard:GetData("name"),
|
||||
receiverCardCid,
|
||||
receiverCard:GetID(),
|
||||
posDevice and string.format("POS device for '%s'", reason) or "terminal"
|
||||
)
|
||||
end)
|
||||
|
||||
function PLUGIN:DatabaseConnected()
|
||||
local query = mysql:Create("ix_cid_transactions")
|
||||
query:Create("id", "INT UNSIGNED NOT NULL AUTO_INCREMENT")
|
||||
query:Create("datetime", "INT NOT NULL")
|
||||
query:Create("sender_name", "VARCHAR(255) NOT NULL")
|
||||
query:Create("sender_cid", "VARCHAR(255) NOT NULL")
|
||||
query:Create("sender_cardid", "INT NOT NULL")
|
||||
query:Create("receiver_name", "VARCHAR(255) NOT NULL")
|
||||
query:Create("receiver_cid", "VARCHAR(255) NOT NULL")
|
||||
query:Create("receiver_cardid", "INT NOT NULL")
|
||||
query:Create("amount", "INT NOT NULL")
|
||||
query:Create("pos", "INT NOT NULL")
|
||||
query:Create("read", "TINYINT(1) NOT NULL")
|
||||
query:Create("reason", "VARCHAR(255) DEFAULT NULL")
|
||||
query:PrimaryKey("id")
|
||||
query:Execute()
|
||||
end
|
||||
|
||||
function PLUGIN:SelectTransactions(client, key, value, maxAge, bNoIncludeRead, customCallback)
|
||||
if (client.ixNextTransactionSelect and client.ixNextTransactionSelect > CurTime()) then
|
||||
client.ixNextTransactionSelect = CurTime() + 1
|
||||
return
|
||||
end
|
||||
client.ixNextTransactionSelect = CurTime() + 1
|
||||
|
||||
maxAge = maxAge or 7
|
||||
local query = mysql:Select("ix_cid_transactions")
|
||||
if (key == "cid") then
|
||||
query.whereList[#query.whereList + 1] = "(`sender_cid` = '"..query:Escape(value).."' OR `receiver_cid` = '"..query:Escape(value).."')"
|
||||
else
|
||||
query:Where(key, value)
|
||||
end
|
||||
query:WhereGTE("datetime", os.time() - maxAge * 24 * 3600)
|
||||
if (bNoIncludeRead) then
|
||||
query:Where("read", 0)
|
||||
end
|
||||
query:Select("id")
|
||||
query:Select("datetime")
|
||||
query:Select("sender_name")
|
||||
query:Select("sender_cid")
|
||||
query:Select("receiver_name")
|
||||
query:Select("receiver_cid")
|
||||
query:Select("amount")
|
||||
query:Select("reason")
|
||||
if (key == "pos") then
|
||||
query:Select("pos")
|
||||
query:Select("read")
|
||||
end
|
||||
query:Callback(function(result)
|
||||
if (!IsValid(client)) then return end
|
||||
if customCallback then
|
||||
customCallback(result)
|
||||
return
|
||||
end
|
||||
|
||||
netstream.Start(client, "ixCreditTransactionLog", result, key == "pos" and !bNoIncludeRead)
|
||||
end)
|
||||
query:OrderByDesc("datetime")
|
||||
query:Execute()
|
||||
end
|
||||
|
||||
function PLUGIN:MarkTransactionsRead(id, bAllFromPos, bRead, pos)
|
||||
local query = mysql:Update("ix_cid_transactions")
|
||||
if (bAllFromPos) then
|
||||
query:Where("pos", id)
|
||||
else
|
||||
query:Where("pos", pos)
|
||||
query:Where("id", id)
|
||||
end
|
||||
query:Update("read", bRead and 1 or 0)
|
||||
query:Execute()
|
||||
end
|
||||
|
||||
netstream.Hook("ixTransactionSetRead", function(client, id, bAllFromPos, bRead, pos)
|
||||
local inventory = client:GetCharacter():GetInventory()
|
||||
local item = inventory:GetItemByID(pos or id)
|
||||
if (!item or (item:GetData("cardIDLock") and !inventory:GetItemByID(item:GetData("cardID")))) then
|
||||
return
|
||||
end
|
||||
|
||||
PLUGIN:MarkTransactionsRead(id, bAllFromPos, bRead, pos)
|
||||
end)
|
||||
|
||||
function PLUGIN:CreateIDCard(character, inventory, credits)
|
||||
local genericdata = character:GetGenericdata()
|
||||
local age, height, eyeColor = character:GetAge(), character:GetHeight(), character:GetEyeColor()
|
||||
local data = {
|
||||
owner = character:GetID(),
|
||||
cid = character:GetCid(),
|
||||
name = character:GetName(),
|
||||
geneticDesc = age.." | "..height.." | "..eyeColor.." EYES",
|
||||
active = true,
|
||||
credits = credits or 0
|
||||
}
|
||||
|
||||
if (character:GetFaction() == FACTION_VORT) then
|
||||
data.geneticDesc = age.." | "..height
|
||||
|
||||
if (istable(genericdata)) then
|
||||
genericdata.cid = data["cid"]
|
||||
character:SetGenericdata(genericdata)
|
||||
character:Save()
|
||||
end
|
||||
end
|
||||
|
||||
local success, error = inventory:Add("id_card", 1, data)
|
||||
|
||||
if (!success) then
|
||||
character:GetPlayer():NotifyLocalized(error or "unknownError")
|
||||
end
|
||||
end
|
||||
|
||||
-- Generic transaction stuff
|
||||
local function DoCreditTransaction(recipientCard, sendingCard, transactionAmount, sending, recipient, bPosDevice, reason, senderCid, receiverCid)
|
||||
if (!recipientCard or !sendingCard) then
|
||||
if (IsValid(sending)) then sending:NotifyLocalized("posError") end
|
||||
if (IsValid(recipient)) then recipient:NotifyLocalized("posError") end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local amount = transactionAmount
|
||||
local senderCard = sendingCard
|
||||
local receiverCard = recipientCard
|
||||
local receiver = recipient
|
||||
local sender = sending
|
||||
local amountPercent = amount / 100
|
||||
local vat = ix.config.Get("transactionVatPercent", 2)
|
||||
vat = math.Round(amountPercent * vat)
|
||||
|
||||
if (amount < 0) then
|
||||
amount = amount * -1
|
||||
|
||||
senderCard = recipientCard
|
||||
receiverCard = sendingCard
|
||||
sender = recipient
|
||||
receiver = sending
|
||||
end
|
||||
|
||||
if (senderCard:HasCredits(amount + vat)) then
|
||||
senderCard:TakeCredits(amount + vat)
|
||||
ix.city.main:AddCredits(vat)
|
||||
receiverCard:GiveCredits(amount)
|
||||
|
||||
if (IsValid(sender)) then
|
||||
sender:NotifyLocalized("posTransactionSuccess")
|
||||
|
||||
netstream.Start(sender, "TerminalUpdateCredits", amount)
|
||||
end
|
||||
|
||||
if (IsValid(receiver)) then receiver:NotifyLocalized("posTransactionSuccess") end
|
||||
ix.log.Add(sending, "creditTransaction", sendingCard, recipientCard, transactionAmount, bPosDevice, reason, senderCid, receiverCid)
|
||||
else
|
||||
if (IsValid(sender)) then sender:NotifyLocalized("transactionNoMoney") end
|
||||
if (IsValid(receiver)) then receiver:NotifyLocalized("transactionNoMoney") end
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:CreditTransaction(receiverCardID, senderCardID, amount, sender, receiver, bPosDevice, reason, senderCid, receiverCid)
|
||||
senderCid = senderCid or false
|
||||
receiverCid = receiverCid or false
|
||||
|
||||
if (ix.config.Get("creditsNoConnection")) then
|
||||
if (IsValid(sender)) then sender:NotifyLocalized("errorNoConnection") end
|
||||
if (IsValid(receiver)) then receiver:NotifyLocalized("errorNoConnection") end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if (!receiverCardID or !senderCardID) then
|
||||
if (IsValid(sender)) then sender:NotifyLocalized("posError") end
|
||||
if (IsValid(receiver)) then receiver:NotifyLocalized("posError") end
|
||||
return
|
||||
end
|
||||
|
||||
if (!ix.item.instances[receiverCardID]) then
|
||||
ix.item.LoadItemByID(receiverCardID, nil, function(receiverCard)
|
||||
if (ix.item.instances[senderCardID]) then
|
||||
DoCreditTransaction(receiverCard, ix.item.instances[senderCardID], amount, sender, receiver, bPosDevice, reason, senderCid, receiverCid)
|
||||
else
|
||||
ix.item.LoadItemByID(senderCardID, function(senderCard)
|
||||
DoCreditTransaction(receiverCard, senderCard, amount, sender, receiver, bPosDevice, reason, senderCid, receiverCid)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if (!ix.item.instances[senderCardID]) then
|
||||
ix.item.LoadItemByID(senderCardID, function(senderCard)
|
||||
DoCreditTransaction(ix.item.instances[receiverCardID], ix.item.instances[senderCardID], amount, sender, receiver, bPosDevice, reason, senderCid, receiverCid)
|
||||
end)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
DoCreditTransaction(ix.item.instances[receiverCardID], ix.item.instances[senderCardID], amount, sender, receiver, bPosDevice, reason, senderCid, receiverCid)
|
||||
end
|
||||
|
||||
-- CHAR funcs
|
||||
do
|
||||
local CHAR = ix.meta.character
|
||||
|
||||
function CHAR:CreateIDCard(credits)
|
||||
PLUGIN:CreateIDCard(self, self:GetInventory(), credits)
|
||||
end
|
||||
|
||||
function CHAR:GetCredits()
|
||||
local itemID = self:GetIdCard()
|
||||
if (!itemID or !ix.item.instances[itemID]) then
|
||||
return 0
|
||||
end
|
||||
|
||||
return ix.item.instances[itemID]:GetCredits()
|
||||
end
|
||||
|
||||
function CHAR:HasCredits(amount)
|
||||
local itemID = self:GetIdCard()
|
||||
if (!itemID or !ix.item.instances[itemID]) then
|
||||
return false
|
||||
end
|
||||
|
||||
return amount <= ix.item.instances[itemID]:GetCredits()
|
||||
end
|
||||
|
||||
function CHAR:SetCredits(amount)
|
||||
local itemID = self:GetIdCard()
|
||||
if (!itemID or !ix.item.instances[itemID]) then
|
||||
return false
|
||||
end
|
||||
|
||||
ix.item.instances[itemID]:SetCredits(amount)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function CHAR:GiveCredits(amount, sender, reason)
|
||||
local itemID = self:GetIdCard()
|
||||
if (!itemID or !ix.item.instances[itemID]) then
|
||||
return false
|
||||
end
|
||||
|
||||
return ix.item.instances[itemID]:GiveCredits(amount, sender, reason)
|
||||
end
|
||||
|
||||
function CHAR:TakeCredits(amount, receiver, reason)
|
||||
local itemID = self:GetIdCard()
|
||||
if (!itemID or !ix.item.instances[itemID]) then
|
||||
return false
|
||||
end
|
||||
|
||||
return ix.item.instances[itemID]:TakeCredits(amount, receiver, reason)
|
||||
end
|
||||
end
|
||||
|
||||
local playerMeta = FindMetaTable("Player")
|
||||
|
||||
function playerMeta:SelectCIDCard(onSuccess, onFail)
|
||||
local items = self:GetCharacter():GetInventory():GetItemsByUniqueID("id_card")
|
||||
local count = table.Count(items)
|
||||
|
||||
if (count == 1) then
|
||||
onSuccess(items[1])
|
||||
elseif (count == 0) then
|
||||
if (onFail) then
|
||||
onFail()
|
||||
end
|
||||
else
|
||||
self.ixSelectCIDSuccess = onSuccess
|
||||
|
||||
if (onFail) then
|
||||
self.ixSelectCIDFail = onFail
|
||||
end
|
||||
|
||||
netstream.Start(self, "ixSelectCID", isfunction(onFail))
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user