Jump to content

[Help Appreciated] Backpack + 2 Amulet Slots


Recommended Posts

Hello there!

I've been trying to add ANOTHER Amulet slot to DST and here's the results:

It shows up as a slot beside the first Amulet slot.

Problem:

It does not actually allow any amulets to be equipped. Right-clicking any amulets will equip it to the first slot. Clicking and dragging to the second slot (while the first slot is empty) also does not work.

Here's the code I'm messing around with (I'm using the only Backpack and Amulet Slots mod available for DST so credit to xVars for guiding my learning :grin:)

local require = GLOBAL.require
local TheInput = GLOBAL.TheInput
local ThePlayer = GLOBAL.ThePlayer
local IsServer = GLOBAL.TheNet:GetIsServer()
local Inv = require "widgets/inventorybar"

Assets =
{
Asset("IMAGE", "images/back.tex"),
Asset("ATLAS", "images/back.xml"),
Asset("IMAGE", "images/neck.tex"),
Asset("ATLAS", "images/neck.xml"),
Asset("IMAGE", "images/neck2.tex"),
Asset("ATLAS", "images/neck2.xml"),
}
-- for key,value in pairs(GLOBAL.EQUIPSLOTS) do print('4r',key,value) end

GLOBAL.EQUIPSLOTS=
{
HANDS = "hands",
HEAD = "head",
BODY = "body",
BACK = "back",
NECK = "neck",
NECK2 = "neck2",
}

AddComponentPostInit("resurrectable", function(self, inst)
local original_FindClosestResurrector = self.FindClosestResurrector
local original_CanResurrect = self.CanResurrect
local original_DoResurrect = self.DoResurrect

self.FindClosestResurrector = function(self)
if IsServer and self.inst.components.inventory then
local item = self.inst.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.NECK)
local item2 = self.inst.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.NECK2)
if item and item.prefab == "amulet" or item2 and item.prefab == "amulet" then
return item
end
end
original_FindClosestResurrector(self)
end

self.CanResurrect = function(self)
if IsServer and self.inst.components.inventory then
local item = self.inst.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.NECK)
local item2 = self.inst.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.NECK2)
if item and item.prefab == "amulet" or item2 and item.prefab == "amulet" then
return true
end
end
original_CanResurrect(self)
end

self.DoResurrect = function(self)
self.inst:PushEvent("resurrect")
if IsServer and self.inst.components.inventory then
local item = self.inst.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.NECK)
local item2 = self.inst.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.NECK2)
if item and item.prefab == "amulet" or item2 and item.prefab == "amulet" then
self.inst.sg:GoToState("amulet_rebirth")
return true
end
end
original_DoResurrect(self)
end
end)

AddComponentPostInit("inventory", function(self, inst)
local original_Equip = self.Equip
self.Equip = function(self, item, old_to_active)
if original_Equip(self, item, old_to_active) and item and item.components and item.components.equippable then
local eslot = item.components.equippable.equipslot
if original_Equip(self, item, old_to_active) and item2 and item.components and item.components.equippable then
local eslot = item.components.equippable.equipslot
if self.equipslots[eslot] ~= item or self.equipslots[eslot] ~= item2 then
if eslot == GLOBAL.EQUIPSLOTS.BACK and item.components.container ~= nil then
self.inst:PushEvent("setoverflow", { overflow = item })
end
end
end
return true
else
return
end
end

self.GetOverflowContainer = function()
if self.ignoreoverflow then
return
end
local item = self:GetEquippedItem(GLOBAL.EQUIPSLOTS.BACK)
return item ~= nil and item.components.container or nil
end
end)

AddGlobalClassPostConstruct("widgets/inventorybar", "Inv", function()
local Inv_Refresh_base = Inv.Refresh or function() return "" end
local Inv_Rebuild_base = Inv.Rebuild or function() return "" end

function Inv:LoadExtraSlots(self)
self.bg:SetScale(1.25,1,1.25)
self.bgcover:SetScale(1.25,1,1.25)

if self.addextraslots == nil then
self.addextraslots = 0

self:AddEquipSlot(GLOBAL.EQUIPSLOTS.NECK2, "images/neck2.xml", "neck2.tex")
self:AddEquipSlot(GLOBAL.EQUIPSLOTS.BACK, "images/back.xml", "back.tex")
self:AddEquipSlot(GLOBAL.EQUIPSLOTS.NECK, "images/neck.xml", "neck.tex")
-- else
-- GLOBAL.GetPlayer().HUD.controls.stickyrecipepopup:Refresh()
end
end

function Inv:Refresh()
Inv_Refresh_base(self)
Inv:LoadExtraSlots(self)
end

function Inv:Rebuild()
Inv_Rebuild_base(self)
Inv:LoadExtraSlots(self)
end
end)

AddPrefabPostInit("inventory_classified", function(inst)
function GetOverflowContainer(inst)
local item = inst.GetEquippedItem(inst, GLOBAL.EQUIPSLOTS.BACK)
return item ~= nil and item.replica.container or nil
end

function Count(item)
return item.replica.stackable ~= nil and item.replica.stackable:StackSize() or 1
end

function Has(inst, prefab, amount)
local count =
inst._activeitem ~= nil and
inst._activeitem.prefab == prefab and
Count(inst._activeitem) or 0

if inst._itemspreview ~= nil then
for i, v in ipairs(inst._items) do
local item = inst._itemspreview
if item ~= nil and item.prefab == prefab then
count = count + Count(item)
end
end
else
for i, v in ipairs(inst._items) do
local item = v:value()
if item ~= nil and item ~= inst._activeitem and item.prefab == prefab then
count = count + Count(item)
end
end
end

local overflow = GetOverflowContainer(inst)
if overflow ~= nil then
local overflowhas, overflowcount = overflow:Has(prefab, amount)
count = count + overflowcount
end

return count >= amount, count
end

-- function IsBusy(inst)
-- return inst._busy or inst._parent == nil
-- end

-- local PushItemGet = inst.PushItemGet
-- local PushStackSize = inst.PushStackSize
-- local ConsumeByName = inst.ConsumeByName

-- function UseItemFromInvTile(inst, item)
-- if not IsBusy(inst) and
-- inst._parent ~= nil and
-- inst._parent.components.playeractionpicker ~= nil and
-- inst._parent.components.playercontroller ~= nil then
-- local actions = inst._activeitem ~= nil and
-- inst._parent.components.playeractionpicker:GetUseItemActions(item, inst._activeitem, true) or
-- inst._parent.components.playeractionpicker:GetInventoryActions(item)
-- if #actions > 0 then
-- if actions[1].action == GLOBAL.ACTIONS.RUMMAGE then
-- local overflow = GetOverflowContainer(inst)
-- if overflow ~= nil and overflow.inst == item then
-- if overflow:IsOpenedBy(inst._parent) then
-- overflow:Close()
-- else
-- overflow:Open(inst._parent)
-- end
-- return
-- end
-- end
-- inst._parent.components.playercontroller:RemoteUseItemFromInvTile(actions[1], item)
-- end
-- end
-- end

-- function ReceiveItem(inst, item, count)
-- if IsBusy(inst) then
-- return
-- end
-- local overflow = GetOverflowContainer(inst)
-- overflow = overflow and overflow.classified or nil
-- if overflow ~= nil and overflow:IsBusy() then
-- return
-- end
-- local isstackable = item.replica.stackable ~= nil
-- local originalstacksize = isstackable and item.replica.stackable:StackSize() or 1
-- if not isstackable or inst._parent.replica.inventory == nil or not inst._parent.replica.inventory:AcceptsStacks() then
-- for i, v in ipairs(inst._items) do
-- if v:value() == nil then
-- local giveitem = SlotItem(item, i)
-- PushItemGet(inst, giveitem)
-- if originalstacksize > 1 then
-- PushStackSize(inst, item, nil, nil, 1, false, true)
-- return originalstacksize - 1
-- else
-- return 0
-- end
-- end
-- end
-- if overflow ~= nil then
-- return overflow:ReceiveItem(item, count)
-- end
-- else
-- local originalcount = count and math.min(count, originalstacksize) or originalstacksize
-- count = originalcount
-- if item.replica.equippable ~= nil then
-- local eslot = item.replica.equippable:EquipSlot()
-- local equip = inst:GetEquippedItem(eslot)
-- if equip ~= nil and
-- equip.prefab == item.prefab and
-- equip.replica.stackable ~= nil and
-- not equip.replica.stackable:IsFull() then
-- local stacksize = equip.replica.stackable:StackSize() + count
-- local maxsize = equip.replica.stackable:MaxSize()
-- if stacksize > maxsize then
-- count = math.max(stacksize - maxsize, 0)
-- stacksize = maxsize
-- else
-- count = 0
-- end
-- PushStackSize(inst, equip, stacksize, true, nil, nil, nil, SlotEquip(equip, eslot))
-- end
-- end
-- if count > 0 then
-- local emptyslot = nil
-- for i, v in ipairs(inst._items) do
-- local slotitem = v:value()
-- if slotitem == nil then
-- if emptyslot == nil then
-- emptyslot = i
-- end
-- elseif slotitem.prefab == item.prefab and
-- slotitem.replica.stackable ~= nil and
-- not slotitem.replica.stackable:IsFull() then
-- local stacksize = slotitem.replica.stackable:StackSize() + count
-- local maxsize = slotitem.replica.stackable:MaxSize()
-- if stacksize > maxsize then
-- count = math.max(stacksize - maxsize, 0)
-- stacksize = maxsize
-- else
-- count = 0
-- end
-- PushStackSize(inst, slotitem, stacksize, true, nil, nil, nil, SlotItem(slotitem, i))
-- if count <= 0 then
-- break
-- end
-- end
-- end
-- if count > 0 then
-- if emptyslot ~= nil then
-- local giveitem = SlotItem(item, emptyslot)
-- PushItemGet(inst, giveitem)
-- if count ~= originalstacksize then
-- PushStackSize(inst, item, nil, nil, count, false, true)
-- end
-- count = 0
-- elseif overflow ~= nil then
-- local remainder = overflow:ReceiveItem(item, count)
-- if remainder ~= nil then
-- count = math.max(count - (originalstacksize - remainder), 0)
-- end
-- end
-- end
-- end
-- if count ~= originalcount then
-- return originalstacksize - (originalcount - count)
-- end
-- end
-- end

-- function RemoveIngredients(inst, recipe, ingredientmod)
-- if IsBusy(inst) then
-- return false
-- end
-- local overflow = GetOverflowContainer(inst)
-- overflow = overflow and overflow.classified or nil
-- if overflow ~= nil and overflow:IsBusy() then
-- return false
-- end
-- for i, v in ipairs(recipe.ingredients) do
-- local amt = math.max(1, GLOBAL.RoundBiasedUp(v.amount * ingredientmod))
-- inst.ConsumeByName(inst, v.type, amt, overflow)
-- end
-- return true
-- end

if not IsServer then
inst.GetOverflowContainer = GetOverflowContainer
inst.Has = Has
-- inst.UseItemFromInvTile = UseItemFromInvTile
-- inst.ReceiveItem = ReceiveItem
-- inst.RemoveIngredients = RemoveIngredients
end
end)

