mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
83
gamemodes/darkrp/plugins/waterloot/cl_plugin.lua
Normal file
83
gamemodes/darkrp/plugins/waterloot/cl_plugin.lua
Normal file
@@ -0,0 +1,83 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
|
||||
netstream.Hook("ixWaterLootDrinkWater", function(itemID, remainingWater)
|
||||
local amountDerma = vgui.Create("DFrame")
|
||||
amountDerma:SetSize(SScaleMin(300 / 3), SScaleMin(150 / 3))
|
||||
amountDerma:Center()
|
||||
amountDerma:SetTitle("Choisir le montant")
|
||||
DFrameFixer(amountDerma)
|
||||
|
||||
local sliderPanel = amountDerma:Add("ixNumSlider")
|
||||
sliderPanel:Dock(TOP)
|
||||
sliderPanel:DockMargin(0, SScaleMin(10 / 3), 0, SScaleMin(10 / 3))
|
||||
sliderPanel:SetTall(SScaleMin(50 / 3))
|
||||
sliderPanel:SetMax(remainingWater)
|
||||
sliderPanel:SetMin(1)
|
||||
sliderPanel:SetValue(1)
|
||||
sliderPanel.label:SetText("1%")
|
||||
sliderPanel.slider.OnValueUpdated = function(panel)
|
||||
sliderPanel.label:SetText(tostring(panel:GetValue()).."%")
|
||||
sliderPanel.label:SizeToContents()
|
||||
|
||||
sliderPanel:OnValueUpdated()
|
||||
end
|
||||
|
||||
local confirm = amountDerma:Add("DButton")
|
||||
confirm:Dock(FILL)
|
||||
confirm:SetFont("MenuFontNoClamp")
|
||||
confirm:SetText("CONFIRMER")
|
||||
confirm:SetContentAlignment(5)
|
||||
confirm.DoClick = function()
|
||||
amountDerma:Remove()
|
||||
netstream.Start("ixWaterLootDrinkWater", itemID, sliderPanel:GetValue())
|
||||
end
|
||||
end)
|
||||
|
||||
netstream.Hook("ixWaterLootCreateProgressTextCookingPot", function(entIndex, updateFinished)
|
||||
if !entIndex then return false end
|
||||
if !Entity(entIndex) or !IsValid(Entity(entIndex)) then return false end
|
||||
local entity = Entity(entIndex)
|
||||
|
||||
if updateFinished then
|
||||
entity.finished = true
|
||||
return
|
||||
elseif updateFinished == false then
|
||||
entity.finished = false
|
||||
return
|
||||
end
|
||||
|
||||
entity.deliveryTime = CurTime() + (ix.config.Get("waterFiltrationTimeNeeded", 1) * 60)
|
||||
entity.finished = false
|
||||
|
||||
entity.Draw = function()
|
||||
entity:DrawModel()
|
||||
local delTime = math.max(math.ceil(entity.deliveryTime - CurTime()), 0)
|
||||
if delTime <= 0 and entity.finished == false then return end
|
||||
if delTime <= 0 and entity.finished == true then delTime = "FAIT" end
|
||||
|
||||
local pos, ang = entity:GetPos(), entity:GetAngles()
|
||||
ang:RotateAroundAxis(entity:GetUp(), 90)
|
||||
ang:RotateAroundAxis(entity:GetRight(), -90)
|
||||
|
||||
pos = pos + entity:GetUp() * 3
|
||||
pos = pos + entity:GetForward() * 8
|
||||
|
||||
local func = function()
|
||||
ix.util.DrawText(delTime, 0, -10, color_white, 1, 5, "ixBigFont")
|
||||
end
|
||||
|
||||
cam.Start3D2D(pos, ang, .15)
|
||||
func()
|
||||
cam.End3D2D()
|
||||
end
|
||||
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/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Tuyau"
|
||||
ENT.Base = "base_entity"
|
||||
ENT.Category = "HL2 RP"
|
||||
ENT.Spawnable = true
|
||||
ENT.AdminOnly = true
|
||||
ENT.PhysgunDisable = true
|
||||
ENT.bNoPersist = true
|
||||
|
||||
if (SERVER) then
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_canal/mattpipe.mdl")
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetMoveType(MOVETYPE_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
local phys = self:GetPhysicsObject()
|
||||
if phys:IsValid() then
|
||||
phys:Wake()
|
||||
phys:EnableMotion(false)
|
||||
end
|
||||
|
||||
self:SpawnProps()
|
||||
end
|
||||
|
||||
function ENT:SpawnProps()
|
||||
local pipe = ents.Create("prop_dynamic")
|
||||
pipe:SetPos(self:GetPos() + self:GetUp() * 39 + self:GetForward() * -4.2)
|
||||
pipe:SetAngles(self:GetAngles())
|
||||
pipe:SetModel("models/props_c17/gaspipes006a.mdl")
|
||||
pipe:Activate()
|
||||
pipe:SetParent(self)
|
||||
pipe:Spawn()
|
||||
pipe:DeleteOnRemove(self)
|
||||
end
|
||||
else
|
||||
function ENT:Draw()
|
||||
self:DrawModel()
|
||||
end
|
||||
|
||||
ENT.PopulateEntityInfo = true
|
||||
|
||||
function ENT:OnPopulateEntityInfo(container)
|
||||
local name = container:AddRow("name")
|
||||
name:SetImportant()
|
||||
name:SetText("Cache à eau")
|
||||
name:SizeToContents()
|
||||
end
|
||||
end
|
||||
153
gamemodes/darkrp/plugins/waterloot/items/sh_canteen.lua
Normal file
153
gamemodes/darkrp/plugins/waterloot/items/sh_canteen.lua
Normal file
@@ -0,0 +1,153 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
ITEM.name = "Water Canteen"
|
||||
ITEM.model = "models/willardnetworks/food/prop_bar_bottle_e.mdl"
|
||||
ITEM.width = 1
|
||||
ITEM.height = 1
|
||||
ITEM.description = "A refillable metal canteen. You can fill it up with water."
|
||||
ITEM.category = "Food"
|
||||
ITEM.maxDurability = 50
|
||||
ITEM.base = "base_tools"
|
||||
|
||||
if (CLIENT) then
|
||||
function ITEM:PopulateTooltip(tooltip)
|
||||
local water = self:GetData("water", 0)
|
||||
local filtrated = self:GetData("filtrated", false) and "YES" or "NO"
|
||||
|
||||
local panel = tooltip:AddRowAfter("name", "remaining tobacco")
|
||||
panel:SetBackgroundColor(derma.GetColor("Warning", tooltip))
|
||||
panel:SetText("Remaining Water: "..water.."%")
|
||||
panel:SizeToContents()
|
||||
|
||||
local panel2 = tooltip:AddRowAfter("remaining tobacco", "filtrated")
|
||||
panel2:SetBackgroundColor(Color(100, 100, 100, 255))
|
||||
panel2:SetText("Filtrated: "..filtrated)
|
||||
panel2:SizeToContents()
|
||||
end
|
||||
end
|
||||
|
||||
ITEM.functions.drink = {
|
||||
name = "Drink Water",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/drink.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
PLUGIN:RequestDrinkWater(client, item)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.drinkquench = {
|
||||
name = "Drink Till Quenched",
|
||||
icon = "icon16/drink.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
local thirst = math.Round(client:GetCharacter():GetThirst())
|
||||
|
||||
if (!PLUGIN:CanDrinkWater(client, item)) then return false end
|
||||
if (thirst <= 1) then return false end
|
||||
|
||||
local water = item:GetData("water", 0)
|
||||
|
||||
if (water < thirst) then
|
||||
thirst = water
|
||||
end
|
||||
|
||||
PLUGIN:DrinkWater(client, item:GetID(), thirst)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.fill = {
|
||||
name = "Fill with Water",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/arrow_in.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
PLUGIN:FillEmptyWaterCannister(client, item)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.empty = {
|
||||
name = "Empty All Water",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/cancel.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
PLUGIN:EmptyWaterCannister(client, item)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.filtrate = {
|
||||
name = "Filtrate Water",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/shading.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
PLUGIN:FiltrateWater(client, item)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.fillcan = {
|
||||
name = "Fill Empty Can",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/shading.png",
|
||||
OnRun = function(item)
|
||||
local target = ix.item.list["drink_breen_water"]
|
||||
local client = item.player
|
||||
local character = client:GetCharacter()
|
||||
local emptyCan = character:GetInventory():HasItem("junk_empty_water")
|
||||
|
||||
emptyCan:Remove()
|
||||
character:GetInventory():Add("drink_breen_water")
|
||||
item:SetData("water", item:GetData("water", 0) - target.thirst)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(item)
|
||||
local target = ix.item.list["drink_breen_water"]
|
||||
if (!target or !target.thirst) then return false end
|
||||
|
||||
if (!item:GetData("filtrated", false) or item:GetData("water", 0) < target.thirst) then return false end
|
||||
|
||||
local client = item.player
|
||||
if (!IsValid(client)) then return false end
|
||||
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return false end
|
||||
|
||||
local emptyCan = character:GetInventory():HasItem("junk_empty_water")
|
||||
if (!emptyCan) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
153
gamemodes/darkrp/plugins/waterloot/items/sh_waterbottle.lua
Normal file
153
gamemodes/darkrp/plugins/waterloot/items/sh_waterbottle.lua
Normal file
@@ -0,0 +1,153 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
ITEM.name = "Bouteille d'eau"
|
||||
ITEM.model = "models/props/cs_office/water_bottle.mdl"
|
||||
ITEM.width = 1
|
||||
ITEM.height = 1
|
||||
ITEM.description = "Une bouteille d'eau est un récipient pratique et essentiel pour transporter et consommer de l'eau. Elle est généralement fabriquée en plastique ou en métal, et sa taille peut varier en fonction des besoins individuels. La bouteille d'eau est conçue pour être légère, portable et résistante aux fuites, ce qui en fait un compagnon idéal. Vous pouvez la remplir d'eau."
|
||||
ITEM.category = "Nourriture"
|
||||
ITEM.maxDurability = 25
|
||||
ITEM.base = "base_tools"
|
||||
|
||||
if (CLIENT) then
|
||||
function ITEM:PopulateTooltip(tooltip)
|
||||
local water = self:GetData("water", 0)
|
||||
local filtrated = self:GetData("filtrated", false) and "OUI" or "NON"
|
||||
|
||||
local panel = tooltip:AddRowAfter("name", "remaining tobacco")
|
||||
panel:SetBackgroundColor(derma.GetColor("Warning", tooltip))
|
||||
panel:SetText("Eau restante : "..water.."%")
|
||||
panel:SizeToContents()
|
||||
|
||||
local panel2 = tooltip:AddRowAfter("remaining tobacco", "filtrated")
|
||||
panel2:SetBackgroundColor(Color(100, 100, 100, 255))
|
||||
panel2:SetText("Filtrée : "..filtrated)
|
||||
panel2:SizeToContents()
|
||||
end
|
||||
end
|
||||
|
||||
ITEM.functions.drink = {
|
||||
name = "Boire de l'eau",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/drink.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
PLUGIN:RequestDrinkWater(client, item)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.drinkquench = {
|
||||
name = "Boire jusqu'à la soif",
|
||||
icon = "icon16/drink.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
local thirst = math.Round(client:GetCharacter():GetThirst())
|
||||
|
||||
if (!PLUGIN:CanDrinkWater(client, item)) then return false end
|
||||
if (thirst <= 1) then return false end
|
||||
|
||||
local water = item:GetData("water", 0)
|
||||
|
||||
if (water < thirst) then
|
||||
thirst = water
|
||||
end
|
||||
|
||||
PLUGIN:DrinkWater(client, item:GetID(), thirst)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.fill = {
|
||||
name = "Remplir d'eau",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/arrow_in.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
PLUGIN:FillEmptyWaterCannister(client, item)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.empty = {
|
||||
name = "Vider toute l'eau",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/cancel.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
PLUGIN:EmptyWaterCannister(client, item)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.filtrate = {
|
||||
name = "Filtrer l'eau",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/shading.png",
|
||||
OnRun = function(item)
|
||||
if (SERVER) then
|
||||
local client = item.player
|
||||
PLUGIN:FiltrateWater(client, item)
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
ITEM.functions.fillcan = {
|
||||
name = "Remplir la canette vide",
|
||||
tip = "applyTip",
|
||||
icon = "icon16/shading.png",
|
||||
OnRun = function(item)
|
||||
local target = ix.item.list["drink_breen_water"]
|
||||
local client = item.player
|
||||
local character = client:GetCharacter()
|
||||
local emptyCan = character:GetInventory():HasItem("crafting_water")
|
||||
|
||||
emptyCan:Remove()
|
||||
character:GetInventory():Add("drink_breen_water")
|
||||
item:SetData("water", item:GetData("water", 0) - target.thirst)
|
||||
return false
|
||||
end,
|
||||
OnCanRun = function(item)
|
||||
local target = ix.item.list["drink_breen_water"]
|
||||
if (!target or !target.thirst) then return false end
|
||||
|
||||
if (!item:GetData("filtrated", false) or item:GetData("water", 0) < target.thirst) then return false end
|
||||
|
||||
local client = item.player
|
||||
if (!IsValid(client)) then return false end
|
||||
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return false end
|
||||
|
||||
local emptyCan = character:GetInventory():HasItem("crafting_water")
|
||||
if (!emptyCan) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}
|
||||
44
gamemodes/darkrp/plugins/waterloot/items/sh_watervalve.lua
Normal file
44
gamemodes/darkrp/plugins/waterloot/items/sh_watervalve.lua
Normal file
@@ -0,0 +1,44 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
ITEM.name = "Valve d'eau"
|
||||
ITEM.model = "models/props/de_nuke/hr_nuke/metal_pipe_001/metal_pipe_001_gauge_valve_low.mdl"
|
||||
ITEM.width = 1
|
||||
ITEM.height = 1
|
||||
ITEM.description = "La valve d'eau est un dispositif mécanique utilisé pour contrôler et réguler le flux d'eau. Elle est généralement composée d'un boîtier en métal ou en plastique contenant une vanne qui peut être ouverte ou fermée pour permettre ou arrêter le passage de l'eau."
|
||||
ITEM.category = "Outils"
|
||||
|
||||
ITEM.functions.Place = {
|
||||
name = "Placer sur la valve d'eau",
|
||||
tip = "equipTip",
|
||||
icon = "icon16/link_add.png",
|
||||
OnRun = function(itemTable)
|
||||
if (SERVER) then
|
||||
local client = itemTable.player
|
||||
PLUGIN:PlaceValve(client, itemTable)
|
||||
|
||||
return false
|
||||
end
|
||||
end,
|
||||
|
||||
OnCanRun = function(itemTable)
|
||||
if IsValid(itemTable.entity) then return false end
|
||||
end
|
||||
}
|
||||
|
||||
function ITEM:OnTransferred(curInv, inventory)
|
||||
if (SERVER) then
|
||||
if self.waterCache and IsValid(self.waterCache) then
|
||||
self.waterCache.HasPotPlaced = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
76
gamemodes/darkrp/plugins/waterloot/sh_plugin.lua
Normal file
76
gamemodes/darkrp/plugins/waterloot/sh_plugin.lua
Normal file
@@ -0,0 +1,76 @@
|
||||
--[[
|
||||
| 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 = "Water Loot"
|
||||
PLUGIN.description = "Adds water pipe entity to loot water and possibility of retrieving water from deep water volumes, filtration required."
|
||||
PLUGIN.author = "Fruity"
|
||||
|
||||
ix.util.Include("sv_plugin.lua")
|
||||
ix.util.Include("cl_plugin.lua")
|
||||
|
||||
ix.config.Add("waterFillPerRefill", 100, "La quantité d'eau en pourcentage que doit contenir une bouteille d'eau lorsqu'elle est remplie.", nil, {
|
||||
data = {min = 1, max = 100},
|
||||
category = "Eau"
|
||||
})
|
||||
|
||||
ix.config.Add("waterFiltrationTimeNeeded", 2, "Temps en minutes nécessaire pour filtrer l'eau dans une marmite.", nil, {
|
||||
data = {min = 1, max = 60},
|
||||
category = "Eau"
|
||||
})
|
||||
|
||||
ix.config.Add("chanceToGetLeech", 50, "Pourcentage de chances d'obtenir une sangsue lors du filtrage de l'eau.", nil, {
|
||||
data = {min = 1, max = 100},
|
||||
category = "Eau"
|
||||
})
|
||||
|
||||
function PLUGIN:InitializedPlugins()
|
||||
local cookingPot = ix.item.list["tool_cookingpot"]
|
||||
if !cookingPot then return end
|
||||
|
||||
cookingPot.functions.Place = {
|
||||
name = "Placer sur la surface de cuisson",
|
||||
tip = "equipTip",
|
||||
icon = "icon16/link_add.png",
|
||||
OnRun = function(itemTable)
|
||||
if (SERVER) then
|
||||
local client = itemTable.player
|
||||
self:PlaceCookingPot(client, itemTable)
|
||||
|
||||
return false
|
||||
end
|
||||
end,
|
||||
|
||||
OnCanRun = function(itemTable)
|
||||
if IsValid(itemTable.entity) then return false end
|
||||
end
|
||||
}
|
||||
|
||||
cookingPot.OnTransferred = function(item, curInv, inventory)
|
||||
if (SERVER) then
|
||||
if item.cookingPlatform and IsValid(item.cookingPlatform) then
|
||||
item.cookingPlatform.HasPotPlaced = nil
|
||||
item.cookingPlatform:StopSound( "ambient/levels/canals/water_flow_loop1.wav" )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:CanTransferItem(itemTable, curInv, inventory)
|
||||
if itemTable and IsValid(itemTable.entity) then
|
||||
local client = itemTable.player
|
||||
if itemTable.entity.HasPotPlaced then
|
||||
if IsValid(client) then client:Notify("Ce four est surmonté d'une marmite !") end
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
439
gamemodes/darkrp/plugins/waterloot/sv_plugin.lua
Normal file
439
gamemodes/darkrp/plugins/waterloot/sv_plugin.lua
Normal file
@@ -0,0 +1,439 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
function PLUGIN:CanPlaceCookingPot(client)
|
||||
if !client then return false end
|
||||
if !client:Alive() then return false end
|
||||
|
||||
local targetEnt = client:GetEyeTraceNoCursor().Entity
|
||||
for _, v in pairs(ents.FindInSphere(client:GetPos(), 50)) do
|
||||
if v:GetClass() != "ix_campfire" then continue end
|
||||
|
||||
targetEnt = v
|
||||
break
|
||||
end
|
||||
|
||||
if !targetEnt then client:Notify("La marmite doit être sur un feu de camp ou un four !") return false end
|
||||
if !IsValid(targetEnt) then client:Notify("La marmite doit être sur un feu de camp ou un four !") return false end
|
||||
if targetEnt.HasPotPlaced then client:Notify("Il y a déjà une marmite sur ce feu de camp ou un four !") return false end
|
||||
local entClass = targetEnt:GetClass()
|
||||
|
||||
if entClass == "ix_campfire" then return targetEnt, "ix_campfire" end
|
||||
if entClass != "ix_item" then client:Notify("La marmite doit être sur un feu de camp ou un four !") return false end
|
||||
if entClass == "ix_item" and !targetEnt:GetItemTable() then client:Notify("La marmite doit être sur un feu de camp ou un four !") return false end
|
||||
local itemTable = targetEnt:GetItemTable()
|
||||
local allowedTools = {"tool_oven_rusty", "tool_oven"}
|
||||
|
||||
if entClass == "ix_item" and table.HasValue(allowedTools, itemTable.uniqueID) then return targetEnt, itemTable.uniqueID end
|
||||
end
|
||||
|
||||
function PLUGIN:PlaceCookingPot(client, item)
|
||||
local cookingSurfaceEnt, uniqueID = self:CanPlaceCookingPot(client)
|
||||
if !cookingSurfaceEnt or (cookingSurfaceEnt and !IsValid(cookingSurfaceEnt)) then return false end
|
||||
|
||||
local bSuccess, error = item:Transfer(nil, nil, nil, item.player)
|
||||
if (!bSuccess and isstring(error)) then
|
||||
client:Notify("Impossible de laisser tomber la marmite ou de placer.")
|
||||
return
|
||||
end
|
||||
|
||||
local potEntity = bSuccess
|
||||
local normPos = 45
|
||||
local rustyPos = 25
|
||||
local campPos = 32
|
||||
local zPos = (uniqueID == "ix_campfire" and campPos or uniqueID =="tool_oven_rusty" and rustyPos or normPos)
|
||||
|
||||
potEntity:SetAngles(cookingSurfaceEnt:GetAngles())
|
||||
potEntity:SetPos(cookingSurfaceEnt:GetPos() + cookingSurfaceEnt:GetUp() * zPos)
|
||||
constraint.Weld( potEntity, cookingSurfaceEnt, 0, 0, 0, true, true )
|
||||
local physObj = potEntity:GetPhysicsObject()
|
||||
if !physObj then return end
|
||||
physObj:EnableMotion(false)
|
||||
|
||||
cookingSurfaceEnt.HasPotPlaced = true
|
||||
item.cookingPlatform = cookingSurfaceEnt
|
||||
potEntity.isFiltrating = false
|
||||
potEntity.cookingPlatform = cookingSurfaceEnt
|
||||
client:EmitSound("physics/metal/metal_barrel_impact_soft1.wav")
|
||||
end
|
||||
|
||||
function PLUGIN:TargetError(client, type)
|
||||
client:Notify("Vous ne regardez pas un "..type.."!")
|
||||
end
|
||||
|
||||
function PLUGIN:CanFiltrateWater(client, item)
|
||||
if !client then return false end
|
||||
if !client:Alive() then return false end
|
||||
if item:GetData("filtrated", false) then client:Notify("Cette eau est déjà filtrée !") return false end
|
||||
if !item:GetData("water") then client:Notify("Il n’y a pas d’eau dans la bouteille !") return false end
|
||||
local currentWaterAmount = item:GetData("water", 0)
|
||||
if currentWaterAmount <= 0 then client:Notify("Il n’y a pas assez d’eau pour filtrer dans la bouteille !") return false end
|
||||
|
||||
local targetEnt = client:GetEyeTraceNoCursor().Entity
|
||||
if !targetEnt then self:TargetError(client, "cooking pot") return false end
|
||||
if !IsValid(targetEnt) then self:TargetError(client, "cooking pot") return false end
|
||||
local entClass = targetEnt:GetClass()
|
||||
if entClass != "ix_item" then self:TargetError(client, "cooking pot") return false end
|
||||
if entClass == "ix_item" and !targetEnt:GetItemTable() then self:TargetError(client, "cooking pot") return false end
|
||||
local itemTable = targetEnt:GetItemTable()
|
||||
|
||||
if itemTable.uniqueID != "tool_cookingpot" then
|
||||
client:Notify("Vous devez regarder un pot de cuisson pour filtrer cette eau.")
|
||||
return false
|
||||
end
|
||||
|
||||
local itemID = targetEnt.ixItemID
|
||||
itemTable = ix.item.instances[itemID]
|
||||
|
||||
if targetEnt.isFiltrating then client:Notify("Cette marmite filtre déjà l’eau !") return false end
|
||||
|
||||
local parent = targetEnt.cookingPlatform
|
||||
if !IsValid(parent) then client:Notify("La marmite doit être sur un feu de camp ou un four !") return false end
|
||||
local parentClass = parent:GetClass()
|
||||
if parentClass == "ix_campfire" then return targetEnt, currentWaterAmount, itemTable end
|
||||
if parentClass == "ix_item" and !parent:GetItemTable() then client:Notify("La marmite doit être sur un feu de camp ou un four !") return false end
|
||||
local allowedTools = {"tool_oven_rusty", "tool_oven"}
|
||||
if table.HasValue(allowedTools, parent:GetItemTable().uniqueID) then return targetEnt, currentWaterAmount, itemTable end
|
||||
|
||||
client:Notify("La marmite doit être sur un feu de camp ou un four!")
|
||||
return false
|
||||
end
|
||||
|
||||
function PLUGIN:FiltrateWater(client, item)
|
||||
local cookingPot, currentWaterAmount, potItem = self:CanFiltrateWater(client, item)
|
||||
if !cookingPot or cookingPot and !IsValid(cookingPot) or !currentWaterAmount then return false end
|
||||
potItem:SetData("durability", math.max(0, potItem:GetDurability() - 1))
|
||||
|
||||
if (potItem:GetDurability() == 0) then
|
||||
if cookingPot.cookingPlatform then
|
||||
cookingPot.cookingPlatform.HasPotPlaced = false
|
||||
end
|
||||
cookingPot:EmitSound("weapons/crowbar/crowbar_impact"..math.random(1, 2)..".wav", 65)
|
||||
cookingPot:Remove()
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
cookingPot.currentWaterAmount = currentWaterAmount
|
||||
item:SetData("water", 0)
|
||||
|
||||
local smoke = ents.Create( "env_smokestack" )
|
||||
smoke:SetPos(cookingPot:GetPos())
|
||||
smoke:SetAngles(cookingPot:GetAngles())
|
||||
|
||||
smoke:SetKeyValue("InitialState", "1")
|
||||
smoke:SetKeyValue("WindAngle", "0 0 0")
|
||||
smoke:SetKeyValue("WindSpeed", "0")
|
||||
smoke:SetKeyValue("rendercolor", "255 255 255")
|
||||
smoke:SetKeyValue("renderamt", "50") -- alpha
|
||||
smoke:SetKeyValue("SmokeMaterial", "particle/smokesprites_0001.vmt")
|
||||
smoke:SetKeyValue("BaseSpread", "1")
|
||||
smoke:SetKeyValue("SpreadSpeed", "3")
|
||||
smoke:SetKeyValue("Speed", "11")
|
||||
smoke:SetKeyValue("StartSize", "8")
|
||||
smoke:SetKeyValue("EndSize", "9")
|
||||
smoke:SetKeyValue("roll", "8")
|
||||
smoke:SetKeyValue("Rate", "24")
|
||||
smoke:SetKeyValue("JetLength", "46")
|
||||
smoke:SetKeyValue("twist", "6")
|
||||
smoke:Spawn()
|
||||
smoke:SetParent(cookingPot)
|
||||
smoke:Activate()
|
||||
|
||||
if (!IsValid(cookingPot.spark)) then
|
||||
cookingPot.spark = ents.Create("env_splash")
|
||||
end
|
||||
cookingPot.spark:SetPos(cookingPot:GetPos())
|
||||
cookingPot.spark:SetKeyValue( "scale", 3 )
|
||||
cookingPot.spark:Fire("Splash")
|
||||
cookingPot:DeleteOnRemove(cookingPot.spark)
|
||||
cookingPot.spark:SetParent(cookingPot)
|
||||
|
||||
if IsValid(cookingPot.cookingPlatform) then
|
||||
cookingPot.cookingPlatform:EmitSound( "ambient/levels/canals/water_flow_loop1.wav", 75, 100, 1, CHAN_AUTO )
|
||||
end
|
||||
|
||||
cookingPot:DeleteOnRemove(smoke)
|
||||
cookingPot.finished = false
|
||||
cookingPot.isFiltrating = true
|
||||
|
||||
netstream.Start(client, "ixWaterLootCreateProgressTextCookingPot", cookingPot:EntIndex())
|
||||
|
||||
local timerName = "ixWaterLootFiltrationTimer_"..cookingPot:EntIndex()
|
||||
timer.Create(timerName, ix.config.Get("waterFiltrationTimeNeeded", 1) * 60, 1, function()
|
||||
if !IsValid(cookingPot) then timer.Remove(timerName) return end
|
||||
if !item or item and !item.GetID then return false end
|
||||
|
||||
if IsValid(cookingPot.cookingPlatform) then
|
||||
cookingPot.cookingPlatform:StopSound( "ambient/levels/canals/water_flow_loop1.wav" )
|
||||
end
|
||||
|
||||
netstream.Start(client, "ixWaterLootCreateProgressTextCookingPot", cookingPot:EntIndex(), true)
|
||||
cookingPot.finished = true
|
||||
cookingPot.isFiltrating = false
|
||||
|
||||
if !IsValid(smoke) then return end
|
||||
smoke:Remove()
|
||||
end)
|
||||
end
|
||||
|
||||
function PLUGIN:IsWaterDeepEnough(client)
|
||||
local pos = client:GetPos() + Vector(0, 0, 15)
|
||||
local trace = {}
|
||||
trace.start = pos
|
||||
trace.endpos = pos + Vector(0, 0, 1)
|
||||
trace.mask = bit.bor( MASK_WATER )
|
||||
local tr = util.TraceLine(trace)
|
||||
|
||||
return tr.Hit
|
||||
end
|
||||
|
||||
function PLUGIN:FillWaterError(client)
|
||||
client:Notify("Vous ne regardez pas une valve d’eau, une marmite avec de l’eau filtrée ou vous n’êtes pas assez profond dans l’eau !")
|
||||
end
|
||||
|
||||
function PLUGIN:CanFillWaterCannister(client)
|
||||
if self:IsWaterDeepEnough(client) then return true end
|
||||
|
||||
local targetEnt = client:GetEyeTraceNoCursor().Entity
|
||||
if !targetEnt then self:FillWaterError(client) return false end
|
||||
if !IsValid(targetEnt) then self:FillWaterError(client) return false end
|
||||
local entClass = targetEnt:GetClass()
|
||||
|
||||
if entClass == "ix_watercache" and !targetEnt.HasPotPlaced then client:Notify("Il n'y a pas de valve sur le cache pour aider à prélever de l'eau !") return false end
|
||||
if entClass == "ix_watercache" and targetEnt.HasPotPlaced then return targetEnt end
|
||||
if entClass != "ix_item" then self:FillWaterError(client) return false end
|
||||
if entClass == "ix_item" and !targetEnt:GetItemTable() then self:FillWaterError(client) return false end
|
||||
local itemTable = targetEnt:GetItemTable()
|
||||
if itemTable.uniqueID != "tool_cookingpot" then
|
||||
self:FillWaterError(client)
|
||||
return false
|
||||
else
|
||||
return targetEnt
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:FillEmptyWaterCannister(client, item)
|
||||
if item:GetData("water", 0) >= 100 then client:Notify("Cette bouteille d’eau est déjà pleine.") return false end
|
||||
local target = self:CanFillWaterCannister(client)
|
||||
if !target then return false end
|
||||
|
||||
if isbool(target) or target:GetClass() == "ix_watercache" then
|
||||
local newValue = math.Clamp(item:GetData("water", 0) + ix.config.Get("waterFillPerRefill", 100), 0, 100)
|
||||
client:Notify("Vous avez rempli "..item:GetName().." à "..newValue.."%")
|
||||
|
||||
item:SetData("filtrated", false)
|
||||
item:SetData("water", newValue)
|
||||
client:EmitSound("ambient/water/water_spray1.wav")
|
||||
|
||||
local leechChance = ix.config.Get("chanceToGetLeech", 50)
|
||||
if self:CalcLeechChance(leechChance) then
|
||||
local itemTable = ix.item.list["ing_raw_leech"]
|
||||
local character = client:GetCharacter()
|
||||
local inventory = character:GetInventory()
|
||||
if IsValid(client) and character and inventory then
|
||||
if (!inventory:FindEmptySlot(itemTable.width, itemTable.height)) then
|
||||
return false
|
||||
end
|
||||
|
||||
inventory:Add("ing_raw_leech")
|
||||
end
|
||||
end
|
||||
|
||||
item:DamageDurability(1)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if IsEntity(target) then
|
||||
if !target.currentWaterAmount then client:Notify("Il n’y a pas d’eau dans cette marmite !") return false end
|
||||
if !target.finished then client:Notify("Cette marmite n’a pas encore bouillie!") return false end
|
||||
if item:GetData("water", 0) > 0 and !item:GetData("filtrated", false) then client:Notify("Cette bouteille contient de l'eau non filtrée !") return false end
|
||||
|
||||
item:SetData("water", target.currentWaterAmount)
|
||||
item:SetData("filtrated", true)
|
||||
|
||||
netstream.Start(client, "ixWaterLootCreateProgressTextCookingPot", target:EntIndex(), false)
|
||||
target.currentWaterAmount = nil
|
||||
target.finished = false
|
||||
client:EmitSound("ambient/water/water_spray1.wav")
|
||||
|
||||
if (!IsValid(target.spark)) then
|
||||
target.spark = ents.Create("env_splash")
|
||||
end
|
||||
|
||||
target.spark:SetPos(target:GetPos())
|
||||
target.spark:SetKeyValue( "scale", 3 )
|
||||
target.spark:Fire("Splash")
|
||||
target:DeleteOnRemove(target.spark)
|
||||
target.spark:SetParent(target)
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:CalcLeechChance(percentage)
|
||||
return math.random() < percentage / 100
|
||||
end
|
||||
|
||||
function PLUGIN:EmptyWaterCannister(client, item)
|
||||
if !client then return false end
|
||||
if !client:Alive() then return false end
|
||||
|
||||
if item:GetData("water", 0) > 0 then
|
||||
item:SetData("water", 0)
|
||||
client:EmitSound("ambient/water/water_spray1.wav")
|
||||
else
|
||||
client:Notify("Il n’y a pas d’eau à vider dans cette bouteille !")
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:CanDrinkWater(client, item)
|
||||
if !client then return false end
|
||||
if !client:Alive() then return false end
|
||||
if !item:GetData("water") then client:Notify("Il n’y a pas d’eau dans cette bouteille !") return false end
|
||||
if item:GetData("water", 0) <= 0 then client:Notify("Il n’y a pas assez d’eau dans cette bouteille !") return false end
|
||||
|
||||
if (ix.faction.Get(client:Team()).bDrinkUnfilteredWater) then return true end
|
||||
|
||||
if !item:GetData("filtrated", false) then client:Notify("Cette eau n’est pas filtrée !") return false end
|
||||
|
||||
return item:GetData("filtrated", false)
|
||||
end
|
||||
|
||||
function PLUGIN:DrinkWater(client, itemID, waterAmount)
|
||||
if !ix.item.instances[itemID] then return false end
|
||||
local item = ix.item.instances[itemID]
|
||||
|
||||
local character = client:GetCharacter()
|
||||
if !character then return false end
|
||||
|
||||
local inventory = character:GetInventory()
|
||||
if !inventory then return false end
|
||||
|
||||
if !inventory:GetItems()[itemID] then
|
||||
local targetEnt = client:GetEyeTraceNoCursor().Entity
|
||||
if !targetEnt then return false end
|
||||
if !IsValid(targetEnt) then return false end
|
||||
if targetEnt:GetClass() != "ix_item" then return false end
|
||||
if targetEnt.ixItemID and targetEnt.ixItemID != itemID then return false end
|
||||
end
|
||||
|
||||
if !self:CanDrinkWater(client, item) then return false end
|
||||
if item:GetData("water", 0) < waterAmount then client:Notify("Vous essayez de boire plus d’eau qu’il n’y en a dans la bouteille!") return false end
|
||||
|
||||
item:SetData("water", item:GetData("water", 0) - waterAmount)
|
||||
character:SetThirst(math.Clamp(character:GetThirst() - math.ceil(waterAmount), 0, 100))
|
||||
client:EmitSound("npc/barnacle/barnacle_gulp2.wav")
|
||||
end
|
||||
|
||||
function PLUGIN:RequestDrinkWater(client, item)
|
||||
if !self:CanDrinkWater(client, item) then return false end
|
||||
netstream.Start(client, "ixWaterLootDrinkWater", item:GetID(), item:GetData("water", 0))
|
||||
end
|
||||
|
||||
function PLUGIN:CanPlaceValve(client, item)
|
||||
if !client then return false end
|
||||
if !client:Alive() then return false end
|
||||
|
||||
local targetEnt = client:GetEyeTraceNoCursor().Entity
|
||||
if !targetEnt then client:Notify("Vous ne regardez pas une cache d’eau !") return false end
|
||||
if !IsValid(targetEnt) then client:Notify("Vous ne regardez pas une cache d’eau !") return false end
|
||||
local entClass = targetEnt:GetClass()
|
||||
if entClass != "ix_watercache" then client:Notify("Vous ne regardez pas une cache d’eau !") return false end
|
||||
if targetEnt.HasPotPlaced then client:Notify("Il y a déjà une valve sur cette cache d’eau !") return false end
|
||||
|
||||
return targetEnt
|
||||
end
|
||||
|
||||
function PLUGIN:PlaceValve(client, item)
|
||||
local waterCacheEnt = self:CanPlaceValve(client, item)
|
||||
if !waterCacheEnt or (waterCacheEnt and !IsValid(waterCacheEnt)) then return false end
|
||||
|
||||
local bSuccess, error = item:Transfer(nil, nil, nil, item.player)
|
||||
if (!bSuccess and isstring(error)) then
|
||||
client:Notify("Impossible de faire tomber la vanne d’eau et de la placer.")
|
||||
return
|
||||
end
|
||||
|
||||
local waterValve = bSuccess
|
||||
local rotation = Vector(90, 0, 0)
|
||||
local angle = waterCacheEnt:GetAngles()
|
||||
angle:RotateAroundAxis(angle:Up(), rotation.x)
|
||||
|
||||
waterValve:SetAngles(angle)
|
||||
waterValve:SetPos(waterCacheEnt:GetPos() + waterCacheEnt:GetUp() * -12.5)
|
||||
constraint.Weld( waterValve, waterCacheEnt, 0, 0, 0, true, true )
|
||||
local physObj = waterValve:GetPhysicsObject()
|
||||
if !physObj then return end
|
||||
physObj:EnableMotion(false)
|
||||
|
||||
waterCacheEnt.HasPotPlaced = true
|
||||
item.waterCache = waterCacheEnt
|
||||
end
|
||||
|
||||
function PLUGIN:RegisterSaveEnts()
|
||||
ix.saveEnts:RegisterEntity("ix_watercache", true, true, true, {
|
||||
OnSave = function(entity, data) --OnSave
|
||||
return {pos = data.pos, angles = data.angles + Angle(0, 180, 0), motion = false}
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
function PLUGIN:LoadWaterCaches()
|
||||
if (!ix.config.Get("SaveEntsOldLoadingEnabled")) then return end
|
||||
|
||||
local waterCaches = ix.data.Get("watercaches")
|
||||
if waterCaches then
|
||||
for _, v in pairs(waterCaches) do
|
||||
local entity = ents.Create("ix_watercache")
|
||||
entity:SetAngles(v.angles)
|
||||
entity:SetPos(v.position)
|
||||
entity:Spawn()
|
||||
|
||||
local physicsObject = entity:GetPhysicsObject()
|
||||
if (IsValid(physicsObject)) then
|
||||
physicsObject:EnableMotion(false)
|
||||
end
|
||||
end
|
||||
MsgC(Color(0, 255, 0), "[WATER LOOT] Valve d’eau chargées.\n")
|
||||
else
|
||||
MsgC(Color(0, 255, 0), "[WATER LOOT] Aucune valve d’eau chargée.\n")
|
||||
end
|
||||
end
|
||||
|
||||
-- A function to save the static props.
|
||||
function PLUGIN:SaveWaterCaches()
|
||||
local waterCaches = {}
|
||||
|
||||
for _, v in pairs(ents.FindByClass("ix_watercache")) do
|
||||
waterCaches[#waterCaches + 1] = {
|
||||
angles = v:GetAngles(),
|
||||
position = v:GetPos()
|
||||
}
|
||||
end
|
||||
|
||||
ix.data.Set("watercaches", waterCaches)
|
||||
end
|
||||
|
||||
-- Called when Helix has loaded all of the entities.
|
||||
function PLUGIN:InitPostEntity()
|
||||
self:LoadWaterCaches()
|
||||
end
|
||||
|
||||
-- Called just after data should be saved.
|
||||
function PLUGIN:SaveData()
|
||||
self:SaveWaterCaches()
|
||||
end
|
||||
|
||||
netstream.Hook("ixWaterLootDrinkWater", function(client, itemID, waterAmount)
|
||||
PLUGIN:DrinkWater(client, itemID, waterAmount)
|
||||
end)
|
||||
Reference in New Issue
Block a user