This commit is contained in:
lifestorm
2024-08-04 23:54:45 +03:00
parent 8064ba84d8
commit 6a58f406b1
7522 changed files with 4011896 additions and 15 deletions

View File

@@ -0,0 +1,240 @@
--[[
| 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 = "Bu eşya hafif"
},
[2] = {
maxRate = 0.004,
color = "yellow",
text = "Bu eşya orta ağırlıkta"
}
}
local energyIcon = ix.util.GetMaterial("willardnetworks/hud/energy.png")
function PLUGIN:DrawBars(client, character, alwaysShow, minimalShow, DrawBar)
if (!character:IsAffectedByFatigue()) then return end
if (alwaysShow or character:GetEnergy() > 20) then
if (alwaysShow or !minimalShow or character:GetEnergy() > 20) then
DrawBar(energyIcon, character:GetEnergy() / 100)
end
end
end
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", "Bu eşya oldukça ağır"
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 = "Dinlenmiş"
end
CreateSubBar(energyPanel, "willardnetworks/hud/stamina.png", "Enerji", 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 = "Yorgun"
},
[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(skillAttributes[2].name .. " niteliğinden büyük artış")
boostedByLabel:SetFont("MenuFontBoldNoClamp")
boostedByLabel:SetContentAlignment(4)
boostedByLabel:SizeToContents()
boostedByLabel:Dock(TOP)
end
if skillAttributes[1] then
local boostedByLabel = boostPanel:Add("DLabel")
boostedByLabel:SetText(skillAttributes[1].name .. " niteliğinden düşük artış")
boostedByLabel:SetFont("MenuFontBoldNoClamp")
boostedByLabel:SetContentAlignment(4)
boostedByLabel:SizeToContents()
boostedByLabel:Dock(TOP)
end
local varBoostLevel, boostedEnergy, boostedEnergyAmount = character:GetSkillBoostLevels(skill.uniqueID)
local varNeedsLevel, reducedHunger, reducedThirst, reducedGas, reducedHealth = character:GetSkillNeedsReducing(skill.uniqueID)
if (varBoostLevel > 0 and boostedEnergy and boostedEnergyAmount and boostedEnergyAmount > 0) then
local energyBoostedLevels = boostPanel:Add("DLabel")
energyBoostedLevels:Dock(TOP)
energyBoostedLevels:SetContentAlignment(4)
energyBoostedLevels:SetFont("MenuFontLargerBoldNoFix")
energyBoostedLevels:SetTextColor(Color(75, 238, 75))
energyBoostedLevels:SetText("+" .. boostedEnergyAmount .. " levels due to low fatigue.")
energyBoostedLevels:SizeToContents()
varBoostLevel = varBoostLevel - boostedEnergyAmount
end
if (varBoostLevel > 0) then
local boostedLevels = boostPanel:Add("DLabel")
boostedLevels:Dock(TOP)
boostedLevels:SetContentAlignment(4)
boostedLevels:SetFont("MenuFontLargerBoldNoFix")
boostedLevels:SetTextColor(Color(75, 238, 75))
boostedLevels:SetText("Karakter niteliklerinden dolayı arttırılan seviye +" .. 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("Yorgunluk sebebiyle -" .. math.Round(reducedEnergy, 1) .. " seviye")
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("Açlık sebebiyle -" .. math.Round(reducedHunger, 1) .. " seviye")
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("Susuzluk sebebiyle -" .. math.Round(reducedThirst, 1) .. " seviye")
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("Zararlı gazlar sebebiyle -" .. math.Round(reducedGas, 1) .. " seviye")
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("Yaralanma sebebiyle -" .. math.Round(reducedHealth, 1) .. " seviye")
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("Toplam düşürülen seviye: -" .. varNeedsLevel)
needsReducing:SizeToContents()
end
end
end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,129 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local 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

View File

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

View File

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

View File

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

View File

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

View 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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,129 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
local 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
local energyBoost
local energyBoostAmount = 0
local energyBuffs = PLUGIN.energySkillShifts.buffs
if (self:IsAffectedByFatigue() and energyBuffs[skillID]) then
local energy = self:GetEnergy()
local energyLevelToApplyBuffs = ix.config.Get("energyLevelToApplyBuffs", 50)
if (energy > energyLevelToApplyBuffs) then
energyBoost = true
energyBoostAmount = math.floor(energyBuffs[skillID] * (energy / 100))
boostExp = energyBoostAmount
else
boostExp = 0
end
else
boostExp = 0
end
for _, attr in ipairs(skill.attributes) do
boostExp = boostExp + self:GetAttrBoostLevels(attr, skill)
end
return boostExp, energyBoost, energyBoostAmount
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 energyLevelToApplyBuffs = ix.config.Get("energyLevelToApplyBuffs", 50)
if (energy > energyLevelToApplyBuffs) then
stamina = stamina * (1 + PLUGIN.energyMaxStaminaOffsetBuff * (energy / 100))
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

View File

@@ -0,0 +1,66 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
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
})

View 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

View 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