mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
451 lines
12 KiB
Lua
451 lines
12 KiB
Lua
|
|
--[[
|
||
|
|
| 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.skill = ix.skill or {}
|
||
|
|
ix.skill.list = ix.skill.list or {}
|
||
|
|
ix.skill.scale = ix.skill.scale or {}
|
||
|
|
|
||
|
|
ix.skill.MAX_SKILL = 50
|
||
|
|
|
||
|
|
if (SERVER) then
|
||
|
|
ix.log.AddType("skillsGetSkill", function(client, name)
|
||
|
|
return string.format("%s has selected the %s skill.", client:GetName(), name)
|
||
|
|
end)
|
||
|
|
ix.log.AddType("skillsRemovedSkill", function(client, name, oldXP)
|
||
|
|
if (oldXP > 0) then
|
||
|
|
return string.format("%s has removed the %s skill (experience was: %d).", client:GetName(), name, oldXP)
|
||
|
|
else
|
||
|
|
return string.format("%s has removed the %s skill.", client:GetName(), name)
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
ix.log.AddType("skillLevelUp", function(client, name, newExp)
|
||
|
|
return string.format("%s has gained level %d in the %s skill.", client:GetName(), newExp, name)
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
ix.char.RegisterVar("skill", {
|
||
|
|
default = {},
|
||
|
|
isLocal = true,
|
||
|
|
bNoDisplay = true,
|
||
|
|
field = "skills",
|
||
|
|
fieldType = ix.type.text,
|
||
|
|
OnSet = function(character, skillID, level)
|
||
|
|
if (!skillID) then
|
||
|
|
ErrorNoHalt("Attempted to set level but no skillID was provided!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local skill = ix.skill:Find(skillID)
|
||
|
|
if (!skill) then
|
||
|
|
ErrorNoHalt("Attempted to set level on invalid skill "..skillID.."!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if (!level) then
|
||
|
|
level = character:GetSkill(skill.uniqueID) + 1
|
||
|
|
end
|
||
|
|
|
||
|
|
level = math.floor(level)
|
||
|
|
|
||
|
|
if (level < 0 or level > ix.skill.MAX_SKILL) then
|
||
|
|
ErrorNoHalt("Attempted to set invalid level '"..level.."' on "..skill.name.."'.")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local skills = character:GetSkill()
|
||
|
|
local totalLevel = character:GetTotalSkillLevel()
|
||
|
|
local currentLevel = skills[skill.uniqueID] or 0
|
||
|
|
if (currentLevel <= level and totalLevel - currentLevel + level > ix.config.Get("MaxTotalSkill")) then
|
||
|
|
ErrorNoHalt("Attempted to add level "..skill.name.." above total skill level!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
local client = character:GetPlayer()
|
||
|
|
if (IsValid(client) and (skills[skill.uniqueID] or 0) < level) then
|
||
|
|
ix.log.Add(client, "skillLevelUp", skill.name, level)
|
||
|
|
if (character:GetSkillAutoLevel(skill.uniqueID)) then
|
||
|
|
client:NotifyLocalized("levelGained", skill.name, character:GetSkill(skill.uniqueID) + 1)
|
||
|
|
end
|
||
|
|
|
||
|
|
net.Start("ixSkillLevelUpSound")
|
||
|
|
net.Send(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (level > 0) then
|
||
|
|
skills[skill.uniqueID] = level
|
||
|
|
else
|
||
|
|
skills[skill.uniqueID] = nil
|
||
|
|
end
|
||
|
|
character.vars.skill = skills
|
||
|
|
|
||
|
|
if (IsValid(client)) then
|
||
|
|
net.Start("ixCharacterSkill")
|
||
|
|
net.WriteUInt(character:GetID(), 32)
|
||
|
|
net.WriteString(skill.uniqueID)
|
||
|
|
net.WriteUInt(skills[skill.uniqueID] or 0, 8)
|
||
|
|
net.Send(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (level == ix.skill.MAX_SKILL) then
|
||
|
|
character:SetSkillStoredExp(skill.uniqueID)
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
OnGet = function(character, skillID)
|
||
|
|
local skills = character.vars.skill or {}
|
||
|
|
|
||
|
|
if (skillID) then
|
||
|
|
if (!ix.skill:Find(skillID)) then
|
||
|
|
ErrorNoHalt("Attempted to get skill level in invalid skill "..skillID..".")
|
||
|
|
end
|
||
|
|
return skills[skillID] != nil and skills[skillID] or 0
|
||
|
|
else
|
||
|
|
return skills
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
OnValidate = function(self, value, data, client)
|
||
|
|
if (value != nil) then
|
||
|
|
if (istable(value)) then
|
||
|
|
local count = 0
|
||
|
|
|
||
|
|
for _, v in pairs(value) do
|
||
|
|
count = count + v
|
||
|
|
end
|
||
|
|
|
||
|
|
if (count > 10) then
|
||
|
|
return false, "unknownError"
|
||
|
|
end
|
||
|
|
else
|
||
|
|
return false, "unknownError"
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
OnAdjust = function(self, client, data, value, newData)
|
||
|
|
newData.skill = value
|
||
|
|
end
|
||
|
|
})
|
||
|
|
|
||
|
|
ix.char.RegisterVar("skillAutoLevel", {
|
||
|
|
default = {},
|
||
|
|
isLocal = true,
|
||
|
|
bNoDisplay = true,
|
||
|
|
field = "skills_autolevel",
|
||
|
|
fieldType = ix.type.text,
|
||
|
|
OnSet = function(character, skillID)
|
||
|
|
if (!skillID) then
|
||
|
|
ErrorNoHalt("Attempted to set experience but no skillID was provided!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local skill = ix.skill:Find(skillID)
|
||
|
|
if (!skill) then
|
||
|
|
ErrorNoHalt("Attempted to set experience on invalid skill "..skillID.."!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local skills = character:GetSkillAutoLevel()
|
||
|
|
skills[skill.uniqueID] = !skills[skill.uniqueID]
|
||
|
|
character.vars.skillAutoLevel = skills
|
||
|
|
|
||
|
|
-- Level skill if possible
|
||
|
|
if (skills[skill.uniqueID] == true) then
|
||
|
|
character:LevelUpSkill(skill.uniqueID)
|
||
|
|
end
|
||
|
|
|
||
|
|
local client = character:GetPlayer()
|
||
|
|
if (IsValid(client)) then
|
||
|
|
net.Start("ixCharacterSkillAutoLevel")
|
||
|
|
net.WriteUInt(character:GetID(), 32)
|
||
|
|
net.WriteString(skill.uniqueID)
|
||
|
|
net.WriteBool(skills[skill.uniqueID])
|
||
|
|
net.Send(client)
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
OnGet = function(character, skillID)
|
||
|
|
local skills = character.vars.skillAutoLevel or {}
|
||
|
|
|
||
|
|
if (skillID) then
|
||
|
|
return skills[skillID] != nil and skills[skillID] or false
|
||
|
|
else
|
||
|
|
return skills
|
||
|
|
end
|
||
|
|
end
|
||
|
|
})
|
||
|
|
|
||
|
|
ix.char.RegisterVar("skillStoredExp", {
|
||
|
|
default = {},
|
||
|
|
isLocal = true,
|
||
|
|
bNoDisplay = true,
|
||
|
|
field = "skills_storedexp",
|
||
|
|
fieldType = ix.type.text,
|
||
|
|
OnSet = function(character, skillID, exp)
|
||
|
|
if (!skillID) then
|
||
|
|
ErrorNoHalt("Attempted to set stored experience but no skillID was provided!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local skill = ix.skill:Find(skillID)
|
||
|
|
if (!skill) then
|
||
|
|
ErrorNoHalt("Attempted to set stored experience on invalid skill "..skillID.."!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
local skills = character:GetSkillStoredExp()
|
||
|
|
if (character:GetSkill(skill.uniqueID) >= ix.skill.MAX_SKILL) then
|
||
|
|
skills[skill.uniqueID] = nil
|
||
|
|
elseif (isbool(exp)) then
|
||
|
|
if (!skills[skill.uniqueID] or skills[skill.uniqueID] < 1000) then
|
||
|
|
ErrorNoHalt("Attempted to level "..skill.name.." without enough stored experience!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
skills[skill.uniqueID] = math.max(skills[skill.uniqueID] - 1000, 0)
|
||
|
|
|
||
|
|
if (skills[skill.uniqueID] == 0 or character:GetSkill(skill.uniqueID) >= ix.skill.MAX_SKILL) then
|
||
|
|
skills[skill.uniqueID] = nil
|
||
|
|
end
|
||
|
|
else
|
||
|
|
exp = exp and math.floor(exp)
|
||
|
|
if (!exp or exp < 0) then
|
||
|
|
ErrorNoHalt("Attempted to set "..skill.name.." to invalid stored experience ("..(exp or "nil")..")!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if (character:GetSkill(skill.uniqueID) >= ix.skill.MAX_SKILL) then
|
||
|
|
ErrorNoHalt("Attempted to add stored experience to "..skill.name.." which is max level already!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if (skills[skill.uniqueID] and skills[skill.uniqueID] + exp >= 2000) then
|
||
|
|
ErrorNoHalt("Attempted to add stored experience to "..skill.name.." above total stored experience ceiling!")
|
||
|
|
end
|
||
|
|
|
||
|
|
skills[skill.uniqueID] = math.min((skills[skill.uniqueID] or 0) + exp, 1999)
|
||
|
|
end
|
||
|
|
|
||
|
|
character.vars.skillStoredExp = skills
|
||
|
|
|
||
|
|
local client = character:GetPlayer()
|
||
|
|
if (IsValid(client)) then
|
||
|
|
net.Start("ixCharacterSkillStoredExp")
|
||
|
|
net.WriteUInt(character:GetID(), 32)
|
||
|
|
net.WriteString(skill.uniqueID)
|
||
|
|
net.WriteInt(skills[skill.uniqueID] or -1, 32)
|
||
|
|
net.Send(client)
|
||
|
|
end
|
||
|
|
end,
|
||
|
|
OnGet = function(character, skillID)
|
||
|
|
local skills = character.vars.skillStoredExp or {}
|
||
|
|
|
||
|
|
if (skillID) then
|
||
|
|
return skills[skillID] != nil and skills[skillID] or 0
|
||
|
|
else
|
||
|
|
return skills
|
||
|
|
end
|
||
|
|
end
|
||
|
|
})
|
||
|
|
|
||
|
|
if (CLIENT) then
|
||
|
|
net.Receive("ixCharacterSkill", function()
|
||
|
|
local id = net.ReadUInt(32)
|
||
|
|
local character = ix.char.loaded[id]
|
||
|
|
|
||
|
|
if (character) then
|
||
|
|
local skill = net.ReadString()
|
||
|
|
local level = net.ReadUInt(8)
|
||
|
|
local skills = character:GetSkill()
|
||
|
|
skills[skill] = (level != 0 and level) or nil
|
||
|
|
|
||
|
|
character.vars.skill = skills
|
||
|
|
|
||
|
|
if (IsValid(ix.gui.skills)) then
|
||
|
|
ix.gui.skills.skillPanels[skill].skillLevel:SetText("Skill Level: "..character:GetSkillLevel(skill).."/"..ix.skill.MAX_SKILL)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
net.Receive("ixCharacterSkillAutoLevel", function()
|
||
|
|
local id = net.ReadUInt(32)
|
||
|
|
local character = ix.char.loaded[id]
|
||
|
|
|
||
|
|
if (character) then
|
||
|
|
local skill = net.ReadString()
|
||
|
|
local skillAutoLevel = character:GetSkillAutoLevel()
|
||
|
|
skillAutoLevel[skill] = net.ReadBool()
|
||
|
|
|
||
|
|
character.vars.skillAutoLevel = skillAutoLevel
|
||
|
|
|
||
|
|
if (IsValid(ix.gui.skills)) then
|
||
|
|
ix.gui.skills.skillPanels[skill].autoLevel.autoLevel = skillAutoLevel[skill]
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
net.Receive("ixCharacterSkillStoredExp", function()
|
||
|
|
local id = net.ReadUInt(32)
|
||
|
|
local character = ix.char.loaded[id]
|
||
|
|
|
||
|
|
if (character) then
|
||
|
|
local skill = net.ReadString()
|
||
|
|
local exp = net.ReadInt(32)
|
||
|
|
local skillStoredExp = character:GetSkillStoredExp()
|
||
|
|
skillStoredExp[skill] = (exp != -1 and exp) or nil
|
||
|
|
|
||
|
|
character.vars.skillStoredExp = skillStoredExp
|
||
|
|
|
||
|
|
if (IsValid(ix.gui.skills)) then
|
||
|
|
local progress = math.Clamp(character:GetSkillStoredExp(skill) / 1000, 0, 1)
|
||
|
|
ix.gui.skills.skillPanels[skill].progressBar.progress = progress
|
||
|
|
ix.gui.skills.skillPanels[skill].processLabel:SetupText(character)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
local levelCD = 0
|
||
|
|
net.Receive("ixSkillLevelUpSound", function()
|
||
|
|
if (levelCD < CurTime()) then
|
||
|
|
surface.PlaySound("willardnetworks/skills/levelup.mp3")
|
||
|
|
levelCD = CurTime() + 5
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
else
|
||
|
|
util.AddNetworkString("ixCharacterSkill")
|
||
|
|
util.AddNetworkString("ixCharacterSkillAutoLevel")
|
||
|
|
util.AddNetworkString("ixCharacterSkillStoredExp")
|
||
|
|
util.AddNetworkString("ixSkillLevelUp")
|
||
|
|
util.AddNetworkString("ixSkillSetAutoLevel")
|
||
|
|
util.AddNetworkString("ixSkillLevelUpSound")
|
||
|
|
|
||
|
|
net.Receive("ixSkillLevelUp", function(len, ply)
|
||
|
|
local character = ply:GetCharacter()
|
||
|
|
local skill = net.ReadString()
|
||
|
|
|
||
|
|
if (character and character:CanLevelSkill(skill)) then
|
||
|
|
character:LevelUpSkill(skill)
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
net.Receive("ixSkillSetAutoLevel", function(len, ply)
|
||
|
|
local character = ply:GetCharacter()
|
||
|
|
local skill = net.ReadString()
|
||
|
|
|
||
|
|
if (character) then
|
||
|
|
character:SetSkillAutoLevel(skill)
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
function ix.skill:RegisterSkill(uniqueID, data)
|
||
|
|
if (!uniqueID or type(uniqueID) != "string") then
|
||
|
|
ErrorNoHalt("Attempted to register skill without valid uniqueID.")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
data.uniqueID = uniqueID
|
||
|
|
|
||
|
|
data.name = data.name or "Unknown"
|
||
|
|
data.description = data.description or "No description given."
|
||
|
|
|
||
|
|
data.actions = data.actions or {}
|
||
|
|
data.attributes = data.attributes or {}
|
||
|
|
data.scale = data.scale or {}
|
||
|
|
|
||
|
|
ix.skill.list[uniqueID] = data
|
||
|
|
end
|
||
|
|
|
||
|
|
function ix.skill:RegisterSkillAction(skillID, action)
|
||
|
|
local skill = self:Find(skillID)
|
||
|
|
if (!skill) then return end
|
||
|
|
|
||
|
|
for k, v in ipairs(skill.actions) do
|
||
|
|
if (v.uniqueID == action.uniqueID) then
|
||
|
|
skill.actions[k] = action
|
||
|
|
return
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
skill.actions[#skill.actions + 1] = action
|
||
|
|
end
|
||
|
|
|
||
|
|
function ix.skill:RegisterAttribute(skillID, attribute)
|
||
|
|
local skill = self:Find(skillID)
|
||
|
|
if (!skill) then return end
|
||
|
|
|
||
|
|
for k, v in ipairs(skill.attributes) do
|
||
|
|
if (v.uniqueID == attribute.uniqueID) then
|
||
|
|
skill.attributes[k] = attribute
|
||
|
|
return
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
skill.attributes[#skill.attributes + 1] = attribute
|
||
|
|
end
|
||
|
|
|
||
|
|
function ix.skill:RegisterSkillScale(skillID, uniqueID, data)
|
||
|
|
local skill = self:Find(skillID)
|
||
|
|
if (!skill) then return end
|
||
|
|
|
||
|
|
data.uniqueID = uniqueID
|
||
|
|
|
||
|
|
data.name = data.name or "Unknown"
|
||
|
|
data.description = data.description or "No description given."
|
||
|
|
|
||
|
|
data.minLevel = data.minLevel or 0
|
||
|
|
data.maxLevel = data.maxLevel or self.MAX_SKILL
|
||
|
|
|
||
|
|
data.minValue = data.minValue or 0
|
||
|
|
data.increase = data.increase or 1
|
||
|
|
|
||
|
|
data.digits = data.digits or 0
|
||
|
|
|
||
|
|
data.skill = skill.uniqueID
|
||
|
|
|
||
|
|
if (ix.skill.scale[uniqueID]) then
|
||
|
|
for k, v in ipairs(skill.scale) do
|
||
|
|
if v.uniqueID == uniqueID then
|
||
|
|
skill.scale[k] = data
|
||
|
|
end
|
||
|
|
end
|
||
|
|
else
|
||
|
|
skill.scale[#skill.scale + 1] = data
|
||
|
|
end
|
||
|
|
|
||
|
|
ix.skill.scale[uniqueID] = data
|
||
|
|
|
||
|
|
-- Register "non-recipe" for current skill scale
|
||
|
|
local RECIPE = ix.recipe:New()
|
||
|
|
|
||
|
|
RECIPE.uniqueID = "skillscale_"..uniqueID
|
||
|
|
RECIPE.name = "Current "..data.name
|
||
|
|
RECIPE.category = "Level Unlocks"
|
||
|
|
RECIPE.noIngredients = true
|
||
|
|
RECIPE.skillScale = true
|
||
|
|
RECIPE.skillScaleID = uniqueID
|
||
|
|
RECIPE.level = 0
|
||
|
|
RECIPE.skill = skillID
|
||
|
|
|
||
|
|
RECIPE:Register()
|
||
|
|
end
|
||
|
|
|
||
|
|
function ix.skill:Find(skill)
|
||
|
|
-- finds a skill based on input by stripping caps on input and looking through DB recursive
|
||
|
|
if (ix.skill.list[skill]) then
|
||
|
|
return ix.skill.list[skill]
|
||
|
|
else
|
||
|
|
skill = string.utf8lower(skill)
|
||
|
|
for _, data in pairs(ix.skill.list) do
|
||
|
|
if (string.find(string.utf8lower(data.name), skill)) then
|
||
|
|
return data
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|