local HEAL_METAL_CONSUMPTION_RATIO = 3 local HEAL_AMOUNT_MAX = 102 local function getEyeAngles(player) local pitch = player["m_angEyeAngles[0]"] local yaw = player["m_angEyeAngles[1]"] return Vector(pitch, yaw, 0) end function WrenchSwung(_, activator) if not util.IsLagCompensationActive() then util.StartLagCompensation(activator) end local trace = { start = activator, -- Start position vector. Can also be set to entity, in this case the trace will start from entity eyes position endpos = nil, -- End position vector. If nil, the trace will be fired in `angles` direction with `distance` length distance = 100, -- Used if endpos is nil angles = getEyeAngles(activator), -- Used if endpos is nil mask = MASK_SOLID, -- Solid type mask, see MASK_* globals collisiongroup = COLLISION_GROUP_PLAYER, -- Pretend the trace to be fired by an entity belonging to this group. See COLLISION_GROUP_* globals -- (royal): filter causes a crash -- filter = function(target) -- print(target) -- if not IsBotABuiltBot(target) then -- return false -- end -- return true -- end, -- Entity to ignore. If nil, filters start entity. Can be a single entity, table of entities, or a function with a single entity parameter that returns true if trace should hit the entity, false otherwise. filter = nil, } local result = util.Trace(trace) util.FinishLagCompensation(activator) if not result then return end local hitBot = result.Entity if not hitBot then return end if not IsValid(hitBot) or not hitBot:IsPlayer() or (hitBot.m_iTeamNum ~= activator.m_iTeamNum) then return end if not IsBotABuiltBot(hitBot) then return end if hitBot.Constructing then hitBot.HasConstructionBoost = true activator:PlaySoundToSelf("Weapon_Wrench.HitBuilding_Success") return end local oldMetal = activator.m_iAmmo[4] local metal = oldMetal local healAmount = HEAL_AMOUNT_MAX local maxPossibleMetalConsumption = math.floor(HEAL_AMOUNT_MAX / HEAL_METAL_CONSUMPTION_RATIO) if maxPossibleMetalConsumption > metal then healAmount = metal * HEAL_METAL_CONSUMPTION_RATIO * activator:GetAttributeValueByClass("mult_repair_value", 1) end local currentHealth = hitBot.m_iHealth local maxHealth = hitBot.m_iMaxHealth if currentHealth + healAmount > maxHealth then healAmount = maxHealth - currentHealth if healAmount < 0 then healAmount = 0 end end local metalConsumption = math.floor(healAmount / HEAL_METAL_CONSUMPTION_RATIO) metal = metal - metalConsumption if metal < 0 then metal = 0 end local metalLost = oldMetal - metal if hitBot.m_iHealth < maxHealth and metalLost > 0 then activator:PlaySoundToSelf("Weapon_Wrench.HitBuilding_Success") activator.m_iAmmo[4] = metal else activator:PlaySoundToSelf("Weapon_Wrench.HitBuilding_Failure") end if hitBot.m_iHealth > maxHealth then hitBot.m_iHealth = maxHealth end hitBot.m_iHealth = hitBot.m_iHealth + healAmount local melee = activator:GetPlayerItemBySlot(LOADOUT_POSITION_MELEE) local takeDamageInfo = { Attacker = activator, -- Attacker Inflictor = melee, -- Direct cause of damage, usually a projectile Weapon = melee, Damage = -healAmount, DamageType = DMG_BULLET, -- Damage type, see DMG_* globals. Can be combined with | operator DamageCustom = TF_DMG_CUSTOM_NONE, -- Custom damage type, see TF_DMG_* globals DamagePosition = hitBot:GetAbsOrigin(), -- Where the target was hit at DamageForce = Vector(0, 0, 0), -- Knockback force of the attack ReportedPosition = activator:GetAbsOrigin(), -- Where the attacker attacked from } hitBot:TakeDamage(takeDamageInfo) FireEvent("player_healed", { patient = hitBot:GetUserId(), healer = activator:GetUserId(), amount = healAmount, }) end