OOP and __Index functions

So recently I have been learning OOP and it’s been going great, but I’m still learning so sorry if this is simple

I’ve been reading about OOP and my main source is the All about OOP post

my goal is to run a function or multiple whenever a certain stat is indexed (like changing the Level to 1)

bit confused currently what I’ve been trying to do is use two of .__index but I don’t think/know if thats possible

I also tried setting two metatables to the NewPet table but I don’t think thats possible
any help is appreciated

math.randomseed(tick())

local Pet = {}
Pet.__index = Pet

--[[
Pet.__index = function(test)
	print(test)
end
--]]

local PetList = {
	["Pug"] = {BaseAmount = 50, BaseStatPoints = 5},
	["German Shepard"] = {BaseAmount = 200, BaseStatPoints = 15},
}

local RarityList = {
	["Common"] = {BaseStatPoints = 8},
	["Uncommon"] = {BaseStatPoints = 16},
	["Rare"] = {BaseStatPoints = 32},
	["Epic"] = {BaseStatPoints = 64},
	["Legendary"] = {BaseStatPoints = 128},
}

function Pet.new(PetType, Rarity)
	if PetList[PetType] and RarityList[Rarity] then
	local NewPet = {}
	
	setmetatable(NewPet, Pet)
	
	NewPet.Stats = {
		Level = 1,
		Exp = 0,
		PetRewardProgress = 0,
		PetType = PetType,
		PetRarity = Rarity,
		StatPoints = PetList[PetType].BaseStatPoints + RarityList[Rarity].BaseStatPoints
	}
	
	NewPet.Attributes = {
		MaxHealth = {Value = 0, StatPoints = 0},
		MaxEnergy = {Value = 0, StatPoints = 0},
		MaxHunger = {Value = 0, StatPoints = 0},
		MaxHygiene = {Value = 0, StatPoints = 0},
	}
	
	local indexlist = {[1] = NewPet.Attributes.MaxHealth, [2] = NewPet.Attributes.MaxEnergy, [3] = NewPet.Attributes.MaxHunger, [4] = NewPet.Attributes.MaxHygiene}
	while NewPet.Stats.StatPoints > 0 do
		local randomindex = math.random(1, 4)
		NewPet.Stats.StatPoints = NewPet.Stats.StatPoints - 1
		indexlist[randomindex].StatPoints = indexlist[randomindex].StatPoints + 1
		wait()
	end
	
	for _, Attribute in pairs (NewPet.Attributes) do
		Attribute.Value = PetList[PetType].BaseAmount + (Attribute.StatPoints * 15)
		
	end
	
	return NewPet
	
	else
		warn("The " .. PetType .. "PetType or The " .. Rarity .. " Rarity could not be found")
	end
end

function Pet:ChangeStat(stat, value)
	stat = stat + value
	print(stat)
end

return Pet

2 Likes

If you want to access from 2 containers (which is what I assume you’re trying) you might want to apply an __index on your initial container pointing to the fallback, and then set the __index on the fallback to be the second fallback container.

Alternatively, you could give a function to __index instead of a table to grab from these as it sees fit.

still confused and I didn’t really understand what you meant

math.randomseed(tick())

local Pet = {}
Pet.__index = Pet

--[[
Pet.__index = function(test)
	print(test)
end
--]]

local PetList = {
	["Pug"] = {BaseAmount = 50, BaseStatPoints = 5},
	["German Shepard"] = {BaseAmount = 200, BaseStatPoints = 15},
}

local RarityList = {
	["Common"] = {BaseStatPoints = 8},
	["Uncommon"] = {BaseStatPoints = 16},
	["Rare"] = {BaseStatPoints = 32},
	["Epic"] = {BaseStatPoints = 64},
	["Legendary"] = {BaseStatPoints = 128},
}

function Pet.new(PetType, Rarity)
	if PetList[PetType] and RarityList[Rarity] then
	local NewPet = {}
	setmetatable(NewPet, Pet)
	
	local StatsMeta = {}
	StatsMeta.__index = function()
		print("test")
	end
	
	
	
	NewPet.Stats = {
		Level = 1,
		Exp = 0,
		PetRewardProgress = 0,
		PetType = PetType,
		PetRarity = Rarity,
		StatPoints = PetList[PetType].BaseStatPoints + RarityList[Rarity].BaseStatPoints
	}
	
	setmetatable(NewPet.Stats, StatsMeta)
	
	NewPet.Attributes = {
		MaxHealth = {Value = 0, StatPoints = 0},
		MaxEnergy = {Value = 0, StatPoints = 0},
		MaxHunger = {Value = 0, StatPoints = 0},
		MaxHygiene = {Value = 0, StatPoints = 0},
	}
	setmetatable(NewPet.Attributes, StatsMeta)
	
	local indexlist = {[1] = NewPet.Attributes.MaxHealth, [2] = NewPet.Attributes.MaxEnergy, [3] = NewPet.Attributes.MaxHunger, [4] = NewPet.Attributes.MaxHygiene}
	while NewPet.Stats.StatPoints > 0 do
		local randomindex = math.random(1, 4)
		NewPet.Stats.StatPoints = NewPet.Stats.StatPoints - 1
		indexlist[randomindex].StatPoints = indexlist[randomindex].StatPoints + 1
		wait()
	end
	
	for _, Attribute in pairs (NewPet.Attributes) do
		Attribute.Value = PetList[PetType].BaseAmount + (Attribute.StatPoints * 15)
		
	end
	
	return NewPet
	
	else
		warn("The " .. PetType .. "PetType or The " .. Rarity .. " Rarity could not be found")
	end
end

function Pet:ChangeStat(stat, value)
	print(self.Stats.Level)
end

return Pet

is this wrong, im trying to do something whenever one of the stats is indexed?

You might consider handling all the stat changes (assuming you mean “changed” when you say “indexed”) through methods of your class. Then you can include whatever function calls you need within those setter methods. So, for example, you might have a ChangeLevel(n) method that calls ChangeStat with the appropriate args and also calls other code that you want to trigger that is specific to level changes or to stat changes more generally.

My goal was that so when you change a certain stat value it would run a function e.g (if a leash stat was turned to true it would equip and leash to the pet and vice versa)

using methods like you said would be a lot easier and better so ill use that

ty guess I was overthinking things