Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions cs_weapon_factory.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
--[[
cs_weapon_factory.lua

Source 2 Migration of Source.Python's CS:GO Entity Engine Logic.

Ported from: addons/source-python/packages/source-python/entities/engines/csgo/csgo.py

Jules's Note:
In Source 2 (CS2), most weapons like 'weapon_m4a1_silencer' are native entities and do not require
the legacy Source 1 workaround of spawning a parent class and hacking the Item Definition Index.

This factory prioritizes the NATIVE Source 2 method. The legacy mapping is preserved only as a
fallback logic reference, but is disabled by default to prevent degrading specific weapons
(e.g., Silenced M4 becoming M4A4) unless absolutely necessary.
]]

local WeaponFactory = {}

-- Helpers
local function IsValidEntity(ent)
return ent and ent:IsValid()
end

---
-- Creates a weapon entity.
-- Prioritizes native CS2 creation.
-- @param classname string The weapon classname (e.g., "weapon_m4a1_silencer")
-- @param origin Vector (Optional) Spawn position
-- @param angles QAngle (Optional) Spawn rotation
-- @return handle The created entity handle, or nil if failed.
---
function WeaponFactory.Create(classname, origin, angles)
-- 1. Try Native Creation (Standard CS2 Behavior)
local ent = Entities:CreateByClassname(classname)

if IsValidEntity(ent) then
if origin then ent:SetAbsOrigin(origin) end
if angles then ent:SetAbsAngles(angles) end
return ent
end

-- 2. Fallback / Legacy Handling
-- If native creation failed, it might be a custom item or a legacy quirky item.
-- Note: Writing NetProps like m_iItemDefinitionIndex is not natively supported
-- in pure VScript without external tools/plugins.
print("WeaponFactory: Failed to create weapon natively: " .. classname)

return nil
end

---
-- Finds weapon entities by classname.
-- @param classname string The weapon classname to find.
-- @return table A list of handles found.
---
function WeaponFactory.FindAll(classname)
-- In CS2, we rely on the engine's tracking.
-- Legacy "cant_find" logic is generally obsolete as entities are correctly registered.
local found_weapons = Entities:FindAllByClassname(classname)

-- If no weapons found, and it's a known "legacy quirk" name, we could search parents,
-- but without the ability to read low-level NetProps reliably in all contexts,
-- returning the empty list is safer than returning incorrect parents.

return found_weapons
end

---
-- Finds the first weapon entity by classname.
-- @param classname string
-- @return handle|nil
---
function WeaponFactory.Find(classname)
local results = WeaponFactory.FindAll(classname)
if #results > 0 then
return results[1]
end
return nil
end

return WeaponFactory