mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
218
gamemodes/darkrp/plugins/fatigue_system/cl_plugin.lua
Normal file
218
gamemodes/darkrp/plugins/fatigue_system/cl_plugin.lua
Normal file
@@ -0,0 +1,218 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
PLUGIN.energyConsumptionRateTooltips = {
|
||||
[1] = {
|
||||
maxRate = 0.002,
|
||||
color = "green",
|
||||
text = "This item is lightweight"
|
||||
},
|
||||
[2] = {
|
||||
maxRate = 0.004,
|
||||
color = "yellow",
|
||||
text = "This item is of medium weight"
|
||||
}
|
||||
}
|
||||
|
||||
function PLUGIN:PopulateItemTooltip(tooltip, item)
|
||||
if (item.energyConsumptionRate) then
|
||||
local color, text
|
||||
|
||||
for _, info in ipairs(self.energyConsumptionRateTooltips) do
|
||||
if (item.energyConsumptionRate <= info.maxRate) then
|
||||
color, text = info.color, info.text
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (!color) then
|
||||
color, text = "red", "This item is pretty heavy"
|
||||
end
|
||||
|
||||
local appendix = tooltip:Add("DLabel")
|
||||
appendix:SetText(text)
|
||||
appendix:SetTextColor(ix.hud.appendixColors[color] or color_white)
|
||||
appendix:SetTextInset(15, 0)
|
||||
appendix:Dock(BOTTOM)
|
||||
appendix:DockMargin(0, 0, 0, 5)
|
||||
appendix:SetFont("ixSmallFont")
|
||||
appendix:SizeToContents()
|
||||
appendix:SetTall(appendix:GetTall() + 15)
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:AdjustInnerStatusPanel(innerStatus, CreateTitle, CreateSubBar)
|
||||
local smallerIconSize = SScaleMin(16 / 3)
|
||||
local energyPanel = innerStatus:Add("Panel")
|
||||
local energy = LocalPlayer():GetCharacter():GetEnergy()
|
||||
local energyText
|
||||
|
||||
for _, v in ipairs(self.energyStatusSubBars) do
|
||||
if (energy <= v.minLevel) then
|
||||
energyText = v.text
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (!energyText) then
|
||||
energyText = "Rested"
|
||||
end
|
||||
|
||||
CreateSubBar(energyPanel, "willardnetworks/hud/stamina.png", "Energy", energyText, smallerIconSize, smallerIconSize)
|
||||
end
|
||||
|
||||
function PLUGIN:RestingEntity_FindValidSequenceOptions(entityModel, client, actName)
|
||||
local sequences = self:FindModelActSequences(client, actName)
|
||||
|
||||
if (!sequences) then
|
||||
return
|
||||
end
|
||||
|
||||
local validSequences = self.restingEntities[entityModel].sequences
|
||||
local options = {}
|
||||
|
||||
for k, v in ipairs(sequences) do
|
||||
if (!validSequences[v]) then
|
||||
continue
|
||||
end
|
||||
|
||||
options[actName .. " " .. k] = function()
|
||||
return {actName = actName, sequenceID = k}
|
||||
end
|
||||
end
|
||||
|
||||
return options
|
||||
end
|
||||
|
||||
function PLUGIN:InitializedPlugins3()
|
||||
self.energyStatusSubBars = {
|
||||
[1] = {
|
||||
minLevel = ix.config.Get("energyLevelToApplyDebuffs", 50),
|
||||
text = "Fatigued"
|
||||
},
|
||||
[2] = {
|
||||
minLevel = 100,
|
||||
text = "Normal"
|
||||
}
|
||||
}
|
||||
|
||||
--[[ OVERRIDES ]]--
|
||||
local WNSkillPanel = vgui.GetControlTable("WNSkillPanel")
|
||||
|
||||
function WNSkillPanel:CreateBoostInfo(boostPanel, skill)
|
||||
local character = LocalPlayer():GetCharacter()
|
||||
local attributes = ix.special.list or {}
|
||||
local skillAttributes = {}
|
||||
|
||||
-- Find the attributes that boost the skill
|
||||
for _, v in pairs(attributes) do
|
||||
if v.skills then
|
||||
if v.skills[skill.uniqueID] then
|
||||
skillAttributes[v.skills[skill.uniqueID]] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if skillAttributes[2] then
|
||||
local boostedByLabel = boostPanel:Add("DLabel")
|
||||
boostedByLabel:SetText("Major boost from " .. skillAttributes[2].name)
|
||||
boostedByLabel:SetFont("MenuFontBoldNoClamp")
|
||||
boostedByLabel:SetContentAlignment(4)
|
||||
boostedByLabel:SizeToContents()
|
||||
boostedByLabel:Dock(TOP)
|
||||
end
|
||||
|
||||
if skillAttributes[1] then
|
||||
local boostedByLabel = boostPanel:Add("DLabel")
|
||||
boostedByLabel:SetText("Minor boost from " .. skillAttributes[1].name)
|
||||
boostedByLabel:SetFont("MenuFontBoldNoClamp")
|
||||
boostedByLabel:SetContentAlignment(4)
|
||||
boostedByLabel:SizeToContents()
|
||||
boostedByLabel:Dock(TOP)
|
||||
end
|
||||
|
||||
local varBoostLevel = character:GetSkillBoostLevels(skill.uniqueID)
|
||||
local varNeedsLevel, reducedEnergy, reducedHunger, reducedThirst, reducedGas, reducedHealth = character:GetSkillNeedsReducing(skill.uniqueID)
|
||||
|
||||
if (varBoostLevel > 0) then
|
||||
-- ATLE HAPPY
|
||||
local boostedLevels = boostPanel:Add("DLabel")
|
||||
boostedLevels:Dock(TOP)
|
||||
boostedLevels:SetContentAlignment(4)
|
||||
boostedLevels:SetFont("MenuFontLargerBoldNoFix")
|
||||
boostedLevels:SetTextColor(Color(75, 238, 75))
|
||||
boostedLevels:SetText("Boosted Levels: +" .. varBoostLevel)
|
||||
boostedLevels:SizeToContents()
|
||||
end
|
||||
|
||||
if (varNeedsLevel > 0) then
|
||||
if (reducedEnergy) then
|
||||
local energyReducing = boostPanel:Add("DLabel")
|
||||
energyReducing:Dock(TOP)
|
||||
energyReducing:SetContentAlignment(4)
|
||||
energyReducing:SetFont("MenuFontLargerBoldNoFix")
|
||||
energyReducing:SetTextColor(Color(238, 75, 75))
|
||||
energyReducing:SetText("-" .. math.Round(reducedEnergy, 1) .. " levels due to Fatigue")
|
||||
energyReducing:SizeToContents()
|
||||
end
|
||||
|
||||
if (reducedHunger) then
|
||||
local hungerReducing = boostPanel:Add("DLabel")
|
||||
hungerReducing:Dock(TOP)
|
||||
hungerReducing:SetContentAlignment(4)
|
||||
hungerReducing:SetFont("MenuFontLargerBoldNoFix")
|
||||
hungerReducing:SetTextColor(Color(238, 75, 75))
|
||||
hungerReducing:SetText("-" .. math.Round(reducedHunger, 1) .. " levels due to Hunger")
|
||||
hungerReducing:SizeToContents()
|
||||
end
|
||||
|
||||
if (reducedThirst) then
|
||||
local thirstReducing = boostPanel:Add("DLabel")
|
||||
thirstReducing:Dock(TOP)
|
||||
thirstReducing:SetContentAlignment(4)
|
||||
thirstReducing:SetFont("MenuFontLargerBoldNoFix")
|
||||
thirstReducing:SetTextColor(Color(238, 75, 75))
|
||||
thirstReducing:SetText("-" .. math.Round(reducedThirst, 1) .. " levels due to Thirst")
|
||||
thirstReducing:SizeToContents()
|
||||
end
|
||||
|
||||
if (reducedGas) then
|
||||
local gasReducing = boostPanel:Add("DLabel")
|
||||
gasReducing:Dock(TOP)
|
||||
gasReducing:SetContentAlignment(4)
|
||||
gasReducing:SetFont("MenuFontLargerBoldNoFix")
|
||||
gasReducing:SetTextColor(Color(238, 75, 75))
|
||||
gasReducing:SetText("-" .. math.Round(reducedGas, 1) .. " levels due to Spores")
|
||||
gasReducing:SizeToContents()
|
||||
end
|
||||
|
||||
if (reducedHealth) then
|
||||
local healthReducing = boostPanel:Add("DLabel")
|
||||
healthReducing:Dock(TOP)
|
||||
healthReducing:SetContentAlignment(4)
|
||||
healthReducing:SetFont("MenuFontLargerBoldNoFix")
|
||||
healthReducing:SetTextColor(Color(238, 75, 75))
|
||||
healthReducing:SetText("-" .. math.Round(reducedHealth, 1) .. " levels due to Injuries")
|
||||
healthReducing:SizeToContents()
|
||||
end
|
||||
|
||||
local needsReducing = boostPanel:Add("DLabel")
|
||||
needsReducing:Dock(TOP)
|
||||
needsReducing:SetContentAlignment(4)
|
||||
needsReducing:SetFont("MenuFontLargerBoldNoFix")
|
||||
needsReducing:SetTextColor(Color(238, 75, 75))
|
||||
needsReducing:SetText("Total Reduced Levels: -" .. varNeedsLevel)
|
||||
needsReducing:SizeToContents()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
include("shared.lua")
|
||||
@@ -0,0 +1,111 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_WORLD)
|
||||
|
||||
self.seatsOccupiers = {}
|
||||
|
||||
self:SetIsFirstSeatOccupied(false)
|
||||
self:SetIsSecondSeatOccupied(false)
|
||||
|
||||
local physObj = self:GetPhysicsObject()
|
||||
|
||||
if (IsValid(physObj)) then
|
||||
physObj:EnableMotion(false)
|
||||
physObj:Sleep()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnOptionSelected(client, option, data)
|
||||
if (!istable(data) or data.actName != "Down" or !isnumber(data.sequenceID)) then
|
||||
return
|
||||
end
|
||||
|
||||
local seatToOccupy, seatOccupyFunc
|
||||
|
||||
if (!self:GetIsFirstSeatOccupied()) then
|
||||
seatToOccupy, seatOccupyFunc = 1, self.SetIsFirstSeatOccupied
|
||||
elseif (!self:GetIsSecondSeatOccupied()) then
|
||||
seatToOccupy, seatOccupyFunc = 2, self.SetIsSecondSeatOccupied
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
local entityData, sequence, sequenceData = PLUGIN:RestingEntity_FindSequenceNameAndDataByID(self:GetModel(), client, data.actName, data.sequenceID)
|
||||
|
||||
if (!sequence) then
|
||||
return
|
||||
end
|
||||
|
||||
client.ixRestingInfo = {
|
||||
entity = self,
|
||||
enterPos = {client:GetPos(), client:EyeAngles()},
|
||||
seatsOccupyFuncs = {[seatToOccupy] = seatOccupyFunc}
|
||||
}
|
||||
|
||||
local angleYawOffset, rightOffset, forwardOffset, upOffset
|
||||
|
||||
if (istable(sequenceData)) then
|
||||
angleYawOffset = sequenceData.angleYawOffset
|
||||
rightOffset = sequenceData.rightOffset or 1
|
||||
forwardOffset = sequenceData.forwardOffset or 1
|
||||
upOffset = sequenceData.upOffset or 1
|
||||
else
|
||||
rightOffset, forwardOffset, upOffset = zero_angle, 1, 1, 1
|
||||
end
|
||||
|
||||
if (seatToOccupy == 2 and entityData.secondOffsets) then
|
||||
local secondOffsets = entityData.secondOffsets
|
||||
|
||||
rightOffset = rightOffset * (secondOffsets.rightOffset or 1)
|
||||
forwardOffset = forwardOffset * (secondOffsets.forwardOffset or 1)
|
||||
upOffset = upOffset * (secondOffsets.upOffset or 1)
|
||||
end
|
||||
|
||||
local clientNewAngles = self:GetAngles()
|
||||
|
||||
if (angleYawOffset) then
|
||||
clientNewAngles:Add(Angle(0, angleYawOffset, 0))
|
||||
end
|
||||
|
||||
client:SetAngles(clientNewAngles)
|
||||
client:SetPos(self:GetPos() + self:GetRight() * rightOffset + self:GetForward() * forwardOffset + self:GetUp() * upOffset)
|
||||
client:SetCollisionGroup(COLLISION_GROUP_WORLD)
|
||||
|
||||
self.seatsOccupiers[seatToOccupy] = client
|
||||
seatOccupyFunc(self, true)
|
||||
|
||||
PLUGIN:EnterUntimedAct(client, sequence)
|
||||
end
|
||||
|
||||
function PLUGIN:OnRemove()
|
||||
for _, client in pairs(self.seatsOccupiers) do
|
||||
local enterPos = client.ixRestingInfo.enterPos
|
||||
|
||||
client:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||||
client:SetPos(enterPos[1])
|
||||
client:SetEyeAngles(enterPos[2])
|
||||
|
||||
client.ixRestingInfo = nil
|
||||
client:LeaveSequence()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Bed"
|
||||
ENT.Spawnable = false
|
||||
ENT.bNoPersist = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Bool", 0, "IsFirstSeatOccupied")
|
||||
self:NetworkVar("Bool", 1, "IsSecondSeatOccupied")
|
||||
end
|
||||
|
||||
function ENT:GetEntityMenu(client)
|
||||
if (client:GetNetVar("actEnterAngle") or (self:GetIsFirstSeatOccupied() and self:GetIsSecondSeatOccupied())) then
|
||||
return
|
||||
end
|
||||
|
||||
return PLUGIN:RestingEntity_FindValidSequenceOptions(self:GetModel(), client, "Down")
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
include("shared.lua")
|
||||
@@ -0,0 +1,90 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_WORLD)
|
||||
|
||||
self:SetIsOccupied(false)
|
||||
|
||||
local physObj = self:GetPhysicsObject()
|
||||
|
||||
if (IsValid(physObj)) then
|
||||
physObj:EnableMotion(false)
|
||||
physObj:Sleep()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnOptionSelected(client, option, data)
|
||||
if (!istable(data) or !isstring(data.actName) or data.actName != self:GetValidActName() or !isnumber(data.sequenceID) or self:GetIsOccupied()) then
|
||||
return
|
||||
end
|
||||
|
||||
local _, sequence, sequenceData = PLUGIN:RestingEntity_FindSequenceNameAndDataByID(self:GetModel(), client, data.actName, data.sequenceID)
|
||||
|
||||
if (!sequence) then
|
||||
return
|
||||
end
|
||||
|
||||
client.ixRestingInfo = {
|
||||
entity = self,
|
||||
enterPos = {client:GetPos(), client:EyeAngles()},
|
||||
seatOccupyFunc = self.SetIsOccupied
|
||||
}
|
||||
|
||||
local angleYawOffset, rightOffset, forwardOffset, upOffset
|
||||
|
||||
if (istable(sequenceData)) then
|
||||
angleYawOffset = sequenceData.angleYawOffset
|
||||
rightOffset = sequenceData.rightOffset or 1
|
||||
forwardOffset = sequenceData.forwardOffset or 1
|
||||
upOffset = sequenceData.upOffset or 1
|
||||
else
|
||||
rightOffset, forwardOffset, upOffset = zero_angle, 1, 1, 1
|
||||
end
|
||||
|
||||
local clientNewAngles = self:GetAngles()
|
||||
|
||||
if (angleYawOffset) then
|
||||
clientNewAngles:Add(Angle(0, angleYawOffset, 0))
|
||||
end
|
||||
|
||||
client:SetAngles(clientNewAngles)
|
||||
client:SetPos(self:GetPos() + self:GetRight() * rightOffset + self:GetForward() * forwardOffset + self:GetUp() * upOffset)
|
||||
client:SetCollisionGroup(COLLISION_GROUP_WORLD)
|
||||
|
||||
self.occupier = client
|
||||
self:SetIsOccupied(true)
|
||||
|
||||
PLUGIN:EnterUntimedAct(client, sequence)
|
||||
end
|
||||
|
||||
function PLUGIN:OnRemove()
|
||||
if (IsValid(self.occupier)) then
|
||||
local enterPos = self.occupier.ixRestingInfo.enterPos
|
||||
|
||||
self.occupier:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||||
self.occupier:SetPos(enterPos[1])
|
||||
self.occupier:SetEyeAngles(enterPos[2])
|
||||
|
||||
self.occupier.ixRestingInfo = nil
|
||||
self.occupier:LeaveSequence()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Chair"
|
||||
ENT.Spawnable = false
|
||||
ENT.bNoPersist = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Bool", 0, "IsOccupied")
|
||||
self:NetworkVar("String", 0, "ValidActName")
|
||||
end
|
||||
|
||||
function ENT:GetEntityMenu(client)
|
||||
if (client:GetNetVar("actEnterAngle") or self:GetIsOccupied()) then
|
||||
return
|
||||
end
|
||||
|
||||
return PLUGIN:RestingEntity_FindValidSequenceOptions(self:GetModel(), client, self:GetValidActName())
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
include("shared.lua")
|
||||
@@ -0,0 +1,129 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
local PLUGIN = PLUGIN
|
||||
|
||||
include("shared.lua")
|
||||
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:PhysicsInit(SOLID_VPHYSICS)
|
||||
self:SetSolid(SOLID_VPHYSICS)
|
||||
self:SetUseType(SIMPLE_USE)
|
||||
self:SetCollisionGroup(COLLISION_GROUP_WORLD)
|
||||
|
||||
self.seatsOccupiers = {}
|
||||
|
||||
self:SetIsFirstSeatOccupied(false)
|
||||
self:SetIsSecondSeatOccupied(false)
|
||||
|
||||
local physObj = self:GetPhysicsObject()
|
||||
|
||||
if (IsValid(physObj)) then
|
||||
physObj:EnableMotion(false)
|
||||
physObj:Sleep()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnOptionSelected(client, option, data)
|
||||
if (!istable(data) or !isstring(data.actName) or !isnumber(data.sequenceID)) then
|
||||
return
|
||||
end
|
||||
|
||||
local bIsSitAct = data.actName == "Sit"
|
||||
local bIsDownAct = data.actName == "Down"
|
||||
|
||||
if (!bIsSitAct and !bIsDownAct) then
|
||||
return
|
||||
end
|
||||
|
||||
local bIsFirstSeatOccupied = self:GetIsFirstSeatOccupied()
|
||||
local bIsSecondSeatOccupied = self:GetIsSecondSeatOccupied()
|
||||
local seatsOccupyFuncs = {}
|
||||
|
||||
if (bIsSitAct) then
|
||||
if (!bIsFirstSeatOccupied) then
|
||||
seatsOccupyFuncs[1] = self.SetIsFirstSeatOccupied
|
||||
elseif (!bIsSecondSeatOccupied) then
|
||||
seatsOccupyFuncs[2] = self.SetIsSecondSeatOccupied
|
||||
else
|
||||
return
|
||||
end
|
||||
elseif (!bIsFirstSeatOccupied and !bIsSecondSeatOccupied) then
|
||||
seatsOccupyFuncs[1] = self.SetIsFirstSeatOccupied
|
||||
seatsOccupyFuncs[2] = self.SetIsSecondSeatOccupied
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
local entityData, sequence, sequenceData = PLUGIN:RestingEntity_FindSequenceNameAndDataByID(self:GetModel(), client, data.actName, data.sequenceID)
|
||||
|
||||
if (!sequence) then
|
||||
return
|
||||
end
|
||||
|
||||
client.ixRestingInfo = {
|
||||
entity = self,
|
||||
enterPos = {client:GetPos(), client:EyeAngles()},
|
||||
seatsOccupyFuncs = seatsOccupyFuncs
|
||||
}
|
||||
|
||||
local angleYawOffset, rightOffset, forwardOffset, upOffset
|
||||
|
||||
if (istable(sequenceData)) then
|
||||
angleYawOffset = sequenceData.angleYawOffset
|
||||
rightOffset = sequenceData.rightOffset or 1
|
||||
forwardOffset = sequenceData.forwardOffset or 1
|
||||
upOffset = sequenceData.upOffset or 1
|
||||
else
|
||||
rightOffset, forwardOffset, upOffset = zero_angle, 1, 1, 1
|
||||
end
|
||||
|
||||
if (!seatsOccupyFuncs[1] and entityData.secondOffsets) then
|
||||
local secondOffsets = entityData.secondOffsets
|
||||
|
||||
rightOffset = rightOffset * (secondOffsets.rightOffset or 1)
|
||||
forwardOffset = forwardOffset * (secondOffsets.forwardOffset or 1)
|
||||
upOffset = upOffset * (secondOffsets.upOffset or 1)
|
||||
end
|
||||
|
||||
local clientNewAngles = self:GetAngles()
|
||||
|
||||
if (angleYawOffset) then
|
||||
clientNewAngles:Add(Angle(0, angleYawOffset, 0))
|
||||
end
|
||||
|
||||
client:SetAngles(clientNewAngles)
|
||||
client:SetPos(self:GetPos() + self:GetRight() * rightOffset + self:GetForward() * forwardOffset + self:GetUp() * upOffset)
|
||||
client:SetCollisionGroup(COLLISION_GROUP_WORLD)
|
||||
|
||||
for k, func in pairs(seatsOccupyFuncs) do
|
||||
self.seatsOccupiers[k] = client
|
||||
func(self, true)
|
||||
end
|
||||
|
||||
PLUGIN:EnterUntimedAct(client, sequence)
|
||||
end
|
||||
|
||||
function PLUGIN:OnRemove()
|
||||
for _, client in pairs(self.seatsOccupiers) do
|
||||
local enterPos = client.ixRestingInfo.enterPos
|
||||
|
||||
client:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||||
client:SetPos(enterPos[1])
|
||||
client:SetEyeAngles(enterPos[2])
|
||||
|
||||
client.ixRestingInfo = nil
|
||||
client:LeaveSequence()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
ENT.Type = "anim"
|
||||
ENT.PrintName = "Couch"
|
||||
ENT.Spawnable = false
|
||||
ENT.bNoPersist = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
self:NetworkVar("Bool", 0, "IsFirstSeatOccupied")
|
||||
self:NetworkVar("Bool", 1, "IsSecondSeatOccupied")
|
||||
end
|
||||
|
||||
function ENT:GetEntityMenu(client)
|
||||
if (client:GetNetVar("actEnterAngle")) then
|
||||
return
|
||||
end
|
||||
|
||||
local bIsFirstSeatOccupied = self:GetIsFirstSeatOccupied()
|
||||
local bIsSecondSeatOccupied = self:GetIsSecondSeatOccupied()
|
||||
|
||||
if (bIsFirstSeatOccupied and bIsSecondSeatOccupied) then
|
||||
return
|
||||
end
|
||||
|
||||
local model = self:GetModel()
|
||||
local options = PLUGIN:RestingEntity_FindValidSequenceOptions(model, client, "Sit")
|
||||
|
||||
if (!bIsFirstSeatOccupied and !bIsSecondSeatOccupied) then
|
||||
local downOptions = PLUGIN:RestingEntity_FindValidSequenceOptions(model, client, "Down")
|
||||
|
||||
for k, v in pairs(downOptions) do
|
||||
options[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
return options
|
||||
end
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
--[[
|
||||
| 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.char.RegisterVar("energy", {
|
||||
default = 100,
|
||||
bNoDisplay = true
|
||||
})
|
||||
@@ -0,0 +1,63 @@
|
||||
--[[
|
||||
| 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
|
||||
|
||||
ix.char.RegisterVar("energy", {
|
||||
field = "energy",
|
||||
fieldType = ix.type.number,
|
||||
default = 100,
|
||||
isLocal = true,
|
||||
bNoDisplay = true,
|
||||
OnSet = function(self, newEnergy, bNoNetwork)
|
||||
newEnergy = newEnergy and math.max(newEnergy, 0) or 0
|
||||
|
||||
if (self.vars.energy == newEnergy) then
|
||||
return false
|
||||
end
|
||||
|
||||
self.vars.energy = newEnergy
|
||||
|
||||
if (!bNoNetwork) then
|
||||
net.Start("ixCharacterVarChanged")
|
||||
net.WriteUInt(self:GetID(), 32)
|
||||
net.WriteString("energy")
|
||||
net.WriteType(self.vars.energy)
|
||||
net.Send(self:GetPlayer())
|
||||
end
|
||||
|
||||
--hook.Run("CharacterVarChanged", self, key, oldVar, value)
|
||||
|
||||
return true
|
||||
end
|
||||
})
|
||||
|
||||
do
|
||||
local charMeta = ix.meta.character
|
||||
|
||||
function charMeta:ShiftEnergy(energyShift, maxBonusEnergy, bNoNetwork)
|
||||
maxBonusEnergy = maxBonusEnergy or 0
|
||||
local newEnergy = self:GetEnergy()
|
||||
local maxEnergy = 100 + maxBonusEnergy
|
||||
|
||||
if (energyShift > 0) then
|
||||
if (newEnergy >= maxEnergy) then
|
||||
return false
|
||||
end
|
||||
|
||||
newEnergy = math.min(newEnergy + energyShift, maxEnergy)
|
||||
else
|
||||
newEnergy = newEnergy + energyShift
|
||||
end
|
||||
|
||||
return self:SetEnergy(newEnergy, energyBonusMax, bNoNetwork)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
--[[
|
||||
| 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
|
||||
local charMeta = ix.meta.character
|
||||
|
||||
function charMeta:IsAffectedByFatigue()
|
||||
return PLUGIN.noFatigueFactions[self:GetFaction()] != true
|
||||
end
|
||||
|
||||
function charMeta:GetActionTimeInfluencedByEnergyLevel(time)
|
||||
if (!self:IsAffectedByFatigue()) then
|
||||
return time
|
||||
end
|
||||
|
||||
local charEnergy = self:GetEnergy()
|
||||
local energyLevelToApplyDebuffs = ix.config.Get("energyLevelToApplyDebuffs", 50)
|
||||
|
||||
if (charEnergy < energyLevelToApplyDebuffs) then
|
||||
local energyMaxActionSpeedDebuff = ix.config.Get("energyMaxActionSpeedDebuff", 50) / 100
|
||||
|
||||
return math.ceil(time + (energyMaxActionSpeedDebuff * (1 - charEnergy / energyLevelToApplyDebuffs)))
|
||||
elseif (charEnergy > 100) then
|
||||
local energyMaxActionSpeedBuff = ix.config.Get("energyMaxActionSpeedBuff", 50) / 100
|
||||
|
||||
return math.floor(time - (time * energyMaxActionSpeedBuff))
|
||||
end
|
||||
|
||||
return time
|
||||
end
|
||||
17
gamemodes/darkrp/plugins/fatigue_system/meta/sh_player.lua
Normal file
17
gamemodes/darkrp/plugins/fatigue_system/meta/sh_player.lua
Normal file
@@ -0,0 +1,17 @@
|
||||
--[[
|
||||
| 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
|
||||
local playerMeta = FindMetaTable("Player")
|
||||
|
||||
function playerMeta:IsAffectedByFatigue()
|
||||
return PLUGIN.noFatigueFactions[self:Team()] != true
|
||||
end
|
||||
1649
gamemodes/darkrp/plugins/fatigue_system/sh_config.lua
Normal file
1649
gamemodes/darkrp/plugins/fatigue_system/sh_config.lua
Normal file
File diff suppressed because it is too large
Load Diff
186
gamemodes/darkrp/plugins/fatigue_system/sh_overrides.lua
Normal file
186
gamemodes/darkrp/plugins/fatigue_system/sh_overrides.lua
Normal file
@@ -0,0 +1,186 @@
|
||||
--[[
|
||||
| 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 ix.storage.Open(client, inventory, info) -- libs/sh_storage.lua
|
||||
assert(IsValid(client) and client:IsPlayer(), "expected valid player")
|
||||
assert(type(inventory) == "table" and inventory:IsInstanceOf(ix.meta.inventory), "expected valid inventory")
|
||||
|
||||
if (!inventory.storageInfo) then
|
||||
info = info or {}
|
||||
|
||||
-- I, perosnally, dislike storage context system at all, because it's not designed for flexible multiple users interaction, but editing is another task completely, so yeah...
|
||||
if (isnumber(info.searchTime) and info.searchTime != 0) then
|
||||
local character = client:GetCharacter()
|
||||
|
||||
info.searchTime = character:GetActionTimeInfluencedByEnergyLevel(info.searchTime)
|
||||
end
|
||||
|
||||
ix.storage.CreateContext(inventory, info)
|
||||
end
|
||||
|
||||
local storageInfo = inventory.storageInfo
|
||||
|
||||
if (storageInfo.bMultipleUsers or !ix.storage.InUse(inventory)) then
|
||||
ix.storage.AddReceiver(client, inventory, true)
|
||||
else
|
||||
client:NotifyLocalized("storageInUse")
|
||||
return
|
||||
end
|
||||
|
||||
if (storageInfo.searchTime > 0) then
|
||||
client:SetAction(storageInfo.searchText, storageInfo.searchTime)
|
||||
client:DoStaredAction(storageInfo.entity, function()
|
||||
if (IsValid(client) and IsValid(storageInfo.entity) and inventory.storageInfo) then
|
||||
ix.storage.Sync(client, inventory)
|
||||
end
|
||||
end, storageInfo.searchTime, function()
|
||||
if (IsValid(client)) then
|
||||
ix.storage.RemoveReceiver(client, inventory)
|
||||
client:SetAction()
|
||||
end
|
||||
end)
|
||||
else
|
||||
ix.storage.Sync(client, inventory)
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:InitializedPlugins2() -- plugins/willard_skills/meta/sh_character.lua
|
||||
local charMeta = ix.meta.character
|
||||
|
||||
function charMeta:GetSkillBoostLevels(skillID)
|
||||
local skill = ix.skill:Find(skillID)
|
||||
if (!skill) then return end
|
||||
|
||||
local boostExp
|
||||
|
||||
if (self:IsAffectedByFatigue()) then
|
||||
local energy = self:GetEnergy()
|
||||
|
||||
if (energy > 100) then
|
||||
local energyBuffs = PLUGIN.energySkillShifts.buffs
|
||||
boostExp = energyBuffs[skillID] or energyBuffs.base
|
||||
else
|
||||
boostExp = 0
|
||||
end
|
||||
else
|
||||
boostExp = 0
|
||||
end
|
||||
|
||||
for _, attr in ipairs(skill.attributes) do
|
||||
boostExp = boostExp + self:GetAttrBoostLevels(attr, skill)
|
||||
end
|
||||
|
||||
return boostExp
|
||||
end
|
||||
|
||||
function charMeta:GetSkillNeedsReducing(skillID)
|
||||
local skill = ix.skill:Find(skillID)
|
||||
if (!skill) then return end
|
||||
|
||||
local levelReduction = 0
|
||||
local realLevel = self:GetSkill(skillID)
|
||||
local reducedEnergy reducedHunger, reducedThirst, reducedGas, reducedHealth = false, false, false, false, false
|
||||
|
||||
if (realLevel == 0) then
|
||||
return levelReduction, reducedEnergy, reducedHunger, reducedThirst, reducedGas, reducedHealth
|
||||
end
|
||||
|
||||
if (self:IsAffectedByFatigue()) then
|
||||
local energy = self:GetEnergy()
|
||||
local energyLevelToApplyDebuffs = ix.config.Get("energyLevelToApplyDebuffs", 50)
|
||||
|
||||
if (energy < energyLevelToApplyDebuffs) then
|
||||
local energyDebuffs = PLUGIN.energySkillShifts.debuffs
|
||||
|
||||
reducedEnergy = realLevel * (energyDebuffs[skillID] or energyDebuffs.base) * (1 - energy / energyLevelToApplyDebuffs)
|
||||
levelReduction = levelReduction + reducedEnergy
|
||||
end
|
||||
end
|
||||
|
||||
if (self.GetHunger and self.GetThirst) then
|
||||
local hunger, thirst = self:GetHunger(), self:GetThirst()
|
||||
|
||||
if (hunger > 50) then
|
||||
reducedHunger = realLevel * 0.5 * (1 - (math.min(hunger, 100) - 50) / 50)
|
||||
levelReduction = levelReduction + reducedHunger
|
||||
end
|
||||
|
||||
if (thirst > 50) then
|
||||
reducedThirst = realLevel * 0.5 * (1 - (math.min(thirst, 100) - 50) / 50)
|
||||
levelReduction = levelReduction + reducedThirst
|
||||
end
|
||||
end
|
||||
|
||||
if (self.GetGasPoints) then
|
||||
local gasPointFraction = self:GetGasPoints() / 120
|
||||
|
||||
if (gasPointFraction > 0.3) then
|
||||
reducedGas = realLevel * 0.4 * ((math.min(gasPointFraction, 1) - 0.3) / 0.7)
|
||||
levelReduction = levelReduction + reducedGas
|
||||
end
|
||||
end
|
||||
|
||||
local client = self:GetPlayer()
|
||||
local health, maxHealth = client:Health(), client:GetMaxHealth()
|
||||
local halfMaxHealth = math.floor(maxHealth / 2)
|
||||
|
||||
if (health < halfMaxHealth) then
|
||||
reducedHealth = realLevel * 0.5 * (1 - health / maxHealth)
|
||||
levelReduction = levelReduction + reducedHealth
|
||||
end
|
||||
|
||||
return math.min(math.Round(levelReduction, 1), realLevel), reducedEnergy, reducedHunger, reducedThirst, reducedGas, reducedHealth
|
||||
end
|
||||
|
||||
if (self.InitializedPlugins3) then
|
||||
self:InitializedPlugins3()
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local charMeta = ix.meta.character
|
||||
|
||||
-- plugins/stamina_enhanced.lua
|
||||
function charMeta:GetMaxStamina()
|
||||
local client = self:GetPlayer()
|
||||
local hunger, thirst, health, maxHealth = self:GetHunger(), self:GetThirst(), client:Health(), client:GetMaxHealth()
|
||||
local stamina = 100
|
||||
|
||||
if (self:IsAffectedByFatigue()) then
|
||||
local energy = self:GetEnergy()
|
||||
local energyLevelToApplyDebuffs = ix.config.Get("energyLevelToApplyDebuffs", 50)
|
||||
|
||||
if (energy < energyLevelToApplyDebuffs) then
|
||||
stamina = stamina * (1 - PLUGIN.energyMaxStaminaOffsetDebuff * (1 - energy / energyLevelToApplyDebuffs))
|
||||
elseif (energy > 100) then
|
||||
stamina = stamina + math.floor(stamina * PLUGIN.energyMaxStaminaOffsetBuff)
|
||||
end
|
||||
end
|
||||
|
||||
if (hunger > 50) then
|
||||
stamina = stamina * (1 - 0.4 * (math.min(hunger - 50, 50) / 50))
|
||||
end
|
||||
|
||||
if (thirst > 50) then
|
||||
stamina = stamina * (1 - 0.4 * (math.min(thirst - 50, 50) / 50))
|
||||
end
|
||||
|
||||
local halfMaxHealth = math.floor(maxHealth * 0.5)
|
||||
|
||||
if (health < halfMaxHealth) then
|
||||
stamina = stamina * (1 - 0.4 * (1 - health / halfMaxHealth))
|
||||
end
|
||||
|
||||
return stamina
|
||||
end
|
||||
end
|
||||
66
gamemodes/darkrp/plugins/fatigue_system/sh_plugin.lua
Normal file
66
gamemodes/darkrp/plugins/fatigue_system/sh_plugin.lua
Normal file
@@ -0,0 +1,66 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
PLUGIN.name = "Fatigue System"
|
||||
PLUGIN.author = "LegAz"
|
||||
PLUGIN.description = "Adds character \"energy\" var that influences several other mechanichs."
|
||||
|
||||
function PLUGIN:SetupAreaProperties()
|
||||
ix.area.AddType("rpArea")
|
||||
end
|
||||
|
||||
function PLUGIN:StartCommand(client, userCmd)
|
||||
if (client:GetNetVar("actEnterAngle") and userCmd:KeyDown(IN_DUCK)) then
|
||||
userCmd:RemoveKey(IN_DUCK)
|
||||
end
|
||||
end
|
||||
|
||||
-- I would've united all resting entities into one instead of creating this func and funcs alike, but this will result in admins having to place all resting entities again
|
||||
function PLUGIN:FindModelActSequences(client, actName)
|
||||
local modelClass = ix.anim.GetModelClass(client:GetModel())
|
||||
local sequences = ix.act.stored[actName][modelClass]
|
||||
|
||||
return sequences and sequences.sequence or false
|
||||
end
|
||||
|
||||
ix.util.Include("meta/sh_player.lua")
|
||||
ix.util.Include("meta/sh_character.lua")
|
||||
|
||||
ix.util.Include("sh_config.lua")
|
||||
ix.util.Include("sh_overrides.lua")
|
||||
ix.util.Include("cl_plugin.lua")
|
||||
ix.util.Include("sv_plugin.lua")
|
||||
ix.util.Include("sv_hooks.lua")
|
||||
|
||||
ix.command.Add("CharSetEnergy", {
|
||||
description = "Set characters current energy level.",
|
||||
privelege = "Manage Character Energy",
|
||||
adminOnly = true,
|
||||
arguments = {
|
||||
ix.type.character,
|
||||
ix.type.number
|
||||
},
|
||||
OnRun = function(self, client, target, energyLevel)
|
||||
local clientName, targetName = client:GetName(), target:GetName()
|
||||
local targetPlayer = target:GetPlayer()
|
||||
energyLevel = math.Clamp(energyLevel, 0, 200)
|
||||
|
||||
target:SetEnergy(energyLevel)
|
||||
|
||||
for _, v in ipairs(player.GetAll()) do
|
||||
if (self:OnCheckAccess(v) or v == targetPlayer) then
|
||||
v:Notify(string.format("%s changed energy level of %s.", clientName, targetName))
|
||||
end
|
||||
end
|
||||
|
||||
ix.log.Add(client, "energy", clientName, targetName, energyLevel)
|
||||
end
|
||||
})
|
||||
336
gamemodes/darkrp/plugins/fatigue_system/sv_hooks.lua
Normal file
336
gamemodes/darkrp/plugins/fatigue_system/sv_hooks.lua
Normal file
@@ -0,0 +1,336 @@
|
||||
--[[
|
||||
| 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 function RestoreClientRestingInfoAndEntityDataToDefault(client)
|
||||
local restingEntity = client.ixRestingInfo.entity
|
||||
|
||||
if (client.ixRestingInfo.seatsOccupyFuncs) then
|
||||
for k, func in pairs(client.ixRestingInfo.seatsOccupyFuncs) do
|
||||
restingEntity.seatsOccupiers[k] = nil
|
||||
|
||||
func(restingEntity, false)
|
||||
end
|
||||
elseif (client.ixRestingInfo.seatOccupyFunc) then
|
||||
client.ixRestingInfo.seatOccupyFunc(restingEntity, false)
|
||||
end
|
||||
|
||||
client.ixRestingInfo = nil
|
||||
end
|
||||
|
||||
local function RestoreUnloadedCharacterDefaultStateAndSimplifyFatigueThinking(pluginTable, client, character)
|
||||
local fatigueTimerID = "ixFatigueThink" .. character:GetID()
|
||||
local bFatigueTimerExists = timer.Exists(fatigueTimerID)
|
||||
|
||||
if (client:GetNetVar("actEnterAngle") and client.ixUntimedSequence) then
|
||||
if (client.ixRestingInfo) then
|
||||
if (bFatigueTimerExists) then
|
||||
local restingEntityModel = client.ixRestingInfo.entity:GetModel()
|
||||
timer.Create(fatigueTimerID, 1, 0, function()
|
||||
local restingEntityData = pluginTable.restingEntities[restingEntityModel]
|
||||
|
||||
if (
|
||||
!character:ShiftEnergy(restingEntityData.energyRestorationRate or
|
||||
ix.config.Get("baseRestingEnergyRestoration", 0.004), restingEntityData.maxEnergyBonus)
|
||||
) then
|
||||
timer.Remove(fatigueTimerID)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
client:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||||
|
||||
local enterPos = client.ixRestingInfo.enterPos
|
||||
character:SetData("pos", {enterPos[1], enterPos[2], game.GetMap()})
|
||||
|
||||
RestoreClientRestingInfoAndEntityDataToDefault(client)
|
||||
elseif (bFatigueTimerExists) then
|
||||
timer.Create(fatigueTimerID, 1, 0, function()
|
||||
if (!character:ShiftEnergy(ix.config.Get("baseRestingEnergyRestoration", 0.004))) then
|
||||
timer.Remove(fatigueTimerID)
|
||||
end
|
||||
end)
|
||||
end
|
||||
elseif (bFatigueTimerExists) then
|
||||
timer.Remove(fatigueTimerID)
|
||||
end
|
||||
end
|
||||
|
||||
local function BagCountFilledSlotsCount(item)
|
||||
local bagInvID = item:GetData("id")
|
||||
local filledSlotsCount = 0
|
||||
|
||||
if (!bagInvID) then
|
||||
return filledSlotsCount
|
||||
end
|
||||
|
||||
local bagInventory = ix.item.inventories[bagInvID]
|
||||
|
||||
-- could've just use "GetFilledSlotCount" instead of a loop, but what if the bag item allows nesting?
|
||||
for _, vItem in pairs(bagInventory:GetItems()) do
|
||||
filledSlotsCount = filledSlotsCount + vItem.width * vItem.height
|
||||
end
|
||||
|
||||
return filledSlotsCount
|
||||
end
|
||||
|
||||
function PLUGIN:PrePlayerLoadedCharacter(client, character, lastCharacter)
|
||||
if (lastCharacter) then
|
||||
RestoreUnloadedCharacterDefaultStateAndSimplifyFatigueThinking(self, client, lastCharacter)
|
||||
|
||||
client.ixEquipmentEnergyConsumptionRate = nil
|
||||
client.ixInventoryFilledSlotsCount = nil
|
||||
end
|
||||
|
||||
if (!character:IsAffectedByFatigue()) then
|
||||
return
|
||||
end
|
||||
|
||||
local equipInventoryID = character:GetEquipInventory()
|
||||
local equipInventory = ix.inventory.Get(equipInventoryID)
|
||||
client.ixEquipmentEnergyConsumptionRate = 0
|
||||
|
||||
if (equipInventory.slots and equipInventory.slots[1]) then
|
||||
for _, item in pairs(equipInventory.slots[1]) do
|
||||
if (!item or !item.energyConsumptionRate) then
|
||||
continue
|
||||
end
|
||||
|
||||
client.ixEquipmentEnergyConsumptionRate = client.ixEquipmentEnergyConsumptionRate + item.energyConsumptionRate
|
||||
end
|
||||
end
|
||||
|
||||
local inventory = character:GetInventory()
|
||||
client.ixInventoryFilledSlotsCount = 0
|
||||
|
||||
for _, item in pairs(inventory:GetItems()) do
|
||||
if (equipInventoryID == item.invID) then
|
||||
continue
|
||||
end
|
||||
|
||||
client.ixInventoryFilledSlotsCount = client.ixInventoryFilledSlotsCount + (item.width * item.height)
|
||||
end
|
||||
|
||||
local fatigueTimerID = "ixFatigueThink" .. character:GetID()
|
||||
|
||||
timer.Create(fatigueTimerID, 1, 0, function()
|
||||
local energy = character:GetEnergy()
|
||||
local energyShift, maxEnergyBonus
|
||||
|
||||
if (client:GetNetVar("actEnterAngle") and client.ixUntimedSequence) then
|
||||
if (client.ixRestingInfo) then
|
||||
local restingEntityModel = client.ixRestingInfo.entity:GetModel()
|
||||
local restingEntityData = self.restingEntities[restingEntityModel]
|
||||
maxEnergyBonus = restingEntityData.maxEnergyBonus or 0
|
||||
|
||||
if (energy >= 100 + maxEnergyBonus) then
|
||||
return
|
||||
end
|
||||
|
||||
energyShift = restingEntityData.energyRestorationRate or ix.config.Get("baseRestingEnergyRestoration", 0.004)
|
||||
|
||||
if (client.ixRestingInfo.seatsOccupyFuncs and #client.ixRestingInfo.seatsOccupyFuncs == 2) then
|
||||
energyShift = energyShift * 1.5
|
||||
end
|
||||
else
|
||||
if (energy >= 100) then
|
||||
return
|
||||
end
|
||||
|
||||
energyShift = ix.config.Get("baseRestingEnergyRestoration", 0.004)
|
||||
end
|
||||
|
||||
if (!client:IsAFK() and client.ixInArea and ix.area.stored[client.ixArea].type == "rpArea") then
|
||||
energyShift = energyShift + ix.config.Get("rpAreaEnergyRestoration", 0.017)
|
||||
end
|
||||
elseif (client.ixInArea and ix.area.stored[client.ixArea].type == "rpArea") then
|
||||
if (energy >= 100 or IsValid(client.ixRagdoll) or client:IsAFK()) then
|
||||
return
|
||||
end
|
||||
|
||||
energyShift = ix.config.Get("rpAreaEnergyRestoration", 0.017)
|
||||
else
|
||||
if (energy == 0 or !client.ixEquipmentEnergyConsumptionRate or IsValid(client.ixRagdoll) or client:IsAFK()) then
|
||||
return
|
||||
end
|
||||
|
||||
local clientVelocityLength = client:GetVelocity():Length2DSqr()
|
||||
|
||||
if (clientVelocityLength < 64) then -- 8 * 8
|
||||
return
|
||||
end
|
||||
|
||||
energyShift = ix.config.Get("baseEnergyConsumption", 0.004)
|
||||
|
||||
local strengthFraction = character:GetSpecial("strength") / 10
|
||||
local equipmentConsumption = client.ixEquipmentEnergyConsumptionRate * (1 - self.maxEquipmentEnergyConsumptionReduction * strengthFraction)
|
||||
local slotsConsumption = client.ixInventoryFilledSlotsCount * ix.config.Get("filledSlotEnergyConsumption", 0.001) *
|
||||
(1 - self.maxFilledSlotsEnergyConsumptionReduction * strengthFraction)
|
||||
|
||||
energyShift = energyShift + equipmentConsumption + slotsConsumption
|
||||
local walkSpeed = client:GetWalkSpeed()
|
||||
|
||||
if (client.searchingGarbage) then
|
||||
energyShift = energyShift + ix.config.Get("garbageCollectingEnergyConsumption", 0.0004)
|
||||
elseif (client:KeyDown(IN_SPEED) and clientVelocityLength >= (walkSpeed * walkSpeed)) then
|
||||
energyShift = energyShift + ix.config.Get("runningEnergyConsumption", 0.008)
|
||||
end
|
||||
|
||||
energyShift = -energyShift
|
||||
end
|
||||
|
||||
character:ShiftEnergy(energyShift, maxEnergyBonus)
|
||||
end)
|
||||
end
|
||||
|
||||
function PLUGIN:OnItemTransferred(item, lastInventory, inventory) -- things I have to do in order to detect equipment consumption rate and filled slots count...
|
||||
local ownerCharacter = ix.char.loaded[inventory.owner]
|
||||
local lastOwnerCharacter = ix.char.loaded[lastInventory.owner]
|
||||
if (!ownerCharacter or !lastOwnerCharacter) then
|
||||
return
|
||||
end
|
||||
local ownerClient, lastOwnerClient
|
||||
|
||||
if (
|
||||
(ownerCharacter and !ownerCharacter:IsAffectedByFatigue() or !ownerCharacter and true) and
|
||||
(lastOwnerCharacter and !lastOwnerCharacter:IsAffectedByFatigue() or !lastOwnerCharacter and true)
|
||||
) then
|
||||
return
|
||||
end
|
||||
|
||||
if (!inventory.owner and lastInventory.owner) then
|
||||
lastOwnerClient = lastOwnerCharacter:GetPlayer()
|
||||
local equipInventory = lastOwnerCharacter:GetEquipInventory()
|
||||
|
||||
if (lastInventory:GetID() == equipInventory) then
|
||||
lastOwnerClient.ixEquipmentEnergyConsumptionRate = lastOwnerClient.ixEquipmentEnergyConsumptionRate - (item.energyConsumptionRate or 0)
|
||||
else
|
||||
lastOwnerClient.ixInventoryFilledSlotsCount = lastOwnerClient.ixInventoryFilledSlotsCount - item.width * item.height
|
||||
end
|
||||
|
||||
-- equipped item can be a bag too
|
||||
lastOwnerClient.ixInventoryFilledSlotsCount = lastOwnerClient.ixInventoryFilledSlotsCount - BagCountFilledSlotsCount(item)
|
||||
elseif (inventory.owner and !lastInventory.owner) then
|
||||
ownerClient = ownerCharacter:GetPlayer()
|
||||
ownerClient.ixInventoryFilledSlotsCount = ownerClient.ixInventoryFilledSlotsCount + item.width * item.height + BagCountFilledSlotsCount(item)
|
||||
elseif (inventory.owner != lastInventory.owner) then
|
||||
ownerClient = ownerCharacter:GetPlayer()
|
||||
lastOwnerClient = lastOwnerCharacter:GetPlayer()
|
||||
|
||||
local itemSize = item.width * item.height
|
||||
ownerClient.ixInventoryFilledSlotsCount = ownerClient.ixInventoryFilledSlotsCount + itemSize
|
||||
lastOwnerClient.ixInventoryFilledSlotsCount = lastOwnerClient.ixInventoryFilledSlotsCount - itemSize - BagCountFilledSlotsCount(item)
|
||||
else
|
||||
ownerClient = ownerCharacter:GetPlayer()
|
||||
lastOwnerClient = lastOwnerCharacter:GetPlayer()
|
||||
|
||||
local equipInventory = ownerCharacter:GetEquipInventory()
|
||||
local bTransferedToEquipInventory
|
||||
|
||||
if (equipInventory == inventory:GetID()) then
|
||||
bTransferedToEquipInventory = true
|
||||
elseif (equipInventory == lastInventory:GetID()) then
|
||||
bTransferedToEquipInventory = false
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
if (bTransferedToEquipInventory) then
|
||||
ownerClient.ixEquipmentEnergyConsumptionRate = ownerClient.ixEquipmentEnergyConsumptionRate + (item.energyConsumptionRate or 0)
|
||||
ownerClient.ixInventoryFilledSlotsCount = ownerClient.ixInventoryFilledSlotsCount - (item.width * item.height)
|
||||
else
|
||||
ownerClient.ixEquipmentEnergyConsumptionRate = ownerClient.ixEquipmentEnergyConsumptionRate - (item.energyConsumptionRate or 0)
|
||||
ownerClient.ixInventoryFilledSlotsCount = ownerClient.ixInventoryFilledSlotsCount + (item.width * item.height)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:OnEntityCreated(entity)
|
||||
if (entity:GetClass() == "ix_chair") then
|
||||
timer.Simple(0, function()
|
||||
if (!IsValid(entity)) then
|
||||
return
|
||||
end
|
||||
|
||||
local entityData = self.restingEntities[entity:GetModel()]
|
||||
entity:SetValidActName(entityData.validActName)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:OnPlayerJump(client)
|
||||
if (!client:IsAffectedByFatigue() or (client.ixInArea and ix.area.stored[client.ixArea].type == "rpArea")) then
|
||||
return
|
||||
end
|
||||
|
||||
local character = client:GetCharacter()
|
||||
character:ShiftEnergy(-ix.config.Get("jumpEnergyConsumption", 0.1))
|
||||
end
|
||||
|
||||
function PLUGIN:PlayerInteractItem(client, action, item)
|
||||
if (item.base == "base_food" and action == "Consume" and item.energyShift) then
|
||||
local character = client:GetCharacter()
|
||||
|
||||
character:ShiftEnergy(item.energyShift)
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:OnCharacterDisconnect(client, character)
|
||||
RestoreUnloadedCharacterDefaultStateAndSimplifyFatigueThinking(self, client, character)
|
||||
end
|
||||
|
||||
function PLUGIN:OnPlayerExitAct(client)
|
||||
if (client.ixRestingInfo) then
|
||||
local enterPos = client.ixRestingInfo.enterPos
|
||||
|
||||
client:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||||
client:SetPos(enterPos[1])
|
||||
client:SetEyeAngles(enterPos[2])
|
||||
|
||||
RestoreClientRestingInfoAndEntityDataToDefault(client)
|
||||
end
|
||||
end
|
||||
|
||||
function PLUGIN:CharacterDeleted(client, charID, bIsCurrentChar)
|
||||
timer.Remove("ixFatigueThink" .. charID)
|
||||
end
|
||||
|
||||
function PLUGIN:OnCharacterBanned(character)
|
||||
timer.Remove("ixFatigueThink" .. character:GetID())
|
||||
end
|
||||
|
||||
function PLUGIN:RegisterSaveEnts()
|
||||
ix.saveEnts:RegisterEntity("ix_chair", true, true, true, {
|
||||
OnSave = function(entity, data)
|
||||
data.model = entity:GetModel()
|
||||
end,
|
||||
OnRestorePreSpawn = function(entity, data)
|
||||
entity:SetModel(data.model)
|
||||
end
|
||||
})
|
||||
|
||||
ix.saveEnts:RegisterEntity("ix_couch", true, true, true, {
|
||||
OnSave = function(entity, data)
|
||||
data.model = entity:GetModel()
|
||||
end,
|
||||
OnRestorePreSpawn = function(entity, data)
|
||||
entity:SetModel(data.model)
|
||||
end
|
||||
})
|
||||
|
||||
ix.saveEnts:RegisterEntity("ix_bed", true, true, true, {
|
||||
OnSave = function(entity, data)
|
||||
data.model = entity:GetModel()
|
||||
end,
|
||||
OnRestorePreSpawn = function(entity, data)
|
||||
entity:SetModel(data.model)
|
||||
end
|
||||
})
|
||||
end
|
||||
51
gamemodes/darkrp/plugins/fatigue_system/sv_plugin.lua
Normal file
51
gamemodes/darkrp/plugins/fatigue_system/sv_plugin.lua
Normal file
@@ -0,0 +1,51 @@
|
||||
--[[
|
||||
| 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.log.AddType("energy", function(client, ...)
|
||||
local arg = {...}
|
||||
|
||||
return Format("%s set energy level of %s to %d.", arg[1], arg[2], arg[3])
|
||||
end)
|
||||
|
||||
function PLUGIN:EnterUntimedAct(client, sequence) -- maybe it's worth to move this to "act" plugin
|
||||
client:SetNetVar("actEnterAngle", client:GetAngles())
|
||||
client.ixUntimedSequence = true
|
||||
client:ForceSequence(sequence, function()
|
||||
client.ixUntimedSequence = nil
|
||||
client:SetNetVar("actEnterAngle")
|
||||
|
||||
hook.Run("OnPlayerExitAct", client)
|
||||
|
||||
net.Start("ixActLeave")
|
||||
net.Send(client)
|
||||
end, 0, nil)
|
||||
|
||||
net.Start("ixActEnter")
|
||||
net.WriteBool(true)
|
||||
net.Send(client)
|
||||
end
|
||||
|
||||
function PLUGIN:RestingEntity_FindSequenceNameAndDataByID(entityModel, client, actName, sequenceID)
|
||||
local sequences = self:FindModelActSequences(client, actName)
|
||||
|
||||
if (!sequences) then
|
||||
return
|
||||
end
|
||||
|
||||
local entityData = self.restingEntities[entityModel]
|
||||
local validSequences = entityData.sequences
|
||||
|
||||
for k, v in ipairs(sequences) do
|
||||
if (sequenceID == k and validSequences[v]) then
|
||||
return entityData, v, validSequences[v]
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user