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

View File

@@ -0,0 +1,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)

View File

@@ -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

View 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
}

View 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
}

View 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

View 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

View 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 ny a pas deau dans la bouteille !") return false end
local currentWaterAmount = item:GetData("water", 0)
if currentWaterAmount <= 0 then client:Notify("Il ny a pas assez deau 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à leau !") 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 deau, une marmite avec de leau filtrée ou vous nêtes pas assez profond dans leau !")
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 deau 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 ny a pas deau dans cette marmite !") return false end
if !target.finished then client:Notify("Cette marmite na 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 ny a pas deau à 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 ny a pas deau dans cette bouteille !") return false end
if item:GetData("water", 0) <= 0 then client:Notify("Il ny a pas assez deau 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 nest 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 deau quil ny 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 deau !") return false end
if !IsValid(targetEnt) then client:Notify("Vous ne regardez pas une cache deau !") return false end
local entClass = targetEnt:GetClass()
if entClass != "ix_watercache" then client:Notify("Vous ne regardez pas une cache deau !") return false end
if targetEnt.HasPotPlaced then client:Notify("Il y a déjà une valve sur cette cache deau !") 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 deau 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 deau chargées.\n")
else
MsgC(Color(0, 255, 0), "[WATER LOOT] Aucune valve deau 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)