Skip to content

Instantly share code, notes, and snippets.

@Pho3niX90
Created February 8, 2020 06:41
Show Gist options
  • Select an option

  • Save Pho3niX90/02aa0ffb126507b2a0c14315630bd57f to your computer and use it in GitHub Desktop.

Select an option

Save Pho3niX90/02aa0ffb126507b2a0c14315630bd57f to your computer and use it in GitHub Desktop.
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Linq;
// oxide 5.2
namespace Oxide.Plugins {
[Info("Death Messages", "QUETE", "2.1.55")]
class DeathMessages : RustPlugin {
private static PluginConfig _config;
private string version = "2.1.55";
private List<DeathMessage> _notes = new List<DeathMessage>();
private Dictionary<ulong, HitInfo> _lastHits = new Dictionary<ulong, HitInfo>();
#region Classes / Enums
class PluginConfig {
[JsonProperty("A. Время показа сообщения (сек)")]
public int Cooldown { get; set; }
[JsonProperty("B. Размер текста")]
public int FontSize { get; set; }
[JsonProperty("C. Показывать убиства животных")]
public bool ShowDeathAnimals { get; set; }
[JsonProperty("D. Показывать убийства спящих")]
public bool ShowDeathSleepers { get; set; }
[JsonProperty("E. Хранение логов")]
public bool Log { get; set; }
[JsonProperty("F. Цвет атакующего")]
public string ColorAttacker { get; set; }
[JsonProperty("G. Цвет убитого")]
public string ColorVictim { get; set; }
[JsonProperty("H. Цвет оружия")]
public string ColorWeapon { get; set; }
[JsonProperty("I. Цвет дистанции")]
public string ColorDistance { get; set; }
[JsonProperty("J. Цвет части тела")]
public string ColorBodyPart { get; set; }
[JsonProperty("K. Дистанция")]
public double Distance { get; set; }
[JsonProperty("L. Название вертолета")]
public string HelicopterName { get; set; }
[JsonProperty("M. Название Bradlay (Танк)")]
public string BradleyAPCName { get; set; }
[JsonProperty("N. Имя NPC")]
public string NPCName { get; set; }
[JsonProperty("O. Имя Zombie")]
public string ZombieName { get; set; }
[JsonProperty("P. Nombre del Cientifio")]
public string ScientistName { get; set; }
[JsonProperty("Оружие")]
public Dictionary<string, string> Weapons { get; set; }
[JsonProperty("Конструкции")]
public Dictionary<string, string> Structures { get; set; }
[JsonProperty("Ловушки")]
public Dictionary<string, string> Traps { get; set; }
[JsonProperty("Турели")]
public Dictionary<string, string> Turrets { get; set; }
[JsonProperty("Животные")]
public Dictionary<string, string> Animals { get; set; }
[JsonProperty("Сообщения")]
public Dictionary<string, string> Messages { get; set; }
[JsonProperty("Части тела")]
public Dictionary<string, string> BodyParts { get; set; }
}
enum AttackerType {
Player,
Helicopter,
Animal,
Turret,
Guntrap,
Structure,
Trap,
Invalid,
Scientist,
NPC,
BradleyAPC,
Zombie,
ZombieDeath
}
enum VictimType {
Player,
Helicopter,
Animal,
Invalid,
NPC,
BradleyAPC,
Zombie,
Scientist,
ZombieDeath
}
enum DeathReason {
Turret,
Guntrap,
Helicopter,
HelicopterDeath,
BradleyAPC,
BradleyAPCDeath,
Structure,
Trap,
Animal,
AnimalDeath,
Generic,
Zombie,
ZombieDeath,
Hunger,
Scientist,
ScientistDeath,
Thirst,
Cold,
Drowned,
Heat,
Bleeding,
Poison,
Suicide,
Bullet,
Arrow,
Flamethrower,
Slash,
Blunt,
Fall,
Radiation,
Stab,
Explosion,
Unknown
}
class Attacker {
public Attacker(BaseEntity entity) {
Entity = entity;
Type = InitializeType();
Name = InitializeName();
}
public BaseEntity Entity { get; }
public string Name { get; }
public AttackerType Type { get; }
private AttackerType InitializeType() {
if (Entity == null)
return AttackerType.Invalid;
if (Entity.name.Contains("machete.weapon"))
return AttackerType.Zombie;
if (Entity is NPCMurderer)
return AttackerType.ZombieDeath;
if (Entity is NPCPlayer)
return AttackerType.NPC;
if (Entity is Scientist)
return AttackerType.Scientist;
if (Entity is BasePlayer)
return AttackerType.Player;
if (Entity is BaseHelicopter)
return AttackerType.Helicopter;
if (Entity is BradleyAPC)
return AttackerType.BradleyAPC;
if (Entity.name.Contains("agents/"))
return AttackerType.Animal;
if (Entity.name.Contains("barricades/") || Entity.name.Contains("wall.external.high"))
return AttackerType.Structure;
if (Entity.name.Contains("beartrap.prefab") || Entity.name.Contains("landmine.prefab") || Entity.name.Contains("spikes.floor.prefab"))
return AttackerType.Trap;
if (Entity.name.Contains("autoturret_deployed.prefab") || Entity.name.Contains("flameturret.deployed.prefab"))
return AttackerType.Turret;
if (Entity.name.Contains("guntrap_deployed.prefab") || Entity.name.Contains("guntrap.deployed.prefab"))
return AttackerType.Guntrap;
return AttackerType.Invalid;
}
private string InitializeName() {
if (Entity == null)
return null;
switch (Type) {
case AttackerType.Player:
return Entity.ToPlayer().displayName;
case AttackerType.NPC:
return string.IsNullOrEmpty(Entity.ToPlayer()?.displayName) ? _config.NPCName : Entity.ToPlayer()?.displayName;
case AttackerType.Scientist:
return string.IsNullOrEmpty(Entity.ToPlayer()?.displayName) ? _config.ScientistName : Entity.ToPlayer()?.displayName;
case AttackerType.Helicopter:
return "Patrol Helicopter";
case AttackerType.BradleyAPC:
case AttackerType.Turret:
case AttackerType.Guntrap:
case AttackerType.Trap:
case AttackerType.Animal:
case AttackerType.Structure:
return FormatName(Entity.name);
}
return string.Empty;
}
}
class Victim {
public Victim(BaseCombatEntity entity) {
Entity = entity;
Type = InitializeType();
Name = InitializeName();
}
public BaseCombatEntity Entity { get; }
public string Name { get; }
public VictimType Type { get; }
private VictimType InitializeType() {
if (Entity is NPCMurderer)
return VictimType.Zombie;
if (Entity.name.Contains("machete.weapon"))
return VictimType.Zombie;
if (Entity.name.Contains("scientist/"))
return VictimType.Scientist;
if (Entity == null)
return VictimType.Invalid;
if (Entity is NPCPlayer)
return VictimType.NPC;
if (Entity is Scientist)
return VictimType.Scientist;
if (Entity is BasePlayer)
return VictimType.Player;
// if (Entity is BaseHelicopter)
// return VictimType.Helicopter;
if (Entity is BradleyAPC)
return VictimType.BradleyAPC;
if (Entity.name.Contains("patrolhelicopter.prefab") && !Entity.name.Contains("gibs"))
return VictimType.Helicopter;
if (Entity.name.Contains("agents/"))
return VictimType.Animal;
return VictimType.Invalid;
}
private string InitializeName() {
switch (Type) {
case VictimType.Zombie:
return "ZombieName";
case VictimType.Player:
return Entity.ToPlayer().displayName;
case VictimType.NPC:
return string.IsNullOrEmpty(Entity.ToPlayer()?.displayName) ? _config.NPCName : Entity.ToPlayer()?.displayName;
case VictimType.Helicopter:
return "HelicopterName";
case VictimType.Scientist:
return string.IsNullOrEmpty(Entity.ToPlayer()?.displayName) ? _config.ScientistName : Entity.ToPlayer()?.displayName;
case VictimType.BradleyAPC:
return "BradleyAPCName";
case VictimType.Animal:
return FormatName(Entity.name);
}
return string.Empty;
}
}
class DeathMessage {
public DeathMessage(Attacker attacker, Victim victim, string weapon, string damageType, string bodyPart, double distance) {
Attacker = attacker;
Victim = victim;
Weapon = weapon;
DamageType = damageType;
BodyPart = bodyPart;
Distance = distance;
Reason = InitializeReason();
Message = InitializeDeathMessage();
if (_config.Distance <= 0) {
Players = BasePlayer.activePlayerList;
} else {
var position = attacker?.Entity?.transform?.position;
if (position == null)
position = victim?.Entity?.transform?.position;
Players = new ListHashSet<BasePlayer>();
if (position != null) {
Players.Clear();
foreach (BasePlayer activePlayer in BasePlayer.activePlayerList) {
if (activePlayer.Distance((UnityEngine.Vector3)position) <= _config.Distance)
Players.Add(activePlayer);
}
}
}
if (victim.Type == VictimType.Player && !Players.Contains(victim.Entity.ToPlayer()))
Players.Add(victim.Entity.ToPlayer());
if (attacker.Type == AttackerType.Player && !Players.Contains(attacker.Entity.ToPlayer()))
Players.Add(attacker.Entity.ToPlayer());
}
public ListHashSet<BasePlayer> Players { get; }
public Attacker Attacker { get; }
public Victim Victim { get; }
public string Weapon { get; }
public string BodyPart { get; }
public string DamageType { get; }
public double Distance { get; }
public DeathReason Reason { get; }
public string Message { get; }
private DeathReason InitializeReason() {
//if (Victim.Type == VictimType.Helicopter)
// return DeathReason.HelicopterDeath;
if (Victim.Type == VictimType.Helicopter)
return DeathReason.HelicopterDeath;
else if (Attacker.Type == AttackerType.Turret)
return DeathReason.Turret;
else if (Attacker.Type == AttackerType.Guntrap)
return DeathReason.Guntrap;
else if (Attacker.Type == AttackerType.Zombie)
return DeathReason.Zombie;
else if (Attacker.Type == AttackerType.Helicopter)
return DeathReason.Helicopter;
else if (Attacker.Type == AttackerType.BradleyAPC)
return DeathReason.BradleyAPC;
else if (Victim.Type == VictimType.BradleyAPC)
return DeathReason.BradleyAPCDeath;
// else if (Victim.Type == VictimType.Scientist)
// return DeathReason.ScientistDeath;
// else if (Victim.Type == VictimType.Scientist)
// return DeathReason.Scientist;
else if (Attacker.Type == AttackerType.Structure)
return DeathReason.Structure;
else if (Attacker.Type == AttackerType.Trap)
return DeathReason.Trap;
else if (Attacker.Type == AttackerType.Animal)
return DeathReason.Animal;
else if (Victim.Type == VictimType.Animal)
return DeathReason.AnimalDeath;
else if (Weapon == "F1 Grenade" || Weapon == "Survey Charge" || Weapon == "Timed Explosive Charge" || Weapon == "Satchel Charge" || Weapon == "Beancan Grenade")
return DeathReason.Explosion;
else if (Weapon == "Flamethrower")
return DeathReason.Flamethrower;
else if (Victim.Type == VictimType.Player || Victim.Type == VictimType.NPC)
return GetDeathReason(DamageType);
else if (Victim.Type == VictimType.Player || Victim.Type == VictimType.Scientist)
return GetDeathReason(DamageType);
else if (Victim.Type == VictimType.Zombie)
return DeathReason.ZombieDeath;
return DeathReason.Unknown;
}
private DeathReason GetDeathReason(string damage) {
var reasons = (Enum.GetValues(typeof(DeathReason)) as DeathReason[]).Where(x => x.ToString().Contains(damage));
if (reasons.Count() == 0)
return DeathReason.Unknown;
return reasons.First();
}
private string InitializeDeathMessage() {
string message = string.Empty;
string reason = string.Empty;
if (Victim.Type == VictimType.Player && Victim.Entity.ToPlayer().IsSleeping() && _config.Messages.ContainsKey(Reason + " Sleeping"))
reason = Reason + " Sleeping";
else
reason = Reason.ToString();
message = GetMessage(reason, _config.Messages);
var attackerName = Attacker.Name;
if (string.IsNullOrEmpty(attackerName) && Attacker.Entity == null && Weapon.Contains("Heli"))
attackerName = _config.HelicopterName;
if (string.IsNullOrEmpty(attackerName) && Attacker.Entity == null && Weapon.Contains("Bradl"))
attackerName = _config.BradleyAPCName;
switch (Attacker.Type) {
case AttackerType.ZombieDeath:
attackerName = _config.ZombieName;
break;
case AttackerType.Zombie:
attackerName = _config.ZombieName;
break;
case AttackerType.Helicopter:
attackerName = _config.HelicopterName;
break;
case AttackerType.BradleyAPC:
attackerName = _config.BradleyAPCName;
break;
case AttackerType.NPC:
attackerName = _config.NPCName;
break;
case AttackerType.Turret:
attackerName = GetMessage(attackerName, _config.Turrets);
break;
case AttackerType.Guntrap:
attackerName = GetMessage(attackerName, _config.Turrets);
break;
case AttackerType.Trap:
attackerName = GetMessage(attackerName, _config.Traps);
break;
case AttackerType.Animal:
attackerName = GetMessage(attackerName, _config.Animals);
break;
case AttackerType.Structure:
attackerName = GetMessage(attackerName, _config.Structures);
break;
}
var victimName = Victim.Name;
switch (Victim.Type) {
case VictimType.Helicopter:
victimName = _config.HelicopterName;
break;
case VictimType.BradleyAPC:
victimName = _config.BradleyAPCName;
break;
case VictimType.NPC:
victimName = _config.NPCName;
break;
case VictimType.Scientist:
victimName = _config.ScientistName;
break;
case VictimType.Zombie:
victimName = _config.ZombieName;
break;
case VictimType.Animal:
victimName = GetMessage(victimName, _config.Animals);
break;
}
message = message.Replace("{attacker}", $"<color={_config.ColorAttacker}>{attackerName}</color>");
message = message.Replace("{victim}", $"<color={_config.ColorVictim}>{victimName}</color>");
message = message.Replace("{distance}", $"<color={_config.ColorDistance}>{Math.Round(Distance, 0)}</color>");
message = message.Replace("{weapon}", $"<color={_config.ColorWeapon}>{GetMessage(Weapon, _config.Weapons)}</color>");
message = message.Replace("{bodypart}", $"<color={_config.ColorBodyPart}>{GetMessage(BodyPart, _config.BodyParts)}</color>");
return message;
}
}
#endregion
#region Oxide Hooks
protected override void LoadDefaultConfig() {
Config.Clear();
Config.WriteObject(new PluginConfig {
Cooldown = 7,
FontSize = 15,
Distance = -1,
Log = true,
ShowDeathAnimals = true,
ShowDeathSleepers = true,
ColorAttacker = "#f0f223",
ColorVictim = "#f0f223",
ColorDistance = "#006ca9",
ColorWeapon = "#006ca9",
ColorBodyPart = "#006ca9",
ScientistName = "Cientifico",
HelicopterName = "Вертолет",
BradleyAPCName = "Танк",
NPCName = "НПЦ",
ZombieName = "Зомби",
Weapons = new Dictionary<string, string>
{
{ "Assault Rifle", "AKA-47" },
{ "Beancan Grenade", "Бобовая граната" },
{ "Nailgun", "Гвоздострел" },
{ "Bolt Action Rifle", "Снайперская винтовка" },
{ "Bone Club", "Костяная дубина" },
{ "Bone Knife", "Костяной нож" },
{ "Crossbow", "Арбалет" },
{ "Chainsaw", "Бензопила" },
{ "Compound Bow", "Блочный лук" },
{ "Flamethrower", "Огнемёт" },
{ "Explosivesatchel", "Сумка с зарядом" },
{ "Custom SMG", "SMG" },
{ "Double Barrel Shotgun", "Двухстволка" },
{ "Eoka Pistol", "Самодельный пистолет" },
{ "F1 Grenade", "F1-граната" },
{ "Hunting Bow", "Охотничий лук" },
{ "Longsword", "Длинный меч" },
{ "LR-300 Assault Rifle", "LR-300" },
{ "M249", "Пулемёт М249" },
{ "M92 Pistol", "Беретта M92" },
{ "Mace", "Булава" },
{ "Machete", "Мачете" },
{ "MP5A4", "MP5A4" },
{ "Jackhammer", "Отбойник" },
{ "Pump Shotgun", "Помповый дробовик" },
{ "Python Revolver", "Питон револьвер" },
{ "Revolver", "Револьвер" },
{ "Salvaged Cleaver", "Самодельный тесак" },
{ "Salvaged Sword", "Самодельный меч" },
{ "Semi-Automatic Pistol", "Полуавтоматический пистолет" },
{ "Semi-Automatic Rifle", "Полуавтоматическая винтовка" },
{ "Stone Spear", "Каменное копьё" },
{ "Spas-12 Shotgun", "Дробовик Spas-12" },
{ "Thompson", "Томпсон" },
{ "Waterpipe Shotgun", "Самодельный дробовик" },
{ "Wooden Spear", "Деревянное копьё" },
{ "Hatchet", "Топор" },
{ "Pick Axe", "Кирка" },
{ "Salvaged Axe", "Самодельный топор" },
{ "Salvaged Hammer", "Самодельный молот" },
{ "Salvaged Icepick", "Самодельный ледоруб" },
{ "Satchel Charge", "Сумка с зарядом" },
{ "Stone Hatchet", "Каменный топор" },
{ "Stone Pick Axe", "Каменная кирка" },
{ "Survey Charge", "Геологический заряд" },
{ "Timed Explosive Charge", "С4" },
{ "Torch", "Факел" },
{ "RocketSpeed", "Скоростная ракета" },
{ "Incendiary Rocket", "Зажигательная ракета" },
{ "Rocket", "Обычная ракета" },
{ "RocketHeli", "Напалм вертолёта" },
{ "RocketBradley", "Напалм танка" }
},
Structures = new Dictionary<string, string>
{
{ "Wooden Barricade", "Деревянная баррикада" },
{ "Barbed Wooden Barricade", "Колючая деревянная баррикада" },
{ "Metal Barricade", "Металлическая баррикада" },
{ "High External Wooden Wall", "Высокая внешняя деревянная стена" },
{ "High External Stone Wall", "Высокая внешняя каменная стена" },
{ "High External Wooden Gate", "Высокие внешние деревянные ворота" },
{ "High External Stone Gate", "Высокие внешние каменные ворота" }
},
Traps = new Dictionary<string, string>
{
{ "Snap Trap", "Капкан" },
{ "Land Mine", "Мина" },
{ "Wooden Floor Spikes", "Деревянные колья" }
},
Turrets = new Dictionary<string, string>
{
{ "Flame Turret", "Огнеметная турель" },
{ "Auto Turret", "Автотурель" },
{ "Guntrap", "Автодробовик" }
},
Animals = new Dictionary<string, string>
{
{ "Boar", "Кабан" },
{ "Horse", "Лошадь" },
{ "Wolf", "Волк" },
{ "Stag", "Олень" },
{ "Chicken", "Курица" },
{ "Bear", "Медведь" }
},
BodyParts = new Dictionary<string, string>
{
{ "body", "Тело" },
{ "pelvis", "Таз" },
{ "hip", "Бедро" },
{ "left knee", "Левое колено" },
{ "right knee", "Правое колено" },
{ "left foot", "Левая стопа" },
{ "right foot", "Правая стопа" },
{ "left toe", "Левый палец" },
{ "right toe", "Правый палец" },
{ "groin", "Пах" },
{ "lower spine", "Нижний позвоночник" },
{ "stomach", "Желудок" },
{ "chest", "Грудь" },
{ "neck", "Шея" },
{ "left shoulder", "Левое плечо" },
{ "right shoulder", "Правое плечо" },
{ "left arm", "Левая рука" },
{ "right arm", "Правая рука" },
{ "left forearm", "Левое предплечье" },
{ "right forearm", "Правое предплечье" },
{ "left hand", "Левая ладонь" },
{ "right hand", "Правая ладонь" },
{ "left ring finger", "Левый безымянный палец" },
{ "right ring finger", "Правый безымянный палец" },
{ "left thumb", "Левый большой палец" },
{ "right thumb", "Правый большой палец" },
{ "left wrist", "Левое запястье" },
{ "right wrist", "Правое запястье" },
{ "head", "Голова" },
{ "jaw", "Челюсть" },
{ "left eye", "Левый глаз" },
{ "right eye", "Правый глаз" }
},
Messages = new Dictionary<string, string>
{
{ "Arrow", "{attacker} убил {victim} ({weapon}, {distance} м.)" },
{ "Blunt", "{attacker} убил {victim} ({weapon})" },
{ "Bullet", "{attacker} убил {victim} ({weapon}, {distance} м.)" },
{ "Flamethrower", "{attacker} сжег заживо игрока {victim} ({weapon})" },
{ "Drowned", "{victim} утонул." },
{ "Explosion", "{attacker} взорвал игрока {victim} ({weapon})" },
{ "Fall", "{victim} разбился." },
{ "Generic", "Смерть забрала {victim} с собой." },
{ "Heat", "{victim} сгорел заживо." },
{ "Helicopter", "{attacker} прямым попаданием убил {victim}." },
{ "BradleyAPC", "{attacker} прямым попаданием убил {victim}." },
{ "BradleyAPCDeath", "{victim} был уничтожен игроком {attacker} ({weapon})" },
{ "HelicopterDeath", "{victim} был сбит игроком {attacker} ({weapon})" },
{ "Animal", "{attacker} добрался до {victim}" },
{ "ZombieDeath", "{attacker} убил {victim} ({weapon}, {distance} м.)" },
{ "Zombie", "{attacker} приследовал {victim}." },
{ "AnimalDeath", "{attacker} убил {victim} ({weapon}, {distance} м.)" },
{ "Hunger", "{victim} умер от голода." },
{ "Poison", "{victim} умер от отравления." },
{ "Radiation", "{victim} умер от радиационного отравления" },
{ "Slash", "{attacker} убил {victim} ({weapon})" },
{ "Stab", "{attacker} убил {victim} ({weapon})" },
{ "Structure", "{victim} умер от сближения с {attacker}" },
{ "Suicide", "{victim} совершил самоубийство." },
{ "Thirst", "{victim} умер от обезвоживания" },
{ "Trap", "{victim} попался на ловушку {attacker}" },
{ "Cold", "{victim} умер от холода" },
{ "Turret", "{victim} был убит автоматической турелью" },
{ "Guntrap", "{victim} был убит ловушкой-дробовиком" },
{ "Unknown", "У {victim} что-то пошло не так." },
{ "Bleeding", "{victim} умер от кровотечения" },
// Sleeping
{ "Blunt Sleeping", "{attacker} убил {victim} ({weapon})" },
{ "Bullet Sleeping", "{attacker} убил {victim} с ({weapon}, с {distance} метров)" },
{ "Flamethrower Sleeping", "{attacker} сжег игрока {victim} ({weapon})" },
{ "Explosion Sleeping", "{attacker} убил {victim} ({weapon})" },
{ "Generic Sleeping", "Смерть забрала {victim} с собой пока он спал." },
{ "Helicopter Sleeping", "{victim} был убит {attacker} пока он спал." },
{ "BradleyAPC Sleeping", "{victim} был убит {attacker} пока он спал." },
{ "Animal Sleeping", "{victim} убил {attacker} пока он спал." },
{ "Slash Sleeping", "{attacker} убил {victim} ({weapon})" },
{ "Stab Sleeping", "{attacker} убил {victim} ({weapon})" },
{ "Unknown Sleeping", "У игрока {victim} что-то пошло не так." },
{ "Turret Sleeping", "{attacker} был убит автоматической турелью." }
}
}, true);
//PrintWarning("Благодарим за приобритение плагина на сайте RustPlugin.ru. Если вы приобрели этот плагин на другом ресурсе знайте - это лишает вас гарантированных обновлений!");
}
private void OnServerInitialized() {
_config = Config.ReadObject<PluginConfig>();
}
private Dictionary<uint, BasePlayer> LastHeli = new Dictionary<uint, BasePlayer>();
private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
if (entity is BasePlayer)
_lastHits[entity.ToPlayer().userID] = info;
if (entity.name.Contains("patrolhelicopter") && info.InitiatorPlayer != null)
LastHeli[entity.net.ID] = info.InitiatorPlayer;
}
private void OnEntityDeath(BaseCombatEntity victim, HitInfo info) {
var _weapon = FirstUpper(info?.Weapon?.GetItem()?.info?.displayName?.english) ?? FormatName(info?.WeaponPrefab?.name);
var _damageType = FirstUpper(victim.lastDamage.ToString());
if (info == null)
if (!(victim is BasePlayer) || !victim.ToPlayer().IsWounded() || !_lastHits.TryGetValue(victim.ToPlayer().userID, out info))
return;
if (victim as BaseCorpse != null) return;
var _victim = new Victim(victim);
var _attacker = new Attacker(info.Initiator);
if (_victim == null)
return;
if (_attacker == null)
return;
if (_victim.Type == VictimType.Invalid)
return;
if (_attacker.Type == AttackerType.Invalid)
return;
if (_victim.Type == VictimType.Helicopter) {
if (LastHeli.ContainsKey(victim.net.ID)) {
_attacker = new Attacker(LastHeli[victim.net.ID]);
}
}
if ((_victim.Type == VictimType.Zombie && _attacker.Type == AttackerType.NPC))
return;
if (!_config.ShowDeathAnimals && _victim.Type == VictimType.Animal) {
return;
}
if (!_config.ShowDeathAnimals && _victim.Type == VictimType.Scientist) {
return;
}
if (!_config.ShowDeathAnimals && _victim.Type == VictimType.NPC) {
return;
}
if (!_config.ShowDeathAnimals && _attacker.Type == AttackerType.Animal) {
return;
}
if (_victim.Type == VictimType.Player && _victim.Entity.ToPlayer().IsSleeping() && !_config.ShowDeathSleepers)
return;
var _bodyPart = victim?.skeletonProperties?.FindBone(info.HitBone)?.name?.english ?? "";
var _distance = info.ProjectileDistance;
if (_config.Log && _victim.Type == VictimType.Player && _attacker.Type == AttackerType.Player) {
LogToFile("log", $"[{DateTime.Now.ToShortTimeString()}] {info.Initiator} убил {victim} ({_weapon} [{_bodyPart}] с дистанции {_distance})", this, true);
}
AddNote(new DeathMessage(_attacker, _victim, _weapon, _damageType, _bodyPart, _distance));
}
private void Unload() {
foreach (var player in BasePlayer.activePlayerList)
DestroyUI(player);
}
#endregion
#region Core
private void AddNote(DeathMessage note) {
_notes.Insert(0, note);
if (_notes.Count > 8)
_notes.RemoveRange(7, _notes.Count - 8);
RefreshUI(note);
timer.Once(_config.Cooldown, () => {
_notes.Remove(note);
RefreshUI(note);
});
}
#endregion
#region UI
private void RefreshUI(DeathMessage note) {
foreach (var player in note.Players) {
DestroyUI(player);
InitilizeUI(player);
}
}
private void DestroyUI(BasePlayer player) {
CuiHelper.DestroyUi(player, "ui.deathmessages");
}
private void InitilizeUI(BasePlayer player) {
var notes = _notes.Where(x => x.Players.Contains(player)).Take(8);
if (notes.Count() == 0)
return;
var container = new CuiElementContainer();
container.Add(new CuiPanel {
Image = { Color = "0 0 0 0" },
RectTransform = { AnchorMin = "0.5 0.8", AnchorMax = "0.99 0.995" }
}, name: "ui.deathmessages");
double index = 1;
foreach (var note in notes) {
InitilizeLabel(container, note.Message, $"0 {index - 0.2}", $"0.99 {index}");
index -= 0.14;
}
CuiHelper.AddUi(player, container);
}
private string InitilizeLabel(CuiElementContainer container, string text, string anchorMin, string anchorMax) {
string Name = CuiHelper.GetGuid();
container.Add(new CuiElement {
Name = Name,
Parent = "ui.deathmessages",
Components =
{
new CuiTextComponent { Align = UnityEngine.TextAnchor.MiddleRight, FontSize = _config.FontSize, Text = text },
new CuiRectTransformComponent { AnchorMin = anchorMin, AnchorMax = anchorMax },
new CuiOutlineComponent { Color = "0 0 0 1", Distance = "1.0 -0.5" }
}
});
return Name;
}
#endregion
#region Helpers
private static string FirstUpper(string str) {
if (string.IsNullOrEmpty(str))
return str;
return string.Join(" ", str.Split(' ').Select(x => x.Substring(0, 1).ToUpper() + x.Substring(1, x.Length - 1)).ToArray());
}
private static string FormatName(string prefab) {
if (string.IsNullOrEmpty(prefab))
return string.Empty;
var formatedPrefab = FirstUpper(prefab.Split('/').Last().Replace(".prefab", "").Replace(".entity", "").Replace(".weapon", "").Replace(".deployed", "").Replace("_", "."));
switch (formatedPrefab) {
case "Autoturret.deployed": return "Auto Turret";
case "Flameturret": return "Flame Turret";
case "Guntrap.deployed": return "Guntrap";
case "Beartrap": return "Snap Trap";
case "Landmine": return "Land Mine";
case "Spikes.floor": return "Wooden Floor Spikes";
case "Barricade.wood": return "Wooden Barricade";
case "Barricade.woodwire": return "Barbed Wooden Barricade";
case "Barricade.metal": return "Metal Barricade";
case "Wall.external.high.wood": return "High External Wooden Wall";
case "Wall.external.high.stone": return "High External Stone Wall";
case "Gates.external.high.stone": return "High External Wooden Gate";
case "Gates.external.high.wood": return "High External Stone Gate";
case "Stone.hatchet": return "Stone Hatchet";
case "Stone.pickaxe": return "Stone Pickaxe";
case "Survey.charge": return "Survey Charge";
case "Explosive.satchel": return "Satchel Charge";
case "Explosive.timed": return "Timed Explosive Charge";
case "Grenade.beancan": return "Beancan Grenade";
case "Grenade.f1": return "F1 Grenade";
case "Hammer.salvaged": return "Salvaged Hammer";
case "Axe.salvaged": return "Salvaged Axe";
case "Icepick.salvaged": return "Salvaged Icepick";
case "Spear.stone": return "Stone Spear";
case "Spear.wooden": return "Wooden Spear";
case "Knife.bone": return "Bone Knife";
case "Rocket.basic": return "Rocket";
case "Flamethrower": return "Flamethrower";
case "Rocket.hv": return "RocketSpeed";
case "Rocket.heli": return "RocketHeli";
case "Rocket.bradley": return "RocketBradley";
default: return formatedPrefab;
}
}
private static string GetMessage(string name, Dictionary<string, string> source) {
if (source.ContainsKey(name))
return source[name];
return name;
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment