Jump to content

Recommended Posts

I'm having a bit of difficulty with a mod i'm tinkering with that would cause the player to slowly lose health when their sanity drops below 50%.

 

I have a good amount of knowledge of using math in scripts, and no, I don't learn well with direct lua tutorials because nothing really seems to help it make sense to me like actually getting my hands dirty, but this one has me quite stumped.

 

local SelfCollapse = Class(function(self, player)self.Health = player.components.healthself.Hunger = player.components.hungerself.Sanity = player.components.sanityplayer:StartUpdatingComponent(self)end)function MentalCollapsePostInit(player)if self.Sanity:GetPercent() <.5 thenself.Health:DoDelta(-1, 60, cause, false)endif self.Sanity:GetPercent() <.25 thenself.Health:DoDelta(-2,60,cause,false)endif self.Sanity:GetPercent() <.05 thenself.Health:DoDelta(-2,60,cause,false)endif self.Sanity:GetPercent() <.01 thenself.Health:DoDelta(-5,60,cause,false)endAddComponentPostInit("sanity", MentalCollapsePostInit)AddComponentPostInit("health", MentalCollapsePostInit)end

 

It loads up properly, but nothing happens. There is a couple lines in the console saying that it's registering prefabs, but there's no actual ingame changes. What exactly am I doing wrong here?

Edited by Silentdarkness1

Anyone? D:

 

Patience. :p

 

Why are you doing this with self?

 

self.Health = player.components.health
 
See if replacing "self.Health" with "local Health" does any good. Self shouldn't be used as a variable in that way, or if it does, I haven't seen it.

Unexpected symbol near 'local' on line 11.

 

local Degeneration = Class(function(self, player)local Health = player.components.healthlocal Hunger = player.components.hungerlocal Sanity = player.components.sanity player:StartUpdatingComponent(self)end) function MentalCollapsePostInit(player)  if local Sanity:GetPercent() <.5 then local Health:DoDelta(-1, 60, cause, false) end  if local Sanity:GetPercent() <.25 then  local Health:DoDelta(-2,60,cause,false)  end    if local Sanity:GetPercent() <.05 then   local Health:DoDelta(-2,60,cause,false)   end      if local Sanity:GetPercent() <.01 then    local Health:DoDelta(-5,60,cause,false)end  AddComponentPostInit("sanity", MentalCollapsePostInit) AddComponentPostInit("health", MentalCollapsePostInit)end

 

Unexpected symbol near 'local' on line 11.

local Degeneration = Class(function(self, player)local Health = player.components.healthlocal Hunger = player.components.hungerlocal Sanity = player.components.sanity player:StartUpdatingComponent(self)end) function MentalCollapsePostInit(player)  if local Sanity:GetPercent() <.5 then local Health:DoDelta(-1, 60, cause, false) end  if local Sanity:GetPercent() <.25 then  local Health:DoDelta(-2,60,cause,false)  end    if local Sanity:GetPercent() <.05 then   local Health:DoDelta(-2,60,cause,false)   end      if local Sanity:GetPercent() <.01 then    local Health:DoDelta(-5,60,cause,false)end  AddComponentPostInit("sanity", MentalCollapsePostInit) AddComponentPostInit("health", MentalCollapsePostInit)end

 

"local" only needs to be used when the variable is called. Also, I'd suggest add "local player = GLOBAL.GetPlayer()" above "local health", etc.

 

 if Sanity:GetPercent() <.5 then
 Health:DoDelta(-1, 60, cause, false)
 end
 
 if Sanity:GetPercent() <.25 then
  Health:DoDelta(-2,60,cause,false)
  end
  
  if Sanity:GetPercent() <.05 then
   Health:DoDelta(-2,60,cause,false)
   end
   
   if Sanity:GetPercent() <.01 then
    Health:DoDelta(-5,60,cause,false)
end

your code do exactly what you made

check some variables on component init and ... nothing more. I m not even sure that OnLoad was finished before this and overwrites your changes anyway.

 

you have to add event handler of "sanitydelta" event

look how similar mods is made or even in game code.

 

for example here code from damage indicators:

AddComponentPostInit("health", function(Health, inst)    inst:ListenForEvent("healthdelta", function(inst, data)        if inst.components.health then            local amount = (data.newpercent - data.oldpercent)*inst.components.health.maxhealth            if math.abs(amount) > 0.001 then                if not (TUNING.SHOW_DAMAGE_ONLY and amount > 0) then                    CreateDamageIndicator(inst, amount)                end            end        end    end)end)

