math.randomseed(os.time())
math.random(); math.random()

local NPC = {}
NPC.__index = NPC

local suffixes = {"", "k", "M", "B", "T", "Q"}

local function abbreviate(n)
    local i = 1
    while n >= 1000 and i < #suffixes do
        n = n / 1000
        i = i + 1
    end
    -- Returns formatted string: 1.5k, 10M, etc.
    return (i == 1 and tostring(n) or string.format("%.1f%s", n, suffixes[i]):gsub("%.0", ""))
end


function printTable(t, indent)
    indent = indent or ""
    for k, v in pairs(t) do
        if type(v) == "table" then
            print(indent .. tostring(k) .. ":")
            printTable(v, indent .. "  ")
        elseif k == "Health" or k == "Damage" then
            print(indent .. tostring(k) .. " = " .. abbreviate(v))
        else
            print(indent .. tostring(k) .. " = " .. tostring(v))
        end
    end
end

local function getAmount(amt)
    if type(amt) == "table" then
        return math.random(amt[1], amt[2])
    end
    return amt or 1
end

function NPC.new(Name, Health, Damage, Speed, Drops)
    local self = setmetatable({}, NPC)
    self.Name = Name
    self.Health = Health
    self.Damage = Damage
    self.Speed = Speed
    self.Drops = Drops
    
    print("--- New NPC Created ---")
    printTable(self) -- Use the recursive print
    print("-----------------------")
    return self
end

function NPC:IsKilled()
    print("NPC died! Calculating drops...")
    local earned = {}

    -- Roll ONE time for all items
    local sharedRoll = math.random(1, 100)
    print("Shared Roll: " .. sharedRoll)

    if self.Drops.Cash then earned.Cash = self.Drops.Cash end
    if self.Drops.XP then earned.XP = self.Drops.XP end
    
    if self.Drops.Items then
        for itemName, info in pairs(self.Drops.Items) do
            -- Every item compares itself to the SAME sharedRoll
            if sharedRoll <= info.Chance then
                earned[itemName] = getAmount(info.Amount)
            end
        end
    end
    
    return earned
end

--[[local myNPC = NPC.new(100, 5, 22, { 
    Cash = 100, 
    XP = 1, 
    Items = { 
        Sword = { Chance = 50, Amount = {1, 3} } 
    } 
})]]

local myNPC2 = NPC.new("Nacker", 5e6, 5, 22, { 
    Cash = 2.7128e9, 
    XP = 4.784e14, 
    Items = { 
        ["Vermite Ore"] = { Chance = 80, Amount = {1, 10000} },
        ["Omega Death Orb"] = { Chance = 10, Amount = {1, 3} },
        
    } 
})

--[[local rewards = myNPC:IsKilled()
for name, amt in pairs(rewards) do
    print("Player received: " .. amt .. "x " .. name)
end]]

local rewards2 = myNPC2:IsKilled()
for name, amt in pairs(rewards2) do
    print("Player received: " .. abbreviate(amt) .. "x " .. name)
end

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: