How to swap armors without dropping items?

Place to post guides, observations, things related to modding that are not mods themselves.
Post Reply
scotthmccoy
Manual Inserter
Manual Inserter
Posts: 4
Joined: Tue Apr 13, 2021 3:31 am
Contact:

How to swap armors without dropping items?

Post by scotthmccoy »

I'm trying to duplicate the effect of picking up an armor from my inventory and dropping it into the armor slot using code. Ideally I'd like to make an armor wardrobe mod for quickly changing between sets of armor that have equipment in them for specialized tasks (fighting, building, moving quickly, etc).

Both of these code snippets swap in the "top-most" power-armor-mk2 in my inventory, but temporarily shrink the size of my inventory, typically dropping a bunch of stuff on the ground:

Code: Select all

/c wornArmor = game.player.get_inventory(defines.inventory.character_armor)[1]
newArmor = game.player.get_main_inventory().find_item_stack("power-armor-mk2")
newArmor.swap_stack(wornArmor)

Code: Select all

/c wornArmor = game.player.get_inventory(defines.inventory.character_armor)[1]
newArmor = game.player.get_main_inventory().find_item_stack("power-armor-mk2")
wornArmor.swap_stack(newArmor)

scotthmccoy
Manual Inserter
Manual Inserter
Posts: 4
Joined: Tue Apr 13, 2021 3:31 am
Contact:

Re: How to swap armors without dropping items?

Post by scotthmccoy »

I figured out a solution! I create a temporary inventory, move everything into there, swap armors, and then move all the items back. If there's a more elegant way to accomplish this, though, I'd love to know!

Code: Select all

mainInventory = game.player.get_main_inventory()
tempInventory = game.create_inventory(#mainInventory)

for i=1, #mainInventory do
	if mainInventory[i].valid_for_read then
  		mainInventory[i].swap_stack(tempInventory[i])
  	end
end

wornArmor = game.player.get_inventory(defines.inventory.character_armor)[1]
newArmor = tempInventory.find_item_stack("power-armor-mk2")
newArmor.swap_stack(wornArmor)

for i=1, #tempInventory do
	if tempInventory[i].valid_for_read then
  		tempInventory[i].swap_stack(mainInventory[i])
  	end
end

tempInventory.destroy()

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: How to swap armors without dropping items?

Post by eradicator »

Code: Select all

player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 1000
newArmor.swap_stack(wornArmor)
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus - 1000
Be wary of other mods that might change the bonus during on_player_armor_inventory_changed. You should only do relative changes.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

scotthmccoy
Manual Inserter
Manual Inserter
Posts: 4
Joined: Tue Apr 13, 2021 3:31 am
Contact:

Re: How to swap armors without dropping items?

Post by scotthmccoy »

I thought about doing that but Ive read that lua lacks thread safety and I'm concerned that one thread might modify the value of the inventory slot bonus while it's being read. Is that a cause for concern?

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: How to swap armors without dropping items?

Post by eradicator »

scotthmccoy wrote:
Tue Apr 13, 2021 5:30 pm
I thought about doing that but Ive read that lua lacks thread safety and I'm concerned that one thread might modify the value of the inventory slot bonus while it's being read. Is that a cause for concern?
No. Factorio lua runs single-threaded. Thus the only access point for another mod is when LuaItemStack.swap_stack() calls the other mods event handler function - at which point your mod is halted until swap_stack() returns.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: How to swap armors without dropping items?

Post by eradicator »

Saw your mod on the portal. Nice idea with the color coding. Just wanted to add that "+1000" was supposed to be an example number that "is probably large enough". Ideally you'd have some fancy logic that calculates a better number - ye never know if some mod doesn't add an armor with a 2000 slot bonus and there's also mods that add grid equipment with bonus. Maybe something like the current size of the inventory.

Code: Select all

#player.get_main_inventory()
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

scotthmccoy
Manual Inserter
Manual Inserter
Posts: 4
Joined: Tue Apr 13, 2021 3:31 am
Contact:

Re: How to swap armors without dropping items?

Post by scotthmccoy »

That's a really good point, I'll update that in the next version.

hyspeed
Long Handed Inserter
Long Handed Inserter
Posts: 69
Joined: Sun Jun 05, 2016 10:18 pm
Contact:

Re: How to swap armors without dropping items?

Post by hyspeed »

I think Scooty's Armor Swap does similar:
https://mods.factorio.com/mod/scootys-armor-swap

Rseding91
Factorio Staff
Factorio Staff
Posts: 13173
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: How to swap armors without dropping items?

Post by Rseding91 »

This was fixed in 1.1.97 so it will simply swap without needing any extra logic.
If you want to get ahold of me I'm almost always on Discord.

Post Reply

Return to “Modding discussion”