AddStategraphPostInit("wilson", function(self)
for key,value in pairs(self.states) do
if value.name == 'amulet_rebirth' then
local original_amulet_rebirth_onexit = self.states[key].onexit


self.states[key].onexit = function(inst)
local item = inst.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.NECK)
local item2 = self.inst.components.inventory:GetEquippedItem(GLOBAL.EQUIPSLOTS.NECK2)
if item and item.prefab == "amulet" or item2 and item.prefab == "amulet" then
item = inst.components.inventory:RemoveItem(item)
if item then
item:Remove()
item.persists = false
end
end
original_amulet_rebirth_onexit(inst)
end
end
end
end)

function backpackpostinit(inst)
if IsServer then
inst.components.equippable.equipslot = GLOBAL.EQUIPSLOTS.BACK
end
end

function amuletpostinit(inst)
if IsServer then
inst.components.equippable.equipslot = GLOBAL.EQUIPSLOTS.NECK
end
end

function amuletpostinit2(inst)
if IsServer then
inst.components.equippable.equipslot = GLOBAL.EQUIPSLOTS.NECK2
end
end

AddPrefabPostInit("amulet", amuletpostinit)
AddPrefabPostInit("blueamulet", amuletpostinit)
AddPrefabPostInit("purpleamulet", amuletpostinit)
AddPrefabPostInit("orangeamulet", amuletpostinit)
AddPrefabPostInit("greenamulet", amuletpostinit)
AddPrefabPostInit("yellowamulet", amuletpostinit)

AddPrefabPostInit("amulet", amuletpostinit2)
AddPrefabPostInit("blueamulet", amuletpostinit2)
AddPrefabPostInit("purpleamulet", amuletpostinit2)
AddPrefabPostInit("orangeamulet", amuletpostinit2)
AddPrefabPostInit("greenamulet", amuletpostinit2)
AddPrefabPostInit("yellowamulet", amuletpostinit2)

AddPrefabPostInit("backpack", backpackpostinit)
AddPrefabPostInit("krampus_sack", backpackpostinit)
AddPrefabPostInit("piggyback", backpackpostinit)
AddPrefabPostInit("icepack", backpackpostinit)

 

