Recommended Posts

Also the code you gave, does it stop the gem tag for a certain color gem if a limit is filled, like:
red == interentinsulation == red stop gem tag
blue == summerinherentinsulation == blue stop gem tag
purple == damage multiplier == purple stop gem tag
orange == movement speed == orange stop gem tag

After eating 5 of one gem you cant eat that gem anymore.

Share this post


Link to post
Share on other sites
w00tyd00d    193
1 hour ago, SomeoneStrange said:

How does this help?

When you're on a world with no caves, you load and play the world locally to your computer, but when it's a world with caves you create a server lobby that you yourself also connect to but with "admin" rights. There's much different behavior to account for whether or not you're a "host" (host of a non-caves world) or a "client" (anyone in a caves world). When dealing with tags and component changes from other components (as opposed to trying to target a specific individual player's component data) you rarely have to worry too much about when to use things like the replica components, but still good to know for debugging purposes when it comes to trying to diagnose any problems.

I'm assuming since you sent me the client_log.txt that you're using a non-caves world for your testing? There doesn't seem to be any lua errors popping up in that particular log, was that a log from after crashing? It's important that it's a log from directly after a crash because the log gets rewritten every time you reload the game.

If you haven't started the game up again, would you mind posting the server_log.txt found in the cluster_# folder of your world? (see post above for file path) I'll take a look at that and see if it has any lua errors popping up.

Share this post


Link to post
Share on other sites
w00tyd00d    193

@SomeoneStrange I actually just realized that the code I gave won't work as it's trying to remove the edible_ tag from only the current item you're trying to eat, not all gem prefabs of the same type (which could also be the cause of your crash). I will take a closer look at it either tonight or tomorrow for you, I just unfortunately don't have the time (or the energy xD) to do it atm.

So for now, just don't use that code, sorry fam :(

Share this post


Link to post
Share on other sites
function EdibleCompPostInit(comp)
	old_OnRemoveFromEntity = comp.OnRemoveFromEntity

	comp.OnRemoveFromEntity = function(self)
		old_OnRemoveFromEntity(self)
		self.inst:RemoveTag("edible_"..FOODTYPE.GEMS)
	end
end
AddComponentPostInit("edible", EdibleCompPostInit)

function GemPostInit(inst)
	inst:AddTag("edible_"..FOODTYPE.GEMS)
end
-- You can run a loop to iterate through each gem, this was just done quickly lol
AddPrefabPostInit("redgem", GemPostInit)
AddPrefabPostInit("bluegem", GemPostInit)
AddPrefabPostInit("purplegem", GemPostInit)
AddPrefabPostInit("orangegem", GemPostInit)

If you were able to create the foodtype like with note green and yellow did not have the tag and it worked like that in game. Is it possible to do something similar but with remove tags like
 

function RemoveGemPostInit(inst)
	inst:RemoveTag("edible_"..FOODTYPE.GEMS)
end

if self.inst:HasTag("DOLL") and self.inst.components.temperature.inherentinsulation >= 100
	RemovePrefabPostInit("redgem", RemoveGemPostInit)
end

or could I do something like this witht he previous working code?
 

function EdibleCompPostInit(comp)
	old_OnRemoveFromEntity = comp.OnRemoveFromEntity
	comp.OnRemoveFromEntity = function(self)
		old_OnRemoveFromEntity(self)
		self.inst:RemoveTag("edible_"..FOODTYPE.GEMS)
	end
end
AddComponentPostInit("edible", EdibleCompPostInit)

function GemPostInit(inst)
	inst:AddTag("edible_"..FOODTYPE.GEMS)
end
if self.inst.components.temperature.inherentinsulation < 100 then
	AddPrefabPostInit("redgem", GemPostInit)
end
AddPrefabPostInit("bluegem", GemPostInit)
AddPrefabPostInit("purplegem", GemPostInit)
AddPrefabPostInit("orangegem", GemPostInit)
--AddPrefabPostInit("yellowgem", GemPostInit)
--AddPrefabPostInit("greengem", GemPostInit)

 

Edited by SomeoneStrange

Share this post


Link to post
Share on other sites
w00tyd00d    193

@SomeoneStrange Alright my friend after a full night's sleep, 2 (large) cups of coffee, and a little over 2 hours of testing/debugging (thankfully I've got the day off from work ;) ) I've got a fully fledged solution for you lol