made same for sanity and check inside that inst is belongs to player, then do your checks

 

second solution - add event listener to player instance  for "sanitydelta" event. (its more proper, but bit harder)

Edited by Rincevvind

 

"local" only needs to be used when the variable is called. Also, I'd suggest add "local player = GLOBAL.GetPlayer()" above "local health", etc.

 

 if Sanity:GetPercent() <.5 then
 Health:DoDelta(-1, 60, cause, false)
 end
 
 if Sanity:GetPercent() <.25 then
  Health:DoDelta(-2,60,cause,false)
  end
  
  if Sanity:GetPercent() <.05 then
   Health:DoDelta(-2,60,cause,false)
   end
   
   if Sanity:GetPercent() <.01 then
    Health:DoDelta(-5,60,cause,false)
end

 

 

Okay. Did that, still isn't working though. It's back to just not doing anything ingame.

 

your code do exactly what you made

check some variables on component init and ... nothing more. I m not even sure that OnLoad was finished before this and overwrites your changes anyway.

 

you have to add event handler of "sanitydelta" event

look how similar mods is made or even in game code.

 

for example here code from damage indicators:

AddComponentPostInit("health", function(Health, inst)

    inst:ListenForEvent("healthdelta", function(inst, data)

        if inst.components.health then

            local amount = (data.newpercent - data.oldpercent)*inst.components.health.maxhealth

            if math.abs(amount) > 0.001 then

                if not (TUNING.SHOW_DAMAGE_ONLY and amount > 0) then

                    CreateDamageIndicator(inst, amount)

                end

            end

        end

    end)

end)

made same for sanity and check inside that inst is belongs to player, then do your checks

 

second solution - add event listener to player instance  for "sanitydelta" event. (its more proper, but bit harder)

 

I'm not quite sure I understand what you're saying. Adding a listener for healthdelta and sanitydelta, then....wat

Edited by Silentdarkness1

e_______e

 

New problems.

local Degeneration = Class(function(self, player)    local player = GLOBAL.GetPlayer()	local Health = player.components.health	local Hunger = player.components.hunger	local Sanity = player.components.sanity	player:StartUpdatingComponent(self)end)function MentalCollapsePostInit(player)AddComponentPostInit("sanity", MentalCollapsePostInit)AddComponentPostInit("health", MentalCollapsePostInit)inst:ListenForEvent("healthdelta", function(inst, data)inst:ListenForEvent("sanitydelta", function(inst, data) if Sanity:GetPercent() <.5 then Health:DoDelta(-1, 60, cause, false) end  if Sanity:GetPercent() <.25 then  Health:DoDelta(-2,60,cause,false)  end    if Sanity:GetPercent() <.05 then   Health:DoDelta(-2,60,cause,false)   end      if Sanity:GetPercent() <.01 then    Health:DoDelta(-5,60,cause,false)	endend)end)

"Unexpected symbol near ")" on line 13"

 

Now what?

Don't even know how to start this. 

 

Yes I know. For the love of all rainbows, unicorns and Power Puff Girls, please format the code. 

 

1. Your function is not closed, you are missing an end

2. inst in the function is not declared anywhere.

3. AddComponentPost init is done in the actual function that does the handling. So who is actually registering the function in Component post init so it can register itself in Component Post Init. (see the dilemma?)

4. You are not using your component (Degeneration) anywhere

 

I could go on.

 

 

