Jump to content

Need help with hand equippable items


Recommended Posts

Recently i started working on an item that can be equipped on the hand using this as help:

But i've been running into an error.

 

"[string "scripts/mainfunctions.lua"]:119: Error loading prefabs/(item name).lua

[string "...mods/(my mod)/scripts/prefabs/(item name).lua"]:31: 'end' expected (to close function at line 6) near 'Prefab'

 LUA ERROR stack traceback:

  =[C] in function 'assert'

  scrips/mainfunctions.lua(119,1)

  =(tail call) ?

  =[C] in function 'xpcall'

  scripts/mods.lua(154,1)

  scripts/mods.lua(593,1) in function 'RegisterPrefabs'

  scripts/GameLogic.lua(226,1) in function 'LoadAssets' "

 

From what i understand, it says it misses 'end' at line 31...except i did put an end there, i even tried putting two, but that didn't seem to do it.

I followed the instructions nearly similar, except changing each instance of MyItem into my item's name.

 

And while we're at it, i would also like if someone could help me give stats to the item, like making it usable in combat, change the damage values it will deal, not destroy when uses deplete (instead becoming unusable, like Bone Armor), and recharge using Silk.

That's all, thanks in advance!

Link to comment
Share on other sites

1 minute ago, alainmcd said:

Without seeing your code, we can only guess. The Lua interpreter is probably expecting you to close your function before return Prefab(...). Notepad++ and proper indentation should make it trivial to find the function.

I am using Notepad++, it doesn't seem to show any error

 

3 minutes ago, Lumina said:

If you want someone's help, it's better to attach your mod and/or post your code, not just the error, even if you did only small modification to example code.

local assets={
    Asset("ANIM", "anim/giita.zip"),
    Asset("ANIM", "anim/swap_giita.zip"),
    Asset("ATLAS", "images/inventoryimages/giita.xml"),
    Asset("IMAGE", "images/inventoryimages/giita.tex"),}
    prefabs = {}local function fn()
    local function OnEquip(inst, owner)
    owner.AnimState:OverrideSymbol("swap_object", "swap_giita", "swap_giita")
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")
    end
    local function OnUnequip(inst, owner)
    owner.AnimState:Hide("ARM_carry")
    owner.AnimState:Show("ARM_normal")
    end
    local inst = CreateEntity()
    local trans = inst.entity:AddTransform()
    local anim = inst.entity:AddAnimState()
    local sound = inst.entity:AddSoundEmitter()
    MakeInventoryPhysics(inst)
    anim:SetBank("giita")
    anim:SetBuild("giita")
    anim:PlayAnimation("idle")
    inst:AddComponent("inspectable")
    inst:AddComponent("inventoryitem")
    inst.components.inventoryitem.imagename = "giita"
    inst.components.inventoryitem.atlasname = "images/inventoryimages/giita.xml"
    inst:AddComponent("equippable")
    inst.components.equippable:SetOnEquip( OnEquip )
    inst.components.equippable:SetOnUnequip( OnUnequip )
    return instendreturn  Prefab("common/inventory/myitem", fn, assets, prefabs)
end

Link to comment
Share on other sites


 

    return instendreturn  Prefab("common/inventory/myitem", fn, assets, prefabs)

 

Also, this, in


    return inst
end

return  Prefab("common/inventory/myitem", fn, assets, prefabs)

 

Sometimes when a post is very old the formating of code is wrong and you have to correct it.

Link to comment
Share on other sites

8 minutes ago, Kooby said:

I am using Notepad++, it doesn't seem to show any error

Notepad++ doesn't check for errors, it simply formats your text. To the left of your code you see when functions begin and end.

local assets = {
	Asset("ANIM", "anim/giita.zip"),
	Asset("ANIM", "anim/swap_giita.zip"),
	Asset("ATLAS", "images/inventoryimages/giita.xml"),
	Asset("IMAGE", "images/inventoryimages/giita.tex"),
}

prefabs = {}

local function fn()
	local function OnEquip(inst, owner)
		owner.AnimState:OverrideSymbol("swap_object", "swap_giita", "swap_giita")
		owner.AnimState:Show("ARM_carry")
		owner.AnimState:Hide("ARM_normal")
	end
	
	local function OnUnequip(inst, owner)
		owner.AnimState:Hide("ARM_carry")
		owner.AnimState:Show("ARM_normal")
	end
	
	local inst = CreateEntity()
	local trans = inst.entity:AddTransform()
	local anim = inst.entity:AddAnimState()
	local sound = inst.entity:AddSoundEmitter()
	
	MakeInventoryPhysics(inst)
	
	anim:SetBank("giita")
	anim:SetBuild("giita")
	anim:PlayAnimation("idle")
	
	inst:AddComponent("inspectable")
	
	inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.imagename = "giita"
	inst.components.inventoryitem.atlasname = "images/inventoryimages/giita.xml"
	
	inst:AddComponent("equippable")
	inst.components.equippable:SetOnEquip( OnEquip )
	inst.components.equippable:SetOnUnequip( OnUnequip )
	
	return inst
