--[[ | This file was obtained through the combined efforts | of Madbluntz & Plymouth Antiquarian Society. | | Credits: lifestorm, Gregory Wayne Rossel JR., | Maloy, DrPepper10 @ RIP, Atle! | | Visit for more: https://plymouth.thetwilightzone.ru/ --]] local PLUGIN = PLUGIN ITEM.name = "ArcCW Weapons" ITEM.base = "base_weapons" ITEM.description = "A Weapon." ITEM.category = "Weapons" ITEM.model = "models/weapons/w_pistol.mdl" ITEM.class = "weapon_pistol" ITEM.width = 2 ITEM.height = 2 ITEM.isWeapon = true ITEM.isGrenade = false ITEM.weaponCategory = "sidearm" ITEM.useSound = "items/ammo_pickup.wav" ITEM.defaultAttachments = {} local color_green = Color(100, 255, 100) local color_red = Color(200, 25, 25) function ITEM:GetDescription() local description = {self.description} return table.concat(description, "") end if (CLIENT) then function ITEM:PaintOver(item, w, h) local shotsBeforeBreak = ITEM.shotsBeforeBreak or ix.config.Get("shotsBeforeBreakingWeapon", 900) local shotsFired = item:GetShotsFired() local width = w - 8 local durLerp = 1 - (shotsFired / shotsBeforeBreak) local color = ix.util.ColorLerp(durLerp, color_red, color_green) surface.SetDrawColor(color) surface.DrawRect(5, h - 8, width * durLerp, 4) end end function ITEM:GetBaseInfo() local baseInfo = {} if (self.balanceCat) then baseInfo[#baseInfo + 1] = "Cartégorie d'arme: " baseInfo[#baseInfo + 1] = self.balanceCat if (self.isMelee) then baseInfo[#baseInfo + 1] = " Mélée" end if (CLIENT) then baseInfo[#baseInfo + 1] = "\nChance de coup critique: " if (self.isMelee) then baseInfo[#baseInfo + 1] = math.max(math.floor(ix.weapons:GetMeleeWeaponBaseHitChance(LocalPlayer():GetCharacter(), self.class) * ix.weapons:GetWeaponAimPenalty(self.class) * 100), 0) else baseInfo[#baseInfo + 1] = math.floor(ix.weapons:GetWeaponSkillMod(LocalPlayer():GetCharacter(), self.class) * ix.weapons:GetWeaponAimPenalty(self.class) * 100) end baseInfo[#baseInfo + 1] = "%%" end end return table.concat(baseInfo, "") end function ITEM:GetExtendedInfo() local extendedInfo = {} if (self.balanceCat) then if (self.isMelee) then extendedInfo[#extendedInfo + 1] = "Dégats: " extendedInfo[#extendedInfo + 1] = ix.weapons:GetMeleeWeaponBaseDamage(self.class) else extendedInfo[#extendedInfo + 1] = "Dégats: " extendedInfo[#extendedInfo + 1] = ix.weapons:GetWeaponBaseDamage(self.class) local min, max, bFlat = ix.weapons:GetWeaponSkillRequired(self.class) if (!bFlat) then extendedInfo[#extendedInfo + 1] = "\nSkill range: " extendedInfo[#extendedInfo + 1] = min.."-"..max else extendedInfo[#extendedInfo + 1] = "\nSkill required: " extendedInfo[#extendedInfo + 1] = min end local minR, effR = ix.weapons:GetWeaponEffectiveRanges(self.class) extendedInfo[#extendedInfo + 1] = "\nMinimum effective range: " extendedInfo[#extendedInfo + 1] = minR.."m" extendedInfo[#extendedInfo + 1] = "\nMaximum effective range: " extendedInfo[#extendedInfo + 1] = effR.."m" extendedInfo[#extendedInfo + 1] = "\nShots per action point: " extendedInfo[#extendedInfo + 1] = ix.weapons:GetWeaponNumShots(self.class) extendedInfo[#extendedInfo + 1] = "\nArmor Penetration: " extendedInfo[#extendedInfo + 1] = math.floor(ix.weapons:GetArmorPen(self.class) * 100).."%%" end end return table.concat(extendedInfo, "") end function ITEM:GetMagazineInfo() if (!self.magazines or table.IsEmpty(self.magazines)) then return "Cette arme n'a pas de chargeur mis en place, signalez ce bug merci!." end local magInfo = {} for mag in pairs(self.magazines) do local itemTable = ix.item.list[mag] if (itemTable) then magInfo[#magInfo + 1] = itemTable:GetName() else magInfo[#magInfo + 1] = mag end end return "Chargeur: "..table.concat(magInfo, ", ") end function ITEM:GetColorAppendix() local info = {["green"] = self:GetMagazineInfo()} if self.balanceCat then info["blue"] = self:GetBaseInfo() info["red"] = self:GetExtendedInfo() end return info end function ITEM:OnRegistered() if (self.balanceCat and ix.weapons) then if (self.isMelee) then ix.weapons:RegisterMeleeWeapon(self.class, self.balanceCat) else ix.weapons:RegisterWeapon(self.class, self.balanceCat) end ix.weapons:RegisterWeaponExceptions(self.class, self.baseDamage, self.armorPen, self.aimPenalty, self.numShots) end if (self.OnRegistered2) then self:OnRegistered2() end end function ITEM.EquipAttachment(client, weapon, slot, attachment) client.ixAttachWeapon = weapon weapon:Attach(slot, attachment, true) client.ixAttachWeapon = nil end function ITEM:OnEquipWeapon(client, weapon) weapon:SetNetVar("ixItemID", weapon.ixItem:GetID()) local oldPrimaryAttack = weapon.PrimaryAttack weapon.PrimaryAttack = function(s) oldPrimaryAttack(s) if !self:GetData("broken", false) then local shotData = self:GetData("FiredShots", 0) self:SetData("FiredShots", shotData + 1) self:OnShotFired(shotData + 1, s, client) end end if (self:GetData("BioLocked") or self:GetData("WeaponAttachments") or !table.IsEmpty(self.defaultAttachments)) then timer.Simple(0.5, function() if (!IsValid(weapon)) then return end weapon:SetNWBool("ArcCW_DisableAutosave", true) weapon:SetNetVar("ixItemDefaultWeaponAtts", self.defaultAttachments) for _, v in pairs(self.defaultAttachments) do if (self:GetData("WeaponDefaultAttachmentsUnequipped", {})[v.attachment]) then continue end self.EquipAttachment(client, weapon, v.slot, v.attachment) end if (self:GetData("WeaponAttachments")) then for _, v in pairs(self:GetData("WeaponAttachments")) do if (istable(v) and v.attachment) then self.EquipAttachment(client, weapon, v.slot, v.attachment) end end end if (self:GetData("BioLocked")) then weapon:SetNetVar("BioLocked", true) end end) end end function ITEM:GetShotsFired() return self:GetData("FiredShots", 0) end function ITEM:OnShotFired(shotsFired, weapon, client) if ITEM.shotsBeforeBreak and shotsFired > ITEM.shotsBeforeBreak or shotsFired > ix.config.Get("shotsBeforeBreakingWeapon", 900) then self:BreakWeapon(client) end end function ITEM:BreakWeapon(client) self:SetData("broken", true) self:Unequip(client) client:EmitSound("physics/metal/metal_sheet_impact_bullet1.wav") end function ITEM:OnUnequipWeapon(client, weapon) weapon:SetNetVar("ixItemID", nil) if (self:GetData("reloadMagazineItem")) then local chamber = math.Clamp(weapon:Clip1(), 0, weapon:GetChamberSize()) PLUGIN:RefundAmmoItem(weapon, client:GetCharacter(), self:GetData("reloadMagazineItem"), weapon:Clip1() + client:GetAmmoCount(weapon:GetPrimaryAmmoType()) - chamber, self:GetData("reloadMagazineInvPos")) self:SetData("ammo", chamber) self:SetData("reloadMagazineItem", nil) client:SetAmmo(0, weapon:GetPrimaryAmmoType()) end end if (SERVER) then ix.log.AddType("potentialMagExploitAbuse", function(client, item, ammoToRefund) return string.format("%s is removing a mag while reloading: Item ID: #(%d) Ammo: %s", client:GetName(), item:GetID(), ammoToRefund) end, FLAG_DANGER) end ITEM.functions.repairWeapon = { name = "Réparer l'arme", icon = "icon16/bullet_wrench.png", OnRun = function(item) local client = item.player local character = client:GetCharacter() local inv = character:GetInventory() local repairKit = inv:HasItem("weapon_repair_kit") if (!repairKit) then client:NotifyLocalized("Vous n'avez pas un kit de réparation d'arme!") return false end client:EmitSound("willardnetworks/skills/skill_medicine.wav") repairKit:DamageDurability(1) item:SetData("FiredShots", 0) item:SetData("broken", false) return false end, OnCanRun = function(item) local client = item.player if (IsValid(item.entity) or !IsValid(item:GetOwner())) then return false end if (!IsValid(client)) then return false end local character = client:GetCharacter() local inv = character:GetInventory() local repairKit = inv:HasItem("weapon_repair_kit") if (!repairKit) then return false end return true end } ITEM.functions.removeMag = { name = "Retirer chargeur", OnRun = function(item, data) local client = item:GetOwner() for k, v in pairs(client:GetWeapons()) do if (v:GetClass() == item.class) then local chamber = math.Clamp(v:Clip1(), 0, v:GetChamberSize()) local ammoToRefund = v:Clip1() + client:GetAmmoCount(v:GetPrimaryAmmoType()) - chamber ix.log.Add(client, "potentialMagExploitAbuse", item, ammoToRefund) PLUGIN:RefundAmmoItem(v, client:GetCharacter(), item:GetData("reloadMagazineItem"), ammoToRefund, item:GetData("reloadMagazineInvPos")) item:SetData("reloadMagazineItem", nil) v:SetClip1(chamber) item:SetData("ammo", chamber) return false end end return false end, OnCanRun = function(item) if (IsValid(item.entity) or !IsValid(item:GetOwner())) then return false end if (!item:GetData("equip") or !item:GetData("reloadMagazineItem")) then return false end for k, v in pairs(item:GetOwner():GetWeapons()) do if (v:GetClass() == item.class) then return true end end return false end } ITEM.functions.clearChamber = { name = "Clear Chamber", OnRun = function(item, data) local ammoItem = ix.item.list[next(item.magazines)] local inventory = ix.item.inventories[item.invID] local amount = item:GetData("ammo", 0) if (!inventory:Add(ammoItem.bullets, 1, {stack = amount, bIsSplit = true})) then ix.item.Spawn(uniqueID, item.player, function(itemT) itemT:SetStack(amount) end) end item:SetData("ammo", chamber) return false end, OnCanRun = function(item) if (IsValid(item.entity) or !IsValid(item:GetOwner())) then return false end if (item:GetData("ammo", 0) <= 0) then return false end if (!item.magazines) then return false end local ammoItem = ix.item.list[next(item.magazines)] if (!ammoItem or !ammoItem.bullets) then return false end if (item:GetData("equip")) then return false end local inventory = ix.item.inventories[item.invID] if (!inventory) then return false end return true end }