static public void CheckDamageLocation(Ped p) { try { List <Bone> damagedBones = DamageBitFlags.PedGetAllDamagedBones(p); List <string> damagedBonesInHuman = damagedBones.Select(b => boneToNameMap[b]).ToList(); Dictionary <string, int> aggregateDamagedBones = new Dictionary <string, int>(); damagedBonesInHuman.ForEach(d => { if (aggregateDamagedBones.ContainsKey(d)) { aggregateDamagedBones[d]++; } else { aggregateDamagedBones[d] = 1; } }); List <string> result = new List <string>(); damagedBonesInHuman.ForEach(d => { if (aggregateDamagedBones[d] > 1) { result.Add($"multiple instances of damage to the {d}"); } else { result.Add($"damage to the {d}"); } }); if (aggregateDamagedBones.Count() > 0) { BaseScript.TriggerEvent("Chat.Message", "", "#AABB88", $"You see {String.Join(",", result)}."); } else { BaseScript.TriggerEvent("Chat.Message", "", "#AABB88", $"There is no damage that is clearly visible to you at the moment."); } } catch (Exception ex) { Log.Error($"PedDamage CheckDamageLocation Error: {ex.Message}"); } }
static public void CheckWeaponSources(Ped p) { try { List <WeaponHash> weaponDamageTypes = DamageBitFlags.PedGetAllWeaponDamageTypes(p); if (weaponDamageTypes.Count > 0) { BaseScript.TriggerEvent("Chat.Message", "", "#AABB88", $"You see damage that was probably caused by weapons such as: {String.Join(",", weaponDamageTypes.Select(w => w.ToString().AddSpacesToCamelCase()))}."); } else { BaseScript.TriggerEvent("Chat.Message", "", "#AABB88", $"There is no damage that is clearly visible to you at the moment."); } } catch (Exception ex) { Log.Error($"PedDamage CheckWeaponSources Error: {ex.Message}"); } }
static async Task PeriodicDamageCheck() { while (true) { try { //if (Function.Call<bool>(Hash.HAS_PLAYER_DAMAGED_AT_LEAST_ONE_PED, Game.Player.Handle)) //{ // //Log.ToChat($"{Function.Call<bool>(Hash.HAS_PLAYER_DAMAGED_AT_LEAST_ONE_PED, Game.Player.Handle)} {(NearbyPeds != null ? NearbyPeds.Count : 0)}"); // Function.Call(Hash.CLEAR_PLAYER_HAS_DAMAGED_AT_LEAST_ONE_PED, Game.Player.Handle); //} if (NearbyPeds != null) { NearbyPeds.ForEach(p => { if (p.Health < p.MaxHealth) { if (!Function.Call <bool>(Hash.HAS_ENTITY_BEEN_DAMAGED_BY_ANY_PED, p.Handle) && !Function.Call <bool>(Hash.HAS_ENTITY_BEEN_DAMAGED_BY_ANY_VEHICLE, p.Handle) /* && !(Game.PlayerPed.IsInVehicle() && Game.PlayerPed.CurrentVehicle.Driver == Game.PlayerPed && Function.Call<bool>(Hash.HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY, p.Handle, Game.PlayerPed.CurrentVehicle.Handle)))*/) { //Log.ToChat("Not by me?"); return; } else { //Log.ToChat("Damaged ped!"); if (Function.Call <bool>(Hash.HAS_ENTITY_BEEN_DAMAGED_BY_ANY_VEHICLE, p.Handle)) { //Log.ToChat("VEHICLE"); IncrementPedFlag(p, "Damage.Vehicle"); if (p.IsDead) { Log.ToChat("VEHICLE KILLER"); Function.Call(Hash.DECOR_SET_INT, p.Handle, "Damage.KillerCategory", KillerCategory.Vehicle); } } else { //Log.ToChat(":( NO VEHICLE"); } if (p.IsDead) { Entity killer = Entity.FromHandle(Function.Call <int>(Hash.GET_PED_SOURCE_OF_DEATH, p.Handle)); if (killer.Exists()) { if ((PedHash)killer.Model.Hash == PedHash.MountainLion) { Log.ToChat("MOUNTAIN LION KILLER"); Function.Call(Hash.DECOR_SET_INT, p.Handle, "Damage.KillerCategory", KillerCategory.MountainLion); } } } PedBone LastDamagedBone = p.Bones.LastDamaged; OutputArgument outBone = new OutputArgument(); Function.Call <bool>(Hash.GET_PED_LAST_DAMAGE_BONE, p.Handle, outBone); //Log.ToChat($"{(Bone)outBone.GetResult<int>()}"); DamageBitFlags.SetPedBoneFlag(p, (Bone)outBone.GetResult <int>()); Enum.GetValues(typeof(WeaponHash)).OfType <WeaponHash>().ToList().ForEach(w => { if (Function.Call <bool>(Hash.HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON, p.Handle, (int)w, 0)) { //Log.ToChat($"{w}"); switch (Function.Call <int>(Hash.GET_WEAPON_DAMAGE_TYPE, (int)w)) { case 2: // Melee if (SharpMeleeWeapons.Contains(w)) { IncrementPedFlag(p, "Damage.Melee.Sharp"); } else { IncrementPedFlag(p, "Damage.Melee.Blunt"); } break; case 3: // Projectile Weapon IncrementPedFlag(p, "Damage.Projectile"); break; case 13: // Gasoline? IncrementPedFlag(p, "Damage.Gas"); break; default: break; } DamageBitFlags.SetPedWeaponFlag(p, w); //Log.ToChat($"{w} Type: {Function.Call<int>(Hash.GET_WEAPON_DAMAGE_TYPE, (int)w)}"); } }); p.Bones.ClearLastDamaged(); Function.Call(Hash.CLEAR_ENTITY_LAST_DAMAGE_ENTITY, p.Handle); p.ClearLastWeaponDamage(); //var builder = new StringBuilder(); //builder.AppendLine($"Damaged by weapons: {String.Join(", ", DamageBitFlags.PedGetAllWeaponDamageTypes(p))}"); //builder.AppendLine($"Damaged in bones: {String.Join(", ", DamageBitFlags.PedGetAllDamagedBones(p))}"); //builder.AppendLine($"Hit by vehicle: {Function.Call<int>(Hash.DECOR_GET_INT, p.Handle, "Damage.Vehicle")}"); //builder.AppendLine($"Shot: {Function.Call<int>(Hash.DECOR_GET_INT, p.Handle, "Damage.Projectile")}"); //builder.AppendLine($"Beaten: {Function.Call<int>(Hash.DECOR_GET_INT, p.Handle, "Damage.Melee.Blunt")}"); //builder.AppendLine($"Cut: {Function.Call<int>(Hash.DECOR_GET_INT, p.Handle, "Damage.Melee.Sharp")}"); //builder.AppendLine($"Gas damage: {Function.Call<int>(Hash.DECOR_GET_INT, p.Handle, "Damage.Gas")}"); //Log.ToChat(builder.ToString()); } } }); } } catch (Exception ex) { Log.Error($"PedDamage PeriodicDamageCheck Error: {ex.Message}"); } await BaseScript.Delay(100); } }