end

return  Prefab("common/inventory/myitem", fn, assets, prefabs)

Your code is for DS and won't work in DST, though.

Edited by alainmcd
Link to comment
Share on other sites

5 minutes ago, Lumina said:


 


    return instendreturn  Prefab("common/inventory/myitem", fn, assets, prefabs)

 

Also, this, in



    return inst
end

return  Prefab("common/inventory/myitem", fn, assets, prefabs)

 

Sometimes when a post is very old the formating of code is wrong and you have to correct it.

Mmmh, didn't notice that.

It doesn't crash the game anymore.

2 minutes ago, alainmcd said:

Notepad++ doesn't check for errors, it simply formats your text. To the left of your code you see when functions begin and end.


local assets = {
	Asset("ANIM", "anim/giita.zip"),
	Asset("ANIM", "anim/swap_giita.zip"),
	Asset("ATLAS", "images/inventoryimages/giita.xml"),
	Asset("IMAGE", "images/inventoryimages/giita.tex"),
}

prefabs = {}

local function fn()
	local function OnEquip(inst, owner)
		owner.AnimState:OverrideSymbol("swap_object", "swap_giita", "swap_giita")
		owner.AnimState:Show("ARM_carry")
		owner.AnimState:Hide("ARM_normal")
	end
	
	local function OnUnequip(inst, owner)
		owner.AnimState:Hide("ARM_carry")
		owner.AnimState:Show("ARM_normal")
	end
	
	local inst = CreateEntity()
	local trans = inst.entity:AddTransform()
	local anim = inst.entity:AddAnimState()
	local sound = inst.entity:AddSoundEmitter()
	
	MakeInventoryPhysics(inst)
	
	anim:SetBank("giita")
	anim:SetBuild("giita")
	anim:PlayAnimation("idle")
	
	inst:AddComponent("inspectable")
	
	inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.imagename = "giita"
	inst.components.inventoryitem.atlasname = "images/inventoryimages/giita.xml"
	
	inst:AddComponent("equippable")
	inst.components.equippable:SetOnEquip( OnEquip )
	inst.components.equippable:SetOnUnequip( OnUnequip )
	
	return inst
end

return  Prefab("common/inventory/myitem", fn, assets, prefabs)

Your code is for DS and won't work in DST, though.

I did check on the left of Notepad++, nothing seemed to be wrong.

And ****. Is there any guide somewhere that works for DST?

Link to comment
Share on other sites

Just now, Kooby said:

And ****. Is there any guide somewhere that works for DST?

I don't think so, but you could probably fix it by looking at a DST item similar to your and add the missing line (like the spear for example)

 

If you code is working without crash now, it's a good sign. You probably just need network and the line to check if you are in master sim (to separate component for the rest), for the item to work fine even when you aren't the host.

Link to comment
Share on other sites

It might just work if you add

	inst.entity:SetPristine()
	if not TheWorld.ismastersim then
		return inst
	end

right after anim:PlayAnimation("idle") in your fn function.

I don't know about good tutorials. Trial and error and asking around, that's what the forums are for.

Link to comment
Share on other sites

I seem to have found most of the necessary coding. Now i've come across 2 issues

1.

Item has no sprites/name. How can i tell it which sprites to use, and what name it will have?

2.

While the coding for the spear was somewhat easy to understand (atleast what i needed to use anyways). I can't seem to understand the coding on the Bone Armor to use a similar fuel system. How do i do this?

Link to comment
Share on other sites

11 minutes ago, Kooby said:

Item has no sprites/name. How can i tell it which sprites to use, and what name it will have?