First off, to account for each gem individually you're going to need to assign each one their own specific FOODTYPE. After that you're actually not going to include it in your FOODGROUP.DOLL table, but instead include them alongside the FOODGROUP.DOLL table when passing your argument through the SetDiet() function. I also noticed your FOODGROUP.DOLL and NOMS tables were identical, so if that's the case and you don't want your character to do the animation to refuse food (like wigfrid and non-meat items) you can just pass FOODGROUP.DOLL as a single argument though the SetDiet() function. The way that function is set up is that if no 2nd argument is provided, it just uses the same table as the 1st argument.

Spoiler

-- This is what you have to change your SetDiet() function to in your characters prefab script
-- I tried to make it look at least a little bit neater for you

inst.components.eater:SetDiet( 
		{
			FOODGROUP.DOLL,
			FOODTYPE.GEM_RED,
			FOODTYPE.GEM_BLUE,
			FOODTYPE.GEM_PURPLE,
			FOODTYPE.GEM_YELLOW,
			FOODTYPE.GEM_ORANGE,
			FOODTYPE.GEM_GREEN,
			FOODTYPE.GEM_OPAL,
		})


-- These will go in your modmain.lua

local FOODTYPE = GLOBAL.FOODTYPE
FOODTYPE.GEM_RED 	= "GEM_RED"
FOODTYPE.GEM_BLUE 	= "GEM_BLUE"
FOODTYPE.GEM_PURPLE 	= "GEM_PURPLE"
FOODTYPE.GEM_YELLOW 	= "GEM_YELLOW"
FOODTYPE.GEM_ORANGE 	= "GEM_ORANGE"
FOODTYPE.GEM_GREEN 	= "GEM_GREEN"
FOODTYPE.GEM_OPAL 	= "GEM_OPAL"

local FOODGROUP = GLOBAL.FOODGROUP
FOODGROUP.DOLL =
{
	name = "DOLL",
	types =
	{
		FOODTYPE.GENERIC,
		FOODTYPE.VEGGIE, 
		FOODTYPE.MEAT, 
		FOODTYPE.INSECT, 
		FOODTYPE.SEEDS,
		FOODTYPE.HORRIBLE,
		FOODTYPE.ROUGHAGE,
	}
}

 

The main reason why you have to separate them like that is because when assigning the "_eater" tag to the player, the game first determines if the entry is a FOODGROUP table, and if so name the tag "FOODGROUP.name_eater" instead of each individual FOODTYPE inside the table. So if you were to group the gems up in to a single FOODGROUP, you wouldn't be able to toggle them individually from your player.

Next, once those have been established you can basically just copy and paste the following code below those new tables and you can fill out the rest to your liking. I tried to set it up in such a way that will make it easier for you to be able to add/configure whatever functions you want to happen when you eat each gem. I also left plenty of comments that briefly go over what each thing is and why it's there.

Spoiler

-- This will all go in to your modmain.lua below the added FOODTYPE and FOODGROUP tables

local gems =
{
	redgem 			= {tag = FOODTYPE.GEM_RED,		bool = true},
	bluegem 		= {tag = FOODTYPE.GEM_BLUE,		bool = true},
	purplegem 		= {tag = FOODTYPE.GEM_PURPLE,	bool = true},
	yellowgem 		= {tag = FOODTYPE.GEM_YELLOW,	bool = true},
	orangegem 		= {tag = FOODTYPE.GEM_ORANGE,	bool = true},
	greengem 		= {tag = FOODTYPE.GEM_GREEN,	bool = true},
	opalpreciousgem = {tag = FOODTYPE.GEM_OPAL,		bool = true},
}

function GemPostInit(inst)
	local tag = gems[inst.prefab].tag	-- Now references the specific gem tag it needs from the "gems" table
	inst:AddTag("edible_"..tag)