I'm not sure what I'm doing wrong. Or maybe it's not possible at all? Google yields nothing. Lol.

Thank you very much in advance if you help! 

Link to comment
Share on other sites

Question: do you want to be Setrakus Ra from "I am Number 4" and carry around multiple amulets/pendants? Is that the reason why you're making a mod with an extra amulet slot? Cause most people rarely use one at the time!

Link to comment
Share on other sites

Question: do you want to be Setrakus Ra from "I am Number 4" and carry around multiple amulets/pendants? Is that the reason why you're making a mod with an extra amulet slot? Cause most people rarely use one at the time!

Holy cow. How did you KNOW?!!?! 

Hahahaha yeah I am a 'lazy' gamer in a sense that I am lazy to keep switching in the Construction Amulet when crafting or keep switching in Life Giving Amulet if I'm going to die or keep switching in Magiluminescence for travelling and I also wish to have a constant Lazy Forager because well.....I'm lazy. 

So I need 5 amulet slots. NO PROBLEMO. :D

But on a serious note, I do wish to see how it's done. 

Link to comment
Share on other sites

@Gigadroid, doing this ideally would be intrusive, having to edit server and client side code.

 

If you are ok with having 4 extra slots, and only being able to equip things like amulets and armor on the extra slots via the right button click:

local EQUIPSLOTS = GLOBAL.EQUIPSLOTSEQUIPSLOTS.NECK1 = "neck1"EQUIPSLOTS.NECK2 = "neck2"EQUIPSLOTS.NECK3 = "neck3"EQUIPSLOTS.NECK4 = "neck4"local HUD_ATLAS = GLOBAL.HUD_ATLASAddClassPostConstruct("widgets/inventorybar", function(self)	self:AddEquipSlot(EQUIPSLOTS.NECK1, HUD_ATLAS, "equip_slot_body.tex")	self:AddEquipSlot(EQUIPSLOTS.NECK2, HUD_ATLAS, "equip_slot_body.tex")	self:AddEquipSlot(EQUIPSLOTS.NECK3, HUD_ATLAS, "equip_slot_body.tex")	self:AddEquipSlot(EQUIPSLOTS.NECK4, HUD_ATLAS, "equip_slot_body.tex")end)AddComponentPostInit("inventory", function(self)	local old = self.Equip	self.Equip = function(self, item, old_to_active)		if not item or not item.components.equippable or not item:IsValid() then			return		end		local oldslot = item.components.equippable.equipslot		if oldslot == EQUIPSLOTS.BODY then			local slots = {"body", "neck1", "neck2", "neck3", "neck4"}			for k, v in ipairs(slots) do				if not self.inst.components.inventory:GetEquippedItem(v) then					item.components.equippable.equipslot = v					break				end			end		end		item:DoTaskInTime(0, function()			item.components.equippable.equipslot = oldslot		end)		return old(self, item, old_to_active)	endend)

You can click and drag to unequip.

 

Implementing drag and drop is tougher. The game assigns one type of slot per equipment, and no item can be in two different slot categories. So to modify this, we would have to touch the inventory bar widget to let a BODY equip go into a NECK equip, and edit pretty much how equippables work, how the inventory equips stuff.

 

xVars has a slot for backpacks, and a slot for amulets. That makes it much more simple.

Link to comment
Share on other sites

Wow thanks DarkXero! 

 

I've tested it out and apparently it now allows extra 4 armor, still only one amulet slot. 

 

Would you mind teaching me how to change what to get for example 2 armor and 2 amulet slots?

 

I've messed around with it and.......I messed up. LOL.

local EQUIPSLOTS = GLOBAL.EQUIPSLOTSEQUIPSLOTS.NECK1 = "neck1"EQUIPSLOTS.NECK2 = "neck2"EQUIPSLOTS.NECK3 = "body1" local HUD_ATLAS = GLOBAL.HUD_ATLAS AddClassPostConstruct("widgets/inventorybar", function(self)    self:AddEquipSlot(EQUIPSLOTS.NECK1, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK2, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.BODY1, HUD_ATLAS, "equip_slot_body.tex")end) AddComponentPostInit("inventory", function(self)    local old = self.Equip    self.Equip = function(self, item, old_to_active)        if not item or not item.components.equippable or not item:IsValid() then            return        end        local oldslot = item.components.equippable.equipslot        if oldslot == EQUIPSLOTS.BODY then            local slots = {"body", "body1"}            for k, v in ipairs(slots) do                if not self.inst.components.inventory:GetEquippedItem(v) then                    item.components.equippable.equipslot = v                    break                end            end        end        local oldslot = item.components.equippable.equipslot        if oldslot == EQUIPSLOTS.NECK then            local slots = {"neck1", "neck2"}            for k, v in ipairs(slots) do                if not self.inst.components.inventory:GetEquippedItem(v) then                    item.components.equippable.equipslot = v                    break                end            end        end            item:DoTaskInTime(0, function()            item.components.equippable.equipslot = oldslot        end)        return old(self, item, old_to_active)    endend)

 

Thank you so much!

Link to comment
Share on other sites

@Gigadroid, my code allows a host or a client to equip any combination of armor and amulets, as long as you right click the things you want to equip. As seen here: http://imgur.com/f4sSObl

 

Two armors and 3 amulets. You can also right click 5 amulets or 5 armor.

 

What you want is something akin to this:

local EQUIPSLOTS = GLOBAL.EQUIPSLOTSEQUIPSLOTS.BODY2 = "body2"EQUIPSLOTS.NECK = "neck"EQUIPSLOTS.NECK2 = "neck2" local HUD_ATLAS = GLOBAL.HUD_ATLAS AddClassPostConstruct("widgets/inventorybar", function(self)	self:AddEquipSlot(EQUIPSLOTS.BODY2, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK2, HUD_ATLAS, "equip_slot_body.tex")end)local amulets = {orangeamulet = true, blueamulet = true, greenamulet = true,amulet = true, yellowamulet = true, purpleamulet = true}AddComponentPostInit("inventory", function(self)    local old = self.Equip    self.Equip = function(self, item, old_to_active)        if not item or not item.components.equippable or not item:IsValid() then            return        end        local oldslot = item.components.equippable.equipslot        if oldslot == EQUIPSLOTS.BODY and not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY2) then			item.components.equippable.equipslot = EQUIPSLOTS.BODY2        end		if amulets[item.prefab] then			item.components.equippable.equipslot = EQUIPSLOTS.NECK	        if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.NECK2)then				item.components.equippable.equipslot = EQUIPSLOTS.NECK2			end		end        item:DoTaskInTime(0, function()            item.components.equippable.equipslot = oldslot        end)        return old(self, item, old_to_active)    endend)

Link to comment
Share on other sites

Awesome job DarkXero!!

I tested it out and it needed a little tweaking to fix the equip priority. I managed to fix it for amulets but unfortunately not for armor. 

Problem: 

Slot 0 is never used except for Backpacks. 

Slot 1 is only used by Rain Coat

 

Slot 2 is constantly overwritten by all other armor (Grass Suit, Log Suit, Thulecite Suit, Belt of Hunger)

 

Below's my code, much much appreciated if the problem could be identified.

local EQUIPSLOTS = GLOBAL.EQUIPSLOTSEQUIPSLOTS.HEAD1 = "head1"EQUIPSLOTS.BODY1 = "body1"EQUIPSLOTS.BODY2 = "body2"EQUIPSLOTS.NECK = "neck"EQUIPSLOTS.NECK1 = "neck1"EQUIPSLOTS.NECK2 = "neck2"  local HUD_ATLAS = GLOBAL.HUD_ATLASAssets ={    Asset("IMAGE", "images/back.tex"),    Asset("ATLAS", "images/back.xml"),    Asset("IMAGE", "images/neck.tex"),    Asset("ATLAS", "images/neck.xml"),}AddClassPostConstruct("widgets/inventorybar", function(self)    self:AddEquipSlot(EQUIPSLOTS.HEAD1, HUD_ATLAS, "equip_slot_head.tex")    self:AddEquipSlot(EQUIPSLOTS.BODY1, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.BODY2, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK, "images/neck.xml", "neck.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK1, "images/neck.xml", "neck.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK2, "images/neck.xml", "neck.tex")end) local amulets = {orangeamulet = true, blueamulet = true, greenamulet = true,amulet = true, yellowamulet = true, purpleamulet = true} AddComponentPostInit("inventory", function(self)    local old = self.Equip    self.Equip = function(self, item, old_to_active)        if not item or not item.components.equippable or not item:IsValid() then            return        end        local oldslot = item.components.equippable.equipslot        if oldslot == EQUIPSLOTS.BODY and not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY) then            item.components.equippable.equipslot = EQUIPSLOTS.BODY            else if oldslot == EQUIPSLOTS.BODY and not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY2) then                item.components.equippable.equipslot = EQUIPSLOTS.BODY2                else if oldslot == EQUIPSLOTS.BODY and not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY1) then                    item.components.equippable.equipslot = EQUIPSLOTS.BODY1                end            end        end        local oldslot = item.components.equippable.equipslot        if oldslot == EQUIPSLOTS.HEAD and not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HEAD1) then            item.components.equippable.equipslot = EQUIPSLOTS.HEAD1        end        if amulets[item.prefab] then            item.components.equippable.equipslot = EQUIPSLOTS.NECK            if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.NECK) then                item.components.equippable.equipslot = EQUIPSLOTS.NECK                else if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.NECK1) then                    item.components.equippable.equipslot = EQUIPSLOTS.NECK1                    else if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.NECK2) then                        item.components.equippable.equipslot = EQUIPSLOTS.NECK2                    end                end            end        end        item:DoTaskInTime(0, function()            item.components.equippable.equipslot = oldslot        end)        return old(self, item, old_to_active)    endend)


