Jump to content

Making a fueled item


Recommended Posts

I took a look at @ZupaleX's Archery Mod to figure it out. My fuel should be papyrus. Here's what I've done (function names are often the same as in the Archery Mod for sake of simplicity and understanding) :

 

-In my modmain : 

AddPrefabPostInit("papyrus", function (inst)inst:AddComponent("fuel")    inst.components.fuel.fueltype = FUELTYPE.PENCILend)

 

-In my prefab (swappable item) : 


local function MagicBowCanAcceptFuelItem(self, item)if item ~= nil and item.components.fuel ~= nil and (item.components.fuel.fueltype == FUELTYPE.PENCIL or item.prefab == "papyrus") thenreturn trueelsereturn falseendendlocal function MagicBowTakeFuel(self, item) if self:CanAcceptFuelItem(item) thenif item.prefab =="papyrus" thenself:DoDelta(25)end        item:Remove()        return true    endend

-In my prefab's main function (fn) : 


inst:AddComponent("fueled")inst.components.fueled.accepting = trueinst.components.fueled.fueltype = FUELTYPE.PENCILinst.components.fueled.maxfuel = 4inst.components.fueled:StopConsuming()inst.components.fueled.CanAcceptFuelItem = MagicBowCanAcceptFuelIteminst.components.fueled.TakeFuelItem = MagicBowTakeFuel

inst:AddComponent("finiteuses")inst.components.finiteuses:SetMaxUses(TUNING.ORANGESTAFF_USES)

So does anyone know what's missing/wrong? :-)

FYI : this is of course only the relevant code

 

Currently the prefab has got for some reason 500% (all the time), even when using it. I have added the component "blinkstaff" to it. It doesn't lose durability after telepoofing for some reason

Edited by Thibooms
Link to comment
Share on other sites

You should not have a "fueled" component and a "finiteuse" component at the same time. Both are doing "similar" stuffs but in different way so having the 2 at the same time creates issues. Just put a fueled component instead.

Then when you use the ability of your item, make it so that instead of decreasing the amount of uses, it reduce the fuel level. Because for the moment I did not see that you said it should reduce the fuel level when used. It's probably reducing the amount of uses from the finiteuses component instead. And as I said, since you put oth component, the behavior of your item is not really predicatable. So put upon use the following stuff

inst.components.fueled:DoDelta(-1)

This will reduce your fuel level by 1, your maxfuel beeing 4. Then you're free to adjust these values however you want.

 

And also you see that you make so if you fuel your item with papyrus you do a DoDelta(25), while you set the maxfuel to 4 :

 

25/4 = 5 => 500%

Edited by ZupaleX
Link to comment
Share on other sites

@ZupaleX, thanks, that explains a lot! :)

 

I don't understand how you can deplete it, I just don't see it in the prefab codes. I've had a look at your magic bow, the mining hat and the mining lantern. Yet I was unable to find in any of these a function or a line talking about the durability depletion.

 

Where do you specify this for you magic bow?

Link to comment
Share on other sites

The mining hat and mining lantern, there is a StartConsuming() function which, as its name indicated, start consuming the fuel over time. In my magic bow I did not want to have that so I put the StopConsuming() because I do not want the fuel to go down over time. And instead I put a DoDelta(-1) in the DoPostAttack function at the beginning of the bow.lua which is called when attacking with the magic bow.

 

Sorry the code is a bit messy in the DST version, I will improve it soon in the same way I improved the one for the DS version which will get an update soon.

Link to comment
Share on other sites

What do you use to edit .lua files?

If you do a search on the bow.lua of DoPostAttack, you'll see 2 occurences. When it's defined, and when it's called in the "onthrown_regular" function which is itself called when attacking with any of my ranged weapon :-)

Link to comment
Share on other sites

What do you use to edit .lua files?

I use Notepad++. I do search for it using the little pop up window, but I usually get to some variable you declared which is linked to another thing which is linked to another thing and so on... xD

 

To be honest, I get kind of lost in all of this glorious moddyness. There's got to be a simple way for what I'm looking for, right? xD 

 

I'm going to dig in some more now, I'll edit my post if I find something that clears my mind.

 

Edit: Okay, so the reason why I had trouble with DoPostAttack was because I kind of was searching in the wrong file.

 

Here's what I have now :

 

local function MagicBowCanAcceptFuelItem(self, item)if item ~= nil and item.components.fuel ~= nil and (item.components.fuel.fueltype == FUELTYPE.PENCIL or item.prefab == "papyrus") thenreturn trueelsereturn falseendendlocal function MagicBowTakeFuel(self, item) if self:CanAcceptFuelItem(item) thenif item.prefab =="papyrus" thenself:DoDelta(2)end        item:Remove()        return true    endendlocal function MagicBowOnSaveFueled(self)    if self.currentfuel > 0 then      return { fuel = self.currentfuel }    endendlocal attacker = FindEntity(inst, 1.8, nil, { "player" })local equiphand = attacker.components.inventory and attacker.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)local function DoPostAttackTask(inst, attacker)if equiphand thenif equiphand.components.fueled ~= nil and not equiphand.components.fueled:IsEmpty() thenequiphand.components.fueled:DoDelta(-1)endendendlocal function fn()local inst = CreateEntity()inst.entity:AddTransform()inst.entity:AddAnimState()inst.entity:AddNetwork()MakeInventoryPhysics(inst)inst.AnimState:SetBank("pencil_thibaud")inst.AnimState:SetBuild("pencil_thibaud")inst.AnimState:PlayAnimation("idle")inst.entity:SetPristine()if not TheWorld.ismastersim thenreturn instendinst:AddComponent("inspectable")inst:AddComponent("weapon")    inst.components.weapon:SetDamage(TUNING.CANE_DAMAGE)inst:AddComponent("inventoryitem")inst.components.inventoryitem.imagename = "pencil_thibaud"inst.components.inventoryitem.atlasname = "images/inventoryimages/pencil_thibaud.xml"inst:AddComponent("equippable")inst.components.equippable:SetOnEquip(OnEquip)inst.components.equippable:SetOnUnequip(OnUnequip)inst:AddComponent("fueled")inst.components.fueled.accepting = trueinst.components.fueled.fueltype = FUELTYPE.PENCILinst.components.fueled.maxfuel = 10inst.components.fueled:StopConsuming()inst.components.fueled.CanAcceptFuelItem = MagicBowCanAcceptFuelIteminst.components.fueled.TakeFuelItem = MagicBowTakeFuelinst:AddComponent("blinkstaff")MakeHauntableLaunch(inst)

What's missing now? :/

Edited by Thibooms
Link to comment
Share on other sites

Well, you do a DoDelta(-1) in the DoPostAttackTask function but you do not call this function anywhere or I'm missing something.

This function is not something which is called by default by the game, it's something I added. You have to find a function which is called when you use your item, and insert a DoDelta(-1) somewhere there.

Link to comment
Share on other sites

onthrown is an event pushed when using a weapon with a projectile.

 

I see you attached the blinkstaff component. You could modify the inst.components.blinkstaff.Blink function to execute the original one + your own PostBlink function where you do your DoDelta on the fueled component and any other stuffs you would like to be executed when using the blinkstaff component

Link to comment
Share on other sites

@ZupaleX,I'm gonna try that. 

 

Edit :

 

Okay, a few things I'd like to ask now :

 

-I added this to the new custom component :

local attacker = FindEntity(inst, 1.8, nil, { "player" })local equiphand = attacker.components.inventory and attacker.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)local function DoPostAttackTask(inst, attacker)if equiphand thenif equiphand.components.fueled ~= nil and not equiphand.components.fueled:IsEmpty() thenequiphand.components.fueled:DoDelta(-1)endendendreturn BlinkStaff_Thibaud

I crash because "inst" is not declared. I never really understood what that was in your mod actually. Any way to make this work?

 

-I still can't use papyrus as a fuel, it doesn't allow me to fuel the item. Why? This is what I did to try to make it a fuel :

 

In my modmain :

AddPrefabPostInit("papyrus", function (inst)inst:AddComponent("fuel")    inst.components.fuel.fueltype = FUELTYPE.PENCILend)

In the "staff" prefab : (in the fn function)

inst:AddComponent("fueled")inst.components.fueled.accepting = trueinst.components.fueled.fueltype = FUELTYPE.PENCILinst.components.fueled.maxfuel = 10inst.components.fueled:StopConsuming()inst.components.fueled.CanAcceptFuelItem = MagicBowCanAcceptFuelIteminst.components.fueled.TakeFuelItem = MagicBowTakeFuel