end
for k,v in pairs(gems) do
	AddPrefabPostInit(k, GemPostInit)
end

function EdibleCompPostInit(comp)
	old_OnRemoveFromEntity = comp.OnRemoveFromEntity

	comp.OnRemoveFromEntity = function(self)	-- Learned that this isnt entirely necessary, but good to have as a failsafe
		old_OnRemoveFromEntity(self)
		local prefab = self.inst.prefab
		for k,v in pairs(gems) do
			if prefab == k then
				self.inst:RemoveTag("edible_"..v.tag)
				break
			end
		end
	end
end
AddComponentPostInit("edible", EdibleCompPostInit)

function EaterCompPostInit(comp)
	local function RedGemfn(self)	-- Food and feeder are also passed through as arguments, but you only need self here
		if self.inst.components.temperature.inherentinsulation < 200 then
			self.inst.components.temperature.inherentinsulation = self.inst.components.temperature.inherentinsulation + 20
			if self.inst.components.temperature.inherentinsulation >= 200 then
				self.edible_gems.redgem.bool = false	-- This allows you to track whether or not redgems can be eaten or not between saves
				self:CheckEdibleGems()	-- Updates whether or not gems should be eaten based on their current boolean value
			end
		end
	end

	local function BlueGemfn(self, food, feeder)	-- Food and feeder are also passed through as arguments if needed

	end
	--You can fill out the rest ;)
	
	comp.edible_gems = gems		-- This stores our locally made "gems" table to the component variable "self.edible_gems"
	comp.edible_gems.redgem.fn 			= RedGemfn		-- Unfortunately these must be added manually, cant concatenate function names :(
	comp.edible_gems.bluegem.fn 		= BlueGemfn
	comp.edible_gems.purplegem.fn 		= PurpleGemfn
	comp.edible_gems.yellowgem.fn 		= YellowGemfn
	comp.edible_gems.orangegem.fn 		= OrangeGemfn
	comp.edible_gems.greengem.fn 		= GreenGemfn
	comp.edible_gems.opalpreciousgem.fn = OpalGemfn

	comp.CheckEdibleGems = function(self)		-- Iterates the self.edible_gems table and checks if it should remove the GEM_COLOR_eater tag
		for k,v in pairs(self.edible_gems) do
			if v.bool ~= true then
				self.inst:RemoveTag(v.tag.."_eater")
			end
		end
	end

	local old_Eat = comp.Eat
	comp.Eat = function(self, food, feeder)
		if self.inst.prefab = "<your character prefab>" then 	-- This can either be a unique tag using self.inst:HasTag() or just identify the specific char prefab
			for k,v in pairs(self.edible_gems) do
				if food.prefab == k then
					v.fn(self, food, feeder)	-- Performs the function attached to the key of the same name of the prefab in self.edible_gems
				end
			end
		end
		return old_Eat(self, food, feeder)
	end

	comp.OnSave = function(self)	-- Changes the OnSave() to include your boolean checks for gems
		local data = {}
		for k,v in pairs(self.edible_gems) do
			data[k] = v.bool
		end
		data.time_since_eat = self:TimeSinceLastEating()
		return data
	end

	comp.OnLoad = function(self, data)	-- Changes the OnLoad() to include your boolean checks for gems
		if data.time_since_eat ~= nil then
	        self.lasteattime = GLOBAL.GetTime() - data.time_since_eat
	    end
	    for k,v in pairs(self.edible_gems) do
		    if data[k] ~= nil then
		    	v.bool = data[k]
		    end
		end    
		self:CheckEdibleGems()
	end
end
AddComponentPostInit("eater", EaterCompPostInit)

 

Lemme know if you have any questions :)

Edited by w00tyd00d

Share this post


Link to post
Share on other sites
7 hours ago, w00tyd00d said:

Lemme know if you have any questions :)

Ummmm I know you put so much time into this and I am very grateful but....
The upgrades are not communicating to the character. I noticed this when I wasn't getting the speed increase and it did not stop the tags.

