mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
180
gamemodes/ixhl2rp/plugins/willardskills/libs/sh_actions.lua
Normal file
180
gamemodes/ixhl2rp/plugins/willardskills/libs/sh_actions.lua
Normal file
@@ -0,0 +1,180 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
-- registers the actions as ix.action and ix.action.list
|
||||
-- registers the functions:
|
||||
-- ix.action.Getactions() - returns actions on character
|
||||
-- ix.action.RegisterSkillAction(uniqueID, data) - registers action specified
|
||||
-- ix.action.Find(action) - finds the action specified
|
||||
|
||||
ix.action = ix.action or {}
|
||||
ix.action.list = ix.action.list or {}
|
||||
|
||||
local isfunction = isfunction
|
||||
|
||||
function ix.action:RegisterSkillAction(skillID, uniqueID, data)
|
||||
if (!uniqueID or type(uniqueID) != "string") then
|
||||
ErrorNoHalt("Attempted to register action without valid uniqueID.")
|
||||
return
|
||||
end
|
||||
|
||||
data.uniqueID = uniqueID
|
||||
|
||||
data.name = data.name or "Unknown"
|
||||
data.description = data.description or "No description given."
|
||||
|
||||
if (data.DoResult and type(data.DoResult) == "table" and data.DoResult[1]) then
|
||||
table.SortByMember(data.DoResult, "level", true)
|
||||
local copy = {}
|
||||
for k, v in pairs(data.DoResult) do
|
||||
copy[v.level] = v.exp
|
||||
end
|
||||
|
||||
local currExp = 0
|
||||
data.DoResult = {}
|
||||
for i = 0, ix.skill.MAX_SKILL - 1 do
|
||||
if (copy[i]) then currExp = copy[i] end
|
||||
data.DoResult[i] = currExp
|
||||
end
|
||||
data.DoResult[ix.skill.MAX_SKILL] = 0
|
||||
end
|
||||
|
||||
if (!skillID or !ix.skill:Find(skillID)) then
|
||||
ErrorNoHalt("Attempted to register '"..uniqueID.."' action without valid skill.")
|
||||
return
|
||||
else
|
||||
data.skill = ix.skill:Find(skillID).uniqueID
|
||||
ix.skill:RegisterSkillAction(data.skill, data)
|
||||
end
|
||||
|
||||
ix.action.list[uniqueID] = data
|
||||
end
|
||||
|
||||
function ix.action:Find(actionID)
|
||||
if (ix.action.list[actionID]) then
|
||||
return ix.action.list[actionID]
|
||||
else
|
||||
for _, action in pairs(ix.action.list) do
|
||||
if (string.find(action.name:utf8lower(), actionID:utf8lower())) then
|
||||
return action
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (SERVER) then
|
||||
ix.log.AddType("actionsDoAction", function(client, name, result, skill)
|
||||
return string.format("%s has performed the '%s' action, gaining %d experience in %s.", client:GetName(), name, result, skill)
|
||||
end)
|
||||
ix.log.AddType("actionsDoActionNoExp", function(client, name)
|
||||
return string.format("%s has performed the '%s' action.", client:GetName(), name)
|
||||
end)
|
||||
end
|
||||
|
||||
do
|
||||
local CHAR = ix.meta.character
|
||||
|
||||
function CHAR:CanDoAction(actionID, ...)
|
||||
local action = ix.action:Find(actionID)
|
||||
if (!action) then
|
||||
--ErrorNoHalt("Attempted to check if player can do invalid action '"..(actionID or "nil").."'.")
|
||||
return
|
||||
end
|
||||
|
||||
if (!action.CanDo) then
|
||||
return true
|
||||
end
|
||||
|
||||
if (!isfunction(action.CanDo)) then
|
||||
return self:GetSkillLevel(action.skill) >= action.CanDo
|
||||
else
|
||||
return action:CanDo(self, self:GetSkillLevel(action.skill), ...)
|
||||
end
|
||||
end
|
||||
|
||||
if (SERVER) then
|
||||
function CHAR:DoAction(actionID, ...)
|
||||
local action = ix.action:Find(actionID)
|
||||
if (!action) then
|
||||
ErrorNoHalt(string.format("[ACTIONS] Attempted to do invalid action '%s'.", actionID))
|
||||
end
|
||||
|
||||
local result = self:GetResult(actionID, ...)
|
||||
|
||||
if (result and result > 0 and self:GetSkillLevel(action.skill) >= 0) then
|
||||
if (self:GetSkill(action.skill) >= ix.skill.MAX_SKILL) then
|
||||
return
|
||||
end
|
||||
|
||||
local storedExp = self:GetSkillStoredExp(action.skill)
|
||||
self:SetSkillStoredExp(action.skill, math.min(result, 1999 - storedExp))
|
||||
|
||||
if (self:GetSkillAutoLevel(action.skill)) then
|
||||
self:LevelUpSkill(action.skill)
|
||||
elseif (self:CanLevelSkill(action.skill) and storedExp < 1000) then
|
||||
local skill = ix.skill:Find(action.skill)
|
||||
self:GetPlayer():NotifyLocalized("levelPossible", skill.name, self:GetSkill(skill.uniqueID) + 1)
|
||||
end
|
||||
|
||||
if (!action.bNoLog) then
|
||||
ix.log.Add(self:GetPlayer(), "actionsDoAction", action.name, result, action.skill)
|
||||
end
|
||||
elseif (action.alwaysLog) then
|
||||
ix.log.Add(self:GetPlayer(), "actionsDoActionNoExp", action.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function GetExp(DoResult, skillLevel)
|
||||
for k, v in ipairs(DoResult) do
|
||||
if (v.level > skillLevel) then
|
||||
break
|
||||
elseif (v.level <= skillLevel and skillLevel < DoResult[k + 1].level) then
|
||||
return v.exp
|
||||
end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function CHAR:GetResult(actionID, ...)
|
||||
local action = ix.action:Find(actionID)
|
||||
if (!action) then
|
||||
--ErrorNoHalt("Attempted to get result from invalid action '"..(actionID or "nil").."'.")
|
||||
return
|
||||
end
|
||||
|
||||
if (!action.DoResult) then
|
||||
return 0
|
||||
end
|
||||
|
||||
local min = self:GetSkill(action.skill)
|
||||
local max = math.max(min, self:GetSkillLevel(action.skill))
|
||||
if (!isfunction(action.DoResult)) then
|
||||
local maxExp = 0
|
||||
for k = min, max do
|
||||
if (action.DoResult[k] and action.DoResult[k] > maxExp) then
|
||||
maxExp = action.DoResult[k]
|
||||
end
|
||||
end
|
||||
return maxExp
|
||||
else
|
||||
local maxExp = 0
|
||||
for i = min, max do
|
||||
local result = action:DoResult(self, i, ...) or 0
|
||||
if (result > maxExp) then
|
||||
maxExp = result
|
||||
end
|
||||
end
|
||||
|
||||
return maxExp
|
||||
end
|
||||
end
|
||||
end
|
||||
245
gamemodes/ixhl2rp/plugins/willardskills/libs/sh_attributes.lua
Normal file
245
gamemodes/ixhl2rp/plugins/willardskills/libs/sh_attributes.lua
Normal file
@@ -0,0 +1,245 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
-- registers the attributes as ix.special and ix.special.list
|
||||
-- registers the functions:
|
||||
-- ix.special.GetSpecial() - returns attributes on character
|
||||
-- ix.special.RegisterAttributes(uniqueID, data) - registers attribute specified
|
||||
-- ix.special.Find(attribute) - finds the attribute specified
|
||||
|
||||
ix.special = ix.special or {}
|
||||
ix.special.list = ix.special.list or {}
|
||||
|
||||
if (SERVER) then
|
||||
ix.log.AddType("specialBoostExtend", function(client, name, type, level)
|
||||
return string.format("%s extended their level %d %s boost in %s.", client:GetName(), level, type, name)
|
||||
end)
|
||||
ix.log.AddType("specialBoostLevel", function(client, name, type, level)
|
||||
return string.format("%s has gained a level %d %s boost in %s.", client:GetName(), level, type, name)
|
||||
end)
|
||||
ix.log.AddType("specialBoostTarget", function(client, name, type, level, current)
|
||||
return string.format("%s has updated their %s %s boost target to %d (current : %d).", client:GetName(), name, type, level, current)
|
||||
end)
|
||||
ix.log.AddType("specialBoostWasted", function(client, name, type, level, current, target)
|
||||
return string.format("%s has wasted a level %d %s boost in %s (current: %d; target: %d).", client:GetName(), level, type, name, current, target)
|
||||
end)
|
||||
end
|
||||
|
||||
ix.char.RegisterVar("special", {
|
||||
default = {},
|
||||
isLocal = true,
|
||||
bNoDisplay = true,
|
||||
field = "special",
|
||||
fieldType = ix.type.text,
|
||||
OnSet = function(character, attribute, value)
|
||||
local special = ix.special:Find(attribute)
|
||||
if (!special) then return end
|
||||
|
||||
local attributes = character:GetSpecial()
|
||||
local client = character:GetPlayer()
|
||||
|
||||
attributes[special.uniqueID] = math.Clamp(value, 0, 10)
|
||||
|
||||
if (IsValid(client)) then
|
||||
net.Start("ixAttributeTbl")
|
||||
net.WriteUInt(character:GetID(), 32)
|
||||
net.WriteString(special.uniqueID)
|
||||
net.WriteInt(value, 8)
|
||||
net.Send(client)
|
||||
end
|
||||
|
||||
character.vars.special = attributes
|
||||
end,
|
||||
OnGet = function(character, key, default)
|
||||
local data = character.vars.special or {}
|
||||
|
||||
if (key) then
|
||||
if (!data) then return 0 end
|
||||
|
||||
return data[key] != nil and data[key] or 0
|
||||
else
|
||||
return data
|
||||
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 > (hook.Run("GetDefaultAttributePoints", client, data) or ix.config.Get("maxAttributes", 30))) then
|
||||
return false, "unknownError"
|
||||
end
|
||||
else
|
||||
return false, "unknownError"
|
||||
end
|
||||
end
|
||||
end,
|
||||
OnAdjust = function(self, client, data, value, newData)
|
||||
newData.special = value
|
||||
end
|
||||
})
|
||||
|
||||
ix.char.RegisterVar("specialBoost", {
|
||||
default = {},
|
||||
isLocal = true,
|
||||
bNoDisplay = true,
|
||||
field = "special_boost",
|
||||
fieldType = ix.type.text,
|
||||
OnSet = function(character, attribute, value, bShort)
|
||||
local client = character:GetPlayer()
|
||||
if (!value and type(attribute) == "table") then
|
||||
character.vars.specialBoost = attribute
|
||||
if (IsValid(client)) then
|
||||
net.Start("ixAttributeBoostTbl")
|
||||
net.WriteUInt(character:GetID(), 32)
|
||||
net.WriteTable(attribute)
|
||||
net.Send(client)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local special = ix.special:Find(attribute)
|
||||
if (!special) then return end
|
||||
|
||||
local boosts = character:GetSpecialBoost()
|
||||
if (!boosts[special.uniqueID]) then
|
||||
boosts[special.uniqueID] = {}
|
||||
end
|
||||
|
||||
local index = bShort and "short" or "long"
|
||||
if (!boosts[special.uniqueID][index]) then
|
||||
boosts[special.uniqueID][index] = {
|
||||
level = 0,
|
||||
time = (bShort and 10) or 30,
|
||||
target = value,
|
||||
targetDuration = (bShort and 15 * 60) or 6 * 60
|
||||
}
|
||||
ix.log.Add(client, "specialBoostLevel", special.name, index, value)
|
||||
else
|
||||
local currentBoost = boosts[special.uniqueID][index]
|
||||
if (currentBoost.level == value and currentBoost.target <= value) then
|
||||
currentBoost.time = (bShort and 15 * 60) or 6 * 60
|
||||
currentBoost.target = 0
|
||||
currentBoost.targetDuration = 0
|
||||
ix.log.Add(client, "specialBoostExtend", special.name, index, value)
|
||||
elseif (currentBoost.level < value and currentBoost.target < value) then
|
||||
if (currentBoost.target < currentBoost.level) then
|
||||
currentBoost.time = (bShort and 10) or 30
|
||||
end
|
||||
currentBoost.target = value
|
||||
currentBoost.targetDuration = (bShort and 15 * 60) or 6 * 60
|
||||
ix.log.Add(client, "specialBoostLevel", special.name, index, value)
|
||||
elseif (currentBoost.level > value and (currentBoost.target <= value or currentBoost.target == 0)) then
|
||||
currentBoost.target = value
|
||||
currentBoost.targetDuration = ((bShort and 15 * 60) or 6 * 60) - currentBoost.time
|
||||
ix.log.Add(client, "specialBoostTarget", special.name, index, value, currentBoost.level)
|
||||
else
|
||||
ix.log.Add(client, "specialBoostWasted", special.name, index, value, currentBoost.level, currentBoost.target)
|
||||
end
|
||||
end
|
||||
|
||||
if (IsValid(client)) then
|
||||
net.Start("ixAttributeBoostTbl")
|
||||
net.WriteUInt(character:GetID(), 32)
|
||||
net.WriteTable(boosts)
|
||||
net.Send(client)
|
||||
end
|
||||
|
||||
character.vars.specialBoost = boosts
|
||||
end,
|
||||
OnGet = function(character, attributeID)
|
||||
local data = character.vars.specialBoost or {}
|
||||
|
||||
if (attributeID) then
|
||||
if (!data or !data[attributeID]) then return 0 end
|
||||
|
||||
local short = (data[attributeID].short and data[attributeID].short.level) or 0
|
||||
local long = (data[attributeID].long and data[attributeID].long.level) or 0
|
||||
|
||||
return short + long
|
||||
else
|
||||
return data
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
if (CLIENT) then
|
||||
net.Receive("ixAttributeTbl", function()
|
||||
local id = net.ReadUInt(32)
|
||||
local character = ix.char.loaded[id]
|
||||
|
||||
if (character) then
|
||||
character.vars.special = character.vars.special or {}
|
||||
character.vars.special[net.ReadString()] = net.ReadInt(8)
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ixAttributeBoostTbl", function()
|
||||
local id = net.ReadUInt(32)
|
||||
local character = ix.char.loaded[id]
|
||||
|
||||
if (character) then
|
||||
character.vars.specialBoost = net.ReadTable()
|
||||
end
|
||||
end)
|
||||
else
|
||||
util.AddNetworkString("ixAttributeTbl")
|
||||
util.AddNetworkString("ixAttributeBoostTbl")
|
||||
end
|
||||
|
||||
function ix.special:RegisterAttribute(uniqueID, data)
|
||||
if (!uniqueID or type(uniqueID) != "string") then
|
||||
ErrorNoHalt("Attempted to register attribute without valid uniqueID.")
|
||||
return
|
||||
end
|
||||
|
||||
data.uniqueID = uniqueID
|
||||
|
||||
data.name = data.name or "Unknown"
|
||||
data.description = data.description or "No description given."
|
||||
|
||||
if (data.skills) then
|
||||
for skillID, _ in pairs(data.skills) do
|
||||
ix.skill:RegisterAttribute(skillID, data)
|
||||
end
|
||||
end
|
||||
|
||||
ix.special.list[uniqueID] = data
|
||||
end
|
||||
|
||||
function ix.special:Find(attribute)
|
||||
if (ix.special.list[attribute]) then
|
||||
return ix.special.list[attribute]
|
||||
else
|
||||
attribute = string.utf8lower(attribute)
|
||||
for _, data in pairs(ix.special.list) do
|
||||
if (string.find(string.utf8lower(data.name), attribute)) then
|
||||
return data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local CHAR = ix.meta.character
|
||||
|
||||
function CHAR:GetAttrBoostLevels(attribute, skill)
|
||||
return self:GetBoostedAttribute(attribute.uniqueID) * (attribute.skills[skill.uniqueID] or 0)
|
||||
end
|
||||
|
||||
function CHAR:GetBoostedAttribute(attributeID)
|
||||
return math.Clamp(self:GetSpecial(attributeID) + self:GetSpecialBoost(attributeID), -10, 10)
|
||||
end
|
||||
end
|
||||
376
gamemodes/ixhl2rp/plugins/willardskills/libs/sh_recipe.lua
Normal file
376
gamemodes/ixhl2rp/plugins/willardskills/libs/sh_recipe.lua
Normal file
@@ -0,0 +1,376 @@
|
||||
--[[
|
||||
| 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 ix = ix
|
||||
|
||||
ix.recipe = ix.recipe or {}
|
||||
ix.recipe.stored = ix.recipe.stored or {}
|
||||
|
||||
--[[
|
||||
Begin defining the recipe class base for other recipe's to inherit from.
|
||||
--]]
|
||||
|
||||
--[[ Set the __index meta function of the class. --]]
|
||||
local CLASS_TABLE = {__index = CLASS_TABLE}
|
||||
|
||||
CLASS_TABLE.name = "Blueprint Base"
|
||||
CLASS_TABLE.uniqueID = "blueprint_base"
|
||||
CLASS_TABLE.skin = 0
|
||||
CLASS_TABLE.model = "models/error.mdl"
|
||||
CLASS_TABLE.category = "Other"
|
||||
CLASS_TABLE.description = "A recipe with no description."
|
||||
|
||||
-- Called when the recipe is converted to a string.
|
||||
function CLASS_TABLE:__tostring()
|
||||
return "RECIPE["..self.name.."]"
|
||||
end
|
||||
|
||||
--[[
|
||||
A function to override an recipe's base data. This is
|
||||
just a nicer way to set a value to go along with
|
||||
the method of querying.
|
||||
--]]
|
||||
function CLASS_TABLE:Override(varName, value)
|
||||
self[varName] = value
|
||||
end
|
||||
|
||||
-- A function to register a new recipe.
|
||||
function CLASS_TABLE:Register()
|
||||
return ix.recipe:Register(self)
|
||||
end
|
||||
|
||||
function CLASS_TABLE:PlayerCanCraftRecipe(client)
|
||||
return ix.recipe:PlayerCanCraftRecipe(self, client)
|
||||
end
|
||||
|
||||
--[[
|
||||
End defining the base recipe class.
|
||||
Begin defining the recipe utility functions.
|
||||
--]]
|
||||
|
||||
-- A function to get all recipes.
|
||||
function ix.recipe:GetAll()
|
||||
return self.stored
|
||||
end
|
||||
|
||||
-- A function to get a new recipe.
|
||||
function ix.recipe:New()
|
||||
local object = {}
|
||||
setmetatable(object, CLASS_TABLE)
|
||||
CLASS_TABLE.__index = CLASS_TABLE
|
||||
return object
|
||||
end
|
||||
|
||||
-- A function to register a new recipe.
|
||||
function ix.recipe:Register(recipe)
|
||||
recipe.uniqueID = string.utf8lower(string.gsub(recipe.uniqueID or string.gsub(recipe.name, "%s", "_"), "['%.]", ""))
|
||||
self.stored[recipe.uniqueID] = recipe
|
||||
|
||||
if (recipe.model) then
|
||||
util.PrecacheModel(recipe.model)
|
||||
|
||||
if (SERVER) then
|
||||
resource.AddFile(recipe.model)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- A function to get an recipe by its name.
|
||||
function ix.recipe:FindByID(identifier)
|
||||
if (identifier and identifier != 0 and type(identifier) != "boolean") then
|
||||
if (self.stored[identifier]) then
|
||||
return self.stored[identifier]
|
||||
end
|
||||
|
||||
local lowerName = string.utf8lower(identifier)
|
||||
local recipe = nil
|
||||
|
||||
for _, v in pairs(self.stored) do
|
||||
local recipeName = v.name
|
||||
|
||||
if (string.find(string.utf8lower(recipeName), lowerName)
|
||||
and (!recipe or string.utf8len(recipeName) < string.utf8len(recipe.name))) then
|
||||
recipe = v
|
||||
end
|
||||
end
|
||||
|
||||
return recipe
|
||||
end
|
||||
end
|
||||
|
||||
function ix.recipe:Initialize()
|
||||
local recipes = self:GetAll()
|
||||
|
||||
for _, v in pairs(recipes) do
|
||||
if (v.OnSetup) then
|
||||
v:OnSetup()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Called when a player attempts to craft an item.
|
||||
function ix.recipe:PlayerCanCraftRecipe(recipe, client, inventory)
|
||||
local character = client:GetCharacter()
|
||||
inventory = inventory or character:GetInventory()
|
||||
|
||||
if (recipe.skill != "bartering" and !character:CanDoAction("recipe_"..recipe.uniqueID)) then
|
||||
return false, "You do not have the required skill level to craft this recipe."
|
||||
end
|
||||
|
||||
-- Check if the player has all the needed tools if there are any needed
|
||||
if (recipe.tool and !istable(recipe.tool)) then
|
||||
if !ix.item.list[recipe.tool] then
|
||||
ErrorNoHalt("[Crafting] Recipe "..recipe.name.." has an unexisting tool "..recipe.tool.."!\n")
|
||||
return false, "Recipe has unexisting tool "..recipe.tool.."!"
|
||||
elseif (!inventory:HasItem(recipe.tool)) then
|
||||
return false, "You do not have a "..ix.item.list[recipe.tool].name.."."
|
||||
end
|
||||
end
|
||||
|
||||
if recipe.tools and istable(recipe.tools) then
|
||||
for _, v in pairs(recipe.tools) do
|
||||
if ix.item.list[v] then
|
||||
if (!inventory:HasItem(v)) then
|
||||
return false, "You do not have a "..ix.item.list[v].name.."."
|
||||
end
|
||||
else
|
||||
ErrorNoHalt("[Crafting] Recipe "..recipe.name.." has an unexisting tool "..v.."!\n")
|
||||
return false, "Recipe has unexisting tool "..v.."!"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for the ingredients
|
||||
if (recipe.ingredients) then
|
||||
for ingredient, amount in pairs(recipe.ingredients) do
|
||||
if (!ix.item.list[ingredient]) then
|
||||
ErrorNoHalt("[Crafting] Recipe "..recipe.name.." has an unexisting ingredient "..ingredient.."!\n")
|
||||
return false, "Recipe has unexisting ingredient "..ingredient.."!"
|
||||
end
|
||||
|
||||
local count = inventory:GetItemCount(ingredient)
|
||||
if (count == 0) then
|
||||
return false, "You do not have any "..ix.item.list[ingredient].name.."."
|
||||
elseif (count < amount) then
|
||||
local name = ingredient
|
||||
if (amount > 1) then
|
||||
name = Schema:Pluralize(ix.item.list[ingredient].name)
|
||||
end
|
||||
return false, "You need at least "..tostring(amount).." "..name.."."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if player is near a crafting station if needed
|
||||
if (recipe.station) then
|
||||
if (!istable(recipe.station)) then
|
||||
if (ix.item.list[recipe.station]) then
|
||||
-- Find the entity the player is looking at
|
||||
local entity = client:GetEyeTraceNoCursor().Entity
|
||||
|
||||
if (IsValid(entity)) then
|
||||
if (entity:GetClass() != "ix_item") then
|
||||
return false, "The attempted station is invalid!"
|
||||
else
|
||||
if !entity.GetItemTable or (entity.GetItemTable and !entity:GetItemTable()) then
|
||||
return false, "This is an invalid type of station for this recipe!"
|
||||
end
|
||||
|
||||
local itemTable = entity:GetItemTable()
|
||||
if (itemTable.uniqueID != recipe.station) then
|
||||
return false, "This is the wrong type of station for this recipe!"
|
||||
end
|
||||
if (client:GetShootPos():DistToSqr(entity:GetPos()) > 100 * 100) then
|
||||
return false, "You need to be closer to the station!"
|
||||
end
|
||||
end
|
||||
else
|
||||
return false, "You need to be looking at a station!"
|
||||
end
|
||||
else
|
||||
ErrorNoHalt("[Crafting] Recipe "..recipe.name.." has an unexisting station "..recipe.station.."!\n")
|
||||
return false, "Recipe has unexisting station "..recipe.station.."!"
|
||||
end
|
||||
else
|
||||
local validStations = {}
|
||||
local bFound, bInvalidStationEntity = false, false
|
||||
|
||||
local entity = client:GetEyeTraceNoCursor().Entity
|
||||
local bEntityValid = IsValid(entity)
|
||||
if (!bEntityValid or client:GetShootPos():DistToSqr(entity:GetPos()) > 100 * 100) then
|
||||
bInvalidStationEntity = true
|
||||
end
|
||||
|
||||
local campFire = recipe.canUseCampfire
|
||||
local campFireText = campFire and " or a Campfire" or ""
|
||||
if (campFire and !bInvalidStationEntity and bEntityValid and entity:GetClass() == "ix_campfire") then
|
||||
bFound = true
|
||||
end
|
||||
|
||||
if (!bFound) then
|
||||
if (entity:GetClass() != "ix_item" or !entity:GetItemTable()) then
|
||||
bInvalidStationEntity = true
|
||||
end
|
||||
|
||||
for _, v in pairs(recipe.station) do
|
||||
if ix.item.list[v] then
|
||||
validStations[#validStations + 1] = ix.item.list[v]:GetName()
|
||||
|
||||
if (bInvalidStationEntity) then continue end -- too far/invalid/wrong class, don't bother checking
|
||||
|
||||
local itemTable = entity:GetItemTable()
|
||||
if (itemTable.uniqueID != v) then
|
||||
continue
|
||||
end
|
||||
|
||||
bFound = true
|
||||
break -- valid station found, stop checking station loop
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (!bFound) then
|
||||
return false, string.format("You need to be near and looking at a %s"..campFireText..".", table.concat(validStations, " or a "))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if player has the crafting license if needed
|
||||
if (recipe.skill == "bartering" and !character:HasPermit(recipe.category)) then
|
||||
return false, "You do not have a business permit for this category of items, contact the Combine Civil Administration."
|
||||
end
|
||||
|
||||
if (recipe.cost and isnumber(recipe.cost)) then
|
||||
local itemID = character:GetIdCard()
|
||||
if (itemID) then
|
||||
if (ix.item.instances[itemID]) then
|
||||
local credits = ix.item.instances[itemID]:GetCredits()
|
||||
|
||||
if (credits < recipe.cost) then
|
||||
return false, "You do not have enough credits to purchase this item!"
|
||||
end
|
||||
else
|
||||
return false, "Could not find ID card!"
|
||||
end
|
||||
else
|
||||
return false, "You do not have an active ID card!"
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if (CLIENT) then
|
||||
function ix.recipe:GetIconInfo(recipe)
|
||||
local model = recipe.model or "models/error.mdl"
|
||||
local skin = recipe.skin
|
||||
|
||||
return model, skin
|
||||
end
|
||||
|
||||
function ix.recipe:CanPlayerSeeRecipe(recipe)
|
||||
if (recipe.hidden) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
else
|
||||
function ix.recipe:PlayerCraftRecipe(recipe, client)
|
||||
if (recipe.PlayerCraftRecipe) then
|
||||
recipe:PlayerCraftRecipe(client)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local character = client:GetCharacter()
|
||||
local inventory = character:GetInventory()
|
||||
|
||||
-- Take all the ingredients
|
||||
for ingredient, amount in pairs(recipe.ingredients) do
|
||||
for _ = 1, amount do
|
||||
local item = inventory:HasItem(ingredient)
|
||||
if (item) then
|
||||
item:Remove()
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Break tools
|
||||
if (recipe.tools and !table.IsEmpty(recipe.tools)) then
|
||||
for k, v in pairs(recipe.tools) do
|
||||
local item = inventory:HasItem(v)
|
||||
|
||||
if (item and item.isTool) then
|
||||
item:DamageDurability(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (recipe.tool) then
|
||||
local item = inventory:HasItem(recipe.tool)
|
||||
|
||||
if (item and item.isTool) then
|
||||
item:DamageDurability(1)
|
||||
end
|
||||
end
|
||||
|
||||
-- Give the result
|
||||
for result, amount in pairs(recipe.result) do
|
||||
local item = ix.item.list[result]
|
||||
if (!item) then continue end
|
||||
|
||||
local actualAmount
|
||||
if (type(amount) == "table") then
|
||||
actualAmount = amount[math.random(1, #amount)]
|
||||
else
|
||||
actualAmount = amount
|
||||
end
|
||||
|
||||
if (item.maxStackSize) then
|
||||
-- fill up existing stacks if possible
|
||||
local items = inventory:GetItemsByUniqueID(result)
|
||||
for _, v in ipairs(items) do
|
||||
if (v:GetStackSize() < v.maxStackSize) then
|
||||
local toAdd = math.min(v.maxStackSize - v:GetStackSize(), actualAmount)
|
||||
actualAmount = actualAmount - toAdd
|
||||
v:AddStack(toAdd)
|
||||
|
||||
if (actualAmount == 0) then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (actualAmount > 0) then
|
||||
for i = 1, actualAmount, (item.maxStackSize or 1) do
|
||||
-- Give new items in stacks if possible
|
||||
local data
|
||||
if (item.maxStackSize) then
|
||||
data = {stack = math.min(actualAmount + 1 - i, item.maxStackSize)}
|
||||
end
|
||||
|
||||
if (!inventory:Add(result, 1, data)) then
|
||||
ix.item.Spawn(result, client, nil, nil, data)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Set the player's next crafting time
|
||||
client.ixNextCraftTime = CurTime() + 2
|
||||
netstream.Start("CraftTime", client.ixNextCraftTime)
|
||||
|
||||
character:DoAction("recipe_"..recipe.uniqueID)
|
||||
end
|
||||
end
|
||||
450
gamemodes/ixhl2rp/plugins/willardskills/libs/sh_skill.lua
Normal file
450
gamemodes/ixhl2rp/plugins/willardskills/libs/sh_skill.lua
Normal file
@@ -0,0 +1,450 @@
|
||||
--[[
|
||||
| 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
|
||||
Reference in New Issue
Block a user