EDIT: I've managed to combine xVars' codes into this and separate backpack as it's own slot. However, the final problem I have is equipping armor/clothing. 

Problem:

 

The clothing seems to have it's own 'slot preference' instead of following the if else procedure in the code (shown below).
Equip Clothing A .........goes to Slot 1
Equip Clothing B .........goes to Slot 3 (for some reason)

Equip Clothing C .........goes to Slot 1 (overwrites Clothing A)

Equip Clothing D .........goes to Slot 2

Equip Clothing A when Slot 1 is full and Slot 2 & Slot 3 are empty .......goes to Slot 2

I'm really stuck with this so I would appreciate it if someone could chip in! 

local require = GLOBAL.requirelocal TheInput = GLOBAL.TheInputlocal ThePlayer = GLOBAL.ThePlayerlocal IsServer = GLOBAL.TheNet:GetIsServer()local Inv = require "widgets/inventorybar"local EQUIPSLOTS = GLOBAL.EQUIPSLOTSEQUIPSLOTS.HEAD1 = "head1"EQUIPSLOTS.BODY1 = "body1"EQUIPSLOTS.BODY2 = "body2"EQUIPSLOTS.BACK = "back"EQUIPSLOTS.NECK = "neck"EQUIPSLOTS.NECK1 = "neck1"EQUIPSLOTS.NECK2 = "neck2"  local HUD_ATLAS = GLOBAL.HUD_ATLASAssets ={    Asset("IMAGE", "images/back.tex"),    Asset("ATLAS", "images/back.xml"),    Asset("IMAGE", "images/neck.tex"),    Asset("ATLAS", "images/neck.xml"),}AddClassPostConstruct("widgets/inventorybar", function(self)    self:AddEquipSlot(EQUIPSLOTS.HEAD1, HUD_ATLAS, "equip_slot_head.tex")    self:AddEquipSlot(EQUIPSLOTS.BODY1, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.BODY2, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.BACK, "images/back.xml", "back.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK, "images/neck.xml", "neck.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK1, "images/neck.xml", "neck.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK2, "images/neck.xml", "neck.tex")end) local amulets = {orangeamulet = true, blueamulet = true, greenamulet = true,amulet = true, yellowamulet = true, purpleamulet = true} AddComponentPostInit("inventory", function(self)    local old = self.Equip    self.Equip = function(self, item, old_to_active)        if not item or not item.components.equippable or not item:IsValid() then            return        end        local oldslot = item.components.equippable.equipslot        if oldslot == EQUIPSLOTS.BODY and not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY) then            item.components.equippable.equipslot = EQUIPSLOTS.BODY            else if oldslot == EQUIPSLOTS.BODY and not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY1) then                item.components.equippable.equipslot = EQUIPSLOTS.BODY1                else if oldslot == EQUIPSLOTS.BODY and not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY2) then                    item.components.equippable.equipslot = EQUIPSLOTS.BODY2                end            end        end        local oldslot = item.components.equippable.equipslot        if oldslot == EQUIPSLOTS.HEAD and not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HEAD1) then            item.components.equippable.equipslot = EQUIPSLOTS.HEAD1        end        if amulets[item.prefab] then            item.components.equippable.equipslot = EQUIPSLOTS.NECK            if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.NECK) then                item.components.equippable.equipslot = EQUIPSLOTS.NECK                else if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.NECK1) then                    item.components.equippable.equipslot = EQUIPSLOTS.NECK1                    else if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.NECK2) then                        item.components.equippable.equipslot = EQUIPSLOTS.NECK2                    end                end            end        end        item:DoTaskInTime(0, function()            item.components.equippable.equipslot = oldslot        end)        return old(self, item, old_to_active)    endend)AddComponentPostInit("inventory", function(self, inst)    local original_Equip = self.Equip    self.Equip = function(self, item, old_to_active)        if original_Equip(self, item, old_to_active) and item and item.components and item.components.equippable then            local eslot = item.components.equippable.equipslot            if self.equipslots[eslot] ~= item then                if eslot == GLOBAL.EQUIPSLOTS.BACK and item.components.container ~= nil then                    self.inst:PushEvent("setoverflow", { overflow = item })                end            end            return true        else            return        end    end    self.GetOverflowContainer = function()        if self.ignoreoverflow then            return        end        local item = self:GetEquippedItem(GLOBAL.EQUIPSLOTS.BACK)        return item ~= nil and item.components.container or nil    endend)AddPrefabPostInit("inventory_classified", function(inst)    function GetOverflowContainer(inst)        local item = inst.GetEquippedItem(inst, GLOBAL.EQUIPSLOTS.BACK)        return item ~= nil and item.replica.container or nil    end    function Count(item)        return item.replica.stackable ~= nil and item.replica.stackable:StackSize() or 1    end    function Has(inst, prefab, amount)        local count =            inst._activeitem ~= nil and            inst._activeitem.prefab == prefab and            Count(inst._activeitem) or 0        if inst._itemspreview ~= nil then            for i, v in ipairs(inst._items) do                local item = inst._itemspreview[i]                if item ~= nil and item.prefab == prefab then                    count = count + Count(item)                end            end        else            for i, v in ipairs(inst._items) do                local item = v:value()                if item ~= nil and item ~= inst._activeitem and item.prefab == prefab then                    count = count + Count(item)                end            end        end        local overflow = GetOverflowContainer(inst)        if overflow ~= nil then            local overflowhas, overflowcount = overflow:Has(prefab, amount)            count = count + overflowcount        end        return count >= amount, count    end    if not IsServer then        inst.GetOverflowContainer = GetOverflowContainer        inst.Has = Has        -- inst.UseItemFromInvTile = UseItemFromInvTile        -- inst.ReceiveItem = ReceiveItem        -- inst.RemoveIngredients = RemoveIngredients    endend)function backpackpostinit(inst)    if IsServer then        inst.components.equippable.equipslot = GLOBAL.EQUIPSLOTS.BACK    endendAddPrefabPostInit("backpack", backpackpostinit)AddPrefabPostInit("krampus_sack", backpackpostinit)AddPrefabPostInit("piggyback", backpackpostinit)AddPrefabPostInit("icepack", backpackpostinit)




EDIT EDIT: Managed to fix the armor equipping priority by using the code below (copied your amulets method). I think this wouldn't work well with custom armor mods and amulets. Any ideas how to improve further?


 
local armorclothing = {    armorgrass = true,    armormarble = true,    armor_sanity = true,    armorsnurtleshell = true,    armorwood = true,    sweatervest = true,    trunkvest_summer = true,    trunkvest_winter = true,    beargervest = true,    raincoat = true,    reflectivevest = true,    hawaiianshirt = true,    armordragonfly = true,    armorslurper = true,    armorruins = true} AddComponentPostInit("inventory", function(self)    local old = self.Equip    self.Equip = function(self, item, old_to_active)        if not item or not item.components.equippable or not item:IsValid() then            return        end        if armorclothing[item.prefab] then             item.components.equippable.equipslot = EQUIPSLOTS.BODY            if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY) then                item.components.equippable.equipslot = EQUIPSLOTS.BODY                else if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY1) then                    item.components.equippable.equipslot = EQUIPSLOTS.BODY1                    else if not self.inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY2) then                        item.components.equippable.equipslot = EQUIPSLOTS.BODY2                    end                end            end        end

 

