This commit is contained in:
lifestorm
2024-08-04 23:12:27 +03:00
parent 8064ba84d8
commit 9c918c46e5
7081 changed files with 2173485 additions and 14 deletions

View 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("Prośba o zapłatę", clientName.." prosi o "..amount.." kredytów od Ciebie z tytułu '"..reason.."'. VAT transakcji: " .. vat .. " kredytów. Której karty chcesz użyć do płatności?",
cards, "Wybierz Kartę ID",
"Potwierdź Operację", function(value, name)
netstream.Start("ixConfirmCreditOperation", value:GetID())
timer.Remove("ixPosTransactionQuery")
end, "Odrzuć prośbę", function()
netstream.Start("ixDenyCreditOperation")
timer.Remove("ixPosTransactionQuery")
end)
elseif (cardsCount == 1) then
PLUGIN.posTransactionPanel = Derma_Query(clientName.." prosi o "..amount.." kredytów od Ciebie z tytułu '"..reason.."'. VAT transakcji: " .. vat .. " kredytów). Czy potwierdzasz tę transakcję?", "Prośba o zapłatę",
"Potwierdź Operację", function()
netstream.Start("ixConfirmCreditOperation", cards[1].value:GetID())
timer.Remove("ixPosTransactionQuery")
end, "Odrzuć Żądanie", function()
netstream.Start("ixDenyCreditOperation")
timer.Remove("ixPosTransactionQuery")
end)
else
LocalPlayer():NotifyLocalized("Otrzymałeś prośbę o zapłatę, lecz nie masz karty ID, aby wykonać transakcję.")
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({["Ustaw dostęp na: członka"] = true, ["Ustaw dostęp na: zarząd"] = true}, entity)
end)
net.Receive("changeLockAccessCmru", function()
local entity = net.ReadEntity()
local accessLevels = {}
for i=1, 5 do
accessLevels["Ustaw Poziom "..tostring(i).." Dostępu"] = true
end
ix.menu.Open(accessLevels, entity)
end)
net.Receive("changeLockAccessCon", function()
local entity = net.ReadEntity()
local accessLevels = {}
for i=1, 5 do
accessLevels["Ustaw Poziom "..tostring(i).." Dostępu"] = 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

View 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")

View 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("DZIENNIK TRANSAKCJI")
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 "PRZECZYTANE" or "NIEPRZECZYTANE")
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 "PRZECZYTANE" or "NIEPRZECZYTANE")
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, "KWOTA: "..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, "POWÓD: ", 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")

