Jump to content

Recommended Posts

I've noticed some or most of the mods use a list of prefabs when choosing to equip a weapon, axe, etc. This limits the mod to be updated every time new items are added to the games, and they wont work with other mods adding new equipments.

 

So here I'll show you how I did it on my mod to make it work forever and with other mods (unless klei changes the api)
 

Repo (in typescript, not lua) https://github.com/danielpza/dst-omnikey

 

So you have an item/prefab on your inventory and you want to check if it is a weapon, a axe, etc, and how good it is, so you can pick the best. First step is to check the item for the appropriate components, for instance you should look for the `weapon` component when looking for a weapon. one trick I've seen in some mods is to create an instance of the prefab you want to inspect, look for the properties of the instance directly, and then remove the created instance. This is part of the code I used to get the values I needed:

 

local copyPrefab, pick
function copyPrefab(prefab)
    local isMasterSim = TheWorld.ismastersim
    TheWorld.ismastersim = true
    local copy = SpawnPrefab(prefab)
    local cache = {
        prefab = prefab,
        components = {
            waterproofer = pick(copy.components.waterproofer, {"effectiveness"}),
            insulator = pick(copy.components.insulator, {"insulation"}),
            eater = pick(copy.components.eater, {"preferseating"}),
            finiteuses = pick(copy.components.finiteuses, {"current", "total", "consumption"}),
            tool = pick(copy.components.tool, {"actions"}),
            weapon = pick(copy.components.weapon, {"damage"}),
            armor = pick(copy.components.armor, {"absorb_percent", "condition", "maxcondition"}),
            healer = pick(copy.components.healer, {"health"}),
            equippable = pick(copy.components.equippable, {"dapperness", "equipslot", "walkspeedmult"}),
            edible = pick(copy.components.edible, {"healthvalue", "hungervalue", "sanityvalue", "foodtype"})
        }
    }
    copy:Remove()
    TheWorld.ismastersim = isMasterSim
    return cache
end
function pick(t, ks)
    if t == nil then
        return nil
    end
    local result = {}
    for ____, k in ipairs(ks) do
        result[k] = t[k]
    end
    return result
end

(if you see any weird code as the `____` in the pick function it's because this is code generated from typescript, source: https://github.com/danielpza/dst-omnikey/blob/master/src/scripts/omnikey/cache.ts)

We have to trick the client into thinking we are the server `TheWorld.ismastersim = true`.

You can improve this further by caching the results:

local prefabCache = {}
function getPrefabCopy(prefab)
    if prefabCache[prefab] == nil then
        prefabCache[prefab] = copyPrefab(prefab)
    end
    return prefabCache[prefab]
end

Then you can check if it's a weapon by checking the results:

function valueAsWeapon(result)
    return ((result.components.weapon and result.components.weapon.damage) or 0)
end

To wrap things up, say you have two items(item1 and item2) and want to see which is a weapon and which is better:

item1Value = valueAsWeapon(getPrefabCopy(item1.prefab))
item2Value = valueAsWeapon(getPrefabCopy(item2.prefab))
if item1Value > item2Value then
  bestItem = item1
end
if item1Value < item2Value then
  bestItem = item2
end

You'll get the best of the two in `bestItem`, if bestItem is nil, then none of them were weapons.

 

You can check all of the code in typescript on github https://github.com/danielpza/dst-omnikey, and the generated lua code on steam by subscribing to the mod or compiling the source code

Hope it helps

Edited by danielpa

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...