Thank you for helping me :)

Edited by Thibooms
Link to comment
Share on other sites

Remove

local attacker = FindEntity(inst, 1.8, nil, { "player" })  local equiphand = attacker.components.inventory and attacker.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)  local function DoPostAttackTask(inst, attacker)if equiphand thenif equiphand.components.fueled ~= nil and not equiphand.components.fueled:IsEmpty() thenequiphand.components.fueled:DoDelta(-1)endendend

from your blinkstaff_thibaud.lua because it makes no sense.

 

Add this after you inst:Addcomponent("blinkstaff_thibaud") in your pencil_thibaud.lua

	inst.components.blinkstaff_thibaud.onblink = function()		inst.components.fueled:DoDelta(-1)	end

You can see that the function "onblink" is called after everything was processed in the Blink function of your component.

 

Btw I did not see any change to the regular blinkstaff. Why don't you just use the regular blinkstaff component?

 

 

About the fuel, it's not good what you did because the papyrus already has a "fuel" component. So you're replacing it's fuel type and it will mess up a lot of stuffs. You should keep the fueltype to burnable, set the fueltype accepted by your pencil to burnable as well, but put

inst.components.fueled.CanAcceptFuelItem = function(self, item)     if item.prefab == "papyrus" then          return true     else          return false     endend
Link to comment
Share on other sites

Remove ? 1 2 3 4 5 6 7 8 9 10 11 12 13 local attacker = FindEntity(inst, 1.8, nil, { "player" })       local equiphand = attacker.components.inventory and attacker.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)       local function DoPostAttackTask(inst, attacker) if equiphand then if equiphand.components.fueled ~= nil and not equiphand.components.fueled:IsEmpty() then equiphand.components.fueled:DoDelta(-1) end end end from your blinkstaff_thibaud.lua because it makes no sense.

Yeah sorry about that, I was trying to figure out how to tell the game I'm blinking.

 

 @ZupaleX, so I did all you said. Now the papyrus fuels correctly.

 

The "staff" still blinks wether it's fueled or not, and doesn't lose any durability when blinking.

 

Here's the (relevant) code I now have in the prefab's lua : (removed the postinit I had in the modmain)

local function MagicBowTakeFuel(self, item) if self:CanAcceptFuelItem(item) thenif item.prefab =="papyrus" thenself:DoDelta(2)end        item:Remove()        return true    endendlocal function fn()local inst = CreateEntity()inst.entity:AddTransform()inst.entity:AddAnimState()inst.entity:AddNetwork()MakeInventoryPhysics(inst)inst.AnimState:SetBank("pencil_thibaud")inst.AnimState:SetBuild("pencil_thibaud")inst.AnimState:PlayAnimation("idle")inst.entity:SetPristine()if not TheWorld.ismastersim thenreturn instendinst:AddComponent("inspectable")inst:AddComponent("weapon")    inst.components.weapon:SetDamage(TUNING.CANE_DAMAGE)inst:AddComponent("inventoryitem")inst.components.inventoryitem.imagename = "pencil_thibaud"inst.components.inventoryitem.atlasname = "images/inventoryimages/pencil_thibaud.xml"inst:AddComponent("equippable")inst.components.equippable:SetOnEquip(OnEquip)inst.components.equippable:SetOnUnequip(OnUnequip)inst:AddComponent("fueled")inst.components.fueled.accepting = trueinst.components.fueled.fueltype = FUELTYPE.BURNABLEinst.components.fueled.maxfuel = 10inst.components.fueled:StopConsuming()inst.components.fueled.TakeFuelItem = MagicBowTakeFuelinst.components.fueled.CanAcceptFuelItem = function(self, item)if item.prefab == "papyrus" thenreturn trueelsereturn falseendendinst:AddComponent("blinkstaff")inst.components.blinkstaff.onblink = function()inst.components.fueled:DoDelta(-1)end
Btw I did not see any change to the regular blinkstaff. Why don't you just use the regular blinkstaff component?

It's definitely useless now, I used the regular blinkstaff component now 

 

Edit : Why are some spaces messed up? Most of my "ends" aren't aligned properly on the forums. I'd like to be able to fix this :-)

 