local function YellowGemfn(self, food, feeder)
		if 	inst.components.locomotor.walkspeed < 6 then
			inst.components.locomotor.walkspeed = inst.components.locomotor.walkspeed + .4
			inst.components.locomotor.runspeed = inst.components.locomotor.runspeed + .8
		elseif inst.components.locomotor.walkspeed >= 6 then
			self.edible_gems.yellowgem.bool = false	-- This allows you to track whether or not redgems can be eaten or not between saves
			self:CheckEdibleGems()
		end
end

Also there was one typo the game says, just an '=' when it was suppose to be '=='

Still you da best. I didn't expect this to be so problematic.

 

Share this post


Link to post
Share on other sites
w00tyd00d    193
3 hours ago, SomeoneStrange said:


The upgrades are not communicating to the character. I noticed this when I wasn't getting the speed increase and it did not stop the tags.

You have to reference them as "self.inst" instead of just "inst" since you're working from the component's script (self referencing the component, inst being the instance it's attached to). Try changing those and see if that fixes your problem.

3 hours ago, SomeoneStrange said:

Also there was one typo the game says, just an '=' when it was suppose to be '=='

Ah yup, the prefab/tag check, must've accidentally scratched one when getting rid of my test code, my b :?

Share this post


Link to post
Share on other sites
w00tyd00d    193

@SomeoneStrange I'm afraid there's probably going to be one more hurdle to get this feature to be completely working as intended, and that's to keep the changed stats persistent throughout saves. With that current code, I believe any stat you do change is going to be temporary to the current playthrough and once you reload the game, if the threshold was reached before it will remember to prevent you from being able to eat that particular gem, but the stat increase from it will most likely have reset.

When I get some extra time tomorrow I'll try to see if I can get a solid way to be able to keep the data persistent amongst saves while still only modifying the "eater" component's code (messing with too many OnSave() functions can lead to bad interactions with other mods). Almost there though ;) I hope most of the changes I've made has at least made sense to you.

Share this post


Link to post
Share on other sites
8 hours ago, w00tyd00d said:

With that current code, I believe any stat you do change is going to be temporary to the current playthrough and once you reload the game

I already have working code for that. it's in my character prefab. I also have the upgrade effect in my character prefab too.

Share this post


Link to post
Share on other sites
w00tyd00d    193
2 minutes ago, SomeoneStrange said:

I already have working code for that. it's in my character prefab. I also have the upgrade effect in my character prefab too.

And it's able to successfully persist the incremental data throughout saves?

Would you mind posting the code? I'm curious as to how you have it set up

Share this post


Link to post
Share on other sites
local function onpreload(inst, data)
	if data then
		if data.maxhealth then
			inst.components.health:SetMaxHealth(data.maxhealth)
		end
		if data.maxhunger then
			inst.components.hunger:SetMax(data.maxhunger)
		end
		
		if data.inherentinsulation then
			inst.components.temperature.inherentinsulation = data.inherentinsulation
		end
		if data.inherentsummerinsulation then
			inst.components.temperature.inherentsummerinsulation = data.inherentsummerinsulation
		end
		
		if data.damagemultiplier then
			inst.components.combat.damagemultiplier = data.damagemultiplier
		end
		
		if data.walkspeed then
			inst.components.locomotor.walkspeed = data.walkspeed
		end
		if data.runspeed then
			inst.components.locomotor.runspeed = data.runspeed
		end
		
	end
end
	
local function OnSave(inst, data)
    data.maxhealth = inst.components.health.maxhealth
	data.maxhunger = inst.components.hunger.max
	data.healthtosave = inst.components.health.current
	data.hungertosave = inst.components.hunger.current
	
	data.inherentinsulation = inst.components.temperature.inherentinsulation
	data.inherentsummerinsulation = inst.components.temperature.inherentsummerinsulation
	data.damagemultiplier = inst.components.combat.damagemultiplier
	data.walkspeed = inst.components.locomotor.walkspeed
	data.runspeed = inst.components.locomotor.runspeed
end

local function OnLoad(inst, data)
	if data then
		if data.hungertosave then
			inst.components.hunger.current = data.hungertosave
		end
		if data.healthtosave then
			inst.components.health:SetCurrentHealth(data.healthtosave)
		end
	end