Btw, THANK YOU so much for all the help DarkXero!!

Still awaiting and appreciating more help on this because I don't think my code is polished. Lol.

Edited by Gigadroid
Link to comment
Share on other sites

@Gigadroid, I'm going to explain how my code works.

local EQUIPSLOTS = GLOBAL.EQUIPSLOTS-- We create 4 slot identifiers to use from now onEQUIPSLOTS.NECK1 = "neck1"EQUIPSLOTS.NECK2 = "neck2"EQUIPSLOTS.NECK3 = "neck3"EQUIPSLOTS.NECK4 = "neck4"-- We get the direction of the HUD, where the inventory islocal HUD_ATLAS = GLOBAL.HUD_ATLAS -- We create 4 extra slots with 4 different identifiersAddClassPostConstruct("widgets/inventorybar", function(self)    self:AddEquipSlot(EQUIPSLOTS.NECK1, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK2, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK3, HUD_ATLAS, "equip_slot_body.tex")    self:AddEquipSlot(EQUIPSLOTS.NECK4, HUD_ATLAS, "equip_slot_body.tex")end) AddComponentPostInit("inventory", function(self)	-- We are going to override the Equip function of inventory	-- By doing so, when equipping something to the BODY slot, we will redirect it into	-- other equipslots, such as NECK1    local old = self.Equip    self.Equip = function(self, item, old_to_active)		-- First we check the item is an equippable item        if not item or not item.components.equippable or not item:IsValid() then            return        end		-- This is important, a must		-- oldslot will be used to restore the slot that the item needs to be BODY.		-- If it isn't restored, then the slot will be NECK, for example, and you will only be able		-- to equip the item in the NECK slot        local oldslot = item.components.equippable.equipslot		-- We check for BODY to see if we have clothes, armor, amulets        if oldslot == EQUIPSLOTS.BODY then			-- We are going to check the next slots to see where are we going to			-- redirect the item            local slots = {"body", "neck1", "neck2", "neck3", "neck4"}            -- The for will loop through the table			for k, v in ipairs(slots) do				-- The if will check for an equipped item on "body", then				-- "neck1", then "neck2"... until we finish the table...                if not self.inst.components.inventory:GetEquippedItem(v) then                    -- or, if we find a free slot that has nothing equipped					-- then we assign the new slot the item needs, the one that is free,					-- that is, we change the equipslot from the item to be "neck1"					-- instead of "body", just for the purpose of equipping					item.components.equippable.equipslot = v					-- we exit the for, we already found a free slot                    break                end            end        end		-- this function is a hack, I know that DoTaskInTime will execute the function		-- on it AFTER this function finishes executing, so I abuse that because I		-- can't make anything execute AFTER the RETURN.		-- What does the function inside do? It restores the equipslot of the item to BODY,		-- because if it stayed at NECK, then you would only be able to equip it at NECK,		-- and you wouldn't be able to redirect it to BODY or NECK2, because the checks we		-- put were for BODY        item:DoTaskInTime(0, function()            item.components.equippable.equipslot = oldslot        end)		-- This executes the common equip function, with the item having the new slot        return old(self, item, old_to_active)    endend)

 

Both of your three codes break the slot items will be going, because in the first two, you can get oldslot get its BODY value overriden by BODY1, or BODY2. The second one the same, but with a mess of functions colliding. The third one just straight up breaks the item, because it overrides BODY and doesn't return the item to the BODY value. So everybody would go to the slot it ends on. Ultimately all items would end up in the last slot.

 

Having said this, you clearly have absolutely no idea what you are doing.

You are just copypasting everything into everything.

I would recommend you to see other mods, to tackle easier things, before doing this.

Edited by DarkXero
Link to comment
Share on other sites

To make everything slowly fill up to the last slot of their own type is actually my plan since I can only right-click (this way some clothing items like belt of hunger that never needs to be removed can be in the last slot that never changes). Not sure of any other methods of fixing this at my level. 

I do very much appreciate your guidance so far!! I really like that you explained things in the coding. Sorry if my methods are wrong rubbed you the wrong way. I'm not going to learn all about coding just to make this thing work. It's working now (as posted above), even though it has coding problems, no errors occurred. 

 

Once more, I wish to thank you very much for your assistance!

Moderators, feel free to close this help thread since the issue is now resolved. (I'm still looking for answers but I guess anyone can just PM me if they have a more efficient way to code it.)

Edited by Gigadroid
Link to comment
Share on other sites

@Gigadroid, I'm sorry if I came off as angry, I'm not angry.

I just believe it would be more productive to start on a simpler project instead of diving right in into a method that uses a hack.

If you want to keep going, we can keep going.

 

Also, the original code already fills up the slots until they are free, as shown in: http://imgur.com/f4sSObl

You should be able to equip armor then belt of hunger, then 3 amulets.

Link to comment
Share on other sites

Hahahaha it's alright. I'm sorry if I'm being too stubborn.

 

How would that work with a backpack? A backpack would need to be on the last slot (last filled up) so that any armor/clothing changes would not replace it. 

Link to comment
Share on other sites

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
 Share

×
  • Create New...