Sprite : create a .tex file (64*64 if i'm not wrong), named giita (since you already have the code for it). Put it in the folder inventoryimages.

If it's not enough, add theses lines in your modmain :


        Assets = 
        {	
			Asset("ATLAS", "images/inventoryimages/giita.xml"),
	}

Strings for name, description, recipe description (remove this one if you don't have a recipe)


        GLOBAL.STRINGS.NAMES.GIITA = "Whatever you want"
		GLOBAL.STRINGS.RECIPE_DESC.GIITA = "Whatever you want"
        GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.GIITA = "Whatever you want"

 

If you want a custom recipe :

		local my_prefab = AddRecipe("my_prefab", {Ingredient("greengem", 1), Ingredient("twigs", 5), Ingredient("custom_prefab", 2,"images/inventoryimages/custom_prefab_inventoryimage.xml", "custom_prefab_inventoryimage")  }, RECIPETABS.MAGIC, TECH.MAGIC_THREE, nil, nil, nil, nil, nil,  "images/inventoryimages/my_prefab_inventoryimage.xml", "my_prefab_inventoryimage.tex" )

 

Also, i suggest to change "myitem" as your name of prefab to something more specific. I used "GIITA" as example for strings, but it's the name of the prefab you should use, so rename it accordingly.

Edited by Lumina
Link to comment
Share on other sites

13 minutes ago, Lumina said:

Sprite : create a .tex file (64*64 if i'm not wrong), named giita (since you already have the code for it). Put it in the folder inventoryimages.

If it's not enough, add theses lines in your modmain :



        Assets = 
        {	
			Asset("ATLAS", "images/inventoryimages/giita.xml"),
	}

Strings for name, description, recipe description (remove this one if you don't have a recipe)



        GLOBAL.STRINGS.NAMES.GIITA = "Whatever you want"
		GLOBAL.STRINGS.RECIPE_DESC.GIITA = "Whatever you want"
        GLOBAL.STRINGS.CHARACTERS.GENERIC.DESCRIBE.GIITA = "Whatever you want"

 

If you want a custom recipe :


		local my_prefab = AddRecipe("my_prefab", {Ingredient("greengem", 1), Ingredient("twigs", 5), Ingredient("custom_prefab", 2,"images/inventoryimages/custom_prefab_inventoryimage.xml", "custom_prefab_inventoryimage")  }, RECIPETABS.MAGIC, TECH.MAGIC_THREE, nil, nil, nil, nil, nil,  "images/inventoryimages/my_prefab_inventoryimage.xml", "my_prefab_inventoryimage.tex" )

 

It doesn't show anything when in my hand/inventory, and when dropped, it shows the sprite it should use when active (probably because the file named 'giita.xml' is for the sprite when in the inventory, 'ground_giita' should be for it beign on the floor, and 'swap_giita' when held, but now, how do i make it use each sprite be used when necessary?).

Link to comment
Share on other sites

3 minutes ago, Lumina said:

Do you have an anim ? Did you created yourself entirely ? Used some existing anim ?

If you mean an anim folder, yeah. Though only has the .zip for swap_giita and giita

Link to comment
Share on other sites

3 minutes ago, Lumina said:

Yeah but how did you create the content of the .zip file ?

Not even sure how it got there, must be that the compiler for some reason only compiled those 2

Link to comment
Share on other sites

53 minutes ago, Kooby said:

While the coding for the spear was somewhat easy to understand (atleast what i needed to use anyways). I can't seem to understand the coding on the Bone Armor to use a similar fuel system. How do i do this?

The relevant code in the fn function in armor_skeleton.lua:

    inst:AddComponent("fueled")
    inst.components.fueled.fueltype = FUELTYPE.NIGHTMARE
    inst.components.fueled:InitializeFuelLevel(4 * TUNING.LARGE_FUEL)
    inst.components.fueled:SetDepletedFn(nofuel)
    inst.components.fueled:SetTakeFuelFn(ontakefuel)
    inst.components.fueled.accepting = true
  • fueltype: What it uses as fuel. See data/scripts/constants.lua to see the different existing fuel types (search for FUELTYPE). The prefab will take items that have the fuel component and are of the same type. The special FUELTYPE.USAGE is for clothing that degrade by being worn.
  • InitializeFuelLevel: The starting fuel level. If there's no maximum set or it's less than the specified amount, the given value will be the new maximum.
  • SetDepletedFn: What to do if it runs out of fuel. Do you want your item to break? Should your character say something? Add a function here to tell it what to do.
  • SetTakeFuelFn: What should it do when it takes fuel. For example, fire pits play a sound.
  • accepting: Whether your prefab should take fuel or not.

There are other mentions of the fueled component in armor_skeleton.lua, for example inst.components.fueled:DoDelta(-TUNING.MED_FUEL) in OnResistDamage, meaning the armour will be "consumed" when resisting damage. There are plenty more things to do with the fueled component, take a look at its file (data/scripts/components.fueled.lua) or other prefabs that use it.

Link to comment
Share on other sites

Got most of it done (just need to workaround with the code to get the fuel-thing working properly)

Now the issue i'm running into is, it doesn't seem to show any sprites. I tried making a .scml file so the compiler makes it into a .zip (and the inventory image into .xml and .tex), but still doesn't show anything.

Link to comment
Share on other sites

23 minutes ago, Lumina said:

We can't help without more information. Like did you rename correctly the spriter and all...

The sprites are all named correctly this time ('giita.zip' should be ground sprite, 'swap_giita.zip' should be swappable, and theres a 'giita.xml' and 'giita.tex' in the images/inventoryimages). I even tried to use all the animations and entities as the tutorial i linked earlier said (swappable entity is 'swap_giita' and animation is named 'BUILD', and ground is 'giita' and 'idle' respectively).

I even have this in giita.lua :

  • local assets =
  • {
  •     Asset("ANIM", "anim/giita.zip"),
  •     Asset("ANIM", "anim/swap_giita.zip"),
  •     
  •     Asset("ATLAS", "images/inventoryimages/giita.xml"),
  •     Asset("IMAGE", "images/inventoryimages/giita.tex"),
  • }

Did i even obtain the files right? (the .tex and .xml from the inventoryimages was by the compiler, the .zip were also by the compiler, but i moved them from their original folder to there, which even seems odd to me, because i was fairly sure the compiler should've done it on its own)

Link to comment
Share on other sites

Update on the issue.

Item name only appears when the item is on the ground, but not on the inventory.

It keeps using the inventory sprite for the ground sprite (which wouldn't be an issue if the image wasn't abysmally tiny), and swap/inventory images are invisible. I already recompiled them a couple of times, this time the compiler actually put the .zips in the anim folder.

Is there anything i'm missing?

Link to comment
Share on other sites

Another update (sorry if i'm over bumping)

Got the animation for the ground to work correctly (although, it appears kinda small, but it doesn't seem to be fixable)

Now the only issue is the swap animations.

I checked everywhere in the code for other mods i have that work like they should that mentions the word "swap" on its files, and copy-pasted all of the stuff (of course, changing filenames accordingly)

Here's the code in giita.lua

 

local assets =
{
    Asset("ANIM", "anim/giita.zip"),
    Asset("ANIM", "anim/swap_giita.zip"),
    
    Asset("ATLAS", "images/inventoryimages/giita.xml"),
    Asset("IMAGE", "images/inventoryimages/giita.tex"),
}
local prefabs =
{
}

local function ShouldAcceptItem(inst, item)
    if item.prefab == "silk" then
       return true
    end
    return false
end

local function OnGetItemFromPlayer(inst, giver, item)
    if item.prefab == "silk" then
       inst.components.finiteuses.current = inst.components.finiteuses.current + 25
    end
    if inst.components.finiteuses.current > inst.components.finiteuses.total then
       inst.components.finiteuses.current = inst.components.finiteuses.total
    end
end

local function OnEquip(inst, owner)
    owner.AnimState:OverrideSymbol("swap_object", "swap_giita", "swap_giita")
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")
end

local function OnUnequip(inst, owner)
    owner.AnimState:Hide("ARM_carry")
    owner.AnimState:Show("ARM_normal")
end

local function fn()
    local inst = CreateEntity()
    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddNetwork()

    MakeInventoryPhysics(inst)

    inst.AnimState:SetBank("giita")
    inst.AnimState:SetBuild("giita")
    inst.AnimState:PlayAnimation("idle")

     inst:AddTag("sharp")

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("weapon")
    inst.components.weapon:SetDamage(60)
    
    inst:AddComponent("finiteuses")
    inst.components.finiteuses:SetMaxUses(150)
    inst.components.finiteuses:SetUses(150)
    if inst.components.finiteuses.current < 0 then
       inst.components.finiteuses.current = 0
    end
    
    inst:AddComponent("trader")
    inst.components.trader.onaccept = OnGetItemFromPlayer
    inst.components.trader:SetAcceptTest(ShouldAcceptItem)

    

    inst:AddComponent("inspectable")

    inst:AddComponent("inventoryitem")
    inst.components.inventoryitem.imagename = "giita"
    inst.components.inventoryitem.atlasname = "images/inventoryimages/giita.xml"

    inst:AddComponent("equippable")
    inst.components.equippable:SetOnEquip(OnEquip)
    inst.components.equippable:SetOnUnequip(OnUnequip)

    MakeHauntableLaunch(inst)

    return inst
end

STRINGS.NAMES.GIITA = "Giita the Guitar"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.GIITA = "Smells like cake."

return Prefab("common/inventory/giita", fn, assets, prefabs)

Edited by Kooby
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...