Edit 2 : I figured the messed up alignment is pretty annoying, here's the complete lua (again)

pencil_thibaud.lua

 

Edited by Thibooms
Link to comment
Share on other sites

It's because I made a mistake in the code I sent you and you just copied/pasted without checking what I wrote :-P

 

If we look together at the blinkstaff component

function BlinkStaff:Blink(pt, caster)    if not TheWorld.Map:IsAboveGroundAtPoint(pt:Get()) then        return false    end    if self.blinktask ~= nil then        self.blinktask:Cancel()    end    self:SpawnEffect(caster)    caster.SoundEmitter:PlaySound("dontstarve/common/staff_blink")    caster:Hide()    if caster.DynamicShadow ~= nil then        caster.DynamicShadow:Enable(false)    end    if caster.components.health ~= nil then        caster.components.health:SetInvincible(true)    end    self.blinktask = caster:DoTaskInTime(0.25, OnBlinked, self, pt)    if self.onblinkfn ~= nil then        self.onblinkfn(self.inst, pt, caster)    end    return trueend

You see that what is called at the end is not self.onblink, but self.onblinkfn. So what you have to do is not to put

inst.components.blinkstaff.onblink = function()     inst.components.fueled:DoDelta(-1)end

but

inst.components.blinkstaff.onblinkfn = function(inst)     inst.components.fueled:DoDelta(-1)end

because the function inst.components.blinkstaff.onblink is never called, so you can assign whatever to it it will never execute it anyway.

 

That for the item not loosing fuel when you blink with it (not durability, but fuel, you're using the fueled component, not the finiteuses). Sidenote: you could also have used the repairer component instead. But well, the result is the same.

 

About the fact that you can still blink if the fuel is depleted, you can notice that indeed there is no check in the Blinkstaff:Blink function on the fuel level of your item, so why shouldn't it blink when the fuel is depleted? You have to add this check yourself. I don't know how you want your stuff to act, but the easiest would be to modify directly the Blinkstaff:Blink function for your item, and put a return false at the beginning with (if you'd like) a message from the player that the stuff is depleted, when you do not have any fuel in.

Link to comment
Share on other sites

t's because I made a mistake in the code I sent you and you just copied/pasted without checking what I wrote

I actually thought everything to be quite logical, so... xD

 

Thanks for the fix!

 

About the fact that you can still blink if the fuel is depleted, you can notice that indeed there is no check in the Blinkstaff:Blink function on the fuel level of your item, so why shouldn't it blink when the fuel is depleted? You have to add this check yourself. I don't know how you want your stuff to act, but the easiest would be to modify directly the Blinkstaff:Blink function for your item, and put a return false at the beginning with (if you'd like) a message from the player that the stuff is depleted, when you do not have any fuel in.

I don't understand how the game works for anything that's depleted. I've looked at the "finiteuses" component as well as "fueled". I tried doing this :

 

local function PencilDepleted(inst, item)if inst.components.fueled ~= nil and not inst.components.fueled:IsEmpty() thenreturn falseendend

in the main function :

inst.components.fueled.SetDepletedFn = PencilDepleted

I don't understand how you'd like to do it using the component.

 

Prefabs using durability/fuel confuse me xD
 
Link to comment
Share on other sites

I'm too tired now to explain you what the issue is in, detail but the point is that by doing so, you replace the function Fueled:SetDepletedFn by your local function PencilDepleted, which is not what you want to do.

 

From fueled.lua

function Fueled:SetDepletedFn(fn)    self.depleted = fnend

Fueled:SetDepletedFn just assign to the member "depleted" of the "fueled" component the function you give as an argument. What you may want to do is to assign your PencilDepleted to this member fueled.depleted  which is called in the Fueled:DoDelta function.

 

But actually that's not even what you want to do. Youwant to prevent the use of your pencil when it's depleted. And to do that, you should just do as I said at the end of my previous post :-)

Link to comment
Share on other sites

  But actually that's not even what you want to do. Youwant to prevent the use of your pencil when it's depleted. And to do that, you should just do as I said at the end of my previous post

I'd love to, but for some reason when using an exact copy of the blinkstaff component, changing every "blinkstaff" to "blinkpencil" doesn't work (no telepoof). And where would you like this return false? Really right at the top of the function? Just like that? :o

 

When will this madness stop? x')

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...