View 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 = "Karta Dostępu CMU"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Karta dostępu Civil Medical Union."
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 "Karta dostępu " .. accessLevel .. " CMU"
end
function ITEM:GetDescription()
local idCard = ix.item.instances[self:GetData("cardID")]
return idCard and string.format(self.description.."\n\nAktualnie przypisany do CID #%s.", idCard:GetData("cardNumber")) or
(self:GetData("cardID") and self.description.."\n\nAktualnie przypisany." or self.description)
end
ITEM.functions.Bind = {
name = "Przypisz CID",
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("Przypisz CID do karty CMU", "Prosze wybrać CID aby go przypisać:",
cards, "Wybierz CID",
"Potwierdź", function(value, name)
netstream.Start("ixBindCMRUCard", itemTable:GetID(), value:GetID())
end, "Anuluj")
elseif (cardsCount == 1) then
Derma_Query("Czy jesteś pewny, że chcesz przypisać ten CID do tej karty dostępu?", "Przypisz CID do karty CMU",
"Potwierdź", function()
netstream.Start("ixBindCMRUCard", itemTable:GetID(), cards[1].value:GetID())
end, "Anuluj")
else
LocalPlayer():NotifyLocalized("Nie posiadasz CID, który można przypisać do tej karty dostępu.")
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 = "Przełącz poziom karty",
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("Ustawiłeś poziom karty na: " .. 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
}

View 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\nAktualnie przypisany do CID #%s.", idCard:GetData("cardNumber")) or
(self:GetData("cardID") and self.description.."\n\nAktualnie przypisany." 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 = "Przełącz poziom karty",
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("Ustawiłeś dostęp karty dla:" .. 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
}

View 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 = "Karta Dostępu CWU"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Karta dostępu Civil Workers Union."
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", "Członek")
return "Karta Dostępu " .. accessLevel .. " CWU"
end
function ITEM:GetFactionInfo()
return self:GetData("faction", false) and ix.factionBudget.list[self:GetData("faction")] and "Przypisano do: " .. ix.factionBudget.list[self:GetData("faction")].name or "Ta karta nie jest przypisana do żadnej z frakcji."
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\nAktualnie przypisany do CID #%s.", idCard:GetData("cardNumber")) or
(self:GetData("cardID") and self.description.."\n\nAktualnie przypisany." or self.description)
end
ITEM.functions.Bind = {
name = "Przypisz CID",
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("Przypisz CID do karty CWU", "Prosze wybrać CID aby go przypisać:",
cards, "Wybierz CID",
"Potwierdź", function(value, name)
netstream.Start("ixBindCWUCard", itemTable:GetID(), value:GetID())
end, "Anuluj")
elseif (cardsCount == 1) then
Derma_Query("Czy jesteś pewny, że chcesz przypisać ten CID do tej karty dostępu?", "Przypisz CID do karty CWU",
"Potwierdź", function()
netstream.Start("ixBindCWUCard", itemTable:GetID(), cards[1].value:GetID())
end, "Anuluj")
else
LocalPlayer():NotifyLocalized("Nie posiadasz CID, który można przypisać do tej karty dostępu.")
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 = "Przełącz poziom karty",
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("Ustawiłeś dostęp karty dla: " .. 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 = "Ustaw kartę frakcji",
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 = "Włóż kartę",
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
}

View 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 = "Karta Dostępu MG"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Karta dostępu Ministerstwa Gospodarki."
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", "Członek")
return "Karta dostępu " .. accessLevel .. " DOB"
end
function ITEM:GetDescription()
local idCard = ix.item.instances[self:GetData("cardID")]
return idCard and string.format(self.description.."\n\nAktualnie przypisany do CID #%s.", idCard:GetData("cardNumber")) or
(self:GetData("cardID") and self.description.."\n\nAktualnie przypisany." or self.description)
end
ITEM.functions.Bind = {
name = "Przypisz CID",
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("Przypisz CID do karty MG", "Prosze wybrać CID aby go przypisać:",
cards, "Wybierz CID",
"Potwierdź", function(value, name)
netstream.Start("ixBindDOBCard", itemTable:GetID(), value:GetID())
end, "Anuluj")
elseif (cardsCount == 1) then
Derma_Query("Czy jesteś pewny, że chcesz przypisać ten CID do tej karty dostępu?", "Przypisz CID do karty MG",
"Potwierdź", function()
netstream.Start("ixBindDOBCard", itemTable:GetID(), cards[1].value:GetID())
end, "Anuluj")
else
LocalPlayer():NotifyLocalized("Nie posiadasz CID, który można przypisać do tej karty dostępu.")
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 = "Przełącz poziom karty",
icon = "icon16/vcard_add.png",
OnRun = function(itemTable)
local client = itemTable.player
local accessLevel = itemTable:GetData("accessLevel", "Członek")
local target = accessLevel == "Członek" and "Zarząd" or "Członek"
itemTable:SetData("accessLevel", target)
client:NotifyLocalized("Ustawiłeś poziom karty na: " .. 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
}

View 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 = "Karta identyfikacyjna #00000"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Obywatelska karta identyfikacyjna przypisana do %s, CID #%s.\n\nNumer karty: %s\nOpis genetyczny:\n%s.\n\nTa karta jest własnością Administracji Miasta Kombinatu. Nielegalne posiadanie i fałszowanie tożsamości są karalne oraz będą skutkować wszczęciem postępowania przez Civil Protection. W przypadku znalezienia czyjejś karty należy niezwłocznie zwrócić ją do najbliższego oddziału Civil Protection."
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 "Karta identyfikacyjna #" .. self:GetData("cid", "00000")
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 OCZY | N/A WŁOSY"))
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

View File

@@ -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 = "Urządzenie do tworzenia fałszywych kart identyfikacyjnych"
ITEM.model = Model("models/props_lab/reciever01a.mdl")
ITEM.description = "Urządzenie do tworzenia fałszywych kart identyfikacyjnych "
ITEM.category = "Tools"
ITEM.functions.CreateID = {
name = "Stwórz fałszywy CID",
icon = "icon16/vcard.png",
OnRun = function(itemTable)
local client = itemTable.player
client:RequestString("Imię", "Wprowadź imię osoby na którą będzie ta karta identyfikacyjna", function(name)
client:RequestString("CID", "Wprowadź CID jakiego używać będzie osoba na którą będzie ta karta identyfikacyjna", function(cid)
client:RequestString("Opis", "Wprowadź opis ogólny osoby która będzie używać tej karty identyfikacyjnej", function(desc)
local inventory = client:GetCharacter():GetInventory()
local card = inventory:HasItem("id_card_blank")
if (!card) then
client:Notify("Potrzebujesz pustej karty CID aby stworzyć fałszywy CID!")
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("Fałszywa karta identyfikacyjna stworzona.")
client:EmitSound("ambient/machines/combine_terminal_idle2.wav")
end, "MŁODY DOROSŁY/DOROSŁY/W ŚREDNIM WIEKU/STARSZY | 0\'00\" | [COLOR] OCZY | [COLOR] WŁOSY")
end, "00000")
end, "")
return false
end
}

View 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 = "Karta identyfikacyjna #00000"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Obywatelska karta identyfikacyjna przypisana do %s, CID #%s.\n\nNumer karty: %s\nOpis genetyczny:\n%s.\n\nTa karta jest własnością Administracji Miasta Kombinatu. Nielegalne posiadanie i fałszowanie tożsamości są karalne oraz będą skutkować wszczęciem postępowania przez Civil Protection. W przypadku znalezienia czyjejś karty należy niezwłocznie zwrócić ją do najbliższego oddziału Civil Protection."
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 "Karta identyfikacyjna #" .. self:GetData("cid", "00000")
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 OCZY | N/A WŁOSY"))
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", "NIEZNANY"))
insert:Insert("receiver_cid", self:GetData("cid", "NIEPRAWIDŁOWY"))
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", "NIEZNANY"))
insert:Insert("sender_cid", self:GetData("cid", "NIEPRAWIDŁOWY"))
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 = "Ustaw Kredyty",
icon = "icon16/money_add.png",
OnClick = function(itemTable)
local client = itemTable.player
Derma_StringRequest("Ustaw Kredyty", "Na jaką wartość chcesz ustawić kredyty?", 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 = "Włóż 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
}

View 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 = "Pusta karta CID"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Pusta karta identyfikacyjna cywila."
ITEM.category = "Combine"
ITEM.iconCam = {
pos = Vector(-509.64, -427.61, 310.24),
ang = Angle(25, 400, 0),
fov = 0.59
}

View 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 = "Urządzenie do tworzenia kart identyfikacyjnych"
ITEM.model = Model("models/props_lab/reciever01d.mdl")
ITEM.description = "Urządzenie do uzupełniania pustych kart identyfikacyjnych i przypisywania ich do danej osoby."
ITEM.category = "Combine"
ITEM.functions.CreateIDTarget = {
name = "Stwórz CID dla celu",
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 = "Stwórz CID dla siebie",
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:// CID #" .. character:GetCid() .. " stworzony przez " .. 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

View 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 = "Karta Dostępu MOP"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Karta dostępu Ministerstwa Oświecenia Publicznego."
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", "Członek")
return "Karta dostępu: " .. accessLevel .. " MOP"
end
function ITEM:GetDescription()
local idCard = ix.item.instances[self:GetData("cardID")]
return idCard and string.format(self.description.."\n\nAktualnie przypisany do CID #%s.", idCard:GetData("cardNumber")) or
(self:GetData("cardID") and self.description.."\n\nAktualnie przypisany." or self.description)
end
ITEM.functions.Bind = {
name = "Przypisz CID",
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("Przypisz CID do karty MOP", "Prosze wybrać CID aby go przypisać:",
cards, "Wybierz CID",
"Potwierdź", function(value, name)
netstream.Start("ixBindMOECard", itemTable:GetID(), value:GetID())
end, "Anuluj")
elseif (cardsCount == 1) then
Derma_Query("Czy jesteś pewny, że chcesz przypisać ten CID do tej karty dostępu?", "Przypisz CID do karty MOP",
"Potwierdź", function()
netstream.Start("ixBindMOECard", itemTable:GetID(), cards[1].value:GetID())
end, "Anuluj")
else
LocalPlayer():NotifyLocalized("Nie posiadasz CID, który można przypisać do tej karty dostępu.")
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 = "Przełącz poziom karty",
icon = "icon16/vcard_add.png",
OnRun = function(itemTable)
local client = itemTable.player
local accessLevel = itemTable:GetData("accessLevel", "Członek")
local target = accessLevel == "Członek" and "Zarząd" or "Członek"
itemTable:SetData("accessLevel", target)
client:NotifyLocalized("Ustawiłeś dostęp karty dla: " .. 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
}

View 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 = "Terminal płatniczy"
ITEM.model = Model("models/willardnetworks/props/posterminal.mdl")
ITEM.description = "Urządzenie dzięki któremu jedna osoba może przelać pieniądze na konto drugiej osoby."
ITEM.category = "Combine"
function ITEM:GetDescription()
local idCard = ix.item.instances[self:GetData("cardID")]
return idCard and string.format(self.description.."\n\nAktualnie przypisany do CID #%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 = "Zażądaj kredytów",
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("Prośba o zapłatę", "Ile chcesz aby ktoś ci zapłacił?", itemTable:GetData("lastAmount", 0), function(text)
local amount = tonumber(text)
if (amount) then
Derma_StringRequest("Prośba o zapłatę - KOMENTARZ", "Wpisz powód transakcji:", "", 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 = "Przypisz CID",
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("Przypisz CID do terminala", "Prosze wybrać CID aby go przypisać:",
cards, "Wybierz CID",
"Potwierdź", function(value, name)
netstream.Start("ixBindTerminal", itemTable:GetID(), value:GetID())
end, "Anuluj")
elseif (cardsCount == 1) then
Derma_Query("Czy jesteś pewny, że chcesz przypisać ten CID do tego terminala płatniczego?", "Przypisz CID do terminala",
"Potwierdź", function()
netstream.Start("ixBindTerminal", itemTable:GetID(), cards[1].value:GetID())
end, "Anuluj")
else
client:NotifyLocalized("Nie posiadasz CID, który można przypisać do tego terminala.")
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 = "Wyświetl transakcje",
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 dzień", data = {1}}}
for i = 2, 6 do
options[#options + 1] = {name = i.." dni", data = {i}}
end
options[#options + 1] = {name = "1 tydzień", data = {7}}
options[#options + 1] = {name = "2 tygodnie", data = {14}}
options[#options + 1] = {name = "1 miesiąc", data = {30}}
options[#options + 1] = {name = "inne", data = {-1}, OnClick = function(itemTable)
Derma_StringRequest("Spis transacji", "Z przed ilu dni chciałbyś wyświetlić transakcje?", "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 = "Zablokuj CID",
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 = "Odblokuj CID",
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
}

View 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 = "Pager"
ITEM.model = Model("models/gibs/shield_scanner_gib1.mdl")
ITEM.description = "Małe urządzenie zgłaszające. Z tyłu widoczne jest logo kombinatu. \n\nNa instrukcji czytamy: Proszę najpierw zarejestrować urządzenie przykładając swój CID do urządzenia. Po zakończeniu rejestracji otrzymasz możliwość wezwania pomocy od Civil Protection, aby to zrobić naciśnij przycisk i zgłoś swoje zgłoszenie. Twoje imię i CID zostanie załączony ze zgłoszeniem.\nProszę być świadomym, że każde fałszywe zgłoszenie jak i korzystanie z urządzenia przypisanego do innej osoby jest karane i skutkować będzie surowymi karami od 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\nAktualnie przypisane do CID #%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, "STWÓRZ ZGŁOSZENIE", "ANULUJ"
)
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 = "Stwórz zgłoszenie do CP",
requestTitle = "Poproś o pomoc Civil Protection",
requestMessage = "Wprowadź swoje zgłoszenie dla Civil Protection. Twoje imię i CID zostaną automatycznie dodane do zgłoszenia.",
requestType = REQUEST_CP
})
ITEM.functions.RequestMed = GetRequestTable({
actionName = "Stwórz zgłoszenie do CMU",
requestTitle = "Poproś o pomoc Civil Medical Union",
requestMessage = "Wprowadź swoje zgłoszenie dla Civil Medical Union. Twoje imię i CID zostaną automatycznie dodane do zgłoszenia. Nie zapomnij podać swojej lokalizacji!",
requestType = REQUEST_MED
})
ITEM.functions.RequestCwu = GetRequestTable({
actionName = "Stwórz zgłoszenie do CWU",
requestTitle = "Poproś o pomoc Civil Workers Union",
requestMessage = "Wprowadź swoje zgłoszenie dla Civil Workers Union. Twoje imię i CID zostaną automatycznie dodane do zgłoszenia. Nie zapomnij podać swojej lokalizacji!",
requestType = REQUEST_WORK
})
ITEM.functions.Bind = {
name = "Przypisz CID",
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("Przypisz CID do Pagera", "Prosze wybrać CID aby go przypisać:",
cards, "Wybierz CID",
"Potwierdź", function(value, name)
netstream.Start("ixBindRequestDevice", itemTable:GetID(), value:GetID())
end, "Anuluj")
elseif (cardsCount == 1) then
Derma_Query("Czy jesteś pewny, że chcesz przypisać ten CID do Pagera?", "Przypisz CID do Pagera",
"Potwierdź", function()
netstream.Start("ixBindRequestDevice", itemTable:GetID(), cards[1].value:GetID())
end, "Anuluj")
else
LocalPlayer():NotifyLocalized("Nie posiadasz CID, który można przypisać do tego pagera.")
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

View File

@@ -0,0 +1,280 @@
--[[
| 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 = "Pobiera kredyty z aktywnej karty CID podanej postaci.",
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("Civil Authority Board pobrało "..amount.." kredytów z twojej karty.")
else
client:Notify("Postać nie posiada takiej liczby kredytów.")
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")
hook.Run("OnPlayerPurchaseDoor", client, entity, true, ix.plugin.list.doors.CallOnDoorChildren)
ix.log.Add(client, "buydoor")
return "@dPurchased", price..(price == 1 and " kredyt" or " kredytów")
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 " kredyt" or " kredytów")
else
-- Otherwise tell them they can not.
return "@notOwner"
end
else
-- Tell the player the door isn't valid.
return "@dNotValid"
end
end
})
end

View File

@@ -0,0 +1,261 @@
--[[
| 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 = "Ustaw postaci kredyty.",
cmdCharGiveCredits = "Daj postaci kredyty.",
cmdRequest = "Wyślij prośbę o pomoc od Civil Protection. Użyje pagera przypisanego kartą ID z twojego ekwipunku.",
setCredits = "Ustawiono kredyty %s's na %s.",
giveCredits = "Dałeś %s %s kredytów.",
scanning = "Skanowanie...",
idNotFound = "BŁĄD: Nie znaleziono sygnatury biologicznej.",
idNoBlank = "BŁĄD: Nie włożono pustej karty.",
idCardAdded = "SUKCES: Utworzono kartę identyfikacyjną.",
idCardRecreated = "SUKCES: Karta identyfikacyjna została odtworzona.",
idNotAllowed = "Urządzenie nie odpowiada przy próbie użycia.",
posBound = "SUKCES: Terminal płatniczy został poprawnie przypisany do karty CID.",
posBoundInactiveCard = "BŁĄD: Przypisana karta CID nie jest już aktywna. Zalecane jest natychmiastowe wyrzucenie nieaktywnej karty.",
posRequestSent = "INFO: Wysłano transakcje...",
posRequestExecuting = "INFO: Dokonywanie transakcji... proszę czekać...",
posTransactionSuccess = "SUKCES: Transakcja zakończona.",
posError = "ERROR: Wystąpił nieoczekiwany błąd. Transakcja przerwana.",
posBoundCardNotActive = "BŁĄD: Przypisana karta CID nie jest już aktywna. Zalecane jest natychmiastowe wyrzucenie nieaktywnej karty.",
posCardNotActive = "BŁĄD: Użyta karta CID nie jest już aktywna. Zalecane jest natychmiastowe wyrzucenie nieaktywnej karty.",
posTransOngoing = "%s próbował wysłać ci trankacje, ale poprzednia nie została zakończona.",
posTransExpired = "Transakcja wygasła.",
posTransactionRefused = "Odrzucono transkacje.",
numNotValid = "Wprowadziłeś błędną ilość kredytów!",
reasonNotValid = "Podałeś nieprawidłowy powód transakcji!",
transactionNoMoney = "BŁĄD: Niewystarczające fundusze.",
transactionOwnChars = "BŁĄD: Nie możesz wysłać pieniędzy między swoimi własnymi postaciami!",
transactionSelf = "BŁĄD: Nie możesz wysłać pieniędzy do siebie!",
rdBound = "SUKCES: Pager został poprawnie przypisany do karty CID.",
rdError = "BŁĄD: Wystąpił nieoczekiwany błąd. Zlokalizuj oficera Civil Protection i zgłoś problem osobiście.",
rdMoreThanOne = "Posiadasz więcej niż jeden przypisany pager, proszę o wybranie tego z którego chcesz skorzystać.",
rdNoRD = "Nie posiadasz pagera lub nie jest on przypisany do karty CID!",
rdFreqLimit = "Proszę odczekać 10 sekund między zgłoszeniami.",
cwuBound = "SUKCES: Karta CWU została poprawnie przypisana do karty CID.",
dobBound = "SUKCES: Karta MG została poprawnie przypisana do karty CID.",
cmruBound = "SUKCES: Karta CMU została poprawnie przypisana do karty CID.",
conBound = "SUKCES: Karta CCR została poprawnie przypisana do karty CID.",
targetTransactionInProgress = "Ta osoba aktualnie dokonuje innej transkacji!",
idCardIssued = "Nowa karta identyfikacja została wydana dla %s przez %s",
errorNoConnection = "BŁĄD: BRAK POŁĄCZENIA"
})
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"
})
ix.lang.AddTable("polish", {
cmdCharSetCredits = "Ustaw postaci kredyty.",
cmdCharGiveCredits = "Daj postaci kredyty.",
cmdRequest = "Wyślij prośbę o pomoc od Civil Protection. Użyje pagera przypisanego kartą ID z twojego ekwipunku.",
setCredits = "Ustawiono kredyty %s's na %s.",
giveCredits = "Dałeś %s %s kredytów.",
scanning = "Skanowanie...",
idNotFound = "BŁĄD: Nie znaleziono sygnatury biologicznej.",
idNoBlank = "BŁĄD: Nie włożono pustej karty.",
idCardAdded = "SUKCES: Utworzono kartę identyfikacyjną.",
idCardRecreated = "SUKCES: Karta identyfikacyjna została odtworzona.",
idNotAllowed = "Urządzenie nie odpowiada przy próbie użycia.",
posBound = "SUKCES: Terminal płatniczy został poprawnie przypisany do karty CID.",
posBoundInactiveCard = "BŁĄD: Przypisana karta CID nie jest już aktywna. Zalecane jest natychmiastowe wyrzucenie nieaktywnej karty.",
posRequestSent = "INFO: Wysłano transakcje...",
posRequestExecuting = "INFO: Dokonywanie transakcji... proszę czekać...",
posTransactionSuccess = "SUKCES: Transakcja zakończona.",
posError = "ERROR: Wystąpił nieoczekiwany błąd. Transakcja przerwana.",
posBoundCardNotActive = "BŁĄD: Przypisana karta CID nie jest już aktywna. Zalecane jest natychmiastowe wyrzucenie nieaktywnej karty.",
posCardNotActive = "BŁĄD: Użyta karta CID nie jest już aktywna. Zalecane jest natychmiastowe wyrzucenie nieaktywnej karty.",
posTransOngoing = "%s próbował wysłać ci trankacje, ale poprzednia nie została zakończona.",
posTransExpired = "Transakcja wygasła.",
posTransactionRefused = "Odrzucono transkacje.",
numNotValid = "Wprowadziłeś błędną ilość kredytów!",
reasonNotValid = "Podałeś nieprawidłowy powód transakcji!",
transactionNoMoney = "BŁĄD: Niewystarczające fundusze.",
transactionOwnChars = "BŁĄD: Nie możesz wysłać pieniędzy między swoimi własnymi postaciami!",
transactionSelf = "BŁĄD: Nie możesz wysłać pieniędzy do siebie!",
rdBound = "SUKCES: Pager został poprawnie przypisany do karty CID.",
rdError = "BŁĄD: Wystąpił nieoczekiwany błąd. Zlokalizuj oficera Civil Protection i zgłoś problem osobiście.",
rdMoreThanOne = "Posiadasz więcej niż jeden przypisany pager, proszę o wybranie tego z którego chcesz skorzystać.",
rdNoRD = "Nie posiadasz pagera lub nie jest on przypisany do karty CID!",
rdFreqLimit = "Proszę odczekać 10 sekund między zgłoszeniami.",
cwuBound = "SUKCES: Karta CWU została poprawnie przypisana do karty CID.",
dobBound = "SUKCES: Karta MG została poprawnie przypisana do karty CID.",
cmruBound = "SUKCES: Karta CMU została poprawnie przypisana do karty CID.",
targetTransactionInProgress = "Ta osoba aktualnie dokonuje innej transkacji!",
idCardIssued = "Nowa karta identyfikacja została wydana dla %s przez %s",
errorNoConnection = "BŁĄD: BRAK POŁĄCZENIA"
})
do
local CLASS = {}
CLASS.color = Color(175, 125, 100)
CLASS.format = "%s, #%s wzywa %s\"%s\""
CLASS.formatCP = "%s wzywa %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

View 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

View 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:// Podmiot o ID #" .. senderCid .. " wysłał " .. amount .. " Kredytów do #" .. 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 (KS: %d) wnioskuje o pomoc", yellow
if (client:IsCombine()) then
alertText = "%s (KS: %d) wnioskuje o pomoc"
elseif (isAC) then
alertText, color = "Antyobywatel %s, #%s wnioskuje o pomoc", red
elseif (isBOL) then
alertText, color = "Poszukiwany BOL %s, #%s wnioskuje o pomoc", orange
elseif (genericData.loyaltyStatus and genericData.loyaltyStatus != "BRAK") then
if (genericData.loyaltyStatus == "Członek CAB") then
alertText, color = "Członek CAB"..alertText, red
else
alertText, color = string.utf8sub(genericData.loyaltyStatus, 1, 6).." Konformista "..alertText, orange
end
elseif (genericData.socialCredits > 90) then
if (genericData.socialCredits >= 175) then
alertText = "Konformista Poziomu 3"..alertText
elseif (genericData.socialCredits >= 125) then
alertText = "Konformista Poziomu 2"..alertText
else
alertText = "Konformista Poziomu 1"..alertText
end
end
if (idCard:GetData("active", false) == false) then
alertText, color = alertText.." z nieaktywnym identyfikatorem", 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)

View 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 ustawił(a) kredyty karty #%d's na %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", "NIEPRAWIDŁOWY")
else
senderCardCid = (tostring(senderCard:GetData("cid", "00000")) == "00000" and senderCID or senderCard:GetData("cid", "NIEPRAWIDŁOWY"))
end
if !receiverCID then
receiverCardCid = receiverCard:GetData("cid", "NIEPRAWIDŁOWY")
else
receiverCardCid = (tostring(receiverCard:GetData("cid", "00000") ) == "00000" and receiverCID or receiverCard:GetData("cid", "NIEPRAWIDŁOWY"))
end
local senderName = senderCard:GetData("name", "NIEZNANY")
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", "NIEZNANY"))
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", "nie podano powodu")
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, przedmiot: %s) wysłał(a) %d kredytów do %s (CID: %s, przedmiot: %s) przez %s.",
senderCard:GetData("name"),
senderCardCid,
senderCard:GetID(),
amount,
receiverCard:GetData("name"),
receiverCardCid,
receiverCard:GetID(),
posDevice and string.format("Urządzenie POS dla '%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.." OCZY",
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