end

This code was working when all gems were FOODTYPE.GEMS. This is in the character prefab

Share this post


Link to post
Share on other sites
w00tyd00d    193

@SomeoneStrange Oh! Right on then buddy, I actually wasn't even aware you could store save data per instance in that fashion. This is exactly why I like helping people because I end up learning new things about the game in the process as well lol

Well in that case you should be all set, then. ;) Lemme know if that fix I suggested worked for you or if there's anything else you need help with.

Share this post


Link to post
Share on other sites
3 minutes ago, w00tyd00d said:

Lemme know if that fix I suggested worked for you

Ya the upgrades are not applying in the first place so idk if the limit check is going off. This is the code in my character prefab, the beefalo wool and the pigskin section work but the gem one wont apply the upgrade.

local function oneat(inst, food)
    if food and food.components.edible and food.components.edible.foodtype == FOODTYPE.HORRIBLE then
        if food.prefab == "pigskin" then
			if inst.components.health.maxhealth < 300 then
				local percent = inst.components.health:GetPercent()
				inst.components.health:SetMaxHealth(inst.components.health.maxhealth + 10)
				inst.components.health:SetPercent(percent)
			elseif inst.components.health.maxhealth >= 300 then
				food.components.edible.healthvalue = 50 
			end
		elseif food.prefab == "beefalowool" then
			if inst.components.hunger.max < 500 then
				local percent = inst.components.hunger:GetPercent()
				inst.components.hunger:SetMax(inst.components.hunger.max + 5)
				inst.components.hunger:SetPercent(percent)
			elseif inst.components.hunger.max >= 500 then
				food.components.edible.hungervalue = 50 
			end
		end
	end	
	
	if food and food.components.edible and food.components.edible.foodtype == FOODTYPE.ROUGHAGE then
        if food.prefab == "cutgrass" then
				food.components.edible.hungervalue = 10
		end
	end
	
	if food and food.components.edible and food.components.edible.foodtype == FOODTYPE.GEM_ORGANGE then
		if 	inst.components.locomotor.walkspeed < 6 then
			inst.components.locomotor.walkspeed = inst.components.locomotor.walkspeed + .4
			inst.components.locomotor.runspeed = inst.components.locomotor.runspeed + .8
		end
       --[[if food.prefab == "redgem" then
			if inst.components.temperature.inherentinsulation < 100 then
				inst.components.temperature.inherentinsulation = inst.components.temperature.inherentinsulation + 20
			end
		if food.prefab == "bluegem" then
			if 	inst.components.temperature.inherentsummerinsulation < 100 then
				inst.components.temperature.inherentsummerinsulation = 	inst.components.temperature.inherentsummerinsulation + 20
			end
		elseif food.prefab == "purplegem" then
			if 	inst.components.combat.damagemultiplier < 3 then
				inst.components.combat.damagemultiplier = inst.components.combat.damagemultiplier + .6
			end
		end]]
	end	
	
end

And in the modmain

	local function OrangeGemfn(self, food, feeder)
		if self.inst.components.locomotor.walkspeed >= 6 then
			self.edible_gems.orangegem.bool = false	-- This allows you to track whether or not redgems can be eaten or not between saves
			self:CheckEdibleGems()
		end
	end

 

Share this post


Link to post
Share on other sites

OK!
So when I removed

food and food.components.edible and food.components.edible.foodtype == FOODTYPE.GEM_ORGANGE 

I replaced it with: food.prefab == "orangegem"
The upgrades were being applied but there was no limit to stop eating them.
So the problem is that my character prefab doesn't know there is a FOODTYPE.GEM_ORANGE
any ideas?

Edited by SomeoneStrange

Share this post


Link to post
Share on other sites
w00tyd00d    193
3 minutes ago, SomeoneStrange said:

FOODTYPE.GEM_ORGANGE

No, the problem is you had a typo my friend :p 

Also the way I set it up was to have the stat applied through the component, not the prefab. When you apply it to the prefab's "oneat" function, that runs after the checks that I added for the "Eat" function in eater. Have you tried doing it like the way I had the red gem example set up for you?

