This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 8064ba84d8
commit 73479cff9e
7338 changed files with 1718883 additions and 14 deletions

View File

@@ -0,0 +1,116 @@
--[[
| 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("Transaction", clientName.." vous demande "..amount.." crédits pour : '"..reason.."'. Transaction vat: " .. vat .. " crédit(s). Quelle carte choisissez-vous pour payer ?",
cards, "Sélectionner carte CID",
"Confirmer", function(value, name)
netstream.Start("ixConfirmCreditOperation", value:GetID())
timer.Remove("ixPosTransactionQuery")
end, "Refuser", function()
netstream.Start("ixDenyCreditOperation")
timer.Remove("ixPosTransactionQuery")
end)
elseif (cardsCount == 1) then
PLUGIN.posTransactionPanel = Derma_Query(clientName.." vous demande "..amount.." crédits pour : '"..reason.."'. Confirmez-vous cette transaction ?" .. vat .. " crédit(s). Confirmer vous cette transaction?", "Transaction",
"Confirmer", function()
netstream.Start("ixConfirmCreditOperation", cards[1].value:GetID())
timer.Remove("ixPosTransactionQuery")
end, "Refuser", function()
netstream.Start("ixDenyCreditOperation")
timer.Remove("ixPosTransactionQuery")
end)
else
LocalPlayer():NotifyLocalized("Vous avez reçu une requête de transaction, mais vous n'avez pas de carte CID.")
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({["Accès Membre"] = true, ["Accès Management"] = true}, entity)
end)
net.Receive("changeLockAccessCmru", function()
local entity = net.ReadEntity()
local accessLevels = {}
for i=1, 5 do
accessLevels["Set Level "..tostring(i).." Access"] = true
end
ix.menu.Open(accessLevels, entity)
end)
function PLUGIN:CreateExtraCharacterTabInfo(character, informationSubframe, CreatePart)
local citizenID = LocalPlayer():GetCharacter():GetCid() or "N/A"
local cidPanel = informationSubframe:Add("Panel")
CreatePart(cidPanel, "CID :", 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("Quel CID voulez-vous utiliser ?")
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("REGISTRE DES TRANSACTIONS")
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 "LIRE" or "NON-LU")
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 "LIRE" or "NON-LU")
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, "MONTANT : "..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, "RAISON : ", 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 = "Carte UCMR"
ITEM.model = Model("models/sky/cmuid.mdl")
ITEM.description = "Une carte pour l'UCMR."
ITEM.category = "Combine"
ITEM.skin = 3
ITEM.iconCam = {
pos = Vector(0, 0, 10),
ang = Angle(90, 90, 0),
fov = 45,
}
function ITEM:GetName()
local accessLevel = self:GetData("accessLevel", 1)
return "CMRU Level " .. accessLevel .. " Access Keycard"
end
function ITEM:GetDescription()
local idCard = ix.item.instances[self:GetData("cardID")]
return idCard and string.format(self.description.."\n\nCurrently bound to identity card #%s.", idCard:GetData("cardNumber")) or
(self:GetData("cardID") and self.description.."\n\nCurrently bound." or self.description)
end
ITEM.functions.Bind = {
name = "Bind ID Card",
icon = "icon16/vcard_edit.png",
OnClick = function(itemTable)
local cards = {}
for _, v in pairs(LocalPlayer():GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
table.insert(cards, {
text = v:GetName(),
value = v
})
end
local cardsCount = table.Count(cards)
if (cardsCount > 1) then
Derma_Select("Bind ID Card to CMRU Card", "Please select a ID card to bind to this CMRU Card:",
cards, "Select ID card",
"Confirm Operation", function(value, name)
netstream.Start("ixBindCMRUCard", itemTable:GetID(), value:GetID())
end, "Cancel")
elseif (cardsCount == 1) then
Derma_Query("Are you sure you wish to bind your ID to this CMRU Card?", "Bind ID Card to CMRU Card",
"Confirm Operation", function()
netstream.Start("ixBindCMRUCard", itemTable:GetID(), cards[1].value:GetID())
end, "Cancel")
else
LocalPlayer():NotifyLocalized("You do not have ID card to bind to this CMRU Card.")
end
end,
OnRun = function(itemTable)
return false
end,
OnCanRun = function(itemTable)
if (IsValid(itemTable.entity)) then
return false
end
if (!IsValid(itemTable.player)) then
return false
end
local inventory = itemTable.player:GetCharacter():GetInventory()
if (!inventory:HasItem("id_card")) then
return false
end
if (itemTable:GetData("cardID")) then
return false
end
return true
end
}
ITEM.functions.SetAccessLevel = {
name = "Toggle Card Access Level",
icon = "icon16/vcard_add.png",
OnRun = function(itemTable)
local client = itemTable.player
local accessLevel = itemTable:GetData("accessLevel", 1)
accessLevel = accessLevel != 5 and accessLevel + 1 or 1
itemTable:SetData("accessLevel", accessLevel)
client:NotifyLocalized("You have set this card's Access Level to Access Level " .. accessLevel .. ".")
return false
end,
OnCanRun = function(itemTable)
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
end
}

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 = "Carte de l'UTC"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Une carte CID de l'UTC."
ITEM.category = "Combine"
ITEM.skin = 3
ITEM.iconCam = {
pos = Vector(0, 0, 10),
ang = Angle(90, 90, 0),
fov = 45,
}
function ITEM:GetName()
local accessLevel = self:GetData("accessLevel", "- Niveau 0")
return "Carte de l'UTC " .. accessLevel .. ""
end
function ITEM:GetFactionInfo()
return self:GetData("faction", false) and ix.factionBudget.list[self:GetData("faction")] and "Lié à: " .. ix.factionBudget.list[self:GetData("faction")].name or "Cette carte n'est lié a aucune faction."
end
function ITEM:GetColorAppendix()
local info = {["green"] = self:GetFactionInfo()}
return info
end
function ITEM:GetDescription()
local idCard = ix.item.instances[self:GetData("cardID")]
return idCard and string.format(self.description.."\n\nActuellement lié au CID #%s.", idCard:GetData("cardNumber")) or
(self:GetData("cardID") and self.description.."\n\nActuellement lié." or self.description)
end
ITEM.functions.Bind = {
name = "Lier la carte 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("Lier le CID à la carte CID", "Veuillez sélectionner un CID à relier à cette carte :",
cards, "Sélectionner carte CID",
"Confirmer", function(value, name)
netstream.Start("ixBindCWUCard", itemTable:GetID(), value:GetID())
end, "Annuler")
elseif (cardsCount == 1) then
Derma_Query("Êtes-vous sûr de vouloir lier votre CID à cette carte ?", "Lier le CID à la carte CID",
"Confirmer", function()
netstream.Start("ixBindCWUCard", itemTable:GetID(), cards[1].value:GetID())
end, "Annuler")
else
LocalPlayer():NotifyLocalized("Vous n'avez pas de carte CID à lier.")
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 = "Modifier le niveau d'accès",
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 .. " Accès"}}
end
return accessLevels
end,
OnRun = function(itemTable, accessLevel)
local client = itemTable.player
itemTable:SetData("accessLevel", accessLevel.aLevel)
client:NotifyLocalized("Vous avez fixé le niveau d'accès de cette carte à : " .. accessLevel.aLevel .. ".")
return false
end,
OnCanRun = function(itemTable)
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
end
}
ITEM.functions.SetFaction = {
name = "Set Card Faction",
icon = "icon16/vcard_add.png",
isMulti = true,
multiOptions = function(item, player)
local factions = {}
for id, faction in pairs(ix.factionBudget.list) do
factions[#factions + 1] = {name = faction.name, data = faction}
end
return factions
end,
OnRun = function(item, data)
item:SetData("faction", data.id)
return false
end,
OnCanRun = function(itemTable)
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
end
}
ITEM.functions.insert = {
name = "Insérez carte",
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 = "Carte de la H.A.A"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Une carte CID de la Haute Autorité Administrative."
ITEM.category = "Combine"
ITEM.skin = 1
ITEM.iconCam = {
pos = Vector(0, 0, 10),
ang = Angle(90, 90, 0),
fov = 45,
}
function ITEM:GetName()
local accessLevel = self:GetData("accessLevel", "- Niveau 0")
return "Carte de la Haute Autorité Administrative " .. accessLevel .. ""
end
function ITEM:GetDescription()
local idCard = ix.item.instances[self:GetData("cardID")]
return idCard and string.format(self.description.."\n\nActuellement lié au CID #%s.", idCard:GetData("cardNumber")) or
(self:GetData("cardID") and self.description.."\n\nActuellement lié." or self.description)
end
ITEM.functions.Bind = {
name = "Lier la carte 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("Lier le CID à la carte CID", "Veuillez sélectionner un CID à relier à cette carte :",
cards, "Sélectionner carte CID",
"Confirmer", function(value, name)
netstream.Start("ixBindDOBCard", itemTable:GetID(), value:GetID())
end, "Annuler")
elseif (cardsCount == 1) then
Derma_Query("Êtes-vous sûr de vouloir lier votre CID à cette carte ?", "Lier le CID à la carte CID",
"Confirmer", function()
netstream.Start("ixBindDOBCard", itemTable:GetID(), cards[1].value:GetID())
end, "Annuler")
else
LocalPlayer():NotifyLocalized("Vous n'avez pas de carte CID à lier.")
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 = "Modifier le niveau d'accès",
icon = "icon16/vcard_add.png",
OnRun = function(itemTable)
local client = itemTable.player
local accessLevel = itemTable:GetData("accessLevel", "0")
local target = accessLevel == "- NIVEAU 1 (MEMBRE)" and "- NIVEAU 2 (ADMINISTRATION)" or "- NIVEAU 1 (MEMBRE)"
itemTable:SetData("accessLevel", target)
client:NotifyLocalized("Vous avez fixé le niveau d'accès de cette carte à : " .. 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 = "Fausse Carte CID de #00000"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Une carte CID de citoyen, attribuée à %s | CID n°%s\n\nCID : %s\nDescription génétique :\n%s.\n\nCette carte est la propriété de l'UTC. La possession illégale et l'usurpation d'identité sont punies, et entraîneront des sanctions par la Protection Civile. Si trouvée, merci de remettre immédiatement cette carte à l'équipe de la Protection Civile la plus proche."ITEM.category = "Combine"
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 "# Carte CID n° : " .. self:GetData("cid", "00000") .. ""
end
function ITEM:GetDescription()
return string.format(self.description,
self:GetData("name", "personne"),
self:GetData("cid", "00000"),
self:GetData("cardNumber", "00-0000-0000-00"),
self:GetData("geneticDesc", "N/A | N/A | YEUX N/A | CHEVEUX N/A"))
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 = "Dispositif de création de carte CID"
ITEM.model = Model("models/props_lab/reciever01a.mdl")
ITEM.description = "Un appareil utilisé pour modifier les cartes CID vierges afin qu'elles ressemblent à de vraies cartes fonctionnelles."
ITEM.category = "Outils"
ITEM.functions.CreateID = {
name = "Créer une carte CID contrefaite",
icon = "icon16/vcard.png",
OnRun = function(itemTable)
local client = itemTable.player
client:RequestString("Nom", "Entrez le nom de la personne à qui cette fausse carte sera destinée", function(name)
client:RequestString("CID", "Entrez le CID de la personne à qui cette fausse carte sera destinée", function(cid)
client:RequestString("Description générique", "Entrez la description génétique de la personne à qui cette fausse carte sera destinée", function(desc)
local inventory = client:GetCharacter():GetInventory()
local card = inventory:HasItem("id_card_blank")
if (!card) then
client:Notify("Vous avez besoin d'une carte CID vierge pour faire une contrefaçon !")
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("Fausse carte CID crée.")
client:EmitSound("ambient/machines/combine_terminal_idle2.wav")
end, "~... ANS | ~..M.. | YEUX ...")
end, "00000")
end, "")
return false
end
}

View File

@@ -0,0 +1,288 @@
--[[
| 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 = "Carte CID de #00000"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Une carte CID de citoyen, attribuée à %s | CID n°%s\n\nCID : %s\nDescription génétique :\n%s.\n\nCette carte est la propriété de l'UTC. La possession illégale et l'usurpation d'identité sont punies, et entraîneront des sanctions par la Protection Civile. Si trouvée, merci de remettre immédiatement cette carte à l'équipe de la Protection Civile la plus proche."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 "# Carte CID n° : " .. 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", "personne"),
self:GetData("cid", "00000"),
self:GetData("cardNumber", "00-0000-0000-00"),
self:GetData("geneticDesc", "N/A | N/A | YEUX N/A | CHEVEUX N/A"))
end
local prime = 9999999787 -- prime % 4 = 3! DO NOT CHANGE EVER
local offset = 100000 -- slightly larger than sqrt(prime) is ok. DO NOT CHANGE EVER
local block = 100000000
local function generateCardNumber(id)
id = (id + offset) % prime
local cardNum = 0
for _ = 1, math.floor(id/block) do
cardNum = (cardNum + (id * block) % prime) % prime
end
cardNum = (cardNum + (id * (id % block) % prime)) % prime
if (2 * id < prime) then
return cardNum
else
return prime - cardNum
end
end
function ITEM:GetCredits()
return self:GetData("credits", 0)
end
function ITEM:HasCredits(amount)
return amount <= self:GetData("credits", 0)
end
if (SERVER) then
function ITEM:SetCredits(amount)
self:SetData("credits", math.floor(amount))
return true
end
function ITEM:GiveCredits(amount, sender, reason)
if (amount < 0 and !self:HasCredits(math.abs(amount))) then
return false
end
if (amount == 0) then
return true
end
if (sender) then
local insert = mysql:Insert("ix_cid_transactions")
insert:Insert("datetime", os.time())
insert:Insert("sender_name", sender)
insert:Insert("sender_cid", "00000")
insert:Insert("sender_cardid", 0)
insert:Insert("receiver_name", self:GetData("name", "UNKNOWN"))
insert:Insert("receiver_cid", self:GetData("cid", "INVALID"))
insert:Insert("receiver_cardid", self:GetID())
insert:Insert("amount", amount)
if (reason and reason != "") then
insert:Insert("reason", string.len(reason) > 250 and string.sub(reason, 1, 250) or reason)
else
insert:Insert("reason", "no reason given")
end
insert:Insert("pos", 0)
insert:Insert("read", 1)
insert:Execute()
end
return self:SetCredits(amount + self:GetCredits())
end
function ITEM:TakeCredits(amount, receiver, reason)
if (amount > 0 and !self:HasCredits(amount)) then
return false
end
if (amount == 0) then
return true
end
if (receiver) then
local insert = mysql:Insert("ix_cid_transactions")
insert:Insert("datetime", os.time())
insert:Insert("sender_name", self:GetData("name", "INCONNU"))
insert:Insert("sender_cid", self:GetData("cid", "INVALIDE"))
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", "aucune raison donnée")
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 = "Attribuer crédits",
icon = "icon16/money_add.png",
OnClick = function(itemTable)
local client = itemTable.player
Derma_StringRequest("Attribuer crédits", "Combien de crédits voulez-vous attribuer ?", itemTable:GetData("credits", 0), function(text)
local amount = tonumber(text)
if (amount and amount >= 0) then
netstream.Start("ixSetIDCardCredits", itemTable:GetID(), math.floor(amount))
else
client:NotifyLocalized("numNotValid")
end
end)
end,
OnRun = function(itemTable)
return false
end,
OnCanRun = function(itemTable)
if (IsValid(itemTable.entity)) then
return false
end
if (!CAMI.PlayerHasAccess(itemTable.player, "Helix - Set Credits")) then
return false
end
if (!itemTable:GetData("active", false)) then
return false
end
return true
end
}
ITEM.functions.insert = {
name = "Insert CID",
icon = "icon16/add.png",
OnRun = function(itemTable)
local client = itemTable.player
local ent = client:GetEyeTrace().Entity
if (!ent.CIDInsert) or client:EyePos():DistToSqr(ent:GetPos()) > 62500 then
return false
end
local bSuccess, error = itemTable:Transfer(nil, nil, nil, client)
if (!bSuccess and isstring(error)) then
client:NotifyLocalized(error)
return false
else
client:EmitSound("npc/zombie/foot_slide" .. math.random(1, 3) .. ".wav", 75, math.random(90, 120), 1)
end
if bSuccess and IsEntity(bSuccess) then
ent:CIDInsert(bSuccess)
end
return false
end,
OnCanRun = function(itemTable)
local client = itemTable.player
if (!client:GetEyeTrace().Entity.CIDInsert) then
return false
end
if (!itemTable:GetData("active", false)) then
return false
end
return true
end
}

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 = "Carte CID vierge"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "Une carte CID vierge sans aucune donnée, prête à être marquée."
ITEM.category = "Combine"
ITEM.iconCam = {
pos = Vector(0, 0, 10),
ang = Angle(90, 90, 0),
fov = 45,
}

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 = "Dispositif de création de carte CID"
ITEM.model = Model("models/props_lab/reciever01d.mdl")
ITEM.description = "Dispositif utilisé pour lier des cartes CID vierges à une personne spécifique."
ITEM.category = "Combine"
ITEM.functions.CreateIDTarget = {
name = "Créer une carte CID pour la cible",
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 = "Créer une carte CID pour soi-même",
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:// Carte CID #" .. character:GetCid() .. " crée par " .. 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 = "MOE Access Card"
ITEM.model = Model("models/n7/props/n7_cid_card.mdl")
ITEM.description = "A Ministry of Enlightenment Access Keycard."
ITEM.category = "Combine"
ITEM.skin = 2
ITEM.iconCam = {
pos = Vector(0, 0, 10),
ang = Angle(90, 90, 0),
fov = 45,
}
function ITEM:GetName()
local accessLevel = self:GetData("accessLevel", "Member Access")
return "MOE " .. accessLevel .. " Keycard"
end
function ITEM:GetDescription()
local idCard = ix.item.instances[self:GetData("cardID")]
return idCard and string.format(self.description.."\n\nCurrently bound to identity card #%s.", idCard:GetData("cardNumber")) or
(self:GetData("cardID") and self.description.."\n\nCurrently bound." or self.description)
end
ITEM.functions.Bind = {
name = "Bind ID Card",
icon = "icon16/vcard_edit.png",
OnClick = function(itemTable)
local cards = {}
for _, v in pairs(LocalPlayer():GetCharacter():GetInventory():GetItemsByUniqueID("id_card")) do
table.insert(cards, {
text = v:GetName(),
value = v
})
end
local cardsCount = table.Count(cards)
if (cardsCount > 1) then
Derma_Select("Bind ID Card to MOE Card", "Please select a ID card to bind to this MOE Card:",
cards, "Select ID card",
"Confirm Operation", function(value, name)
netstream.Start("ixBindMOECard", itemTable:GetID(), value:GetID())
end, "Cancel")
elseif (cardsCount == 1) then
Derma_Query("Are you sure you wish to bind your ID to this MOE Card?", "Bind ID Card to MOE Card",
"Confirm Operation", function()
netstream.Start("ixBindMOECard", itemTable:GetID(), cards[1].value:GetID())
end, "Cancel")
else
LocalPlayer():NotifyLocalized("You do not have ID card to bind to this MOE Card.")
end
end,
OnRun = function(itemTable)
return false
end,
OnCanRun = function(itemTable)
if (IsValid(itemTable.entity)) then
return false
end
if (!IsValid(itemTable.player)) then
return false
end
local inventory = itemTable.player:GetCharacter():GetInventory()
if (!inventory:HasItem("id_card")) then
return false
end
if (itemTable:GetData("cardID")) then
return false
end
return true
end
}
ITEM.functions.SetAccessLevel = {
name = "Toggle Card Access Level",
icon = "icon16/vcard_add.png",
OnRun = function(itemTable)
local client = itemTable.player
local accessLevel = itemTable:GetData("accessLevel", "Member Access")
local target = accessLevel == "Member Access" and "Management Access" or "Member Access"
itemTable:SetData("accessLevel", target)
client:NotifyLocalized("You have set this card's Access Level to " .. target .. ".")
return false
end,
OnCanRun = function(itemTable)
return (!IsValid(itemTable.entity) and IsValid(itemTable.player) and (itemTable.player:Team() == FACTION_ADMIN or itemTable.player:IsCombine() or itemTable.player:GetCharacter():HasFlags("M"))) == true
end
}

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 POS"
ITEM.model = Model("models/willardnetworks/props/posterminal.mdl")
ITEM.description = "Dispositif permettant à quelqu'un de demander à une autre personne de déposer des crédits sur une autre carte CID."
ITEM.category = "Combine"
function ITEM:GetDescription()
local idCard = ix.item.instances[self:GetData("cardID")]
return idCard and string.format(self.description.."\n\nLié à la carte CID n°#%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 = "Demander des crédits",
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("Demander des crédits", "Combien de crédits demandez-vous ?", itemTable:GetData("lastAmount", 0), function(text)
local amount = tonumber(text)
if (amount) then
Derma_StringRequest("Demander des crédits - RAISON", "Entrez une raison pour cette transaction :", "", function(reason)
if (text == "") then
client:NotifyLocalized("reasonNotValid")
return
end
netstream.Start("ixRequestCredits", itemTable:GetID(), math.floor(amount), reason)
end)
else
client:NotifyLocalized("numNotValid")
end
end)
end,
OnRun = function(itemTable)
return false
end,
OnCanRun = function(itemTable)
if (IsValid(itemTable.entity)) then
return false
end
if (!itemTable:GetData("cardID", false)) then
return false
end
return true
end
}
ITEM.functions.Bind = {
name = "Lier la carte 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("Liaison du CID au terminal", "Veuillez sélectionner un CID à relier à ce terminal :",
cards, "Sélectionner la carte",
"Confirmer", function(value, name)
netstream.Start("ixBindTerminal", itemTable:GetID(), value:GetID())
end, "Annuler")
elseif (cardsCount == 1) then
Derma_Query("Êtes-vous sûr de vouloir lier CID à ce terminal ?", "Liaison du CID au terminal",
"Confirmer", function()
netstream.Start("ixBindTerminal", itemTable:GetID(), cards[1].value:GetID())
end, "Annuler")
else
client:NotifyLocalized("Vous n'avez pas de carte CID à lier.")
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 = "Transactions récentes",
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 jour", data = {1}}}
for i = 2, 6 do
options[#options + 1] = {name = i.." Jours", data = {i}}
end
options[#options + 1] = {name = "1 Semaine", data = {7}}
options[#options + 1] = {name = "2 Semaines", data = {14}}
options[#options + 1] = {name = "1 Mois", data = {30}}
options[#options + 1] = {name = "Plus", data = {-1}, OnClick = function(itemTable)
Derma_StringRequest("Registre", "Entrez le nombre de jours auxquels vous voulez voir les registres.", "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 = "Bloquer la Carte",
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 = "Débloquer la Carte",
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 = "Dispositif d'aide"
ITEM.model = Model("models/gibs/shield_scanner_gib1.mdl")
ITEM.description = "Un petit appareil aux coins arrondis, abritant un bouton. Un petit logo du Cartel est visible.\n\nLes instructions sont : veuillez d'abord enregistrer cet appareil en tenant votre carte CID contre cet appareil. Une fois l'inscription terminée, vous pouvez demander l'assistance de la Protection Civile en appuyant sur le bouton et en précisant votre demande. Votre nom et votre CID sont automatiquement inclus dans la demande.\nVeuillez noter que l'utilisation abusive du dispositif de demande, les fausses déclarations à la Protection Civile et l'usurpation d'identité sont punissables sévèrements et entraîneront des poursuites par la Protection Civile."
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\nActuellement lié à la carte CID n°#%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, "FAIRE UNE DEMANDE", "ANNULER"
)
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 = "Requête Protection Civile",
requestTitle = "Demander de l'aide à la Protection Civile",
requestMessage = "Entrez la raison de votre demande. Votre nom & votre CID sont automatiquement inclus.",
requestType = REQUEST_CP
})
ITEM.functions.RequestMed = GetRequestTable({
actionName = "Requête UCMR",
requestTitle = "Demander de l'aide à L'union Civile de Médecine et de Recherche",
requestMessage = "Entrez la raison de votre demande. Votre nom & votre CID sont automatiquement inclus. N'oubliez pas de dire votre position!",
requestType = REQUEST_MED
})
ITEM.functions.RequestCwu = GetRequestTable({
actionName = "Requête UTC",
requestTitle = "Demander de l'aide à l'Union des Travailleurs Civile",
requestMessage = "Entrez la raison de votre demande. Votre nom & votre CID sont automatiquement inclus.",
requestType = REQUEST_WORK
})
ITEM.functions.Bind = {
name = "Lié carte 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("Lier le CID au dispositif", "Veuillez sélectionner un CID à relier au dispositif :",
cards, "Sélectionner carte CID",
"Confirmer", function(value, name)
netstream.Start("ixBindRequestDevice", itemTable:GetID(), value:GetID())
end, "Annuler")
elseif (cardsCount == 1) then
Derma_Query("Êtes-vous sûr de vouloir lier votre CID à ce dispositif ?", "Lier le CID au dispositif",
"Confirmer", function()
netstream.Start("ixBindRequestDevice", itemTable:GetID(), cards[1].value:GetID())
end, "Annuler")
else
LocalPlayer():NotifyLocalized("Vous n'avez pas de carte CID à lier.")
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,281 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local ix = ix
local math = math
local tostring = tostring
local pairs = pairs
local netstream = netstream
local CurTime = CurTime
local IsValid = IsValid
local util = util
local hook = hook
local ipairs = ipairs
local table = table
local PLUGIN = PLUGIN
ix.command.Add("CharSetCredits", {
description = "@cmdCharSetMoney",
privilege = "Set Credits",
arguments = {
ix.type.character,
ix.type.number
},
OnRun = function(self, client, target, amount)
amount = math.Round(amount)
if (amount <= 0) then
return "@invalidArg", 2
end
target:SetCredits(amount)
client:NotifyLocalized("setCredits", target:GetName(), tostring(amount))
end
})
ix.command.Add("CharGiveCredits", {
description = "@cmdCharGiveCredits",
privilege = "Set Credits",
arguments = {
ix.type.character,
ix.type.number
},
OnRun = function(self, client, target, amount)
amount = math.Round(amount)
target:GiveCredits(amount)
client:NotifyLocalized("giveCredits", target:GetName(), tostring(amount))
end
})
ix.command.Add("Request", {
description = "@cmdRequest",
arguments = {
ix.type.text
},
combineBeep = true,
OnRun = function(self, client, text)
local character = client:GetCharacter()
if (!character) then return end
local items = character:GetInventory():GetItems()
local requestDevices = {}
for _, item in pairs(items) do
if (item.uniqueID == "request_device" and item:GetData("cardID")) then
requestDevices[#requestDevices + 1] = item
end
end
if (#requestDevices > 1) then
client:NotifyLocalized("rdMoreThanOne")
netstream.Start(client, "rdMoreThanOneText", text)
return
elseif (#requestDevices == 0) then
client:NotifyLocalized("rdNoRD")
return
end
if (ix.config.Get("creditsNoConnection")) then
client:EmitSound("hl1/fvox/buzz.wav", 60, 100, 0.5)
return
end
local idCard = ix.item.instances[requestDevices[1]:GetData("cardID")]
if (!idCard) then
client:NotifyLocalized("rdError")
return
end
if (client.ixNextRequest and client.ixNextRequest > CurTime()) then
client:NotifyLocalized("rdFreqLimit")
return
else
client.ixNextRequest = CurTime() + 10
end
idCard:LoadOwnerGenericData(PLUGIN.RequestSuccess, PLUGIN.RequestError, client, text)
end
})
ix.command.Add("WithdrawCredit", {
description = "Retirer des crédits d'un personnage sur sa carte CID active.",
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, "Union")
target:GetPlayer():Notify("L'Union vous a retiré "..amount.." crédits de votre carte.")
else
client:Notify("Le personnage n'a pas autant de crédits.")
end
end
})
ix.command.Add("CreateCid", {
description = "Crée un nouveau CID pour un personnage.",
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, "Logement", "Logement acheté")
ix.city.main:AddCredits(price)
hook.Run("OnPlayerPurchaseDoor", client, entity, true, ix.plugin.list.doors.CallOnDoorChildren)
ix.log.Add(client, "buydoor")
return "@dPurchased", price..(price == 1 and " crédit" or " crédits")
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, "Logement", "Logement vendu")
hook.Run("OnPlayerPurchaseDoor", client, entity, false, PLUGIN.CallOnDoorChildren)
ix.log.Add(client, "selldoor")
return "@dSold", price..(price == 1 and " crédit" or " crédits")
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,259 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local CAMI = CAMI
local ix = ix
local IsValid = IsValid
local net = net
local tonumber = tonumber
local Color = Color
local chat = chat
local string = string
local PLUGIN = PLUGIN
PLUGIN.name = "CID"
PLUGIN.author = "Gr4Ss"
PLUGIN.description = "Adds identification cards and credits as digital currency."
CAMI.RegisterPrivilege({
Name = "Helix - Set Credits",
MinAccess = "superadmin"
})
ix.config.Add("creditsNoConnection", false, "Disable the use of credits in some situations, simulating the connection to the Combine network being down.", nil, {
category = "Miscellaneous"
})
ix.config.Add("requestDeviceAction", "just used request device.", "The action that should be sent after someone uses request device.", nil, {
category = "Miscellaneous"
})
ix.char.RegisterVar("cid", {
field = "cid",
fieldType = ix.type.string,
default = nil,
bNoDisplay = true
})
ix.char.RegisterVar("idCardBackup", {
field = "idCardBackup",
default = {},
bNoDisplay = true,
bNoNetworking = true
})
ix.char.RegisterVar("idCard", {
field = "idcard",
fieldType = ix.type.number,
default = nil,
bNoDisplay = true,
OnSet = function(self, value)
local client = self:GetPlayer()
if (IsValid(client)) then
self.vars.idCard = value
net.Start("ixCharacterVarChanged")
net.WriteUInt(self:GetID(), 32)
net.WriteString("idCard")
net.WriteType(self.vars.idCard)
net.Broadcast()
end
end,
OnGet = function(self, default)
local idCard = self.vars.idCard
return tonumber(idCard) or 0
end,
OnAdjust = function(self, client, data, value, newData)
newData.idCard = value
end
})
ix.util.Include("cl_plugin.lua")
ix.util.Include("sh_commands.lua")
ix.util.Include("sv_hooks.lua")
ix.util.Include("sv_net.lua")
ix.util.Include("sv_plugin.lua")
ix.lang.AddTable("english", {
cmdCharSetCredits = "Set a character's Credits.",
cmdCharGiveCredits = "Give a character Credits.",
cmdRequest = "Make a request for assistance to Civil Protection. Will use a ID card-bound request device from your inventory.",
setCredits = "You have set %s's credits to %s.",
giveCredits = "You have given %s %s credits.",
scanning = "Scanning...",
idNotFound = "ERROR: Biological signature not found.",
idNoBlank = "ERROR: No blank card inserted.",
idCardAdded = "SUCCESS: ID Card created.",
idCardRecreated = "SUCCESS: ID Card recreated.",
idNotAllowed = "Device does not respond when you try to use it.",
posBound = "SUCCESS: POS terminal bound to the specified ID Card.",
posBoundInactiveCard = "ERROR: ID Card is no longer active. Please dispose of inactive card immediately.",
posRequestSent = "INFO: Performing credit transaction...",
posRequestExecuting = "INFO: Executing transaction... please wait...",
posTransactionSuccess = "SUCCESS: Transaction complete.",
posError = "ERROR: Unexpected error occurred. Transaction was terminated.",
posBoundCardNotActive = "ERROR: Bound ID Card no longer active. Please dispose of inactive card immediately.",
posCardNotActive = "ERROR: Used ID Card no longer active. Please dispose of inactive card immediately.",
posTransOngoing = "%s tried to start a new transaction, but you are still finishing another transaction.",
posTransExpired = "Your transaction has expired.",
posTransactionRefused = "Your POS transaction was refused or timed out.",
numNotValid = "You specified invalid amount of credits!",
reasonNotValid = "You specified an invalid reason for the transaction!",
transactionNoMoney = "ERROR: Insufficient credits.",
transactionOwnChars = "ERROR: You cannot transfer credits between your own characters!",
transactionSelf = "ERROR: You cannot transfer credits to yourself!",
rdBound = "SUCCESS: Request Device successfully bound to the specified ID Card.",
rdError = "ERROR: Unexpected error occurred. Please find a Civil Protection officer to file your request manually.",
rdMoreThanOne = "You have more than one bound request device, please select in your inventory which one you want to use.",
rdNoRD = "You do not have a request device, or it is not bound to an ID card!",
rdFreqLimit = "Please wait at least 10 seconds between requests.",
cwuBound = "SUCCESS: CWU Card successfully bound to the specified ID Card.",
dobBound = "SUCCESS: DOB Card successfully bound to the specified ID Card.",
cmruBound = "SUCCESS: CMRU Card successfully bound to the specified ID Card.",
targetTransactionInProgress = "This person already has a transaction in progress!",
idCardIssued = "New identity card issued for %s by %s",
errorNoConnection = "ERROR: NO CONNECTION"
})
ix.lang.AddTable("french", {
cmdCharSetCredits = "Définissez les crédits d'un personnage.",
cmdCharGiveCredits = "Donnez des crédits à un personnage.",
cmdRequest = "Faire une demande d'assistance à la Protection Civile. Utilisera un dispositif de demande lié à la carte CID de votre inventaire.",
setCredits = "Vous avez défini les crédits de %s sur %s.",
giveCredits = "Vous avez donné %s %s crédits.",
scanning = "Scan...",
idNotFound = "ERREUR : Signature biologique introuvable.",
idNoBlank = "ERREUR : Aucune carte vierge insérée.",
idCardAdded = "SUCCÈS : Création de la carte CID.",
idCardRecreated = "SUCCÈS : Carte CID recréée.",
idNotAllowed = "L'appareil ne répond pas lorsque vous essayez de l'utiliser.",
posBound = "RÉUSSITE : Terminal POS lié.",
posBoundInactiveCard = "ERREUR : La carte CID n'est plus active. Veuillez détruire immédiatement la carte inactive.",
posRequestSent = "INFO : Opération de crédit en cours...",
posRequestExecuting = "INFO : Exécution de la transaction...Veuillez patienter...",
posTransactionSuccess = "SUCCÈS : Transaction terminée.",
posError = "ERREUR : Une erreur inattendue s'est produite. La transaction a été terminée.",
posBoundCardNotActive = "ERREUR : La carte CID liée n'est plus active. Veuillez détruire immédiatement la carte inactive.",
posCardNotActive = "ERREUR : la carte CID utilisée n'est plus active. Veuillez détruire immédiatement la carte inactive.",
posTransOngoing = "%s a essayé de démarrer une nouvelle transaction, mais vous êtes encore en train de terminer une autre transaction.",
posTransExpired = "Votre transaction a expirée.",
posTransactionRefused = "Votre transaction POS a été refusée ou a expirée.",
numNotValid = "Vous avez spécifié un montant de crédits non valide !",
reasonNotValid = "Vous avez spécifié un motif invalide pour la transaction! ",
transactionNoMoney = "ERREUR : Crédits insuffisants. Paiement refusé.",
transactionOwnChars = "ERREUR : Vous ne pouvez pas transférer de crédits entre vos propres personnages !",
transactionSelf = "ERREUR : Vous ne pouvez pas vous transférer de crédits !",
rdBound = "SUCCÈS : Dispositif d'assistance lié avec succès à la carte CID spécifiée.",
rdError = "ERREUR : Une erreur inattendue s'est produite. Veuillez trouver une unité de la Protection Civile pour déposer votre demande manuellement.",
rdMoreThanOne = "Vous avez plus d'un appareil d'assistance lié, veuillez sélectionner dans votre inventaire celui que vous souhaitez utiliser.",
rdNoRD = "Vous n'avez pas de dispositif d'assistance, ou il n'est pas lié à une carte CID !",
rdFreqLimit = "Veuillez attendre au moins 10 secondes entre les requêtes.",
cwuBound = "RÉUSSITE : La carte de l'UTC a été liée avec succès à la carte d'identité spécifiée.",
cmuBound = "RÉUSSITE : La carte des Médecins de l'UTC a été liée avec succès à la carte d'identité spécifiée.",
dobBound = "RÉUSSITE : La carte de la Haute Autorité Administrative a été liée avec succès à la carte d'identité spécifiée.",
briBound = "RÉUSSITE : La carte du BRI a été liée avec succès à la carte d'identité spécifiée.",
targetTransactionInProgress = "Cette personne a déjà une transaction en cours !",
idCardIssued = "Nouvelle carte CID émise pour %s par %s"
})
ix.lang.AddTable("spanish", {
posBoundCardNotActive = "ERROR: La tarjeta ID vinculada ya no está activa. Por favor, deshágase de la tarjeta inactiva inmediatamente.",
posTransExpired = "Tu transacción ha caducado.",
posTransactionSuccess = "ÉXITO: Transacción completada.",
posTransOngoing = "%s ha intentado iniciar una nueva transacción, pero todavía estás terminando otra transacción.",
posRequestExecuting = "INFO: Ejecutando la transacción... por favor espere...",
numNotValid = "¡Has especificado una cantidad de créditos inválida!",
posError = "ERROR: Se ha producido un error inesperado. La transacción ha finalizado.",
posCardNotActive = "ERROR: La tarjeta ID vinculada ya no está activa. Por favor, deshágase de la tarjeta inactiva inmediatamente.",
reasonNotValid = "¡Has especificado un motivo no válido para la transacción!",
transactionOwnChars = "ERROR: ¡No puedes transferir créditos entre tus propios personajes!",
transactionNoMoney = "ERROR: Créditos insuficientes.",
targetTransactionInProgress = "¡Esta persona ya tiene una transacción en curso!",
transactionSelf = "ERROR: ¡No puedes transferirte créditos a ti mismo!",
rdError = "ERROR: Se ha producido un error inesperado. Por favor, busque a un agente de Protección Civil para presentar tu solicitud manualmente.",
giveCredits = "Has dado %s %s créditos.",
scanning = "Escaneando...",
cmdCharSetCredits = "Establecer los créditos de un personaje.",
cmdCharGiveCredits = "Dar créditos a un personaje.",
posTransactionRefused = "Su transacción en del datafono ha sido rechazada o ha expirado.",
idNoBlank = "ERROR: No se ha insertado ninguna tarjeta en blanco.",
posBoundInactiveCard = "ERROR: La tarjeta de identificación ya no está activa. Por favor, deshágase de la tarjeta inactiva inmediatamente.",
rdNoRD = "¡No tiene un dispositivo de socorro, o no está vinculado a una tarjeta de identificación!",
idCardAdded = "ÉXITO: Tarjeta de identificación creada.",
posRequestSent = "INFO: Realizando una transacción de crédito...",
idCardRecreated = "ÉXITO: Tarjeta de identificación recreada.",
posBound = "ÉXITO: El datafono está vinculado a la tarjeta de identificación especificada.",
idNotAllowed = "El dispositivo no responde cuando intentas utilizarlo.",
idNotFound = "ERROR: Señal Biológica no encontrada.",
rdMoreThanOne = "Tienes más de un dispositivo de socorro vinculado, por favor selecciona en tu inventario cuál quieres usar.",
rdFreqLimit = "Por favor, espere al menos 10 segundos entre peticiones.",
cmdRequest = "Realiza una solicitud de ayuda a Protección Civil. Utilizará un dispositivo de socorro vinculado a una tarjeta de identificación de tu inventario.",
rdBound = "ÉXITO: El dispositivo de socorro se ha vinculado con éxito a la tarjeta de identificación especificada.",
setCredits = "Los créditos de %s han sido establecidos a %s.",
cwuBound = "ÉXITO: Tarjeta UTC vinculada con éxito a la tarjeta ID especificada.",
idCardIssued = "Nuevo documento de identidad emitido para %s por %s"
})
do
local CLASS = {}
CLASS.color = Color(175, 125, 100)
CLASS.format = "%s, #%s demande %s\"%s\""
CLASS.formatCP = "%s demande %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, "Unité de la Protection Civile", 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,447 @@
--[[
| 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:// CID #" .. senderCid .. " a envoyé " .. amount .. " crédits au CID #" .. receiverCid, nil, client)
PLUGIN:CreditTransaction(result[1].idcard, senderCardID, amount, client, receiver, nil, "Terminal POS", senderCid, receiverCid)
end)
receiverQuery:Execute()
end)
-- Request stuff
local red = Color(255, 0, 0, 255)
local orange = Color(255, 165, 0, 255)
local yellow = Color(255, 255, 0, 255)
local function createCombineAlert(client, text, color)
ix.combineNotify:AddImportantNotification(text, color, client)
end
function PLUGIN.RequestSuccess(idCard, genericData, client, text, requestType)
local isBOL = genericData.bol
local isAC = genericData.anticitizen
local alertText, color = "%s, #%s (SC: %d) demande assistance", yellow
if (client:IsCombine()) then
alertText = "%s (SC: %d) demande assistance"
elseif (isAC) then
alertText, color = "Anti-Citoyen %s, #%s demande assistance", red
elseif (isBOL) then
alertText, color = "Citoyen Recherché %s, #%s demande assistance", orange
elseif (genericData.loyaltyStatus and genericData.loyaltyStatus != "NONE") then
if (genericData.loyaltyStatus == "MEMBRE H.A.A") then
alertText, color = "MEMBRE H.A.A "..alertText, red
else
alertText, color = string.utf8sub(genericData.loyaltyStatus, 1, 6).." Loyaliste "..alertText, orange
end
elseif (genericData.socialCredits >= 90) then
if (genericData.socialCredits >= 225) then
alertText = "Haut Collaborateur"..alertText
elseif (genericData.socialCredits >= 175) then
alertText = "Collaborateur"..alertText
else
alertText = "Partisan"..alertText
end
end
if (idCard:GetData("active", false) == false) then
alertText, color = alertText.." avec une carte CID inactive", 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("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("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,389 @@
--[[
| 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")
ix.log.AddType("creditIDCardSetCredits", function(client, itemId, amount)
return string.format("%s a défini les crédits le crédits de #%d à %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", "INVALIDE")
else
senderCardCid = (tostring(senderCard:GetData("cid", "00000")) == "00000" and senderCID or senderCard:GetData("cid", "INVALIDE"))
end
if !receiverCID then
receiverCardCid = receiverCard:GetData("cid", "INVALIDE")
else
receiverCardCid = (tostring(receiverCard:GetData("cid", "00000") ) == "00000" and receiverCID or receiverCard:GetData("cid", "INVALIDE"))
end
local senderName = senderCard:GetData("name", "INCONNU")
if (IsValid(client) and client:HasActiveCombineMask()) then
senderName = "IDENTITÉ CONFIDENTIELLE"
senderCardCid = "CONFIDENTIELLE"
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", "INCONNU"))
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", "aucune raison donnée")
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 - Objet : %s) a envoyé %d crédits à %s (CID : %s - Objet : %s) via un %s.",
senderCard:GetData("name"),
senderCardCid,
senderCard:GetID(),
amount,
receiverCard:GetData("name"),
receiverCardCid,
receiverCard:GetID(),
posDevice and string.format("Terminal POS pour '%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.." | YEUX "..eyeColor.."",
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