Best advice I can give you (don't take it personal), follow the tutorials and do simple stuff first.

 

 

PS. Boy did you get your hands dirty!!

Edited by RazvanM

Don't even know how to start this. 

 

Yes I know. For the love of all rainbows, unicorns and Power Puff Girls, please format the code. 

 

1. Your function is not closed, you are missing an end

2. inst in the function is not declared anywhere.

3. AddPrefabPost init is done in the actual function that does the handling. So who is actually registering the function in prefab post init so it can register itself in Prefab Post Init. (see the dilemma?)

4. You are not using your component (Degeneration) anywhere

 

I could go on.

 

 

Best advice I can give you (don't take it personal), follow the tutorials and do simple stuff first.

 

 

PS. Boy did you get your hands dirty!!

1. Are you sure? Wouldn't the game crash if there wasn't an end?

2. Well, currently there are no insts in my code anymore.

3. I moved the postinits into the main function, and that did nothing.

4. The point of that function was to establish some variables. In that case, does it need to be triggered?

 

Also, lua tutorials don't work for me. Not ones outside of Don't Starve, at least.

Well you have tutorials on modding created by the DN developers. Take those. This is turning into another discussion.

function MentalCollapsePostInit(player)	AddComponentPostInit("sanity", MentalCollapsePostInit)	AddComponentPostInit("health", MentalCollapsePostInit)	inst:ListenForEvent("healthdelta", function(inst, data)		inst:ListenForEvent("sanitydelta", function(inst, data)			if Sanity:GetPercent() <.5 then				Health:DoDelta(-1, 60, cause, false)			end			if Sanity:GetPercent() <.25 then				Health:DoDelta(-2,60,cause,false)			end			if Sanity:GetPercent() <.05 then				Health:DoDelta(-2,60,cause,false)			end			if Sanity:GetPercent() <.01 then				Health:DoDelta(-5,60,cause,false)			end		end) -- end first "inst" - sanity delta	end) -- end second "inst" - health delta

To the point.

1. No, it would not even start. You will get an error like you already did.

2. Perfect

3. Perfect

4. If it is just for that you don't need it, you could do it another way (not telling), what I will tell you is that you don't even need variables if you are listening for events, you get the instance as parameter, just go inst.components.sanity:GetPercent() < 0.5 (In the ListenForEvent handler)

inst:ListenForEvent("sanitydelta", function(inst, data)	if inst.components.sanity:GetPercent() <.5 then		inst.components.health:DoDelta(-1, 60, cause, false)	end	................end)

5. Depending on how you attach that you will get an error. I believe only the player has sanity. So you should really attach on PrefabPostInit.

Edited by RazvanM

I learn better through visual examples. What's the problem here is that none of the example mods i've seen so far, (and yes I went onto the stickied thread in Mods and Tools) address modification of player stats. The Delta stuff.

 

If there is one, then it's buried somewhere.

 

Getting back on this, however: So, if i'm using prefabpostinit, what'd it be? Player?

Here's what I have currently: 

function MentalCollapsePostInit(player)AddComponentPostInit("sanity", MentalCollapsePostInit)AddComponentPostInit("health", MentalCollapsePostInit)print ("Componentpostinit finished")inst:ListenForEvent("sanitydelta", function(inst, data) if Sanity:GetPercent() <.5 then Health:DoDelta(-1, 60, cause, false) print "lowsanity" end   if Sanity:GetPercent() <.25 then  Health:DoDelta(-2,60,cause,false)  print ("lowsanity")  end    if Sanity:GetPercent() <.05 then   Health:DoDelta(-2,60,cause,false)   print ("lowsanity")   end      if Sanity:GetPercent() <.01 then    Health:DoDelta(-5,60,cause,false)	print ("lowsanity")	end

I can't put the final parentheses on the event listener however, because that causes an unknown symbol error, no matter which end I put it on.

Ok, this is the last time I'm going to reply to this. Learn a programming language. Does not matter what. Learn about variables. Functions. And the rest.

 

You can't put a parentheses because you have an error somewhere . You said no "inst", I see an "inst". You said you removed the init functions, I see the init functions.

 

I think it is a special function for player post init. I don't know it by hand. 

 

Also a tip. For each "function" word and "if" word, you also need an "end" word.

Edited by RazvanM

Then I don't quite understand how to accomplish this without inst. I'm already comfortable with how variables and math work, and the problem with functions was just me not noticing that the function was missing an end. Error is fixed, and now i'm back to the code not doing anything.

function MentalCollapsePostInit(player)inst:ListenForEvent("sanitydelta", function(inst, data) if inst.components.sanity:GetPercent() <.5 then Health:DoDelta(-1, 60, cause, false) print "lowsanity" end   if inst.components.sanity:GetPercent() <.25 then  Health:DoDelta(-2,60,cause,false)  print ("lowsanity")  end    if inst.components.sanity:GetPercent() <.05 then   Health:DoDelta(-2,60,cause,false)   print ("lowsanity")   end      if inst.components.sanity:GetPercent() <.01 then    Health:DoDelta(-5,60,cause,false)	print ("lowsanity")	end		end )	end

I really have no idea at this point what to use. Looking at the built-in components only seems to have made things more confusing, and there's no mod I can find that REALLY has what i'm looking for. I'm apparently doing SOMETHING wrong, but I just can't tell what it is. And yes, i've been looking at sample mods.

I really have no idea at this point what to use. Looking at the built-in components only seems to have made things more confusing, and there's no mod I can find that REALLY has what i'm looking for. I'm apparently doing SOMETHING wrong, but I just can't tell what it is. And yes, i've been looking at sample mods.

 

What you want to do is add an event listener to the player entity, then call your function that checks sanity percentage and applies health delta.

 

GLOBAL.GetPlayer():ListenForEvent(sanitydelta, function() yourfunctionname end)

 

I'll explain some things that you seem to be having trouble with.

 

Firstly, "inst" is always that particular instance. If you are modifying a rabbit prefab, "inst" is that specific rabbit. It will apply to every rabbit if you put it in the constructor (that's the main function of the prefab), but if you put it in a function that is called on a specific event, it will only apply to the entity involved in that event.

 

You need to understand what a variable is and how to declare and use one.

 

A variable is an arbitrary value. If you do something like:

 

foo.components.sanity

 

without declaring what "foo" actually is, it will give you an error.

 

You need to declare "foo", like this:

 

local foo = GLOBAL.GetPlayer()

 

If you cannot learn from the lua tutorials and examples, or by examining the game's code, you're going to have a very rough time with modding.

 

My advice is to start reading simpler prefabs (like "meat" and "deadlyfeast") and work your way up to understanding the more complex prefabs (like "pighouse" and "maxwellthrone".)

 

It's good to get your hands dirty, certainly, but if you find you get stuck absolutely, you should backtrack and work your way up to that point.

I said it would be a last post, I also see a little progress.

You are very close.

I want you to listen to something on the radio. The first thing I have to give you is a radio and the frequency. Than you can listen to a specific news.

Back to your function. You want to listen to an event sanitydelta. I have to give you the player. Than you can listen to the event. The way you have it, you get the player, however you are not doing anything with it.

Second. You removed sanity and used the components. Why did you continued to use Health? Health is also a component, inst.component.health.

What you want to do is add an event listener to the player entity, then call your function that checks sanity percentage and applies health delta.

 

GLOBAL.GetPlayer():ListenForEvent(sanitydelta, function() yourfunctionname end)

 

I'll explain some things that you seem to be having trouble with.

 

Firstly, "inst" is always that particular instance. If you are modifying a rabbit prefab, "inst" is that specific rabbit. It will apply to every rabbit if you put it in the constructor (that's the main function of the prefab), but if you put it in a function that is called on a specific event, it will only apply to the entity involved in that event.

 

You need to understand what a variable is and how to declare and use one.

 

A variable is an arbitrary value. If you do something like:

 

foo.components.sanity

 

without declaring what "foo" actually is, it will give you an error.

 

You need to declare "foo", like this:

 

local foo = GLOBAL.GetPlayer()

 

If you cannot learn from the lua tutorials and examples, or by examining the game's code, you're going to have a very rough time with modding.

 

My advice is to start reading simpler prefabs (like "meat" and "deadlyfeast") and work your way up to understanding the more complex prefabs (like "pighouse" and "maxwellthrone".)

 

It's good to get your hands dirty, certainly, but if you find you get stuck absolutely, you should backtrack and work your way up to that point.

Two things on this is that, one, I have no idea where to start looking to understand how event listeners work, and two, getting a fresh error on the event listener.

GLOBAL.CHEATS_ENABLED = trueGLOBAL.require( 'debugkeys' )local mindpain = GLOBAL.GetPlayer()GLOBAL.GetPlayer():ListenForEvent("sanitydelta", function() MentalCollapseCore end)function MentalCollapseCore(inst) if mindpain.components.Sanity:GetPercent() <.5 then mindpain.components.health:DoDelta(-1, 60, cause, false) print "lowsanity" end   if mindpain.components.sanity:GetPercent() <.25 then  mindpain.components.health:DoDelta(-2,60,cause,false)  print ("lowsanity")  end    if mindpain.components.sanity:GetPercent() <.05 then   mindpain.components.health:DoDelta(-2,60,cause,false)   print ("lowsanity")   end      if mindpain.components.sanity:GetPercent() <.01 then    mindpain.components.health:DoDelta(-5,60,cause,false)	print ("lowsanity")	end	end		AddComponentPostInit("sanity", MentalCollapseCore)	AddComponentPostInit("health", MentalCollapseCore)

" "=" expected near 'end', line 4"

 

I've also tried moving where the end and the "" are, and the error remains the same. I don't recall this sort of thing requiring an extra variable definition = before. Also tried moving the entire thing inside the function, to no avail.

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
×
  • Create New...