Jump to content

Perishable + FiniteUses?


Recommended Posts

Hey guys. I'm modifying traps so that it takes a couple carrots, but then comes prebaited for its 10 uses. Now, since it's a trap I want to leave the finite uses, but I also want to add a perishable component to it. Then in the display it should show the % of the FiniteUses, and have the green background from perishable.

I'm not even sure where the icon is drawn exactly, so pointer would be appreciated.

Link to comment
Share on other sites

@kaosuryoko,

 

This will be a little bit more difficult than you imagine.  Baiting traps effectively just sits whatever item is being used as bait on the ground in the same spot as the trap.  Rabbits have a behaviour in their brain file that specifically attracts them to carrots* (or more specifically, to any item that is edible to them.)

 

The behaviour actually uses this:

local target = FindEntity(inst, SEE_BAIT_DIST, function(item) return inst.components.eater:CanEat(item) and item.components.bait and not item:HasTag("planted") and not (item.components.inventoryitem and item.components.inventoryitem:IsHeld()) end)

You could replace that behaviour with one that also looks for your traps, but since the rabbit would then try to eat your trap, the best thing to do would be to insert another behaviour into the rabbit's brain.

 

 

As for the other question..  both the Perishable and FiniteUses use functionality provided by the ItemTile widget.  ItemTile listens for the events "percentusedchange", and "perishchange", and updates the display.  Here's the listeners:

    self.inst:ListenForEvent("percentusedchange",            function(inst, data)                self:SetPercent(data.percent)            end, invitem)    self.inst:ListenForEvent("perishchange",            function(inst, data)				if self.item.components.perishable then                    if self:HasSpoilage() then                        self:SetPerishPercent(data.percent)    				else                        self:SetPercent(data.percent)    				end                end            end, invitem)

And here's the SetPerish/Percent functions:

function ItemTile:SetPerishPercent(percent)	if self:HasSpoilage() then		self.spoilage:GetAnimState():SetPercent("anim", 1-self.item.components.perishable:GetPercent())	endendfunction ItemTile:SetPercent(percent)            if not self.percent then        self.percent = self:AddChild(Text(NUMBERFONT, 42))        if JapaneseOnPS4() then            self.percent:SetHorizontalSqueeze(0.7)        end        self.percent:SetPosition(5,-32+15,0)    end    local val_to_show = percent*100    if val_to_show > 0 and val_to_show < 1 then        val_to_show = 1    end	self.percent:SetString(string.format("%2.0f%%", val_to_show))        end

You can see from there that the percentage text is a text widget.

self.spoilage is a UIAnim widget that uses the "spoiled_meter" bank/build.

 


 

* "Fun fact" about rabbits -- their actual diet consists mostly of very hard-to-digest grasses and leaves.  The bacteria in their gut does weakens the cell walls a bit, so rabbits eat their own fecal pellets to continue digestion until most of the water is removed. Carrots are considered very unhealthy for rabbits.  It'd be like a human eating a stick of butter.  Anyhoo, think about THAT next time you see a cute little bunny rabbit.

Link to comment
Share on other sites

After diving into the source a little more, it looks like you can get the perishable effect to display by adding a tag to the prefab

inst:AddTag("show_spoilage")

As long as you also have the Perishable component on the prefab as well, it'll have the green freshness meter in the background.

Link to comment
Share on other sites

* "Fun fact" about rabbits -- Carrots are considered very unhealthy for rabbits.  It'd be like a human eating a stick of butter.

 

But eating a haphazard stick of butter off the ground is really useful when fighting a spider queen... :p

Link to comment
Share on other sites

You guys are awesome, I'll be checking out the ShowSpoilage, though I'm not sure I can make it work without digging deeper. As is when I attach perishable to the trap it decrements the same value that finiteuses decrements, so you end up with less than ten uses because of spoilage. So even if it displays the percentage and the spoilage meter, they'll just be pointing to the same number it looks like.

I actually dealt with the autobait by literally auto baiting the trap. So I override the trap stategraph with a near copy. In onplaced I call spawnprefab("carrot"), use SetBait on the trap with the new carrot, then remove its inventoryitem component so it can't be picked up by the player. Then in onpicked I use the traps reference to its bait to call its Remove().

Overall I'm pretty happy with it without spoilage, I changed the trap recipe to also cost 4 carrots so you get a bit more bang for your carrot. It was mostly QoL thing for Wigfried.

Of course then I remembered you can bait a trap with more than just carrots, so I should probably create this as a separate rabbit trap item...

Link to comment
Share on other sites

Oh yeah, now that I actually look closer at the event listeners you pasted I see that perishable and finiteuses both ultimately call self.setpercent. So I'd have to dig in and split that into separate variable and associated getters/setters. I don't know of its worth the effort though, we'll see.

Link to comment
Share on other sites

function trapPostInit(inst)	inst.components.finiteuses = nilendAddPrefabPostInit("trap", trapPostInit)

If I add the above to my modmain it works fine, as just an infinite trap.

It actually won't pick up the trap immediately on harvest because of 

        if self.inst.components.finiteuses and self.inst.components.finiteuses:GetUses() > 0 then            doer.components.inventory:GiveItem(self.inst, nil, Vector3(TheSim:GetScreenPos(self.inst.Transform:GetWorldPosition())))        end

in the components/trap.lua. Would be easy to work around, though that's not my aim.

Link to comment
Share on other sites

@kaosuryoko,

If you could perhaps do me a favor, edit your last post, switch off wysiwyg mode, and change "code=nocode" to "code=auto" on your first code snippit.

There's an issue with the syntax highlighter that makes it pop up an alert ~10 times when nocode is used X.x

In any case, it's normally best to call inst:RemoveComponent().

Link to comment
Share on other sites

@Corrosive

I noticed that bug as soon as I posted... I even looked a bit but for the life of me I can't seem to find the edit button... >< Got a pointer for that?

For some reason as soon as I posted another reply the edit buttons became visible. *shrug* Fixed now.

Also good call, I didn't notice RemoveComponent was a thing, I'll definitely use it for any release stuff. But nil was a quick convenient test for my purposes at the time.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...