Share this post


Link to post
Share on other sites
19 minutes ago, w00tyd00d said:

Have you tried doing it like the way I had the red gem example set up for you?

I have tried it like that but it didn't apply the upgrades
And that typo wasn't there in my prefab I swear so idk.

It doesn't look like the modmain and the prefab are communicating correctly though.

Like the FOODTYPE is being conveyed

 

Edited by SomeoneStrange

Share this post


Link to post
Share on other sites
w00tyd00d    193
20 minutes ago, SomeoneStrange said:

It doesn't look like the modmain and the prefab are communicating correctly though.

Like the FOODTYPE is being conveyed

If it doesn't crash for you on loading they should be going through fine :\ I'll take a gander at it when I'm home a bit later.

Share this post


Link to post
Share on other sites
w00tyd00d    193

@SomeoneStrange I can confirm from a buddy of mine that this code works fine for both client and server:

local function RedGemfn(self)
	if self.inst.components.sanity then
		self.inst.components.sanity:DoDelta(-25)
		if self.inst.components.sanity:GetPercent() <= 0.5 then
			self.edible_gems.redgem.bool = false
			self:CheckEdibleGems()
		end
	end
end

Are you sure you're checking for the right prefab/tag under the new Eat function I provided?

Share this post


Link to post
Share on other sites
w00tyd00d    193
26 minutes ago, SomeoneStrange said:

No changes were made to the gem.lua

What do you mean no changes made to gem.lua? We're not trying to/cant change anything in gems.lua, like I said before gem.lua is only a blueprint for all of the gem prefabs in the game. In order to change an item in the game, you need to refer to its prefab (in this case redgem, bluegem, etc), we don't actually get access to the gem.lua file itself unless we want to override it.

Remember, all gem.lua does is create a common prefab script for all of the individual gem prefabs since, as items, they all have the same properties (it's what they're used to craft with is what makes them unique, that and their sprite and prefab name). In order to access those individual gems, however, you need to refer to their prefab, which to us only exists in digital space (see the bottom of gem.lua's script).

26 minutes ago, SomeoneStrange said:

and I do not know what you by

I mean the prefab/tag check under the comp.Eat function I provided to you in the EaterCompPostInit function.

local old_Eat = comp.Eat
comp.Eat = function(self, food, feeder)
	if self.inst:HasTag("player") then		-- I use this for testing purposes and works fine, should work for any other tag directly attached as well
	--if self.inst.prefab == "<your character prefab>" then		-- same goes for the prefab check
		for k,v in pairs(self.edible_gems) do
			if food.prefab == k then
				v.fn(self, food, feeder)
			end
		end
	end
	return old_Eat(self, food, feeder)
end

 

Edited by w00tyd00d

Share this post


Link to post
Share on other sites
5 minutes ago, w00tyd00d said:

I mean the prefab/tag check under the comp.Eat function I provided to you in the EaterCompPostInit function

Oh I do have that tag.
So what is the problem with the code?

Edited by SomeoneStrange

Share this post


Link to post
Share on other sites
w00tyd00d    193
Just now, SomeoneStrange said:

Oh I do have that tag but is there suppose to be a reference in the modmain for gem.lua?

No xD how many times do I have to say to forget about gem.lua :p 

Just remember that gem.lua ~= a prefab. Gem.lua creates 7 different prefabs named redgem, bluegem, etc. and that's what we need to plug in to lol which we do using the GemPostInit function I provided.

Share this post


Link to post
Share on other sites
w00tyd00d    193
5 minutes ago, SomeoneStrange said:

wait so wtf is the problem? :confused:

That's what I'm trying to figure out for you ;P

Would you mind just sending a zip of your entire mod folder so I can get a better scope as to how you have it set up? It's hard to know exactly what you have where compared to what I have on my end :\

EDIT: Nvm, I didn't even notice you posted your modmain and character files earlier, Ill give them a look over and get back to you

Edited by w00tyd00d

Share this post


Link to post
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
Sign in to follow this