Hello, I am working on a gamemode where custom props (entities) have health and can be destroyed. Ive got a health system working with ENT:OnTakeDamage() but some things are not working, and I am unable to get them to work.
-When I spawn multiple of the same entity, they share health. You can attack different ones and it takes health from a global variable.
-When I spawn a new entity, it does not reset the health to what I set it to
How can I get each prop/entity to save its own Health?
Here is the code:
[CODE]Health = MaxHealth
MaxHealth = 500
function ENT:OnTakeDamage(dmg)
-- if(Health <= 0) then return end (Taken Out For Now)
Health = Health - dmg:GetDamage()
if(Health <= 0) then
self:Remove()
end
Trans = Health/MaxHealth*255
self:SetColor(Color(196, 196, 196, Trans))
print(dmg:GetDamage(),Health,Trans)
end[/CODE]
I have tried moving the MaxHealth and Health lines to ENT:Initialize() or ENT:SpawnFunction() as well as putting "local" infront of some things, and it did not make a difference.
Thank you, Endus322
When you made those variables local, they were local to the [i]script[/i]. Since only 1 instance of the [i]script[/i] exists, they are still shared between all instances of the entity. What you want to do is store those values on the entity table.
[code]
function ENT:Initialize()
self.MaxHealth = 500
self.Health = self.MaxHealth
end
[/code]
People tend to get confused on what the colon means, and what exactly 'self' is. When you define a function with a colon, it specifies an implicit 'self' parameter that is passed to the function, and in the case of entities, it represents the current entity that the function is running for. You can define the exact same function in 3 different ways:
[code]
function ENT:OnTakeDamage(dmg)
-- code
end
function ENT.OnTakeDamage(self, dmg)
-- code
end
ENT.OnTakeDamage = function(self, dmg)
-- code
end
[/code]
When you call a function with a colon, the 'self' parameter is still implicitly there, and the value passed to it is the table (or object) you called it from. The following function calls mean exactly the same thing.
[code]
myentity:DoSomething(someparam)
myentity.DoSomething(myentity, someparam)
[/code]
[QUOTE=Jcw87;52401209]When you made those variables local, they were local to the [i]script[/i]. Since only 1 instance of the [i]script[/i] exists, they are still shared between all instances of the entity. What you want to do is store those values on the entity table.
[code]
function ENT:Initialize()
self.MaxHealth = 500
self.Health = self.MaxHealth
end
[/code]
People tend to get confused on what the colon means, and what exactly 'self' is. When you define a function with a colon, it specifies an implicit 'self' parameter that is passed to the function, and in the case of entities, it represents the current entity that the function is running for. You can define the exact same function in 3 different ways:
[code]
function ENT:OnTakeDamage(dmg)
-- code
end
function ENT.OnTakeDamage(self, dmg)
-- code
end
ENT.OnTakeDamage = function(self, dmg)
-- code
end
[/code]
When you call a function with a colon, the 'self' parameter is still implicitly there, and the value passed to it is the table (or object) you called it from. The following function calls mean exactly the same thing.
[code]
myentity:DoSomething(someparam)
myentity.DoSomething(myentity, someparam)
[/code][/QUOTE]
Thank you very much, but now I get an error in console about 'Health' being a nil value. Do I keep 'Health' and 'MaxHealth' inside the Initialize Function? Or move it out?
Edit: And do I need to change ALL the Health/MaxHealth to self.Health/self.MaxHealth?
Change all instances of Health to self.Health and same with MaxHealth. You should really either use the built-in SetHealth/SetMaxHealth for entities or have different variable names since by default, Health is a function.
[QUOTE=code_gs;52401455]Change all Health to self.Health and same with MaxHealth. You should really either use the built-in SetHealth/SetMaxHealth for entities or have different variable names since by default, Health is a function.[/QUOTE]
I added self. and changed it to propHealth and propMaxHealth but I still get an error
[CODE]
[ERROR] gamemodes/castledefenders/entities/entities/1x1 wall/init.lua:61: attempt to perform arithmetic on field 'propHealth' (a nil value)
1. unknown - gamemodes/castledefenders/entities/entities/1x1 wall/init.lua:61[/CODE]
And using the built in Health lines, how would I go about making it "take damage?" Or does it do that for you
Can you post the code again?
[QUOTE=code_gs;52401653]Can you post the code again?[/QUOTE]
[CODE]
function ENT:Initialize()
self.propMaxHealth = 500
self.propHealth = self.PropMaxHealth
end
function ENT.OnTakeDamage(self, dmg)
-- if(self.Health <= 0) then return end
self.propHealth = self.propHealth - dmg:GetDamage()
if(self.propHealth <= 0) then
self:Remove()
end
Trans = self.propHealth/500*255
self:SetColor(Color(196, 196, 196, Trans))
print(dmg:GetDamage(),self.propHealth,Trans)
end
[/CODE]
Variables are case sensative. Your declaration of self.propHealth as PropMaxHealth instead of propMaxHealth makes it nil.
[QUOTE=code_gs;52401744]Variables are case sensative. Your declaration of self.propHealth as PropMaxHealth instead of propMaxHealth makes it nil.[/QUOTE]
I guess I didn't see that error
Thanks so much for all the help!
- Endus322
Sorry, you need to Log In to post a reply to this thread.