diff --git a/CHANGELOG.md b/CHANGELOG.md index eebf33d..263feb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to SurvivorCore are recorded here. The format follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). At release time, `## Unreleased` is promoted to the new version and `main` is tagged `vX.Y.Z`. +## 0.7.1 — 2026-07-06 + +### Fixed +- **Ghost tools** — the hotbar→Tool bridge now verifies the player actually CARRIES a pinned item + before equipping it: a pin is only a pointer, and a stale/seeded pin without a backing stack + could previously conjure a usable Tool out of thin air. +- The hotbar now **dims** a pinned item's icon (same 0.45 convention as the Crafting tab) when the + player has none of it, so an inert pin reads as inert. +- Demo: the husks spawn farther out — new players are no longer farmed at the spawn point before + they've picked up a weapon. + ## 0.7.0 — 2026-07-06 ### Added diff --git a/demo/server/Boot.server.luau b/demo/server/Boot.server.luau index b6b6a25..2d6dadd 100644 --- a/demo/server/Boot.server.luau +++ b/demo/server/Boot.server.luau @@ -580,8 +580,10 @@ local function buildWeaponTemplates() end buildWeaponTemplates() -SurvivorCore.Mobs.spawn("husk", CFrame.new(40, 5, 20), { respawn = true }) -SurvivorCore.Mobs.spawn("husk", CFrame.new(48, 5, 32), { respawn = true }) +-- Husks live out past their aggro+wander reach of spawn — new players shouldn't get farmed at +-- the spawn point before they've picked up a weapon (they'll still hunt you in their territory). +SurvivorCore.Mobs.spawn("husk", CFrame.new(70, 5, 45), { respawn = true }) +SurvivorCore.Mobs.spawn("husk", CFrame.new(82, 5, 58), { respawn = true }) SurvivorCore.Mobs.spawn("boar", CFrame.new(-30, 5, 18)) -- The quest-giver post: offers `slay_husk` (hold E to accept; return to turn in). Any mesh works — diff --git a/src/client/Hotbar.luau b/src/client/Hotbar.luau index 648539c..c8ccafe 100644 --- a/src/client/Hotbar.luau +++ b/src/client/Hotbar.luau @@ -87,14 +87,17 @@ local function bindHotbar(root: Instance) local active = math.floor(tonumber(localPlayer:GetAttribute(InventoryTypes.HOTBAR_EQUIPPED_ATTR)) or 0) local icon = slot:FindFirstChild("Icon") + local qty = totalQty(itemId) if icon and (icon:IsA("ImageLabel") or icon:IsA("ImageButton")) then local id = if itemId ~= "" then SlotGrid.resolveItemIcon(itemId) else "" icon.Image = id icon.Visible = id ~= "" + -- A pin without a backing stack is inert (the server refuses to use/equip it) — show it + -- dimmed, the same 0.45 "can't afford" convention the Crafting tab uses. + icon.ImageTransparency = if itemId ~= "" and qty <= 0 then 0.45 else 0 end local count = slot:FindFirstChild("Count") if count and count:IsA("TextLabel") then - local qty = totalQty(itemId) count.Text = if qty > 1 then tostring(qty) else "" count.Visible = qty > 1 end diff --git a/src/init.luau b/src/init.luau index 0b1a3d9..a140ea2 100644 --- a/src/init.luau +++ b/src/init.luau @@ -65,7 +65,7 @@ require(script.shared.LootBagsConfig) local SurvivorCore = {} -SurvivorCore.VERSION = "0.7.0" +SurvivorCore.VERSION = "0.7.1" -- Foundation SurvivorCore.Config = Config diff --git a/src/systems/ToolEquip.luau b/src/systems/ToolEquip.luau index abba77e..4b83d83 100644 --- a/src/systems/ToolEquip.luau +++ b/src/systems/ToolEquip.luau @@ -20,6 +20,7 @@ local RunService = game:GetService("RunService") assert(RunService:IsServer(), "SurvivorCore.ToolEquip is server-only — require it via SurvivorCore.start()") local Registries = require(script.Parent.Parent.registries) +local Inventory = require(script.Parent.Inventory) local InventoryTypes = require(script.Parent.Parent.shared.InventoryTypes) local ToolEquip = {} @@ -119,6 +120,12 @@ local function refresh(player: Player) local def = itemId ~= "" and Registries.Items.get(itemId) or nil local toolType = def and def.toolType + -- Possession gate: a pin is only a POINTER — never equip an item the player doesn't actually + -- carry (a stale/seeded pin without a backing stack would otherwise conjure a ghost tool). + if toolType and Inventory.getQty(player, itemId) <= 0 then + toolType = nil + end + -- Already holding the right tool? Leave it (avoids re-equip flicker on a re-press). local held = currentEngineTool(player) if toolType and held and held:GetAttribute("_ItemId") == itemId then diff --git a/wally.toml b/wally.toml index 75149d9..c73bfb9 100644 --- a/wally.toml +++ b/wally.toml @@ -1,7 +1,7 @@ [package] name = "temujincalidius/survivorcore" description = "Batteries-included, creator-extensible survival game framework for Roblox." -version = "0.7.0" +version = "0.7.1" license = "MIT" authors = ["Samuel Lison"] registry = "https://github.com/UpliftGames/wally-index"