mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 05:43:46 +03:00
Upload
This commit is contained in:
561
gamemodes/ixhl2rp/plugins/goi_cityfunds/derma/cl_cteditor.lua
Normal file
561
gamemodes/ixhl2rp/plugins/goi_cityfunds/derma/cl_cteditor.lua
Normal file
@@ -0,0 +1,561 @@
|
||||
--[[
|
||||
| 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 = {}
|
||||
|
||||
local function CheckItemRates(actualTD)
|
||||
if actualTD.highRateProduction < actualTD.averageRateProduction and
|
||||
actualTD.highRateProduction < actualTD.lowRateProduction and
|
||||
actualTD.averageRateProduction < actualTD.lowRateProduction then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function PANEL:CreateDivider(parent, dock)
|
||||
local divider = parent:Add("Panel")
|
||||
divider:Dock(dock)
|
||||
divider:SetHeight(SScaleMin(10 / 3))
|
||||
divider.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawLine(0, h * 0.5, w, h * 0.5)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Init()
|
||||
if (ix.gui.ctEditor and ix.gui.ctEditor != self) then
|
||||
ix.gui.ctEditor:Remove()
|
||||
end
|
||||
|
||||
ix.gui.ctEditor = self
|
||||
|
||||
self:SetSize(ScrW(), ScrH())
|
||||
|
||||
self.typeData = {}
|
||||
self.typeList = {}
|
||||
|
||||
self.innerContent = self:Add("Panel")
|
||||
self.innerContent:SetSize(SScaleMin(900 / 3), SScaleMin(640 / 3))
|
||||
self.innerContent:Center()
|
||||
self.innerContent:MakePopup()
|
||||
self.innerContent.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(0, 0, 0, 130)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
self.topbar = self.innerContent:Add("Panel")
|
||||
self.topbar:SetHeight(SScaleMin(40 / 3))
|
||||
self.topbar:Dock(TOP)
|
||||
self.topbar.Paint = function(s, width, height)
|
||||
surface.SetDrawColor(8, 8, 8, 130)
|
||||
surface.DrawRect(0, 0, width, height)
|
||||
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawLine(0, height * 0.95, width, height * 0.95)
|
||||
end
|
||||
|
||||
local exit = self.topbar:Add("DImageButton")
|
||||
exit:SetMaterial(Material("willardnetworks/tabmenu/navicons/exit.png", "smooth"))
|
||||
exit:SetSize(SScaleMin(25 / 3), SScaleMin(20 / 3))
|
||||
exit:DockMargin(0, SScaleMin(6 / 3), SScaleMin(6 / 3), SScaleMin(6 / 3))
|
||||
exit:Dock(RIGHT)
|
||||
exit.DoClick = function()
|
||||
self:Remove()
|
||||
surface.PlaySound("helix/ui/press.wav")
|
||||
end
|
||||
|
||||
local titleText = self.topbar:Add("DLabel")
|
||||
titleText:SetFont("CharCreationBoldTitleNoClamp")
|
||||
titleText:Dock(LEFT)
|
||||
titleText:SetText("City Type Editor")
|
||||
titleText:DockMargin(SScaleMin(10 / 3), 0, 0, 0)
|
||||
titleText:SetContentAlignment(4)
|
||||
titleText:SizeToContents()
|
||||
end
|
||||
|
||||
function PANEL:AddTypeToList(typeID, parent, typeData)
|
||||
local pnl = parent:Add("DButton")
|
||||
pnl:Dock(LEFT)
|
||||
pnl:DockMargin(SScaleMin(6 / 3), SScaleMin(6 / 3), SScaleMin(6 / 3), 0)
|
||||
pnl:SetFont("TitlesFontNoClamp")
|
||||
pnl:SetText(typeID)
|
||||
pnl:SetWide(SScaleMin(128 / 3))
|
||||
pnl.typeData = typeData
|
||||
pnl.DoClick = function(s)
|
||||
self:BuildEditor(s.typeData)
|
||||
surface.PlaySound("willardnetworks/charactercreation/boop" .. math.random(1, 3) .. ".wav")
|
||||
end
|
||||
pnl.DoRightClick = function(s)
|
||||
local menu = DermaMenu()
|
||||
menu:AddOption( "Remove", function()
|
||||
Derma_Query("Are you sure you want to remove this type?", "REMOVING TYPE",
|
||||
"Yes", function()
|
||||
net.Start("ix.city.RemoveType")
|
||||
net.WriteString(s.typeData.name)
|
||||
net.SendToServer()
|
||||
self.typeData[s.typeData.name] = nil
|
||||
if (self.actualTD and self.actualTD.name == s.typeData.name and self.innerScroller) then
|
||||
self.innerScroller:Remove()
|
||||
end
|
||||
s:Remove()
|
||||
surface.PlaySound("willardnetworks/datapad/close.wav")
|
||||
end,
|
||||
"No", nil)
|
||||
end)
|
||||
menu:Open()
|
||||
end
|
||||
parent:AddPanel( pnl )
|
||||
|
||||
self.typeList[#self.typeList + 1] = pnl
|
||||
return pnl
|
||||
end
|
||||
|
||||
function PANEL:CreateItemButton(itemID, parent, category)
|
||||
if (self.itemsPanel.items[itemID]) then
|
||||
return LocalPlayer():NotifyLocalized("Item already exists or its invalid.")
|
||||
end
|
||||
self.itemsPanel.items[itemID] = category
|
||||
if category == "high" then
|
||||
self.actualTD.itemsHighRate[itemID] = true
|
||||
elseif category == "average" then
|
||||
self.actualTD.itemsAverageRate[itemID] = true
|
||||
elseif category == "low" then
|
||||
self.actualTD.itemsLowRate[itemID] = true
|
||||
end
|
||||
|
||||
local button = parent:Add("DButton")
|
||||
button:SetContentAlignment(5)
|
||||
button:SetFont("LargerTitlesFontNoClamp")
|
||||
button:SetText(ix.item.list[itemID].name)
|
||||
button:Dock(TOP)
|
||||
button:SetHeight(SScaleMin(64 / 3))
|
||||
button:DockMargin(SScaleMin(6 / 3), SScaleMin(6 / 3), SScaleMin(6 / 3), 0)
|
||||
button.DoClick = function(s)
|
||||
local menu = DermaMenu()
|
||||
menu:AddOption( "Remove", function()
|
||||
Derma_Query("Are you sure you want to remove this item?", "REMOVING ITEM",
|
||||
"Yes", function()
|
||||
self.itemsPanel.items[itemID] = nil
|
||||
if category == "high" then
|
||||
self.actualTD.itemsHighRate[itemID] = nil
|
||||
elseif category == "average" then
|
||||
self.actualTD.itemsAverageRate[itemID] = nil
|
||||
elseif category == "low" then
|
||||
self.actualTD.itemsLowRate[itemID] = nil
|
||||
end
|
||||
surface.PlaySound("willardnetworks/datapad/close.wav")
|
||||
s:Remove()
|
||||
end,
|
||||
"No", nil)
|
||||
end)
|
||||
menu:Open()
|
||||
end
|
||||
|
||||
local icon = button:Add("SpawnIcon")
|
||||
icon:SetModel(ix.item.list[itemID].model)
|
||||
icon:Dock(LEFT)
|
||||
end
|
||||
|
||||
function PANEL:Populate()
|
||||
if ix.gui.fundManager and IsValid(ix.gui.fundManager) then
|
||||
ix.gui.fundManager:Remove()
|
||||
end
|
||||
|
||||
self.returnButton = self.innerContent:Add("DButton")
|
||||
self.returnButton:SetContentAlignment(5)
|
||||
self.returnButton:SetFont("LargerTitlesFontNoClamp")
|
||||
self.returnButton:SetText("RETURN")
|
||||
self.returnButton:Dock(TOP)
|
||||
self.returnButton:SetHeight(SScaleMin(32 / 3))
|
||||
self.returnButton:DockMargin(SScaleMin(6 / 3), 0, SScaleMin(6 / 3), 0)
|
||||
self.returnButton.DoClick = function(s)
|
||||
self:Remove()
|
||||
vgui.Create("ixFundManager")
|
||||
end
|
||||
|
||||
self.createType = self.innerContent:Add("DButton")
|
||||
self.createType:SetContentAlignment(5)
|
||||
self.createType:SetFont("LargerTitlesFontNoClamp")
|
||||
self.createType:SetText("CREATE TYPE")
|
||||
self.createType:Dock(TOP)
|
||||
self.createType:SetHeight(SScaleMin(32 / 3))
|
||||
self.createType:DockMargin(SScaleMin(6 / 3), SScaleMin(6 / 3), SScaleMin(6 / 3), 0)
|
||||
self.createType.DoClick = function(s)
|
||||
Derma_StringRequest("Type name", "Insert type name here.", "", function(text)
|
||||
if self.typeData[text] then
|
||||
return LocalPlayer():NotifyLocalized("Type with this name already exists.")
|
||||
end
|
||||
|
||||
net.Start("ix.city.CreateType")
|
||||
net.WriteString(text)
|
||||
net.SendToServer()
|
||||
|
||||
net.Start("ix.city.RequestUpdateTypes")
|
||||
net.SendToServer()
|
||||
end)
|
||||
end
|
||||
|
||||
self:CreateDivider(self.innerContent, TOP)
|
||||
|
||||
self.typePanel = self.innerContent:Add("DHorizontalScroller")
|
||||
self.typePanel:Dock(TOP)
|
||||
self.typePanel:DockMargin(SScaleMin(6 / 3), 0, SScaleMin(12 / 3), 0)
|
||||
self.typePanel:SetHeight(SScaleMin(48 / 3))
|
||||
self.typePanel:SetOverlap(-64)
|
||||
|
||||
for typeID, type in pairs(self.typeData) do
|
||||
self:AddTypeToList(typeID, self.typePanel, type)
|
||||
end
|
||||
|
||||
self:CreateDivider(self.innerContent, TOP)
|
||||
end
|
||||
|
||||
function PANEL:CreateOptionWang(parent, text, dock, font)
|
||||
local pnl = parent:Add("Panel")
|
||||
pnl:Dock(dock)
|
||||
pnl:DockMargin(SScaleMin(3 / 3), SScaleMin(3 / 3), SScaleMin(3 / 3), SScaleMin(3 / 3))
|
||||
pnl:SetWide(SScaleMin( (480 / 3) / 3))
|
||||
|
||||
local label = pnl:Add("DLabel")
|
||||
label:SetFont(font or "SubtitleFont")
|
||||
label:Dock(TOP)
|
||||
label:SetText(text)
|
||||
label:SetContentAlignment(5)
|
||||
label:SizeToContents()
|
||||
|
||||
local numWang = pnl:Add("DNumberWang")
|
||||
numWang:Dock(BOTTOM)
|
||||
numWang:DockMargin(SScaleMin(48 / 3), 0, SScaleMin(48 / 3), 0)
|
||||
numWang:SetMax(9999)
|
||||
numWang.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawOutlinedRect(0, 0, w, h, 1)
|
||||
|
||||
draw.SimpleText(s:GetValue(), "SubtitleFont", w * 0.25, h * 0.15)
|
||||
end
|
||||
|
||||
return numWang
|
||||
end
|
||||
|
||||
local btnColor = Color(111, 111, 136, 255)
|
||||
|
||||
function PANEL:UpdateTypes(newTbl)
|
||||
self.typeData = newTbl
|
||||
|
||||
for _, pnl in pairs(self.typeList) do
|
||||
pnl:Remove()
|
||||
end
|
||||
|
||||
if (self.innerScroller) then
|
||||
self.innerScroller:Remove()
|
||||
end
|
||||
|
||||
for typeID, type in pairs(self.typeData) do
|
||||
self:AddTypeToList(typeID, self.typePanel, type)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:BuildEditor(typeData)
|
||||
if (self.innerScroller) then
|
||||
self.innerScroller:Remove()
|
||||
end
|
||||
|
||||
self.actualTD = typeData
|
||||
|
||||
self.innerScroller = self.innerContent:Add("DScrollPanel")
|
||||
self.innerScroller:Dock(FILL)
|
||||
|
||||
local itemsText = self.innerScroller:Add("DLabel")
|
||||
itemsText:SetFont("CharCreationBoldTitleNoClamp")
|
||||
itemsText:Dock(TOP)
|
||||
itemsText:SetText("ITEM PRODUCTION TABLES")
|
||||
itemsText:DockMargin(0, SScaleMin(12 / 3), 0, 0)
|
||||
itemsText:SetContentAlignment(5)
|
||||
itemsText:SizeToContents()
|
||||
|
||||
self.itemsPanel = self.innerScroller:Add("Panel")
|
||||
self.itemsPanel:Dock(TOP)
|
||||
self.itemsPanel:SetHeight(SScaleMin(348 / 3))
|
||||
self.itemsPanel:DockMargin(SScaleMin(8 / 3), SScaleMin(4 / 3), 0, 0)
|
||||
self.itemsPanel.items = {}
|
||||
|
||||
self.itemsHPScroller = self.itemsPanel:Add("DScrollPanel")
|
||||
self.itemsHPScroller:Dock(LEFT)
|
||||
self.itemsHPScroller:DockMargin(SScaleMin(12 / 3), 0, 0, 0)
|
||||
self.itemsHPScroller:SetWide(self.innerContent:GetWide() * 0.31)
|
||||
self.itemsHPScroller.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawOutlinedRect(0, 0, w, h, 2)
|
||||
end
|
||||
|
||||
local hpText = self.itemsHPScroller:Add("DLabel")
|
||||
hpText:SetFont("TitlesFontNoBoldNoClamp")
|
||||
hpText:Dock(TOP)
|
||||
hpText:SetText("HIGH PRODUCTION")
|
||||
hpText:DockMargin(0, SScaleMin(4 / 3), 0, 0)
|
||||
hpText:SetContentAlignment(5)
|
||||
hpText:SizeToContents()
|
||||
|
||||
local addHPButton = self.itemsHPScroller:Add("DButton")
|
||||
addHPButton:SetFont("MenuFontNoClamp")
|
||||
addHPButton:Dock(TOP)
|
||||
addHPButton:SetText("Add item")
|
||||
addHPButton:DockMargin(SScaleMin(36 / 3), SScaleMin(6 / 3), SScaleMin(36 / 3), 0)
|
||||
addHPButton:SetContentAlignment(5)
|
||||
addHPButton:SizeToContents()
|
||||
addHPButton.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(Color(0, 0, 0, 100))
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
surface.SetDrawColor(btnColor)
|
||||
surface.DrawOutlinedRect(0, 0, w, h)
|
||||
end
|
||||
addHPButton.DoClick = function(s)
|
||||
surface.PlaySound("helix/ui/press.wav")
|
||||
Derma_StringRequest("Item ID", "Insert item's ID you want to add here.", "", function(text)
|
||||
if !ix.item.list[text] then
|
||||
return LocalPlayer():NotifyLocalized("Wrong item ID.")
|
||||
end
|
||||
self:CreateItemButton(text, self.itemsHPScroller, "high")
|
||||
end)
|
||||
end
|
||||
|
||||
self:CreateDivider(self.itemsHPScroller, TOP)
|
||||
|
||||
self.itemsAPScroller = self.itemsPanel:Add("DScrollPanel")
|
||||
self.itemsAPScroller:Dock(LEFT)
|
||||
self.itemsAPScroller:DockMargin(SScaleMin(12 / 3), 0, 0, 0)
|
||||
self.itemsAPScroller:SetWide(self.innerContent:GetWide() * 0.31)
|
||||
self.itemsAPScroller.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawOutlinedRect(0, 0, w, h, 2)
|
||||
end
|
||||
|
||||
local apText = self.itemsAPScroller:Add("DLabel")
|
||||
apText:SetFont("TitlesFontNoBoldNoClamp")
|
||||
apText:Dock(TOP)
|
||||
apText:SetText("AVERAGE PRODUCTION")
|
||||
apText:DockMargin(0, SScaleMin(4 / 3), 0, 0)
|
||||
apText:SetContentAlignment(5)
|
||||
apText:SizeToContents()
|
||||
|
||||
local addAPButton = self.itemsAPScroller:Add("DButton")
|
||||
addAPButton:SetFont("MenuFontNoClamp")
|
||||
addAPButton:Dock(TOP)
|
||||
addAPButton:SetText("Add item")
|
||||
addAPButton:DockMargin(SScaleMin(36 / 3), SScaleMin(6 / 3), SScaleMin(36 / 3), 0)
|
||||
addAPButton:SetContentAlignment(5)
|
||||
addAPButton:SizeToContents()
|
||||
addAPButton.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(Color(0, 0, 0, 100))
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
surface.SetDrawColor(btnColor)
|
||||
surface.DrawOutlinedRect(0, 0, w, h)
|
||||
end
|
||||
addAPButton.DoClick = function(s)
|
||||
surface.PlaySound("helix/ui/press.wav")
|
||||
Derma_StringRequest("Item ID", "Insert item's ID you want to add here.", "", function(text)
|
||||
if !ix.item.list[text] then
|
||||
return LocalPlayer():NotifyLocalized("Wrong item ID.")
|
||||
end
|
||||
self:CreateItemButton(text, self.itemsAPScroller, "average")
|
||||
end)
|
||||
end
|
||||
|
||||
self:CreateDivider(self.itemsAPScroller, TOP)
|
||||
|
||||
self.itemsLPScroller = self.itemsPanel:Add("DScrollPanel")
|
||||
self.itemsLPScroller:Dock(LEFT)
|
||||
self.itemsLPScroller:DockMargin(SScaleMin(12 / 3), 0, 0, 0)
|
||||
self.itemsLPScroller:SetWide(self.innerContent:GetWide() * 0.31)
|
||||
self.itemsLPScroller.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawOutlinedRect(0, 0, w, h, 2)
|
||||
end
|
||||
|
||||
local lpText = self.itemsLPScroller:Add("DLabel")
|
||||
lpText:SetFont("TitlesFontNoBoldNoClamp")
|
||||
lpText:Dock(TOP)
|
||||
lpText:SetText("LOW PRODUCTION")
|
||||
lpText:DockMargin(0, SScaleMin(4 / 3), 0, 0)
|
||||
lpText:SetContentAlignment(5)
|
||||
lpText:SizeToContents()
|
||||
|
||||
local addLPButton = self.itemsLPScroller:Add("DButton")
|
||||
addLPButton:SetFont("MenuFontNoClamp")
|
||||
addLPButton:Dock(TOP)
|
||||
addLPButton:SetText("Add item")
|
||||
addLPButton:DockMargin(SScaleMin(36 / 3), SScaleMin(6 / 3), SScaleMin(36 / 3), 0)
|
||||
addLPButton:SetContentAlignment(5)
|
||||
addLPButton:SizeToContents()
|
||||
addLPButton.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(Color(0, 0, 0, 100))
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
surface.SetDrawColor(btnColor)
|
||||
surface.DrawOutlinedRect(0, 0, w, h)
|
||||
end
|
||||
addLPButton.DoClick = function(s)
|
||||
surface.PlaySound("helix/ui/press.wav")
|
||||
Derma_StringRequest("Item ID", "Insert item's ID you want to add here.", "", function(text)
|
||||
if !ix.item.list[text] then
|
||||
return LocalPlayer():NotifyLocalized("Wrong item ID.")
|
||||
end
|
||||
self:CreateItemButton(text, self.itemsLPScroller, "low")
|
||||
end)
|
||||
end
|
||||
|
||||
self:CreateDivider(self.itemsLPScroller, TOP)
|
||||
|
||||
for itemID, _ in pairs(self.actualTD.itemsHighRate) do
|
||||
self:CreateItemButton(itemID, self.itemsHPScroller, "high")
|
||||
end
|
||||
for itemID, _ in pairs(self.actualTD.itemsAverageRate) do
|
||||
self:CreateItemButton(itemID, self.itemsAPScroller, "average")
|
||||
end
|
||||
for itemID, _ in pairs(self.actualTD.itemsLowRate) do
|
||||
self:CreateItemButton(itemID, self.itemsLPScroller, "low")
|
||||
end
|
||||
|
||||
local productionPanel = self.innerScroller:Add("Panel")
|
||||
productionPanel:Dock(TOP)
|
||||
productionPanel:SetHeight(SScaleMin(96 / 3))
|
||||
productionPanel:DockMargin(SScaleMin(196 / 3), SScaleMin(4 / 3), SScaleMin(196 / 3), 0)
|
||||
local high = self:CreateOptionWang(productionPanel, "HIGH PRODUCTION RATE", LEFT)
|
||||
high:SetValue(self.actualTD.highRateProduction)
|
||||
high:GetParent():SetHelixTooltip(function(tooltip)
|
||||
local name = tooltip:AddRow("name")
|
||||
name:SetImportant()
|
||||
name:SetText("High production rate")
|
||||
name:SizeToContents()
|
||||
|
||||
local info = tooltip:AddRow("info")
|
||||
info:SetText("Defines the rate of production in hours. If you'll leave this row with value of 1, the items from high production category will produce every hour.")
|
||||
info:SizeToContents()
|
||||
|
||||
tooltip:SizeToContents()
|
||||
end)
|
||||
high.OnValueChanged = function(s, value)
|
||||
self.actualTD.highRateProduction = value
|
||||
end
|
||||
|
||||
local avrg = self:CreateOptionWang(productionPanel, "AVERAGE PRODUCTION RATE", LEFT)
|
||||
avrg:SetValue(self.actualTD.averageRateProduction)
|
||||
avrg:GetParent():SetHelixTooltip(function(tooltip)
|
||||
local name = tooltip:AddRow("name")
|
||||
name:SetImportant()
|
||||
name:SetText("Average production rate")
|
||||
name:SizeToContents()
|
||||
|
||||
local info = tooltip:AddRow("info")
|
||||
info:SetText("Defines the rate of production in hours. If you'll leave this row with value of 1, the items from high production category will produce every hour.")
|
||||
info:SizeToContents()
|
||||
|
||||
tooltip:SizeToContents()
|
||||
end)
|
||||
avrg.OnValueChanged = function(s, value)
|
||||
self.actualTD.averageRateProduction = value
|
||||
end
|
||||
|
||||
local low = self:CreateOptionWang(productionPanel, "LOW PRODUCTION RATE", LEFT)
|
||||
low:SetValue(self.actualTD.lowRateProduction)
|
||||
low:GetParent():SetHelixTooltip(function(tooltip)
|
||||
local name = tooltip:AddRow("name")
|
||||
name:SetImportant()
|
||||
name:SetText("Low production rate")
|
||||
name:SizeToContents()
|
||||
|
||||
local info = tooltip:AddRow("info")
|
||||
info:SetText("Defines the rate of production in hours. If you'll leave this row with value of 1, the items from high production category will produce every hour.")
|
||||
info:SizeToContents()
|
||||
|
||||
tooltip:SizeToContents()
|
||||
end)
|
||||
low.OnValueChanged = function(s, value)
|
||||
self.actualTD.lowRateProduction = value
|
||||
end
|
||||
|
||||
self:CreateDivider(self.innerScroller, TOP)
|
||||
|
||||
local incomeText = self.innerScroller:Add("DLabel")
|
||||
incomeText:SetFont("CharCreationBoldTitleNoClamp")
|
||||
incomeText:Dock(TOP)
|
||||
incomeText:SetText("CREDIT INCOME")
|
||||
incomeText:DockMargin(0, SScaleMin(12 / 3), 0, 0)
|
||||
incomeText:SetContentAlignment(5)
|
||||
incomeText:SizeToContents()
|
||||
|
||||
local incomePanel = self.innerScroller:Add("Panel")
|
||||
incomePanel:Dock(TOP)
|
||||
incomePanel:SetHeight(SScaleMin(96 / 3))
|
||||
|
||||
local passiveIncome = incomePanel:Add("Panel")
|
||||
passiveIncome:Dock(LEFT)
|
||||
passiveIncome:SetWide(SScaleMin(225 / 3))
|
||||
passiveIncome:DockMargin(SScaleMin(64 / 3), 1, 0, 0)
|
||||
|
||||
local incomeWang = self:CreateOptionWang(passiveIncome, "Passive income in credits", FILL, "TitlesFontNoBoldNoClamp")
|
||||
incomeWang:SetValue(self.actualTD.passiveIncome)
|
||||
incomeWang.OnValueChanged = function(s, value)
|
||||
self.actualTD.passiveIncome = value
|
||||
end
|
||||
local passiveIncomeRate = incomePanel:Add("Panel")
|
||||
passiveIncomeRate:SetWide(SScaleMin(225 / 3))
|
||||
passiveIncomeRate:DockMargin(0, 1, SScaleMin(64 / 3), 0)
|
||||
passiveIncomeRate:Dock(RIGHT)
|
||||
|
||||
local rateWang = self:CreateOptionWang(passiveIncomeRate, "Passive income in hours", FILL, "TitlesFontNoBoldNoClamp")
|
||||
rateWang:SetValue(self.actualTD.passiveIncomeRate)
|
||||
rateWang.OnValueChanged = function(s, value)
|
||||
self.actualTD.passiveIncomeRate = value
|
||||
end
|
||||
|
||||
self:CreateDivider(self.innerScroller, TOP)
|
||||
|
||||
local saveChanges = self.innerScroller:Add("DButton")
|
||||
saveChanges:SetFont("MenuFontNoClamp")
|
||||
saveChanges:Dock(TOP)
|
||||
saveChanges:SetText("SAVE CHANGES")
|
||||
saveChanges:DockMargin(SScaleMin(96 / 3), SScaleMin(6 / 3), SScaleMin(96 / 3), SScaleMin(6 / 3))
|
||||
saveChanges:SetContentAlignment(5)
|
||||
saveChanges:SizeToContents()
|
||||
saveChanges.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(Color(0, 0, 0, 100))
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
surface.SetDrawColor(btnColor)
|
||||
surface.DrawOutlinedRect(0, 0, w, h)
|
||||
end
|
||||
saveChanges.DoClick = function(s)
|
||||
if !CheckItemRates(self.actualTD) then
|
||||
return LocalPlayer():NotifyLocalized("You've settuped item production variables in a wrong way. High rate must be not more than average, and low rate must be the biggest value.")
|
||||
end
|
||||
Derma_Query("Are you sure you want to save the changes you've made?", "SAVING CHANGES",
|
||||
"Yes", function()
|
||||
net.Start("ix.city.UpdateType")
|
||||
net.WriteString(util.TableToJSON(self.actualTD))
|
||||
net.SendToServer()
|
||||
end,
|
||||
"No", nil)
|
||||
end
|
||||
|
||||
self:CreateDivider(self.innerScroller, TOP)
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
surface.SetDrawColor(63, 58, 115, 220)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
Derma_DrawBackgroundBlur(self, 1)
|
||||
end
|
||||
|
||||
vgui.Register("ixCtEditor", PANEL, "Panel")
|
||||
546
gamemodes/ixhl2rp/plugins/goi_cityfunds/derma/cl_fundmanager.lua
Normal file
546
gamemodes/ixhl2rp/plugins/goi_cityfunds/derma/cl_fundmanager.lua
Normal file
@@ -0,0 +1,546 @@
|
||||
--[[
|
||||
| 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:AddCityToList(cityID, parent, cityData)
|
||||
local pnl = parent:Add("DButton")
|
||||
pnl:Dock(TOP)
|
||||
pnl:DockMargin(SScaleMin(6 / 3), SScaleMin(6 / 3), SScaleMin(6 / 3), 0)
|
||||
pnl:SetFont("TitlesFontNoClamp")
|
||||
pnl:SetText(cityID != "1" and "CITY-" .. cityID or "CITY-" .. ix.config.Get("mainCityNumber", 24))
|
||||
pnl:SetHeight(SScaleMin(32 / 3))
|
||||
pnl.cityData = cityData
|
||||
pnl.DoClick = function(s)
|
||||
self:BuildEditor(cityID == "1", s.cityData)
|
||||
|
||||
surface.PlaySound("willardnetworks/charactercreation/boop" .. math.random(1, 3) .. ".wav")
|
||||
end
|
||||
pnl.DoRightClick = function(s)
|
||||
if s.cityData.id == "1" then
|
||||
return
|
||||
end
|
||||
|
||||
local menu = DermaMenu()
|
||||
menu:AddOption( "Remove", function()
|
||||
Derma_Query("Are you sure you want to remove this city?", "REMOVING CITY",
|
||||
"Yes", function()
|
||||
net.Start("ix.city.RemoveCity")
|
||||
net.WriteString(s.cityData.id)
|
||||
net.SendToServer()
|
||||
self.cities[s.cityData.id] = nil
|
||||
if (self.cityData.id == s.cityData.id and self.editorPanel) then
|
||||
self.cityData.id:Remove()
|
||||
end
|
||||
s:Remove()
|
||||
surface.PlaySound("willardnetworks/datapad/close.wav")
|
||||
end,
|
||||
"No", nil)
|
||||
end)
|
||||
menu:Open()
|
||||
end
|
||||
|
||||
self.cityList[#self.cityList + 1] = pnl
|
||||
return pnl
|
||||
end
|
||||
|
||||
function PANEL:CreateButton(parent, text, color, callback)
|
||||
parent:Dock(TOP)
|
||||
parent:SetText(text)
|
||||
parent:SetHeight(SScaleMin(36 / 3))
|
||||
parent:DockMargin(SScaleMin(8 / 3), SScaleMin(6 / 3), 0, 0)
|
||||
parent:SetFont("MenuFontNoClamp")
|
||||
parent.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(Color(0, 0, 0, 100))
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
surface.SetDrawColor(color)
|
||||
surface.DrawOutlinedRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
parent.DoClick = function()
|
||||
surface.PlaySound("helix/ui/press.wav")
|
||||
callback()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:RequestPopulate()
|
||||
net.Start("ix.city.PopulateFunds")
|
||||
net.SendToServer()
|
||||
end
|
||||
|
||||
function PANEL:Populate(data)
|
||||
self.cities = data
|
||||
for index, city in pairs(self.cities) do
|
||||
self:AddCityToList(city.id, self.cityListFrame, city)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:CreateLabeledNumWang(parent, text, dock, icon)
|
||||
local pnl = parent:Add("Panel")
|
||||
pnl:Dock(dock)
|
||||
pnl:DockMargin(SScaleMin(6 / 3), SScaleMin(6 / 3), SScaleMin(6 / 3), SScaleMin(6 / 3))
|
||||
pnl:SetWide(parent:GetWide() * 0.84)
|
||||
|
||||
local label = pnl:Add("DLabel")
|
||||
label:SetFont("SubtitleFont")
|
||||
label:Dock(TOP)
|
||||
label:SetText(text)
|
||||
label:SetContentAlignment(5)
|
||||
label:SizeToContents()
|
||||
|
||||
local iconP = pnl:Add("Panel")
|
||||
iconP:Dock(TOP)
|
||||
iconP:SetHeight(SScaleMin(16 / 3))
|
||||
iconP:DockMargin(0, SScaleMin(6 / 3), 0, 0)
|
||||
iconP.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(255, 255, 255)
|
||||
surface.SetMaterial(icon)
|
||||
surface.DrawTexturedRect(w * .35, 0, 16, 16)
|
||||
end
|
||||
|
||||
local numWang = pnl:Add("DNumberWang")
|
||||
numWang:Dock(BOTTOM)
|
||||
numWang:SetMax(9999)
|
||||
numWang.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawOutlinedRect(0, 0, w, h, 1)
|
||||
|
||||
draw.SimpleText(s:GetValue(), "SubtitleFont", w * 0.25, h * 0.15)
|
||||
end
|
||||
|
||||
return numWang
|
||||
end
|
||||
|
||||
local priceMat = Material("willardnetworks/tabmenu/charmenu/chips.png", "smooth")
|
||||
local amountMat = Material("willardnetworks/tabmenu/navicons/inventory.png", "smooth")
|
||||
local mulTDMat = Material("willardnetworks/tabmenu/crafting/plus.png", "smooth")
|
||||
local redTDMat = Material("willardnetworks/tabmenu/crafting/minus.png", "smooth")
|
||||
|
||||
function PANEL:CreateItemButton(itemID, parent, data, isMain)
|
||||
if (!self.cityData.items[itemID] or parent.items[itemID]) then
|
||||
return LocalPlayer():NotifyLocalized("Item already exists or its invalid.")
|
||||
end
|
||||
|
||||
parent.items[itemID] = true
|
||||
|
||||
local button = parent:Add("DButton")
|
||||
button:SetContentAlignment(5)
|
||||
button:SetFont("LargerTitlesFontNoClamp")
|
||||
button:SetText(ix.item.list[itemID].name)
|
||||
button:Dock(TOP)
|
||||
button:SetHeight(SScaleMin(64 / 3))
|
||||
button:DockMargin(SScaleMin(6 / 3), SScaleMin(6 / 3), SScaleMin(6 / 3), 0)
|
||||
|
||||
local icon = button:Add("SpawnIcon")
|
||||
icon:SetModel(ix.item.list[itemID].model)
|
||||
icon:Dock(LEFT)
|
||||
|
||||
local adjustment = parent:Add("Panel")
|
||||
adjustment:Dock(TOP)
|
||||
adjustment:DockMargin(SScaleMin(6 / 3), 0, SScaleMin(6 / 3), 0)
|
||||
adjustment:SetHeight(SScaleMin(112 / 3))
|
||||
adjustment.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(8, 8, 8, 130)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawOutlinedRect(0, 0, w, h, 1)
|
||||
end
|
||||
|
||||
local amount = self:CreateLabeledNumWang(adjustment, "Amount", LEFT, amountMat)
|
||||
amount:GetParent():SetHelixTooltip(function(tooltip)
|
||||
local name = tooltip:AddRow("name")
|
||||
name:SetImportant()
|
||||
name:SetText("Amount")
|
||||
name:SizeToContents()
|
||||
|
||||
local info = tooltip:AddRow("info")
|
||||
info:SetText("Current accessable amount of this item.")
|
||||
info:SizeToContents()
|
||||
|
||||
tooltip:SizeToContents()
|
||||
end)
|
||||
amount.OnValueChanged = function(s, value)
|
||||
self.cityData.items[itemID].amount = value
|
||||
end
|
||||
amount:SetValue(data and data.amount or 0)
|
||||
self.cityData.items[itemID].amount = amount:GetValue()
|
||||
|
||||
if (!isMain) then
|
||||
local price = self:CreateLabeledNumWang(adjustment, "Price", LEFT, priceMat)
|
||||
price:GetParent():SetHelixTooltip(function(tooltip)
|
||||
local name = tooltip:AddRow("name")
|
||||
name:SetImportant()
|
||||
name:SetText("Price")
|
||||
name:SizeToContents()
|
||||
|
||||
local info = tooltip:AddRow("info")
|
||||
info:SetText("This is default price of an item not affected by abundance and lack thresholds.")
|
||||
info:SizeToContents()
|
||||
|
||||
tooltip:SizeToContents()
|
||||
end)
|
||||
price.OnValueChanged = function(s, value)
|
||||
self.cityData.items[itemID].price = value
|
||||
end
|
||||
price:SetValue(data and data.price or 0)
|
||||
self.cityData.items[itemID].price = price:GetValue()
|
||||
|
||||
local mulTD = self:CreateLabeledNumWang(adjustment, "Mul.TD", LEFT, mulTDMat)
|
||||
mulTD:GetParent():SetHelixTooltip(function(tooltip)
|
||||
local name = tooltip:AddRow("name")
|
||||
name:SetImportant()
|
||||
name:SetText("Lack threshold")
|
||||
name:SizeToContents()
|
||||
|
||||
local info = tooltip:AddRow("info")
|
||||
info:SetText("How many of this items must be in stock to consider them 'lacking'. If item amount is lower than this value - then its price multiplicates by P.Mul value.")
|
||||
info:SizeToContents()
|
||||
|
||||
tooltip:SizeToContents()
|
||||
end)
|
||||
mulTD:SetValue(data and data.priceMulptiplicationTD or 10)
|
||||
self.cityData.items[itemID].priceMulptiplicationTD = mulTD:GetValue()
|
||||
mulTD.OnValueChanged = function(s, value)
|
||||
self.cityData.items[itemID].priceMulptiplicationTD = value
|
||||
end
|
||||
local redTD = self:CreateLabeledNumWang(adjustment, "Red.TD", LEFT, redTDMat)
|
||||
redTD:GetParent():SetHelixTooltip(function(tooltip)
|
||||
local name = tooltip:AddRow("name")
|
||||
name:SetImportant()
|
||||
name:SetText("Abundance threshold")
|
||||
name:SizeToContents()
|
||||
|
||||
local info = tooltip:AddRow("info")
|
||||
info:SetText("How many of this items must be in stock to consider them 'abundant'. If item amount is more than this value - then its price divides by P.Div value.")
|
||||
info:SizeToContents()
|
||||
|
||||
tooltip:SizeToContents()
|
||||
end)
|
||||
redTD:SetValue(data and data.priceReductionTD or 90)
|
||||
self.cityData.items[itemID].priceReductionTD = redTD:GetValue()
|
||||
redTD.OnValueChanged = function(s, value)
|
||||
self.cityData.items[itemID].priceReductionTD = value
|
||||
end
|
||||
local pMul = self:CreateLabeledNumWang(adjustment, "P.Mul", LEFT, mulTDMat)
|
||||
pMul:SetValue(data and data.priceMul or 2)
|
||||
self.cityData.items[itemID].priceMul = pMul:GetValue()
|
||||
pMul.OnValueChanged = function(s, value)
|
||||
self.cityData.items[itemID].priceMul = value
|
||||
end
|
||||
local pDiv = self:CreateLabeledNumWang(adjustment, "P.Div", LEFT, redTDMat)
|
||||
pDiv:SetValue(data and data.priceDiv or 2)
|
||||
self.cityData.items[itemID].priceDiv = pDiv:GetValue()
|
||||
pDiv.OnValueChanged = function(s, value)
|
||||
self.cityData.items[itemID].priceDiv = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:CreateDivider(parent, dock)
|
||||
local divider = parent:Add("Panel")
|
||||
divider:Dock(dock)
|
||||
divider:SetHeight(SScaleMin(10 / 3))
|
||||
divider.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawLine(0, h * 0.5, w, h * 0.5)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:AddItemToCityData(itemID)
|
||||
self.cityData.items[itemID] = {}
|
||||
end
|
||||
|
||||
function PANEL:BuildEditor(isMain, cityData)
|
||||
if IsValid(self.editorPanel) then
|
||||
self.editorPanel:Remove()
|
||||
end
|
||||
|
||||
self.cityData = {}
|
||||
self.cityData = cityData
|
||||
|
||||
self.editorPanel = self.cityPanel:Add("DScrollPanel")
|
||||
self.editorPanel:Dock(FILL)
|
||||
|
||||
local cityID = cityData.id
|
||||
local cityName = self.editorPanel:Add("DLabel")
|
||||
cityName:SetFont("TitlesFontNoBoldNoClamp")
|
||||
cityName:Dock(TOP)
|
||||
cityName:SetText(cityID != "1" and "CITY-" .. cityID or "CITY-" .. ix.config.Get("mainCityNumber", 24))
|
||||
cityName:SetContentAlignment(5)
|
||||
cityName:SizeToContents()
|
||||
|
||||
self:CreateDivider(self.editorPanel, TOP)
|
||||
if (!isMain) then
|
||||
local type = self.editorPanel:Add("DLabel")
|
||||
type:SetFont("TitlesFontNoBoldNoClamp")
|
||||
type:Dock(TOP)
|
||||
type:SetText("TYPE")
|
||||
type:SetContentAlignment(5)
|
||||
type:SizeToContents()
|
||||
|
||||
local curType = self.editorPanel:Add("DLabel")
|
||||
curType:SetFont("MenuFontOutlined")
|
||||
curType:SetText(cityData.type.name and "CURRENT TYPE: " .. cityData.type.name or "THIS CITY DON'T HAVE ANY TYPE YET")
|
||||
curType:Dock(TOP)
|
||||
curType:SizeToContents()
|
||||
|
||||
local typeButton = self.editorPanel:Add("DButton")
|
||||
self:CreateButton(typeButton, "CHANGE TYPE", Color(111, 111, 136, 255), function()
|
||||
local types = DermaMenu()
|
||||
for index, t in pairs(self.types) do
|
||||
types:AddOption(index, function()
|
||||
cityData.type = self.types[index]
|
||||
curType:SetText(cityData.type and "CURRENT TYPE: " .. cityData.type.name)
|
||||
curType:SizeToContents()
|
||||
end)
|
||||
end
|
||||
types:Open()
|
||||
end)
|
||||
typeButton:DockMargin(0, SScaleMin(16 / 3), 0, SScaleMin(16 / 3))
|
||||
typeButton:SetHeight(SScaleMin(29 / 3))
|
||||
|
||||
|
||||
self:CreateDivider(self.editorPanel, TOP)
|
||||
|
||||
local items = self.editorPanel:Add("DLabel")
|
||||
items:SetFont("TitlesFontNoBoldNoClamp")
|
||||
items:Dock(TOP)
|
||||
items:SetText("ITEMS")
|
||||
items:SetContentAlignment(5)
|
||||
items:SizeToContents()
|
||||
end
|
||||
|
||||
self.itemsPanel = self.editorPanel:Add("DScrollPanel")
|
||||
self.itemsPanel:Dock(TOP)
|
||||
self.itemsPanel:SetHeight(SScaleMin(400 / 3))
|
||||
self.itemsPanel.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawOutlinedRect(0, 0, w, h, 2)
|
||||
end
|
||||
self.itemsPanel.items = {}
|
||||
|
||||
for item, itemTbl in pairs(self.cityData.items) do
|
||||
self:CreateItemButton(item, self.itemsPanel, itemTbl, isMain)
|
||||
end
|
||||
|
||||
local createItemButton = self.editorPanel:Add("DButton")
|
||||
self:CreateButton(createItemButton, "ADD ITEM", Color(111, 111, 136, 255), function()
|
||||
Derma_StringRequest("Item ID", "Insert item's ID you want to add here.", "", function(text)
|
||||
if !ix.item.list[text] then
|
||||
return LocalPlayer():NotifyLocalized("Wrong item ID.")
|
||||
end
|
||||
self:AddItemToCityData(text)
|
||||
self:CreateItemButton(text, self.itemsPanel, nil, isMain)
|
||||
end)
|
||||
end)
|
||||
createItemButton:DockMargin(0, SScaleMin(16 / 3), 0, SScaleMin(16 / 3))
|
||||
createItemButton:SetHeight(SScaleMin(29 / 3))
|
||||
|
||||
self:CreateDivider(self.editorPanel, TOP)
|
||||
|
||||
local credits = self.editorPanel:Add("DLabel")
|
||||
credits:SetFont("TitlesFontNoBoldNoClamp")
|
||||
credits:Dock(TOP)
|
||||
credits:SetText("CREDITS")
|
||||
credits:SetContentAlignment(5)
|
||||
credits:SizeToContents()
|
||||
|
||||
local credPanel = self.editorPanel:Add("Panel")
|
||||
credPanel:Dock(TOP)
|
||||
credPanel:SetHeight(SScaleMin(24 / 3))
|
||||
credPanel:DockMargin(0, SScaleMin(8 / 3), 0, 0)
|
||||
|
||||
local credLabel = credPanel:Add("DLabel")
|
||||
credLabel:SetFont("TitlesFontNoBoldNoClamp")
|
||||
credLabel:Dock(LEFT)
|
||||
credLabel:SetText("CITY CREDITS:")
|
||||
credLabel:SetContentAlignment(4)
|
||||
credLabel:SizeToContents()
|
||||
|
||||
local credWang = credPanel:Add("DNumberWang")
|
||||
credWang:Dock(LEFT)
|
||||
credWang:SetMax(999999)
|
||||
credWang:DockMargin(SScaleMin(8 / 3), 0, 0, 0)
|
||||
credWang.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawOutlinedRect(0, 0, w, h, 1)
|
||||
|
||||
draw.SimpleText(s:GetValue(), "SubtitleFont", w * 0.25, h * 0.15)
|
||||
end
|
||||
credWang.OnValueChanged = function(s, value)
|
||||
self.cityData.credits = value
|
||||
end
|
||||
credWang:SetValue(self.cityData.credits or 0)
|
||||
|
||||
self:CreateDivider(self.editorPanel, TOP)
|
||||
|
||||
local saveChangesButton = self.editorPanel:Add("DButton")
|
||||
self:CreateButton(saveChangesButton, "SAVE CHANGES", Color(111, 111, 136, 255), function()
|
||||
Derma_Query("Are you sure you want to save the changes you've made?", "SAVING CHANGES",
|
||||
"Yes", function()
|
||||
net.Start("ix.city.UpdateCity")
|
||||
net.WriteString(util.TableToJSON(self.cityData))
|
||||
net.WriteBool(isMain)
|
||||
net.SendToServer()
|
||||
end,
|
||||
"No", nil)
|
||||
end)
|
||||
saveChangesButton:DockMargin(0, SScaleMin(16 / 3), 0, SScaleMin(16 / 3))
|
||||
saveChangesButton:SetHeight(SScaleMin(29 / 3))
|
||||
end
|
||||
|
||||
function PANEL:Init()
|
||||
if (ix.gui.fundManager and ix.gui.fundManager != self) then
|
||||
ix.gui.fundManager:Remove()
|
||||
end
|
||||
|
||||
if (ix.gui.ctEditor and IsValid(ix.gui.ctEditor)) then
|
||||
ix.gui.ctEditor:Remove()
|
||||
end
|
||||
|
||||
ix.gui.fundManager = self
|
||||
|
||||
self:SetSize(ScrW(), ScrH())
|
||||
self:SetAlpha(0)
|
||||
self:AlphaTo(255, 0.5, 0)
|
||||
|
||||
self.cityList = {}
|
||||
self.cityData = {}
|
||||
|
||||
self.innerContent = self:Add("Panel")
|
||||
self.innerContent:SetSize(SScaleMin(900 / 3), SScaleMin(640 / 3))
|
||||
self.innerContent:Center()
|
||||
self.innerContent:MakePopup()
|
||||
self.innerContent.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(0, 0, 0, 130)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawLine(w * 0.5, SScaleMin(40 / 3), w * 0.5, h)
|
||||
end
|
||||
|
||||
self.topbar = self.innerContent:Add("Panel")
|
||||
self.topbar:SetHeight(SScaleMin(40 / 3))
|
||||
self.topbar:Dock(TOP)
|
||||
self.topbar.Paint = function(s, width, height)
|
||||
surface.SetDrawColor(8, 8, 8, 130)
|
||||
surface.DrawRect(0, 0, width, height)
|
||||
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawLine(0, height * 0.95, width, height * 0.95)
|
||||
end
|
||||
|
||||
local exit = self.topbar:Add("DImageButton")
|
||||
exit:SetMaterial(Material("willardnetworks/tabmenu/navicons/exit.png", "smooth"))
|
||||
exit:SetSize(SScaleMin(25 / 3), SScaleMin(20 / 3))
|
||||
exit:DockMargin(0, SScaleMin(6 / 3), SScaleMin(6 / 3), SScaleMin(6 / 3))
|
||||
exit:Dock(RIGHT)
|
||||
exit.DoClick = function()
|
||||
self:Remove()
|
||||
surface.PlaySound("helix/ui/press.wav")
|
||||
end
|
||||
|
||||
local titleText = self.topbar:Add("DLabel")
|
||||
titleText:SetFont("CharCreationBoldTitleNoClamp")
|
||||
titleText:Dock(LEFT)
|
||||
titleText:SetText("City Fund Manager")
|
||||
titleText:DockMargin(SScaleMin(10 / 3), 0, 0, 0)
|
||||
titleText:SetContentAlignment(4)
|
||||
titleText:SizeToContents()
|
||||
|
||||
self.cityListPanel = self.innerContent:Add("Panel")
|
||||
self.cityListPanel:Dock(LEFT)
|
||||
self.cityListPanel:DockMargin(SScaleMin(12 / 3), SScaleMin(6 / 3), 0, SScaleMin(6 / 3))
|
||||
self.cityListPanel:SetWide(SScaleMin(400 / 3))
|
||||
|
||||
self.cityPanel = self.innerContent:Add("Panel")
|
||||
self.cityPanel:Dock(FILL)
|
||||
self.cityPanel:DockMargin(SScaleMin(48 / 3), SScaleMin(16 / 3), SScaleMin(16 / 3), SScaleMin(16 / 3))
|
||||
|
||||
self.citiesLabel = self.cityListPanel:Add("DLabel")
|
||||
self.citiesLabel:SetFont("TitlesFontNoBoldNoClamp")
|
||||
self.citiesLabel:Dock(TOP)
|
||||
self.citiesLabel:SetText("CITIES")
|
||||
self.citiesLabel:DockMargin(SScaleMin(8 / 3), SScaleMin(16 / 3), 0, 0)
|
||||
self.citiesLabel:SetContentAlignment(5)
|
||||
self.citiesLabel:SizeToContents()
|
||||
|
||||
self.cityListFrame = self.cityListPanel:Add("DScrollPanel")
|
||||
self.cityListFrame:Dock(TOP)
|
||||
self.cityListFrame:DockMargin(SScaleMin(8 / 3), 1, 0, 0)
|
||||
self.cityListFrame:SetHeight(SScaleMin(400 / 3))
|
||||
self.cityListFrame.Paint = function(s, w, h)
|
||||
surface.SetDrawColor(111, 111, 136, 76)
|
||||
surface.DrawOutlinedRect(0, 0, w, h, 2)
|
||||
end
|
||||
|
||||
self.cityCreate = self.cityListPanel:Add("DButton")
|
||||
self:CreateButton(self.cityCreate, "Create city", Color(111, 111, 136, 255), function()
|
||||
local cityNumber
|
||||
local cityType
|
||||
Derma_StringRequest("City number", "Insert city number here.", "", function(text)
|
||||
text = tonumber(text)
|
||||
if self.cities[text] or !text then
|
||||
return LocalPlayer():NotifyLocalized("City with this number already exists or you've entered words instead of number.")
|
||||
end
|
||||
cityNumber = tostring(text)
|
||||
Derma_StringRequest("City type", "Insert city type ID here. It must be accurate.", "", function(typeID)
|
||||
if !self.types[typeID] then
|
||||
return LocalPlayer():NotifyLocalized("Type doesn't exist.")
|
||||
end
|
||||
cityType = typeID
|
||||
net.Start("ix.city.CreateCity")
|
||||
net.WriteString(cityNumber)
|
||||
net.WriteString(cityType)
|
||||
net.SendToServer()
|
||||
|
||||
net.Start("ix.city.RequestUpdateCities")
|
||||
net.SendToServer()
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
self.switchToType = self.cityListPanel:Add("DButton")
|
||||
self:CreateButton(self.switchToType, "Switch to type editor", Color(111, 111, 136, 255), function()
|
||||
local ctEditor = vgui.Create("ixCtEditor")
|
||||
ctEditor.typeData = self.types
|
||||
ctEditor:Populate()
|
||||
self:Remove()
|
||||
end)
|
||||
|
||||
self:RequestPopulate()
|
||||
end
|
||||
|
||||
function PANEL:UpdateCities(newTbl)
|
||||
self.cities = newTbl
|
||||
|
||||
for _, pnl in pairs(self.cityList) do
|
||||
pnl:Remove()
|
||||
end
|
||||
|
||||
if IsValid(self.editorPanel) then
|
||||
self.editorPanel:Remove()
|
||||
end
|
||||
|
||||
for index, city in pairs(self.cities) do
|
||||
self:AddCityToList(city.id, self.cityListFrame, city)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:Paint(w, h)
|
||||
surface.SetDrawColor(63, 58, 115, 220)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
|
||||
Derma_DrawBackgroundBlur(self, 1)
|
||||
end
|
||||
|
||||
vgui.Register("ixFundManager", PANEL, "Panel")
|
||||
84
gamemodes/ixhl2rp/plugins/goi_cityfunds/libs/sh_city.lua
Normal file
84
gamemodes/ixhl2rp/plugins/goi_cityfunds/libs/sh_city.lua
Normal file
@@ -0,0 +1,84 @@
|
||||
--[[
|
||||
| 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 pairs = pairs
|
||||
local string = string
|
||||
local isnumber = isnumber
|
||||
local util = util
|
||||
local net = net
|
||||
|
||||
ix.city = ix.city or {}
|
||||
ix.city.list = ix.city.list or {}
|
||||
ix.city.main = ix.city.main or false
|
||||
|
||||
ix.city.types = ix.city.types or {}
|
||||
ix.city.types.list = ix.city.types.list or {}
|
||||
|
||||
ix.city.cwuAccess = {
|
||||
["Member"] = {
|
||||
creditInteraction = false,
|
||||
budgetInteraction = false,
|
||||
marketInteraction = false,
|
||||
stockInteraction = true
|
||||
},
|
||||
["Management"] = {
|
||||
creditInteraction = false,
|
||||
budgetInteraction = true,
|
||||
marketInteraction = true,
|
||||
stockInteraction = true
|
||||
},
|
||||
["Logistics"] = {
|
||||
creditInteraction = false,
|
||||
budgetInteraction = false,
|
||||
marketInteraction = true,
|
||||
stockInteraction = true
|
||||
}
|
||||
}
|
||||
|
||||
function ix.city:TranslateCardLevel(cwuCard)
|
||||
local accessLevel = cwuCard:GetData("accessLevel", "Member Access")
|
||||
|
||||
for reqAcLevel, perms in pairs(ix.city.cwuAccess) do
|
||||
local s1, s2 = string.find(accessLevel, reqAcLevel)
|
||||
|
||||
if !isnumber(s1) or !isnumber(s2) then continue end
|
||||
|
||||
local level = string.sub( reqAcLevel, s1, s2 )
|
||||
|
||||
return level
|
||||
end
|
||||
end
|
||||
|
||||
function ix.city:IsAccessable(cwuCard, interaction)
|
||||
if !cwuCard then return false end
|
||||
|
||||
local accessLevel = ix.city:TranslateCardLevel(cwuCard)
|
||||
|
||||
if ix.city.cwuAccess[accessLevel] and ix.city.cwuAccess[accessLevel][interaction] then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
function ix.city:SyncCityStock(client)
|
||||
local cityStock = util.TableToJSON(ix.city.main.items)
|
||||
|
||||
net.Start("ix.city.SyncCityStock")
|
||||
net.WriteString(cityStock)
|
||||
net.Send(client)
|
||||
end
|
||||
else
|
||||
function ix.city:SyncCityStock()
|
||||
net.Start("ix.city.SyncCityStock")
|
||||
net.SendToServer()
|
||||
end
|
||||
end
|
||||
39
gamemodes/ixhl2rp/plugins/goi_cityfunds/libs/sh_fbudget.lua
Normal file
39
gamemodes/ixhl2rp/plugins/goi_cityfunds/libs/sh_fbudget.lua
Normal file
@@ -0,0 +1,39 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
ix.factionBudget = ix.factionBudget or {}
|
||||
ix.factionBudget.list = ix.factionBudget.list or {}
|
||||
|
||||
function ix.factionBudget:RegisterFB(id, factionName)
|
||||
if !isstring(id) then return end
|
||||
id = string.utf8upper(id)
|
||||
|
||||
ix.factionBudget.list[id] = {
|
||||
id = id,
|
||||
name = factionName,
|
||||
credits = 0
|
||||
}
|
||||
end
|
||||
|
||||
function ix.factionBudget:GetFB(id)
|
||||
return ix.factionBudget.list[id]
|
||||
end
|
||||
|
||||
-- never use "INF" in any case. it breaks every faction with any ID that is "INF".
|
||||
|
||||
function ix.factionBudget:InitializeFactionBudgets()
|
||||
ix.factionBudget:RegisterFB("CWRU", "Research Union")
|
||||
ix.factionBudget:RegisterFB("CWU", "Civil Workers Union")
|
||||
ix.factionBudget:RegisterFB("CPU", "Civil Protection")
|
||||
ix.factionBudget:RegisterFB("CCA", "Civil Administration")
|
||||
ix.factionBudget:RegisterFB("CMU", "Medical Union")
|
||||
ix.factionBudget:RegisterFB("BOE", "Enlightenment")
|
||||
ix.factionBudget:RegisterFB("SCO", "Security Council")
|
||||
end
|
||||
357
gamemodes/ixhl2rp/plugins/goi_cityfunds/libs/sv_city.lua
Normal file
357
gamemodes/ixhl2rp/plugins/goi_cityfunds/libs/sv_city.lua
Normal file
@@ -0,0 +1,357 @@
|
||||
--[[
|
||||
| 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 isstring = isstring
|
||||
local setmetatable = setmetatable
|
||||
local isnumber = isnumber
|
||||
local tostring = tostring
|
||||
local util = util
|
||||
local table = table
|
||||
local pairs = pairs
|
||||
local ents = ents
|
||||
local net = net
|
||||
local istable = istable
|
||||
local tonumber = tonumber
|
||||
|
||||
ix.city.disallowments = ix.city.disallowments or {}
|
||||
ix.city.combineRestrictions = ix.city.combineRestrictions or {}
|
||||
|
||||
function ix.city:UpdateCityFunds()
|
||||
for index, city in pairs(ix.city.list) do
|
||||
if city:IsMain() then
|
||||
city:IncrementLoanProgress()
|
||||
end
|
||||
if !city.type then continue end
|
||||
city:HandleItemConsumption()
|
||||
city:IncrementProductionProgress()
|
||||
city:IncrementIncomeProgress()
|
||||
end
|
||||
end
|
||||
|
||||
function ix.city:AddDisallowment(itemID)
|
||||
if !isstring(itemID) then return end
|
||||
|
||||
ix.city.disallowments[itemID] = true
|
||||
end
|
||||
|
||||
function ix.city:IsDisallowment(itemID)
|
||||
return ix.city.disallowments[itemID] or false
|
||||
end
|
||||
|
||||
function ix.city:AddCombineRestriction(itemID)
|
||||
if !isstring(itemID) then return end
|
||||
|
||||
ix.city.combineRestrictions[itemID] = true
|
||||
end
|
||||
|
||||
function ix.city:IsCombineRestricted(itemID)
|
||||
return ix.city.combineRestrictions[itemID] or false
|
||||
end
|
||||
|
||||
|
||||
function ix.city:InitializeMainCity()
|
||||
local city = setmetatable({
|
||||
id = "1",
|
||||
credits = 0,
|
||||
type = {},
|
||||
items = {},
|
||||
loan = 0,
|
||||
loanRate = 0
|
||||
}, ix.meta.city)
|
||||
ix.city.main = city
|
||||
|
||||
ix.city:AddCityData("1", city)
|
||||
|
||||
return city
|
||||
end
|
||||
|
||||
function ix.city:CreateCity(id, type)
|
||||
if isnumber(id) then id = tostring(id) end
|
||||
if !ix.city.types.list[type] then return end
|
||||
if ix.city.list[id] or ix.city.main:GetID() == id then return end
|
||||
type = ix.city.types.list[type]
|
||||
|
||||
local city = setmetatable({
|
||||
id = id,
|
||||
credits = 0,
|
||||
type = type or {},
|
||||
items = {},
|
||||
loan = 0,
|
||||
loanRate = 0
|
||||
}, ix.meta.city)
|
||||
city:OnCreated()
|
||||
ix.city.list[id] = city
|
||||
|
||||
|
||||
ix.city:AddCityData(id, city)
|
||||
|
||||
return city
|
||||
end
|
||||
|
||||
function ix.city:LoadType(name, data)
|
||||
ix.city.types.list[name] = {
|
||||
name = name,
|
||||
itemsHighRate = data.itemsHighRate,
|
||||
itemsLowRate = data.itemsLowRate,
|
||||
itemsAverageRate = data.itemsAverageRate,
|
||||
highRateProduction = data.highRateProduction,
|
||||
lowRateProduction = data.lowRateProduction,
|
||||
averageRateProduction = data.averageRateProduction,
|
||||
passiveIncome = data.passiveIncome,
|
||||
passiveIncomeRate = data.passiveIncomeRate
|
||||
}
|
||||
|
||||
return ix.city.types.list[name]
|
||||
end
|
||||
|
||||
function ix.city:LoadCity(id, tbl)
|
||||
if isnumber(id) then id = tostring(id) end
|
||||
|
||||
local city = setmetatable({
|
||||
id = id,
|
||||
credits = tbl.credits,
|
||||
type = tbl.type,
|
||||
items = tbl.items,
|
||||
loan = tbl.loan
|
||||
}, ix.meta.city)
|
||||
ix.city.list[id] = city
|
||||
|
||||
return city
|
||||
end
|
||||
|
||||
function ix.city:LoadMainCity(tbl)
|
||||
local mainCity = ix.city.main and ix.city.main or setmetatable({
|
||||
id = "1",
|
||||
credits = tbl.credits,
|
||||
type = {},
|
||||
items = tbl.items,
|
||||
loan = tbl.loan
|
||||
}, ix.meta.city)
|
||||
ix.city.main = mainCity
|
||||
|
||||
return mainCity
|
||||
end
|
||||
|
||||
function ix.city:GetCity(id)
|
||||
return id != "1" and ix.city.list[id] or ix.city:GetMainCity()
|
||||
end
|
||||
|
||||
function ix.city:Remove(id)
|
||||
if ix.city.list[id] then ix.city.list[id] = nil end
|
||||
|
||||
ix.city:DeleteCity(id)
|
||||
end
|
||||
|
||||
function ix.city:IsMain(city)
|
||||
if isstring(city) and city == "1" or city == ix.city.main then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function ix.city:GetMainCity()
|
||||
return ix.city.main
|
||||
end
|
||||
|
||||
function ix.city.types:RegisterType(name, tbl)
|
||||
if ix.city.types.list[name] then return end
|
||||
|
||||
-- Rates here stands for time in hours.
|
||||
local type = {
|
||||
name = name,
|
||||
itemsHighRate = tbl.itemsHighRate,
|
||||
itemsLowRate = tbl.itemsLowRate,
|
||||
itemsAverageRate = tbl.itemsAverageRate,
|
||||
highRateProduction = tbl.highRateProduction,
|
||||
lowRateProduction = tbl.lowRateProduction,
|
||||
averageRateProduction = tbl.averageRateProduction,
|
||||
passiveIncome = tbl.passiveIncome,
|
||||
passiveIncomeRate = tbl.passiveIncomeRate
|
||||
}
|
||||
ix.city.types.list[name] = type
|
||||
|
||||
ix.city:AddTypeData(name, type)
|
||||
end
|
||||
|
||||
function ix.city:AddCityData(id, city)
|
||||
local queryAdd = mysql:Insert("ix_cities")
|
||||
queryAdd:Insert("ct_id", id)
|
||||
queryAdd:Insert("ct_credits", city:GetCredits())
|
||||
queryAdd:Insert("ct_type", util.TableToJSON(city:GetType()))
|
||||
queryAdd:Insert("ct_items", util.TableToJSON(city.items))
|
||||
queryAdd:Insert("ct_loan", city:GetLoan())
|
||||
queryAdd:Insert("ct_loanRate", city.loanRate)
|
||||
queryAdd:Execute()
|
||||
end
|
||||
|
||||
function ix.city:UpdateCity(id)
|
||||
if !isstring(id) then id = id:GetID() end
|
||||
local city = id != "1" and ix.city.list[id] or ix.city.main
|
||||
|
||||
local queryUpdate = mysql:Update("ix_cities")
|
||||
queryUpdate:Where("ct_id", id)
|
||||
queryUpdate:Update("ct_credits", city:GetCredits())
|
||||
queryUpdate:Update("ct_type", util.TableToJSON(city:GetType() or {}))
|
||||
queryUpdate:Update("ct_items", util.TableToJSON(city.items))
|
||||
queryUpdate:Update("ct_loan", city:GetLoan())
|
||||
queryUpdate:Update("ct_loanRate", city.loanRate)
|
||||
queryUpdate:Execute()
|
||||
|
||||
-- update main city on all terminals (main cities are refreshing automatically)
|
||||
if id == "1" then
|
||||
ix.city:UpdateCWUTerminals()
|
||||
end
|
||||
end
|
||||
|
||||
function ix.city:UpdateCWUTerminals()
|
||||
local dataToSend = table.Copy(ix.city.main)
|
||||
dataToSend.factionBudgets = ix.factionBudget.list
|
||||
|
||||
for _, terminal in pairs(ents.FindByClass("ix_cwuterminal")) do
|
||||
|
||||
local client = terminal:GetUsedBy()
|
||||
|
||||
if client and client:IsPlayer() and terminal.curGenData then
|
||||
net.Start("ix.terminal.UpdateCWUTerminals")
|
||||
net.WriteString(util.TableToJSON(dataToSend))
|
||||
net.WriteEntity(terminal)
|
||||
net.Send(terminal:GetUsedBy())
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
-- debug function
|
||||
function ix.city:LoadCityData(id)
|
||||
if !isstring(id) then id = id:GetID() end
|
||||
local queryLoad = mysql:Select("ix_cities")
|
||||
queryLoad:Where("ct_id", id)
|
||||
queryLoad:Callback(function(dataSelectResult)
|
||||
if (!istable(dataSelectResult) or #dataSelectResult == 0) then
|
||||
return
|
||||
end
|
||||
print(id .. ": DATA SELECT RESULT")
|
||||
PrintTable(dataSelectResult)
|
||||
return dataSelectResult
|
||||
end)
|
||||
queryLoad:Execute()
|
||||
end
|
||||
|
||||
function ix.city:DeleteCity(id)
|
||||
if !isstring(id) then id = id:GetID() end
|
||||
local queryDelete = mysql:Delete("ix_cities")
|
||||
queryDelete:Where("ct_id", id)
|
||||
queryDelete:Execute()
|
||||
end
|
||||
|
||||
-- for debug and develop only
|
||||
function ix.city:PurgeCities()
|
||||
local queryPurge = mysql:Drop("ix_cities")
|
||||
queryPurge:Execute()
|
||||
end
|
||||
|
||||
function ix.city:LoadTypes()
|
||||
local queryLoad = mysql:Select("ix_citytypes")
|
||||
queryLoad:Callback(function(dataSelectResult)
|
||||
if (!istable(dataSelectResult) or #dataSelectResult == 0) then
|
||||
return
|
||||
end
|
||||
return ix.city:InitializeTypes(dataSelectResult)
|
||||
end)
|
||||
queryLoad:Execute()
|
||||
end
|
||||
|
||||
function ix.city:LoadCities()
|
||||
local queryLoad = mysql:Select("ix_cities")
|
||||
queryLoad:Callback(function(dataSelectResult)
|
||||
if (!istable(dataSelectResult) or #dataSelectResult == 0) then
|
||||
return
|
||||
end
|
||||
return ix.city:InitializeCities(dataSelectResult)
|
||||
end)
|
||||
queryLoad:Execute()
|
||||
end
|
||||
|
||||
function ix.city:InitializeCities(cities)
|
||||
for _, city in pairs(cities) do
|
||||
local cityData = {}
|
||||
cityData.id = isstring(city["ct_id"]) and city["ct_id"] or tostring(city["ct_id"])
|
||||
cityData.items = util.JSONToTable(city["ct_items"]) or {}
|
||||
cityData.type = util.JSONToTable(city["ct_type"]) or {}
|
||||
cityData.credits = tonumber(city["ct_credits"])
|
||||
cityData.loan = tonumber(city["ct_loan"])
|
||||
cityData.loanRate = tonumber(city["ct_loanRate"])
|
||||
|
||||
if cityData.id == "1" then
|
||||
ix.city:LoadMainCity(cityData)
|
||||
else
|
||||
ix.city:LoadCity(cityData.id, cityData)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ix.city:AddTypeData(name, typeData)
|
||||
local queryAdd = mysql:Insert("ix_citytypes")
|
||||
queryAdd:Insert("t_name", name)
|
||||
queryAdd:Insert("t_data", util.TableToJSON(typeData))
|
||||
queryAdd:Execute()
|
||||
end
|
||||
|
||||
function ix.city:UpdateType(name)
|
||||
if !isstring(name) then name = tostring(name) end
|
||||
|
||||
local queryUpdate = mysql:Update("ix_citytypes")
|
||||
queryUpdate:Where("t_name", name)
|
||||
queryUpdate:Update("t_data", util.TableToJSON(ix.city.types.list[name]))
|
||||
queryUpdate:Execute()
|
||||
end
|
||||
|
||||
-- make sure to include data / metaobject in global table later
|
||||
function ix.city:LoadTypeData(name)
|
||||
local queryLoad = mysql:Select("ix_citytypes")
|
||||
queryLoad:Where("t_name", name)
|
||||
queryLoad:Callback(function(dataSelectResult)
|
||||
if (!istable(dataSelectResult) or #dataSelectResult == 0) then
|
||||
return
|
||||
end
|
||||
return dataSelectResult
|
||||
end)
|
||||
queryLoad:Execute()
|
||||
end
|
||||
|
||||
function ix.city:DeleteType(name)
|
||||
local queryDelete = mysql:Delete("ix_citytypes")
|
||||
queryDelete:Where("t_name", name)
|
||||
queryDelete:Execute()
|
||||
end
|
||||
|
||||
function ix.city:InitializeTypes(types)
|
||||
for _, type in pairs(types) do
|
||||
local typeData = {}
|
||||
typeData.name = type["t_name"]
|
||||
typeData.data = util.JSONToTable(type["t_data"]) or {}
|
||||
ix.city:LoadType(typeData.name, typeData.data)
|
||||
end
|
||||
end
|
||||
|
||||
-- for debug and develop only
|
||||
function ix.city:PurgeTypes()
|
||||
local queryPurge = mysql:Drop("ix_citytypes")
|
||||
queryPurge:Execute()
|
||||
end
|
||||
|
||||
-- cwu terminal related
|
||||
function ix.city:IsAuthorized(client, ent)
|
||||
if ent and (ent:GetUsedBy() == client and ent.curGenData and ent:IsFullyAuthed() and (client:EyePos():DistToSqr(ent:GetPos()) < 10000)) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
55
gamemodes/ixhl2rp/plugins/goi_cityfunds/libs/sv_fbudget.lua
Normal file
55
gamemodes/ixhl2rp/plugins/goi_cityfunds/libs/sv_fbudget.lua
Normal file
@@ -0,0 +1,55 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
function ix.factionBudget:GetFBCredits(id)
|
||||
return ix.factionBudget:GetFB(id).credits
|
||||
end
|
||||
|
||||
function ix.factionBudget:SetFBCredits(id, credits)
|
||||
ix.factionBudget.list[id].credits = math.Clamp(credits, 0, 50000)
|
||||
end
|
||||
|
||||
function ix.factionBudget:AddFBCredits(id, credits)
|
||||
local curCreds = ix.factionBudget:GetFBCredits(id)
|
||||
ix.factionBudget.list[id].credits = math.Clamp(curCreds + credits, 0, 50000)
|
||||
end
|
||||
|
||||
function ix.factionBudget:TakeFBCredits(id, credits)
|
||||
local curCreds = ix.factionBudget:GetFBCredits(id)
|
||||
ix.factionBudget.list[id].credits = math.Clamp(curCreds - credits, 0, 50000)
|
||||
end
|
||||
|
||||
function ix.factionBudget:HasCredits(id, credits)
|
||||
local curCreds = ix.factionBudget:GetFBCredits(id)
|
||||
if curCreds >= credits then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function ix.factionBudget:SaveBudgets()
|
||||
ix.data.Set("factionBudgets", ix.factionBudget.list, false, true)
|
||||
|
||||
ix.city:UpdateCWUTerminals()
|
||||
end
|
||||
|
||||
function ix.factionBudget:LoadBudgets()
|
||||
ix.factionBudget:InitializeFactionBudgets()
|
||||
|
||||
local budgetList = ix.data.Get("factionBudgets", false, false, true)
|
||||
if budgetList then
|
||||
for k, v in pairs(budgetList) do
|
||||
if ix.factionBudget.list[k] then
|
||||
ix.factionBudget.list[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
341
gamemodes/ixhl2rp/plugins/goi_cityfunds/meta/sv_city.lua
Normal file
341
gamemodes/ixhl2rp/plugins/goi_cityfunds/meta/sv_city.lua
Normal file
@@ -0,0 +1,341 @@
|
||||
--[[
|
||||
| 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 math = math
|
||||
local ix = ix
|
||||
local pairs = pairs
|
||||
local table = table
|
||||
local istable = istable
|
||||
local string = string
|
||||
|
||||
local CITY = ix.meta.city or {}
|
||||
CITY.__index = CITY
|
||||
CITY.id = 0
|
||||
CITY.credits = 0
|
||||
CITY.type = {}
|
||||
CITY.items = {}
|
||||
CITY.loan = 0
|
||||
CITY.loanRate = 0
|
||||
|
||||
function CITY:__tostring()
|
||||
return "CITY-" .. self.id
|
||||
end
|
||||
|
||||
function CITY:__eq(other)
|
||||
return self:GetID() == other:GetID()
|
||||
end
|
||||
|
||||
function CITY:GetID()
|
||||
return self.id
|
||||
end
|
||||
|
||||
function CITY:OnCreated()
|
||||
self:SetType(self.type, true)
|
||||
end
|
||||
|
||||
function CITY:TakeCredits(amount)
|
||||
self.credits = math.Clamp(self.credits - amount, -ix.config.Get("minusCityCap", 0), 999999)
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:AddCredits(amount)
|
||||
self.credits = math.Clamp(self.credits + amount, -ix.config.Get("minusCityCap", 0), 999999)
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:SetCredits(amount)
|
||||
self.credits = math.Clamp(amount, -ix.config.Get("minusCityCap", 0), 999999)
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:HasCredits(amount)
|
||||
local creditsToCheck = self.credits
|
||||
|
||||
if creditsToCheck < 0 and creditsToCheck != -ix.config.Get("minusCityCap", 0) then
|
||||
creditsToCheck = ix.config.Get("minusCityCap", 0) + creditsToCheck
|
||||
end
|
||||
|
||||
if creditsToCheck >= amount then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function CITY:GetCredits()
|
||||
return self.credits
|
||||
end
|
||||
|
||||
function CITY:GetLoan()
|
||||
return self.loan
|
||||
end
|
||||
|
||||
function CITY:SetLoan(amount)
|
||||
self.loan = math.Clamp(amount, 0, 999999)
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:AddLoan(amount)
|
||||
self.loan = math.Clamp(self.loan + amount, 0, 999999)
|
||||
self:AddCredits(amount)
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:TakeLoan(amount)
|
||||
self.loan = math.Clamp(self.loan - amount, 0, 999999)
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:PayLoan(amount)
|
||||
if !self:HasCredits(amount) then return "Your city don't have enough credits." end
|
||||
|
||||
self:TakeLoan(amount)
|
||||
self:TakeCredits(amount)
|
||||
end
|
||||
|
||||
function CITY:IsMain()
|
||||
return self:GetID() == "1"
|
||||
end
|
||||
|
||||
function CITY:AddItem(item, amount, price, priceMulptiplicationTD, priceReductionTD, priceMul, priceDiv)
|
||||
if self.items[item] then
|
||||
amount = self.items[item].amount + amount
|
||||
end
|
||||
|
||||
if !self:IsMain() then
|
||||
self.items[item] = {
|
||||
amount = amount,
|
||||
price = price and price or self.items[item] and self.items[item].price and self.items[item].price or 0,
|
||||
priceMulptiplicationTD = priceMulptiplicationTD and priceMulptiplicationTD or self.items[item] and self.items[item].priceMulptiplicationTD or 10,
|
||||
priceReductionTD = priceReductionTD and priceReductionTD or self.items[item] and self.items[item].priceReductionTD or 90,
|
||||
priceMul = priceMul and priceMul or self.items[item] and self.items[item].priceMul or 2,
|
||||
priceDiv = priceDiv and priceDiv or self.items[item] and self.items[item].priceDiv or 2
|
||||
}
|
||||
else
|
||||
self.items[item] = {
|
||||
amount = amount
|
||||
}
|
||||
end
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:HasItem(item)
|
||||
if self.items[item] and self.items[item].amount > 0 then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function CITY:RemoveItem(item, amount)
|
||||
amount = amount or 1
|
||||
if self.items[item] and (self.items[item].amount - amount) >= 0 then
|
||||
self.items[item].amount = self.items[item].amount - amount
|
||||
end
|
||||
end
|
||||
|
||||
function CITY:OnItemTaken(item) end
|
||||
|
||||
function CITY:TakeItem(item, amount)
|
||||
if self:HasItem(item) then
|
||||
self:RemoveItem(item, amount)
|
||||
self:OnItemTaken(item)
|
||||
end
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:GetItemPrice(itemTbl)
|
||||
if itemTbl.priceMulptiplicationTD and itemTbl.amount <= itemTbl.priceMulptiplicationTD then
|
||||
return math.ceil(itemTbl.price * itemTbl.priceMul)
|
||||
elseif itemTbl.priceReductionTD and itemTbl.amount >= itemTbl.priceReductionTD then
|
||||
return math.ceil(itemTbl.price / itemTbl.priceDiv)
|
||||
else
|
||||
return itemTbl.price
|
||||
end
|
||||
end
|
||||
|
||||
function CITY:SellItems(item, fund, amount)
|
||||
local itemTbl = self.items[item]
|
||||
local fundItem = fund.items[item]
|
||||
|
||||
local cityStr = "CITY-" .. self.id
|
||||
local fundStr = "CITY-" .. fund.id
|
||||
|
||||
if !itemTbl or itemTbl.amount <= 0 then
|
||||
return cityStr .. " don't have this: '" .. ix.item.list[item].name .. "' with amount of " .. amount
|
||||
end
|
||||
|
||||
if fund.id != "1" and !fundItem then
|
||||
return fundStr .. " don't want to make any deals with this item."
|
||||
end
|
||||
|
||||
local price = self.id != "1" and self:GetItemPrice(itemTbl) or fund:GetItemPrice(fundItem)
|
||||
|
||||
if !fund:HasCredits(price * amount) then
|
||||
return fundStr .. " don't have enough credits. (Available at this moment: " .. fund:GetCredits() .. ")"
|
||||
end
|
||||
|
||||
fund:AddItem(item, amount)
|
||||
fund:TakeCredits(price * amount)
|
||||
|
||||
self:AddCredits(price * amount)
|
||||
self:TakeItem(item, amount)
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
|
||||
return price * amount
|
||||
end
|
||||
|
||||
function CITY:AutoSell(item, amount)
|
||||
local citiesWithItem = {}
|
||||
local selectedCity = false
|
||||
|
||||
for cityID, city in pairs(ix.city.list) do
|
||||
if city.items[item] then
|
||||
local itemPrice = self:GetItemPrice(city.items[item])
|
||||
|
||||
if city:HasCredits(itemPrice) then
|
||||
citiesWithItem[#citiesWithItem + 1] = {
|
||||
price = itemPrice,
|
||||
cityID = cityID,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort( citiesWithItem, function(a, b) return a.price > b.price end )
|
||||
|
||||
if #citiesWithItem != 0 and citiesWithItem[#citiesWithItem] then
|
||||
selectedCity = citiesWithItem[1].cityID
|
||||
else
|
||||
return "Can't find city to sell."
|
||||
end
|
||||
|
||||
local sellItems = self:SellItems(item, ix.city.list[selectedCity], amount)
|
||||
|
||||
return sellItems
|
||||
end
|
||||
|
||||
function CITY:ExportItems(item, city, amount)
|
||||
|
||||
end
|
||||
|
||||
function CITY:GetItems()
|
||||
return self.items
|
||||
end
|
||||
|
||||
function CITY:GetType()
|
||||
return self.type
|
||||
end
|
||||
|
||||
function CITY:SetType(tbl, noUpdate)
|
||||
self.type = tbl
|
||||
self.type.cIncomeProgress = 0
|
||||
self.type.productionProgress = {
|
||||
lowRateProduction = 0,
|
||||
averageRateProduction = 0,
|
||||
highRateProduction = 0
|
||||
}
|
||||
|
||||
if !noUpdate then
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
end
|
||||
|
||||
function CITY:IncrementLoanProgress()
|
||||
if !self:IsMain() then return end
|
||||
if self:GetCredits() <= 0 then return end
|
||||
|
||||
self.loanRate = self.loanRate + 1
|
||||
|
||||
if self.loanRate >= 24 then
|
||||
local credPercent = self:GetCredits() / 100
|
||||
|
||||
self:TakeCredits(math.Round(credPercent * ix.config.Get("loanPercent")))
|
||||
self.loanRate = 0
|
||||
end
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:IncrementIncomeProgress()
|
||||
if !self.type or !istable(self.type) or table.IsEmpty(self.type) then return end
|
||||
|
||||
self.type.cIncomeProgress = self.type.cIncomeProgress + 1
|
||||
|
||||
if self.type.cIncomeProgress >= self.type.passiveIncomeRate then
|
||||
self:AddCredits(self.type.passiveIncome)
|
||||
self.type.cIncomeProgress = 0
|
||||
end
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:IncrementProductionProgress()
|
||||
if !self.type or !istable(self.type) or table.IsEmpty(self.type) then return end
|
||||
|
||||
for i, production in pairs(self.type.productionProgress) do
|
||||
self.type.productionProgress[i] = self.type.productionProgress[i] + 1
|
||||
|
||||
if self.type.productionProgress[i] >= self.type[i] then
|
||||
self:HandleItemProduction(i)
|
||||
self.type.productionProgress[i] = 0
|
||||
end
|
||||
end
|
||||
|
||||
ix.city:UpdateCity(self)
|
||||
end
|
||||
|
||||
function CITY:HandleItemConsumption()
|
||||
if !self.type or !istable(self.type) or table.IsEmpty(self.type) then return end
|
||||
if table.IsEmpty(self.items) then return end
|
||||
|
||||
local range = {ix.config.Get("randItemDeletionAmountRangeMin"), ix.config.Get("randItemDeletionAmountRangeMax")}
|
||||
local difItemsToTake = ix.config.Get("randItemDeletions")
|
||||
|
||||
for i = 1, difItemsToTake do
|
||||
local itemsAmountToTake = math.random(range[1], range[2])
|
||||
local _, itemID = table.Random(self.items)
|
||||
|
||||
self:TakeItem(itemID, itemsAmountToTake)
|
||||
end
|
||||
end
|
||||
|
||||
function CITY:HandleItemProduction(rate)
|
||||
local itemTable
|
||||
local range
|
||||
if string.match(rate, "high") then
|
||||
itemTable = self.type.itemsHighRate
|
||||
range = {ix.config.Get("highItemProductionMinRange"), ix.config.Get("highItemProductionMaxRange")}
|
||||
elseif string.match(rate, "average") then
|
||||
itemTable = self.type.itemsAverageRate
|
||||
range = {ix.config.Get("averageItemProductionMinRange"), ix.config.Get("averageItemProductionMaxRange")}
|
||||
elseif string.match(rate, "low") then
|
||||
itemTable = self.type.itemsLowRate
|
||||
range = {ix.config.Get("lowItemProductionMinRange"), ix.config.Get("lowItemProductionMaxRange")}
|
||||
end
|
||||
|
||||
if !istable(itemTable) or !range then return end
|
||||
|
||||
local itemsProduced = math.random(range[1], range[2])
|
||||
for item, _ in pairs(itemTable) do
|
||||
if self.items[item] then
|
||||
self:AddItem(item, itemsProduced)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ix.meta.city = CITY
|
||||
69
gamemodes/ixhl2rp/plugins/goi_cityfunds/nets/cl_nets.lua
Normal file
69
gamemodes/ixhl2rp/plugins/goi_cityfunds/nets/cl_nets.lua
Normal file
@@ -0,0 +1,69 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
net.Receive("ix.city.CreateCFEditor", function()
|
||||
vgui.Create("ixFundManager")
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.SyncCityStock", function()
|
||||
local items = util.JSONToTable(net.ReadString())
|
||||
|
||||
if !istable(ix.city.main) then
|
||||
ix.city.main = {}
|
||||
end
|
||||
|
||||
ix.city.main.items = items
|
||||
|
||||
if ix.gui.barteringpanel then
|
||||
if !ix.gui.barteringpanel.built then
|
||||
ix.gui.barteringpanel:Proceed()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.RequestTypes", function()
|
||||
local parent = ix.gui.fundManager
|
||||
|
||||
if !parent then return end
|
||||
|
||||
local typeTbl = util.JSONToTable(net.ReadString())
|
||||
parent.types = typeTbl
|
||||
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.PopulateFunds", function()
|
||||
local parent = ix.gui.fundManager
|
||||
|
||||
if !parent then return end
|
||||
|
||||
local cityTbl = util.JSONToTable(net.ReadString())
|
||||
parent:Populate(cityTbl)
|
||||
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.RequestUpdateTypes", function()
|
||||
local parent = ix.gui.ctEditor
|
||||
|
||||
if !parent then return end
|
||||
|
||||
local typeTbl = util.JSONToTable(net.ReadString())
|
||||
parent:UpdateTypes(typeTbl)
|
||||
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.RequestUpdateCities", function()
|
||||
local parent = ix.gui.fundManager
|
||||
|
||||
if !parent then return end
|
||||
|
||||
local cityTbl = util.JSONToTable(net.ReadString())
|
||||
parent:UpdateCities(cityTbl)
|
||||
|
||||
end)
|
||||
585
gamemodes/ixhl2rp/plugins/goi_cityfunds/nets/sv_nets.lua
Normal file
585
gamemodes/ixhl2rp/plugins/goi_cityfunds/nets/sv_nets.lua
Normal file
@@ -0,0 +1,585 @@
|
||||
--[[
|
||||
| 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 util = util
|
||||
local net = net
|
||||
local ix = ix
|
||||
local tonumber = tonumber
|
||||
local istable = istable
|
||||
local isnumber = isnumber
|
||||
local pairs = pairs
|
||||
local CAMI = CAMI
|
||||
|
||||
-- one day i definitely should re-do the networking here..
|
||||
|
||||
util.AddNetworkString("ix.city.CreateCFEditor")
|
||||
util.AddNetworkString("ix.city.SyncCityStock")
|
||||
util.AddNetworkString("ix.city.PopulateFunds")
|
||||
util.AddNetworkString("ix.city.RequestTypes")
|
||||
util.AddNetworkString("ix.city.RequestUpdateTypes")
|
||||
util.AddNetworkString("ix.city.RequestUpdateCities")
|
||||
util.AddNetworkString("ix.city.CreateType")
|
||||
util.AddNetworkString("ix.city.CreateCity")
|
||||
util.AddNetworkString("ix.city.UpdateType")
|
||||
util.AddNetworkString("ix.city.UpdateCity")
|
||||
util.AddNetworkString("ix.city.RemoveType")
|
||||
util.AddNetworkString("ix.city.RemoveCity")
|
||||
util.AddNetworkString("ix.city.Autosell")
|
||||
util.AddNetworkString("ix.city.Sell")
|
||||
util.AddNetworkString("ix.city.TakeItem")
|
||||
util.AddNetworkString("ix.city.BuyCart")
|
||||
util.AddNetworkString("ix.city.WithdrawCredits")
|
||||
util.AddNetworkString("ix.city.DepositCredits")
|
||||
util.AddNetworkString("ix.city.PayLoan")
|
||||
util.AddNetworkString("ix.city.TakeLoan")
|
||||
util.AddNetworkString("ix.city.SetFactionBudget")
|
||||
util.AddNetworkString("ix.city.WithdrawFactionBudget")
|
||||
util.AddNetworkString("ix.city.DepositFactionBudget")
|
||||
|
||||
net.Receive("ix.city.SyncCityStock", function(len, client)
|
||||
ix.city:SyncCityStock(client)
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.DepositFactionBudget", function(len, client)
|
||||
local budgetID = net.ReadString()
|
||||
local credits = net.ReadInt(15)
|
||||
local ent = net.ReadEntity()
|
||||
|
||||
if !ent then return end
|
||||
if !credits then return end
|
||||
if !budgetID then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "budgetInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
|
||||
local fName = ix.factionBudget.list[budgetID].name
|
||||
local idCard = ix.item.instances[ent:GetCID()]
|
||||
if idCard:HasCredits(credits) then
|
||||
ix.factionBudget:AddFBCredits(budgetID, credits)
|
||||
idCard:TakeCredits(credits, "CWU terminal", "Credits deposited in faction budget: "..fName)
|
||||
else
|
||||
return client:NotifyLocalized("You don't have this amount of credits.")
|
||||
end
|
||||
|
||||
ix.factionBudget:SaveBudgets()
|
||||
client:NotifyLocalized("Success!")
|
||||
ix.log.Add(client, "factionBudgetCWU", "deposited", credits, fName)
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.WithdrawFactionBudget", function(len, client)
|
||||
local budgetID = net.ReadString()
|
||||
local credits = net.ReadInt(15)
|
||||
local ent = net.ReadEntity()
|
||||
|
||||
if !ent then return end
|
||||
if !credits then return end
|
||||
if !budgetID then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "budgetInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
|
||||
local fName = ix.factionBudget.list[budgetID].name
|
||||
local idCard = ix.item.instances[ent:GetCID()]
|
||||
if ix.factionBudget:HasCredits(budgetID, credits) then
|
||||
ix.factionBudget:TakeFBCredits(budgetID, credits)
|
||||
idCard:GiveCredits(credits, "CWU terminal", "Credits withdrawen from faction budget: "..fName)
|
||||
else
|
||||
return client:NotifyLocalized("Faction budget don't have this amount of credits.")
|
||||
end
|
||||
|
||||
ix.factionBudget:SaveBudgets()
|
||||
client:NotifyLocalized("Success!")
|
||||
ix.log.Add(client, "factionBudgetCWU", "withdrew", credits, fName)
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.TakeItem", function(len, client)
|
||||
local incomingData = net.ReadString()
|
||||
local itemTbl = ix.item.list[incomingData]
|
||||
local ent = net.ReadEntity()
|
||||
local isCombine = ent.curGenData and ent.curGenData.combine or false
|
||||
|
||||
if !ent then return end
|
||||
if !incomingData then return end
|
||||
if !ent.curGenData then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!itemTbl) then
|
||||
ix.city.main.items[incomingData] = nil
|
||||
return
|
||||
end
|
||||
if (ix.city:IsCombineRestricted(incomingData) or ix.city:IsCombineRestricted(itemTbl.category)) and (!isCombine) then
|
||||
return client:NotifyLocalized("You are not allowed to take this item out of stock.")
|
||||
end
|
||||
if (!isCombine) then
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "stockInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
end
|
||||
|
||||
if ix.city.main:HasItem(incomingData) then
|
||||
local charID = ent.curGenData.id
|
||||
local char = ix.char.loaded[ent.curGenData.id]
|
||||
local charName = ent.curGenData.name
|
||||
if char then
|
||||
char:SetPurchasedItems(incomingData, 1)
|
||||
else
|
||||
local dataSelect = mysql:Select("ix_characters_data")
|
||||
dataSelect:Where("id", tonumber(charID))
|
||||
dataSelect:WhereIn("key", "purchasedItems")
|
||||
dataSelect:Callback(function(dataSelectResult)
|
||||
if (!istable(dataSelectResult) or #dataSelectResult == 0) then
|
||||
return
|
||||
end
|
||||
|
||||
local purchasedItems = util.JSONToTable(dataSelectResult[1].data)
|
||||
if !purchasedItems then return end
|
||||
|
||||
if purchasedItems[incomingData] then
|
||||
purchasedItems[incomingData] = purchasedItems[incomingData] + 1
|
||||
else
|
||||
purchasedItems[incomingData] = 1
|
||||
end
|
||||
|
||||
local updateQuery = mysql:Update("ix_characters_data")
|
||||
updateQuery:Update("data", util.TableToJSON(purchasedItems))
|
||||
updateQuery:Where("id", tonumber(charID))
|
||||
updateQuery:Where("key", "purchasedItems")
|
||||
updateQuery:Execute()
|
||||
end)
|
||||
dataSelect:Execute()
|
||||
end
|
||||
ix.city.main:TakeItem(incomingData)
|
||||
|
||||
client:NotifyLocalized("Item added to pickup terminal.")
|
||||
ix.log.Add(client, "stockInteraction", incomingData)
|
||||
ix.combineNotify:AddNotification("FND:// ".. charName .. " took "..ix.item.list[incomingData].name.." from city stock", nil, client)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.Autosell", function(len, client)
|
||||
local incomingData = net.ReadString()
|
||||
local ent = net.ReadEntity()
|
||||
local isCombine = ent.curGenData and ent.curGenData.combine or false
|
||||
|
||||
if !ent then return end
|
||||
if !incomingData then return end
|
||||
if !ent.curGenData then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!isCombine) then
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "marketInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
end
|
||||
|
||||
local charName = ent.curGenData.name
|
||||
local item = util.JSONToTable(incomingData)
|
||||
local successCheck = ix.city.main:AutoSell(item.itemID, item.amount)
|
||||
if successCheck and !isnumber(successCheck) then
|
||||
client:NotifyLocalized("Can't find any city to sell this item.")
|
||||
else
|
||||
ix.combineNotify:AddNotification("FND:// ".. charName .. " has sold 1 items(s) from city stock: "..ix.item.list[item.itemID].name, nil, client)
|
||||
ix.log.Add(client, "marketInteraction", "sold", 1, item.itemID, successCheck)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.Sell", function(len, client)
|
||||
local incomingData = net.ReadString()
|
||||
local ent = net.ReadEntity()
|
||||
local isCombine = ent.curGenData and ent.curGenData.combine or false
|
||||
|
||||
if !ent then return end
|
||||
if !incomingData then return end
|
||||
if !ent.curGenData then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!isCombine) then
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "marketInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
end
|
||||
|
||||
local charName = ent.curGenData.name
|
||||
local data = util.JSONToTable(incomingData)
|
||||
local successCheck = ix.city.main:SellItems(data.itemID, ix.city.list[data.cityID], data.amount)
|
||||
if successCheck and !isnumber(successCheck) then
|
||||
client:NotifyLocalized(successCheck)
|
||||
else
|
||||
client:NotifyLocalized("Success!")
|
||||
ix.combineNotify:AddNotification("FND:// ".. charName .. " has sold "..data.amount.." items(s) from city stock: "..ix.item.list[data.itemID].name, nil, client)
|
||||
ix.log.Add(client, "marketInteraction", "sold", data.amount, data.itemID, successCheck)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.BuyCart", function(len, client)
|
||||
local incomingData = net.ReadString()
|
||||
local ent = net.ReadEntity()
|
||||
local isCombine = ent.curGenData and ent.curGenData.combine or false
|
||||
|
||||
if !ent then return end
|
||||
if !incomingData then return end
|
||||
if !ent.curGenData then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!isCombine) then
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "marketInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
end
|
||||
|
||||
local charName = ent.curGenData.name
|
||||
local cart = util.JSONToTable(incomingData)
|
||||
local successCheck
|
||||
for _, cartSlot in pairs(cart) do
|
||||
local item = cartSlot.itemData.id
|
||||
local itemAmount = cartSlot.amount
|
||||
local city = ix.city.list[cartSlot.city]
|
||||
|
||||
successCheck = city:SellItems(item, ix.city.main, itemAmount)
|
||||
if successCheck and !isnumber(successCheck) then
|
||||
client:NotifyLocalized(successCheck)
|
||||
else
|
||||
ix.combineNotify:AddNotification("FND:// ".. charName .. " has sold "..itemAmount.." items(s) from city stock: "..ix.item.list[item].name, nil, client)
|
||||
ix.log.Add(client, "marketInteraction", "bought", itemAmount, item, successCheck)
|
||||
end
|
||||
end
|
||||
|
||||
if !successCheck or isnumber(successCheck) then
|
||||
client:NotifyLocalized("Purchase successful!")
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.WithdrawCredits", function(len, client)
|
||||
local incomingData = net.ReadInt(15)
|
||||
local ent = net.ReadEntity()
|
||||
local isCombine = ent.curGenData and ent.curGenData.combine or false
|
||||
|
||||
if !ent then return end
|
||||
if !incomingData then return end
|
||||
if !ent.curGenData then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!isCombine) then
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "creditInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
end
|
||||
|
||||
if ix.city.main:HasCredits(incomingData) then
|
||||
local charName = ent.curGenData.name
|
||||
local idCard = ix.item.instances[ent:GetCID()]
|
||||
idCard:GiveCredits(incomingData, "CWU terminal", "Credits withdrawen from city fund.")
|
||||
ix.city.main:TakeCredits(incomingData)
|
||||
|
||||
ix.combineNotify:AddNotification("FND:// ".. charName .. " withdrew " .. incomingData .. " credits from city fund", color_red, client)
|
||||
ix.log.Add(client, "cityFundInteraction", "withdrew", incomingData)
|
||||
else
|
||||
return client:NotifyLocalized("City don't have enough credits.")
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.DepositCredits", function(len, client)
|
||||
local incomingData = net.ReadInt(15)
|
||||
local ent = net.ReadEntity()
|
||||
local isCombine = ent.curGenData and ent.curGenData.combine or false
|
||||
|
||||
if !ent then return end
|
||||
if !incomingData then return end
|
||||
if !ent.curGenData then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!isCombine) then
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "creditInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
end
|
||||
|
||||
local idCard = ix.item.instances[ent:GetCID()]
|
||||
if idCard:HasCredits(incomingData) then
|
||||
local charName = ent.curGenData.name
|
||||
idCard:TakeCredits(incomingData, "CWU terminal", "Credits deposited in city fund.")
|
||||
ix.city.main:AddCredits(incomingData)
|
||||
|
||||
ix.combineNotify:AddNotification("FND:// ".. charName .. " deposited " .. incomingData .. " credits in city fund", color_green, client)
|
||||
ix.log.Add(client, "cityFundInteraction", "deposited", incomingData)
|
||||
else
|
||||
return client:NotifyLocalized("You don't have enough credits.")
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.PayLoan", function(len, client)
|
||||
local incomingData = net.ReadInt(15)
|
||||
local ent = net.ReadEntity()
|
||||
local isCombine = ent.curGenData and ent.curGenData.combine or false
|
||||
|
||||
if !ent then return end
|
||||
if !incomingData then return end
|
||||
if !ent.curGenData then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!isCombine) then
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "creditInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
end
|
||||
|
||||
if ix.city.main:HasCredits(incomingData) then
|
||||
local charName = ent.curGenData.name
|
||||
ix.city.main:PayLoan(incomingData)
|
||||
|
||||
ix.combineNotify:AddNotification("FND:// ".. charName .. " paid loan with " .. incomingData .. " credits taken from city fund", color_green, client)
|
||||
ix.log.Add(client, "cityFundInteraction", "paid loan with", incomingData)
|
||||
else
|
||||
return client:NotifyLocalized("City don't have enough credits.")
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.TakeLoan", function(len, client)
|
||||
local incomingData = net.ReadInt(15)
|
||||
local ent = net.ReadEntity()
|
||||
local isCombine = ent.curGenData and ent.curGenData.combine or false
|
||||
|
||||
if !ent then return end
|
||||
if !incomingData then return end
|
||||
if !ent.curGenData then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!isCombine) then
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "creditInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
end
|
||||
|
||||
local charName = ent.curGenData.name
|
||||
ix.city.main:AddLoan(incomingData)
|
||||
ix.combineNotify:AddNotification("FND:// ".. charName .. " took out a " .. incomingData .. " credits loan", color_red, client)
|
||||
ix.log.Add(client, "cityFundInteraction", "took out loan: ", incomingData)
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.SetFactionBudget", function(len, client)
|
||||
local incomingData = net.ReadString()
|
||||
local ent = net.ReadEntity()
|
||||
local isCombine = ent.curGenData and ent.curGenData.combine or false
|
||||
|
||||
if !ent then return end
|
||||
if !incomingData then return end
|
||||
if !ent.curGenData then return end
|
||||
if (!ix.city:IsAuthorized(client, ent)) then return end
|
||||
if (!isCombine) then
|
||||
if (!ix.city:IsAccessable(ix.item.instances[ent:GetCWUCard()], "creditInteraction") and !ent.curGenData.isCCA) then
|
||||
return client:NotifyLocalized("No access.")
|
||||
end
|
||||
end
|
||||
|
||||
incomingData = util.JSONToTable(incomingData)
|
||||
|
||||
local budget = ix.factionBudget:GetFB(incomingData.budgetID)
|
||||
local budgetName = budget.name
|
||||
local newBudget = incomingData.newBudget
|
||||
local oldBudget = budget.credits
|
||||
local remains = oldBudget - newBudget
|
||||
|
||||
if remains < 0 and !ix.city.main:HasCredits(-remains) then return "No credits" end
|
||||
|
||||
budget.credits = newBudget
|
||||
ix.factionBudget:SaveBudgets()
|
||||
|
||||
if remains > 0 then
|
||||
ix.city.main:AddCredits(remains)
|
||||
else
|
||||
ix.city.main:TakeCredits(-remains)
|
||||
end
|
||||
|
||||
ix.log.Add(client, "factionBudget", budgetName, oldBudget, newBudget)
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.RequestUpdateTypes", function(len, client)
|
||||
if (!CAMI.PlayerHasAccess(client, "Helix - Manage City Fund")) then return end
|
||||
|
||||
net.Start("ix.city.RequestUpdateTypes")
|
||||
net.WriteString(util.TableToJSON(ix.city.types.list))
|
||||
net.Send(client)
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.RequestUpdateCities", function(len, client)
|
||||
if (!CAMI.PlayerHasAccess(client, "Helix - Manage City Fund")) then return end
|
||||
|
||||
local cityTbl = {}
|
||||
for index, city in pairs(ix.city.list) do
|
||||
cityTbl[index] = city
|
||||
end
|
||||
cityTbl["1"] = ix.city.main
|
||||
|
||||
net.Start("ix.city.RequestUpdateCities")
|
||||
net.WriteString(util.TableToJSON(cityTbl))
|
||||
net.Send(client)
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.RemoveType", function(len, client)
|
||||
if (!CAMI.PlayerHasAccess(client, "Helix - Manage City Fund")) then return end
|
||||
local tID = net.ReadString()
|
||||
|
||||
if (ix.city.types.list[tID]) then
|
||||
ix.city.types.list[tID] = nil
|
||||
ix.city:DeleteType(tID)
|
||||
|
||||
for cityID, city in pairs(ix.city.list) do
|
||||
if city.type.name == tID then
|
||||
city.type = false
|
||||
ix.city:UpdateCity(cityID)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.RemoveCity", function(len, client)
|
||||
if (!CAMI.PlayerHasAccess(client, "Helix - Manage City Fund")) then return end
|
||||
local cID = net.ReadString()
|
||||
|
||||
if (ix.city.list[cID]) then
|
||||
ix.city.list[cID] = nil
|
||||
ix.city:DeleteCity(cID)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.CreateType", function(len, client)
|
||||
if (!CAMI.PlayerHasAccess(client, "Helix - Manage City Fund")) then return end
|
||||
local tID = net.ReadString()
|
||||
|
||||
if (!ix.city.types.list[tID]) then
|
||||
ix.city.types:RegisterType(tID, {
|
||||
name = tID,
|
||||
itemsHighRate = {},
|
||||
itemsLowRate = {},
|
||||
itemsAverageRate = {},
|
||||
highRateProduction = 1,
|
||||
lowRateProduction = 3,
|
||||
averageRateProduction = 2,
|
||||
passiveIncome = 100,
|
||||
passiveIncomeRate = 1
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.CreateCity", function(len, client)
|
||||
if (!CAMI.PlayerHasAccess(client, "Helix - Manage City Fund")) then return end
|
||||
|
||||
local cityID = net.ReadString()
|
||||
local cityType = net.ReadString()
|
||||
|
||||
ix.city:CreateCity(cityID, cityType)
|
||||
end)
|
||||
|
||||
local function CheckItemRates(actualTD)
|
||||
if actualTD.highRateProduction < actualTD.averageRateProduction and
|
||||
actualTD.highRateProduction < actualTD.lowRateProduction and
|
||||
actualTD.averageRateProduction < actualTD.lowRateProduction then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
net.Receive("ix.city.UpdateType", function(len, client)
|
||||
if (!CAMI.PlayerHasAccess(client, "Helix - Manage City Fund")) then return end
|
||||
|
||||
local incomingData = net.ReadString()
|
||||
|
||||
local tTbl = util.JSONToTable(incomingData)
|
||||
|
||||
if !CheckItemRates(tTbl) then
|
||||
return
|
||||
end
|
||||
|
||||
if ix.city.types.list[tTbl.name] then
|
||||
ix.city.types.list[tTbl.name].itemsHighRate = tTbl.itemsHighRate or {}
|
||||
ix.city.types.list[tTbl.name].itemsLowRate = tTbl.itemsLowRate or {}
|
||||
ix.city.types.list[tTbl.name].itemsAverageRate = tTbl.itemsAverageRate or {}
|
||||
ix.city.types.list[tTbl.name].highRateProduction = tTbl.highRateProduction or 1
|
||||
ix.city.types.list[tTbl.name].lowRateProduction = tTbl.lowRateProduction or 3
|
||||
ix.city.types.list[tTbl.name].averageRateProduction = tTbl.averageRateProduction or 2
|
||||
ix.city.types.list[tTbl.name].passiveIncome = tTbl.passiveIncome or 100
|
||||
ix.city.types.list[tTbl.name].passiveIncomeRate = tTbl.passiveIncomeRate or 1
|
||||
end
|
||||
|
||||
ix.city:UpdateType(tTbl.name)
|
||||
end)
|
||||
|
||||
local function ValidateCityData(cTbl, client)
|
||||
for item, itemData in pairs(cTbl.items) do
|
||||
itemData.amount = isnumber(itemData.amount) and itemData.amount or tonumber(itemData.amount) or 1
|
||||
itemData.price = isnumber(itemData.price) and itemData.price or tonumber(itemData.price) or 50
|
||||
itemData.priceDiv = isnumber(itemData.priceDiv) and itemData.priceDiv or tonumber(itemData.priceDiv) or 2
|
||||
itemData.priceMul = isnumber(itemData.priceMul) and itemData.priceMul or tonumber(itemData.priceMul) or 2
|
||||
itemData.priceMulptiplicationTD = isnumber(itemData.priceMulptiplicationTD) and itemData.priceMulptiplicationTD or tonumber(itemData.priceMulptiplicationTD) or 10
|
||||
itemData.priceReductionTD = isnumber(itemData.priceReductionTD) and itemData.priceReductionTD or tonumber(itemData.priceReductionTD) or 90
|
||||
end
|
||||
end
|
||||
|
||||
net.Receive("ix.city.UpdateCity", function(len, client)
|
||||
if (!CAMI.PlayerHasAccess(client, "Helix - Manage City Fund")) then return end
|
||||
|
||||
local incomingData = net.ReadString()
|
||||
local isMain = net.ReadBool()
|
||||
|
||||
local cTbl = util.JSONToTable(incomingData)
|
||||
ValidateCityData(cTbl, client)
|
||||
|
||||
for item, itemData in pairs(cTbl.items) do
|
||||
itemData.amount = itemData.amount or 0
|
||||
itemData.price = itemData.price or 0
|
||||
itemData.priceDiv = itemData.priceDiv or 2
|
||||
itemData.priceMul = itemData.priceMul or 2
|
||||
itemData.priceMulptiplicationTD = itemData.priceMulptiplicationTD or 10
|
||||
itemData.priceReductionTD = itemData.priceReductionTD or 90
|
||||
end
|
||||
|
||||
if ix.city.list[cTbl.id] and !isMain then
|
||||
ix.city.list[cTbl.id].credits = tonumber(cTbl.credits) or 0
|
||||
ix.city.list[cTbl.id].items = cTbl.items or {}
|
||||
ix.city.list[cTbl.id].loan = tonumber(cTbl.loan) or 0
|
||||
if ix.city.types.list[cTbl.type.name] then
|
||||
ix.city.list[cTbl.id].type = cTbl.type or {}
|
||||
end
|
||||
ix.city:UpdateCity(cTbl.id)
|
||||
elseif isMain then
|
||||
if istable(cTbl.items) then
|
||||
for itemID, item in pairs(cTbl.items) do
|
||||
cTbl.items[itemID] = {amount = item.amount}
|
||||
end
|
||||
|
||||
ix.city.main.items = cTbl.items
|
||||
end
|
||||
ix.city.main.credits = tonumber(cTbl.credits)
|
||||
ix.city.main.loan = tonumber(cTbl.loan)
|
||||
|
||||
ix.city:UpdateCity(cTbl.id)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ix.city.PopulateFunds", function(len, client)
|
||||
if (!CAMI.PlayerHasAccess(client, "Helix - Manage City Fund")) then return end
|
||||
|
||||
local cityTbl = {}
|
||||
for index, city in pairs(ix.city.list) do
|
||||
cityTbl[index] = city
|
||||
end
|
||||
cityTbl["1"] = ix.city.main
|
||||
|
||||
local typeTbl = {}
|
||||
for index, type in pairs(ix.city.types.list) do
|
||||
typeTbl[index] = type
|
||||
end
|
||||
|
||||
local cityData = util.TableToJSON(cityTbl)
|
||||
local typeData = util.TableToJSON(typeTbl)
|
||||
|
||||
net.Start("ix.city.RequestTypes")
|
||||
net.WriteString(typeData)
|
||||
net.Send(client)
|
||||
|
||||
net.Start("ix.city.PopulateFunds")
|
||||
net.WriteString(cityData)
|
||||
net.Send(client)
|
||||
end)
|
||||
118
gamemodes/ixhl2rp/plugins/goi_cityfunds/sh_plugin.lua
Normal file
118
gamemodes/ixhl2rp/plugins/goi_cityfunds/sh_plugin.lua
Normal file
@@ -0,0 +1,118 @@
|
||||
--[[
|
||||
| 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
|
||||
PLUGIN.name = "City Funds"
|
||||
PLUGIN.author = "Naast"
|
||||
PLUGIN.description = "Adds city funds. Yeah."
|
||||
|
||||
CAMI.RegisterPrivilege({
|
||||
Name = "Helix - Manage City Fund",
|
||||
MinAccess = "superadmin"
|
||||
})
|
||||
|
||||
ix.util.IncludeDir(PLUGIN.folder .. "/meta", true)
|
||||
ix.util.IncludeDir(PLUGIN.folder .. "/nets", true)
|
||||
|
||||
ix.util.Include("sv_plugin.lua")
|
||||
ix.util.Include("sv_hooks.lua")
|
||||
ix.util.Include("sv_stock_disallowments.lua")
|
||||
ix.util.Include("sv_stock_restrictions.lua")
|
||||
|
||||
ix.config.Add("loanPercent", 2, "The amount of credits in percents that should be taken from city fund every day if it has a loan.", nil, {
|
||||
data = {min = 0, max = 100},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("transactionVatPercent", 2, "The amount of credits in percents that should from player's transactions.", nil, {
|
||||
data = {min = 0, max = 100},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("minusCityCap", 1000, "The maximum cap of negative balance of our city.", nil, {
|
||||
data = {min = 0, max = 10000},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("mainCityNumber", 24, "Number of main (current playable) city.", nil, {
|
||||
data = {min = 1, max = 99},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("averageItemProductionMaxRange", 15, "Max amount of average production items after rate time passes.", nil, {
|
||||
data = {min = 10, max = 100},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("averageItemProductionMinRange", 5, "Min amount of average production items after rate time passes.", nil, {
|
||||
data = {min = 1, max = 9},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("lowItemProductionMinRange", 5, "Min amount of low production items after rate time passes.", nil, {
|
||||
data = {min = 1, max = 9},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("lowItemProductionMaxRange", 15, "Max amount of low production items after rate time passes.", nil, {
|
||||
data = {min = 10, max = 100},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("highItemProductionMinRange", 5, "Min amount of high production items after rate time passes.", nil, {
|
||||
data = {min = 1, max = 9},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("highItemProductionMaxRange", 15, "Max amount of high production items after rate time passes.", nil, {
|
||||
data = {min = 10, max = 100},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("randItemDeletions", 3, "How much random item types (this can be one item multiple times) should be taken from every non-main city every hour.", nil, {
|
||||
data = {min = 1, max = 100},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("randItemDeletionAmountRangeMin", 1, "Min range for taking one single item type from every non-main city every hour.", nil, {
|
||||
data = {min = 1, max = 9},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.config.Add("randItemDeletionAmountRangeMax", 15, "Min range for taking one single item type from every non-main city every hour.", nil, {
|
||||
data = {min = 10, max = 100},
|
||||
category = "City Fund"
|
||||
})
|
||||
|
||||
ix.command.Add("CityFundEditor", {
|
||||
description = "Manage and create cities.",
|
||||
privilege = "Manage City Fund",
|
||||
OnRun = function(self, client)
|
||||
net.Start("ix.city.CreateCFEditor")
|
||||
net.Send(client)
|
||||
end
|
||||
})
|
||||
|
||||
ix.command.Add("SimulateGOItime", {
|
||||
description = "Updates city funds by forcing cities to handle their production functions.",
|
||||
privilege = "Manage City Fund",
|
||||
arguments = ix.type.number,
|
||||
OnRun = function(self, client, time)
|
||||
if time > 20 then return client:NotifyLocalized("Time is too high!") end
|
||||
|
||||
for i = 1, time do
|
||||
ix.city:UpdateCityFunds()
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
if CLIENT then
|
||||
ix.factionBudget:InitializeFactionBudgets()
|
||||
end
|
||||
24
gamemodes/ixhl2rp/plugins/goi_cityfunds/sv_hooks.lua
Normal file
24
gamemodes/ixhl2rp/plugins/goi_cityfunds/sv_hooks.lua
Normal file
@@ -0,0 +1,24 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
function PLUGIN:SaveData()
|
||||
if timer.Exists("ixCityFund") then
|
||||
ix.data.Set("cityFundTimer", timer.TimeLeft("ixCityFund"))
|
||||
end
|
||||
ix.factionBudget:SaveBudgets()
|
||||
end
|
||||
|
||||
function PLUGIN:LoadData()
|
||||
ix.factionBudget:LoadBudgets()
|
||||
end
|
||||
|
||||
function PLUGIN:InitPostEntity()
|
||||
self:SetupProductionTimer()
|
||||
end
|
||||
72
gamemodes/ixhl2rp/plugins/goi_cityfunds/sv_plugin.lua
Normal file
72
gamemodes/ixhl2rp/plugins/goi_cityfunds/sv_plugin.lua
Normal file
@@ -0,0 +1,72 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
function PLUGIN:DatabaseConnected()
|
||||
local aQuery = mysql:Create("ix_citytypes")
|
||||
aQuery:Create("t_id", "INT UNSIGNED NOT NULL AUTO_INCREMENT")
|
||||
aQuery:Create("t_name", "TEXT")
|
||||
aQuery:Create("t_data", "TEXT")
|
||||
aQuery:PrimaryKey("t_id")
|
||||
aQuery:Callback(function()
|
||||
ix.city:LoadTypes()
|
||||
end)
|
||||
aQuery:Execute()
|
||||
|
||||
local nQuery = mysql:Create("ix_cities")
|
||||
nQuery:Create("ct_id", "INT UNSIGNED NOT NULL")
|
||||
nQuery:Create("ct_credits", "TEXT")
|
||||
nQuery:Create("ct_type", "TEXT")
|
||||
nQuery:Create("ct_items", "LONGTEXT")
|
||||
nQuery:Create("ct_loan", "TEXT")
|
||||
nQuery:Create("ct_loanRate", "TEXT")
|
||||
nQuery:PrimaryKey("ct_id")
|
||||
nQuery:Callback(function()
|
||||
local fQuery = mysql:Select("ix_cities")
|
||||
fQuery:Where("ct_id", "1")
|
||||
fQuery:Callback(function(result)
|
||||
if (!istable(result) or #result == 0) then
|
||||
ix.city:InitializeMainCity()
|
||||
return
|
||||
end
|
||||
ix.city:LoadCities()
|
||||
end)
|
||||
fQuery:Execute()
|
||||
end)
|
||||
nQuery:Execute()
|
||||
end
|
||||
|
||||
function PLUGIN:SetupProductionTimer()
|
||||
if timer.Exists("ixCityFund") then return end
|
||||
|
||||
timer.Create("ixCityFund", ix.data.Get("cityFundTimer", 3600), 0, function()
|
||||
ix.city:UpdateCityFunds()
|
||||
timer.Adjust("ixCityFund", 3600)
|
||||
end)
|
||||
end
|
||||
|
||||
ix.log.AddType("cityFundInteraction", function(client, operationType, creditAmount)
|
||||
return string.format("[CITY FUND] %s has %s %s credits.", client:Name(), operationType, isstring(creditAmount) and creditAmount or tostring(creditAmount))
|
||||
end)
|
||||
|
||||
ix.log.AddType("factionBudget", function(client, faction, from, to)
|
||||
return string.format("[CITY FUND] %s has changed %s's budget from %s to %s credits.", client:Name(), faction, isstring(from) and from or tostring(from), isstring(to) and to or tostring(to))
|
||||
end)
|
||||
|
||||
ix.log.AddType("factionBudgetCWU", function(client, operationType, creditAmount, faction)
|
||||
return string.format("[CITY FUND] %s has %s %s credits from/in %s's budget.", client:Name(), operationType, isstring(creditAmount) and creditAmount or tostring(creditAmount), faction)
|
||||
end)
|
||||
|
||||
ix.log.AddType("marketInteraction", function(client, interactionType, amount, item, credAmount)
|
||||
return string.format("[CITY FUND] %s has %s %s item(s): %s for %s credits.", client:Name(), interactionType, isstring(amount) and amount or tostring(amount), item, isstring(credAmount) and credAmount or tostring(credAmount))
|
||||
end)
|
||||
|
||||
ix.log.AddType("stockInteraction", function(client, item)
|
||||
return string.format("[CITY FUND] %s took %s from city stock.", client:Name(), item)
|
||||
end)
|
||||
@@ -0,0 +1,62 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
-- example: ix.city:AddDisallowment("comp_plastic")
|
||||
ix.city:AddDisallowment("apartmentkey")
|
||||
ix.city:AddDisallowment("shopkey")
|
||||
ix.city:AddDisallowment("legs_black_padded_pants")
|
||||
ix.city:AddDisallowment("legs_blue_padded_pants")
|
||||
ix.city:AddDisallowment("legs_green_padded_pants")
|
||||
ix.city:AddDisallowment("torso_green_rebel_uniform")
|
||||
ix.city:AddDisallowment("torso_blue_rebel_uniform")
|
||||
ix.city:AddDisallowment("torso_medical_rebel_uniform")
|
||||
ix.city:AddDisallowment("torso_blue_kevlar")
|
||||
ix.city:AddDisallowment("torso_green_kevlar")
|
||||
ix.city:AddDisallowment("torso_green_kevlar_t3")
|
||||
ix.city:AddDisallowment("torso_medical_kevlar")
|
||||
ix.city:AddDisallowment("torso_green_kevlar_t2")
|
||||
ix.city:AddDisallowment("combine_card")
|
||||
ix.city:AddDisallowment("id_card")
|
||||
ix.city:AddDisallowment("fake_id_card")
|
||||
ix.city:AddDisallowment("dummy_smallbomb")
|
||||
ix.city:AddDisallowment("dummy_mediumbomb")
|
||||
ix.city:AddDisallowment("dummy_biolock_expar2")
|
||||
ix.city:AddDisallowment("dummy_biolock_ar2")
|
||||
ix.city:AddDisallowment("dummy_biolock_ociw")
|
||||
ix.city:AddDisallowment("dummy_biolock_sr1")
|
||||
ix.city:AddDisallowment("dummy_emp")
|
||||
ix.city:AddDisallowment("dummy_largebomb")
|
||||
ix.city:AddDisallowment("dummy_littlebomb")
|
||||
ix.city:AddDisallowment("funnybugbait")
|
||||
ix.city:AddDisallowment("trash_biolock")
|
||||
ix.city:AddDisallowment("cmbkey")
|
||||
ix.city:AddDisallowment("militarykey")
|
||||
ix.city:AddDisallowment("customitem_m")
|
||||
ix.city:AddDisallowment("customitem_s")
|
||||
ix.city:AddDisallowment("customitem_l")
|
||||
ix.city:AddDisallowment("customitem_xl")
|
||||
ix.city:AddDisallowment("itemlabel")
|
||||
ix.city:AddDisallowment("vendingmachinekey")
|
||||
ix.city:AddDisallowment("fake_id_card_creator")
|
||||
ix.city:AddDisallowment("shackleskey")
|
||||
ix.city:AddDisallowment("newspaper_printer_cracked")
|
||||
ix.city:AddDisallowment("ing_xen_extract")
|
||||
ix.city:AddDisallowment("ic_cluster_hive")
|
||||
ix.city:AddDisallowment("ic_coarctate_mucus")
|
||||
ix.city:AddDisallowment("ic_thanarok_embryo")
|
||||
ix.city:AddDisallowment("ic_thanatos_embryo")
|
||||
ix.city:AddDisallowment("ic_nosos_heart")
|
||||
ix.city:AddDisallowment("tool_chembench")
|
||||
ix.city:AddDisallowment("tool_metalbench")
|
||||
ix.city:AddDisallowment("tool_oven")
|
||||
ix.city:AddDisallowment("tool_oven_rusty")
|
||||
ix.city:AddDisallowment("tool_mixer")
|
||||
ix.city:AddDisallowment("tool_creammachine")
|
||||
ix.city:AddDisallowment("tool_craftingbench")
|
||||
@@ -0,0 +1,43 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
-- example: ix.city:AddCombineRestriction("akm")
|
||||
-- also, you are able to restrict the whole item category just like this: ix.city:AddCombineRestriction("Weapons")
|
||||
ix.city:AddCombineRestriction("Weapons")
|
||||
ix.city:AddCombineRestriction("Combine")
|
||||
ix.city:AddCombineRestriction("Clothing - CCA")
|
||||
ix.city:AddCombineRestriction("manhack")
|
||||
ix.city:AddCombineRestriction("health_syringe")
|
||||
ix.city:AddCombineRestriction("turret_placer")
|
||||
ix.city:AddCombineRestriction("barricade_placer")
|
||||
ix.city:AddCombineRestriction("tool_repair")
|
||||
ix.city:AddCombineRestriction("Ammunition (New)")
|
||||
ix.city:AddCombineRestriction("Ammunition")
|
||||
ix.city:AddCombineRestriction("Combine")
|
||||
ix.city:AddCombineRestriction("Attachments")
|
||||
ix.city:AddCombineRestriction("Attachments (ArcCW)")
|
||||
ix.city:AddCombineRestriction("Clothing - Collaborator")
|
||||
ix.city:AddCombineRestriction("Loyalism")
|
||||
ix.city:AddCombineRestriction("Xen")
|
||||
ix.city:AddCombineRestriction("landline")
|
||||
ix.city:AddCombineRestriction("tuner_cmb")
|
||||
ix.city:AddCombineRestriction("tuner_reb")
|
||||
ix.city:AddCombineRestriction("armband_green")
|
||||
ix.city:AddCombineRestriction("armband_black")
|
||||
ix.city:AddCombineRestriction("armband_blue")
|
||||
ix.city:AddCombineRestriction("armband_icobt")
|
||||
ix.city:AddCombineRestriction("armband_grey")
|
||||
ix.city:AddCombineRestriction("armband_orange")
|
||||
ix.city:AddCombineRestriction("armband_purple")
|
||||
ix.city:AddCombineRestriction("armband_red")
|
||||
ix.city:AddCombineRestriction("armband_white")
|
||||
ix.city:AddCombineRestriction("armband_whitestar")
|
||||
ix.city:AddCombineRestriction("armband_yellow")
|
||||
ix.city:AddCombineRestriction("wn_zip_tie")
|
||||
Reference in New Issue
Block a user