C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Linq;
using Oxide.Game.Rust.Cui;
using Newtonsoft.Json;
using Oxide.Core;
using Rust;
using System.Collections.Generic;
using Facepunch;
using UnityEngine;
using Rust.Ai.Gen2;
using System;
namespace Oxide.Plugins {
[Info("DeathMessages", "rustmods.ru", "2.0.1")]
public partial class DeathMessages : RustPlugin {
private void RemoveUITemplate(BasePlayer player) {
CuiHelper.DestroyUi(player, PANEL_NAME);
}
private void AddUISettings(BasePlayer player) {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = "DMUI", Parent = "Overlay", Components = {
new CuiRectTransformComponent {
AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = $"{-385} {-25}", OffsetMax = $"{-365} {-5}"
}
, new CuiImageComponent {
Color = "1 1 1 0.8", Sprite = "assets/icons/tools.png", Material = "assets/icons/iconmaterial.mat",
}
}
}
);
if (Instance.DeathMessagesConfig.UIConfig.Outline) container[container.Count - 1].Components.Add(new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "-0.5 0.5"
}
);
container.Add(new CuiButton {
Button = {
Command = $"deathmessages show", Color = "0 0 0 0",
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1",
}
, Text = {
Text = "",
}
,
}
, "DMUI", "DMUI.Button");
CuiHelper.AddUi(player, container);
}
internal Dictionary<ulong, HitInfo> LastAttacks = new Dictionary<ulong, HitInfo>();
internal Dictionary<string, string> Names = new Dictionary<string, string>() {
["npcplayer"]
= "NPC", ["guntrap.deployed"] = "Guntrap", ["landmine"] = "Landmine", ["beartrap"] = "Bear trap", ["flameturret.deployed"] = "Flame turret", ["flameturret_fireball"] = "Flame turret", ["autoturret_deployed"] = "Turret", ["sentry.scientist.static"] = "Turret NPC", ["sentry.bandit.static"] = "Turret NPC", ["spikes.floor"] = "Spikes", ["spikes_static"] = "Spikes", ["teslacoil.deployed"] = "Tesla", ["barricade.wood"] = "Barricade", ["barricade.woodwire"] = "Barricade", ["barricade.metal"] = "Barricade", ["bradleyapc"] = "BradleyAPC", ["gates.external.high.wood"] = "Gates", ["gates.external.high.stone"] = "Gates", ["icewall"] = "Ice Wall", ["wall.external.high.ice"] = "Ice wall", ["wall.external.high.stone"] = "Wall", ["wall.external.high.wood"] = "Wall", ["campfire"] = "Campfire", ["skull_fire_pit"] = "Campfire", ["lock.code"] = "Codelock", ["boar"] = "Boar", ["bear"] = "Bear", ["polarbear"] = "Polar Bear", ["wolf"] = "Wolf", ["stag"] = "Stag", ["chicken"] = "Chicken", ["horse"] = "Horse", ["minicopter.entity"] = "Minicopter", ["scraptransporthelicopter"] = "Transport helicopter", ["patrolhelicopter"] = "Patrol helicopter", ["napalm"] = "Napalm", ["fireball_small"] = "Fire", ["fireball_small_shotgun"] = "Fire", ["fireball_small_arrow"] = "Fire", ["sam_site_turret_deployed"] = "SAM", ["cactus-1"] = "Cactus", ["cactus-2"] = "Cactus", ["cactus-3"] = "Cactus", ["cactus-4"] = "Cactus", ["cactus-5"] = "Cactus", ["cactus-6"] = "Cactus", ["cactus-7"] = "Cactus", ["hotairballoon"] = "Hot Air Balloon", ["cave_lift_trigger"] = "Lift", ["wolf2"] = "Wolf", ["simpleshark"] = "Shark", ["door_barricade_b"] = "Barricade", ["modular_car_1mod_storage"] = "Car", ["modular_car_1mod_trade"] = "Car", ["modular_car_2mod_fuel_tank"] = "Car", ["modular_car_camper_storage"] = "Car", ["modular_car_fuel_storage"] = "Car", ["modular_car_i4_engine_storage"] = "Car", ["modular_car_sleepingbag_campervan"] = "Car", ["modular_car_v8_engine_storage"] = "Car", ["sam_static"] = "SAM", ["sentry.bandit.static"] = "Bandit", ["sentry.scientist.static"] = "Scientist", ["supply_drop"] = "Supply Drop", ["npc_bandit_guard"] = "Bandit Guard", ["scientistnpc_arena"] = "Scientist", ["scientistnpc_bradley"] = "Scientist", ["scientistnpc_bradley_heavy"] = "Heavy Scientist", ["scientistnpc_cargo"] = "Scientist", ["scientistnpc_cargo_turret_any"] = "Scientist", ["scientistnpc_cargo_turret_lr300"] = "Scientist", ["scientistnpc_ch47_gunner"] = "Scientist", ["scientistnpc_excavator"] = "Scientist", ["scientistnpc_full_any"] = "Scientist", ["scientistnpc_full_lr300"] = "Scientist", ["scientistnpc_full_mp5"] = "Scientist", ["scientistnpc_full_pistol"] = "Scientist", ["scientistnpc_full_shotgun"] = "Scientist", ["scientistnpc_heavy"] = "Heavy Scientist", ["scientistnpc_junkpile_pistol"] = "Scientist", ["scientistnpc_oilrig"] = "Scientist", ["scientistnpc_patrol"] = "Scientist", ["scientistnpc_peacekeeper"] = "Scientist", ["scientistnpc_roam"] = "Scientist", ["scientistnpc_roam_nvg_variant"] = "Scientist", ["scientistnpc_roamethetered"] = "Scientist", ["npc_tunneldweller"] = "Tunnel Dweller", ["npc_tunneldwellerspawned"] = "Tunnel Dweller", ["npc_underwaterdweller"] = "Underwater Dweller", ["npcplayertest"] = "Player Test",
}
;
internal Dictionary<string, int> PrefabName2Item = new Dictionary<string, int>() {
["40mm_grenade_he"]
= -1123473824, ["rocket_basic"] = 442886268, ["rocket_admin"] = 442886268, ["rocket_hv"] = 442886268, ["rocket_fire"] = 442886268,
}
;
private void RemoveUISettings(BasePlayer player) {
CuiHelper.DestroyUi(player, "DMUI");
}
internal static string HexToRGBA(string hexColor) {
if (ColorUtility.TryParseHtmlString(hexColor, out Color color)) return string.Format("{0:F2} {1:F2} {2:F2} {3:F2}", color.r, color.g, color.b, color.a);
return "1 1 1 1";
}
[ChatCommand("dm")]
private void CMDChatMain(BasePlayer player, string cmd, string[] args) {
if (Instance.DeathMessagesConfig.UIConfig.EnableUISettings == false) return;
PlayersData.TryGetValue(player.userID, out PlayerData playerData);
if (args.Length > 0) {
switch (args[0]) {
case "hidemyname" : {
bool result = SwitchHideMyName(player);
SendReply(player, $"<size=16><color=#ffa>DeathMessages</color></size>\nEnabled:\t\t {(playerData != null && playerData.HideMessages ? "On" : "Off")}\nHide name:\t\t {(result ? "On" : "Off")}\nUsage:\t\t/dm hidemessages|hidemyname");
break;
}
case "hidemessages" : {
bool? result = SwitchHideMessages(player);
if (result.HasValue) SendReply(player, $"<size=16><color=#ffa>DeathMessages</color></size>\nEnabled:\t\t {(result.Value ? "On" : "Off")}\nHide name:\t\t {(playerData != null && playerData.HideMyName ? "On" : "Off")}\nUsage:\t\t/dm hidemessages|hidemyname");
break;
}
}
}
else {
SendReply(player, $"<size=16><color=#ffa>DeathMessages</color></size>\nEnabled:\t\t {(playerData != null && playerData.HideMessages ? "On" : "Off")}\nHide name:\t\t {(playerData != null && playerData.HideMyName ? "On" : "Off")}\nUsage:\t\t/dm hidemessages|hidemyname");
}
}
private void AddUIRow(string message, string distance, int weaponIcon, List<int> weaponModIcons) {
LAST_ROW_MODIFY_TIME = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
CuiElementContainer container = new CuiElementContainer();
for (int i = Instance.DeathMessagesConfig.UIConfig.Rows - 1; i > 0; i--) {
container.Add(new CuiElement {
Name = $"{PANEL_NAME}R{(LAST_ROW_ID + i - 1) % Instance.DeathMessagesConfig.UIConfig.Rows}", Components = {
new CuiRectTransformComponent {
OffsetMin = i >= DeathRow.DeathRows.Count ? $"380 {-20 - i * 25}" : $"0 {-20 - i * 25}", OffsetMax = $"380 {0 - i * 25}"
}
}
, Update = true
}
);
}
LAST_ROW_ID = (LAST_ROW_ID - 1 + Instance.DeathMessagesConfig.UIConfig.Rows) % Instance.DeathMessagesConfig.UIConfig.Rows;
container.Add(new CuiElement {
Name = $"{PANEL_NAME}R{LAST_ROW_ID}", Components = {
new CuiRectTransformComponent {
OffsetMin = "0 -20", OffsetMax = "380 0"
}
}
, Update = true
}
);
container.Add(new CuiElement {
Name = $"{PANEL_NAME}R{LAST_ROW_ID}DT", Components = {
new CuiTextComponent {
Text = distance
}
,
}
, Update = true
}
);
container.Add(new CuiElement {
Name = $"{PANEL_NAME}R{LAST_ROW_ID}K", Components = {
new CuiTextComponent {
Text = message
}
, new CuiRectTransformComponent {
OffsetMin = $"{0 - (6 - weaponModIcons.Count) * 18} 0", OffsetMax = $"{190 + (6 - weaponModIcons.Count) * 18} 20"
}
,
}
, Update = true
}
);
container.Add(new CuiElement {
Name = $"{PANEL_NAME}R{LAST_ROW_ID}WP", Components = {
new CuiRectTransformComponent {
OffsetMin = $"{305 - (weaponModIcons.Count * 18)} 0", OffsetMax = "325 20"
}
,
}
, Update = true
}
);
container.Add(new CuiElement {
Name = $"{PANEL_NAME}R{LAST_ROW_ID}IW", Components = {
new CuiImageComponent {
ItemId = weaponIcon
}
,
}
, Update = true
}
);
for (int j = 0; j < weaponModIcons.Count; j++) {
container.Add(new CuiElement {
Name = $"{PANEL_NAME}R{LAST_ROW_ID}IM{5 - j}", Components = {
new CuiImageComponent {
ItemId = weaponModIcons[j]
}
,
}
, Update = true
}
);
}
string jsonContainer = container.ToJson();
foreach (var player in BasePlayer.activePlayerList) {
if (Instance.PlayersData.TryGetValue(player.userID, out PlayerData playerData)) {
if (playerData.HideMessages) continue;
}
CuiHelper.AddUi(player, jsonContainer);
}
}
private void SwitchPlayerHideMessages(BasePlayer player) {
SwitchHideMessages(player);
}
private void AddUIRows(BasePlayer player) {
if (Instance.PlayersData.TryGetValue(player.userID, out PlayerData playerData)) {
if (playerData.HideMessages) return;
}
CuiElementContainer container = new CuiElementContainer();
for (int i = Instance.DeathMessagesConfig.UIConfig.Rows - 1; i >= 0; i--) {
if (i < DeathRow.DeathRows.Count) {
int currentRowIndex = (LAST_ROW_ID + i) % Instance.DeathMessagesConfig.UIConfig.Rows;
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + currentRowIndex, Parent = PANEL_NAME, Components = {
new CuiRectTransformComponent {
OffsetMin = $"0 {-20 - (i) * 25}", OffsetMax = $"380 {0 - (i) * 25}"
}
,
}
, Update = true
}
);
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + currentRowIndex + "D" + "T", Parent = PANEL_NAME + "R" + currentRowIndex, Components = {
new CuiTextComponent {
Text = DeathRow.DeathRows[i].Distance,
}
,
}
, Update = true
}
);
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + currentRowIndex + "K", Parent = PANEL_NAME + "R" + currentRowIndex, Components = {
new CuiTextComponent {
Text = DeathRow.DeathRows[i].Message,
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = $"0 0", OffsetMax = $"{190 + (6 - DeathRow.DeathRows[i].WeaponModsIcons.Count) * 18} 20"
}
,
}
, Update = true
}
);
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + currentRowIndex + "WP", Parent = PANEL_NAME + "R" + currentRowIndex, Components = {
new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = $"{305 - (DeathRow.DeathRows[i].WeaponModsIcons.Count * 18)} 0", OffsetMax = $"{325} 20"
}
,
}
, Update = true
}
);
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + currentRowIndex + "I" + "W", Parent = PANEL_NAME + "R" + currentRowIndex + "WP", Components = {
new CuiImageComponent {
ItemId = DeathRow.DeathRows[i].WeaponIcon,
}
}
, Update = true
}
);
for (int j = 0; j < DeathRow.DeathRows[i].WeaponModsIcons.Count; j++) {
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + currentRowIndex + "I" + "M" + (5 - j).ToString(), Parent = PANEL_NAME + "R" + currentRowIndex + "WP", Components = {
new CuiImageComponent {
ItemId = DeathRow.DeathRows[i].WeaponModsIcons.ElementAt(j),
}
,
}
, Update = true
}
);
}
}
}
CuiHelper.AddUi(player, container);
}
private string CreateUITemplate() {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = PANEL_NAME, Parent = HUD, Components = {
new CuiRectTransformComponent {
AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = $"{-385 - Instance.DeathMessagesConfig.UIConfig.OffsetX} {-250 - Instance.DeathMessagesConfig.UIConfig.OffsetY}", OffsetMax = $"{-5 - Instance.DeathMessagesConfig.UIConfig.OffsetX} {-5 - Instance.DeathMessagesConfig.UIConfig.OffsetY}"
}
, new CuiImageComponent {
Color = "0 0 0 0"
}
,
}
}
);
for (int i = 0; i < Instance.DeathMessagesConfig.UIConfig.Rows; i++) {
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + i, Parent = PANEL_NAME, Components = {
new CuiRectTransformComponent {
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = $"380 {-20 - i * 25}", OffsetMax = $"380 {0 - i * 25}"
}
, new CuiImageComponent {
Color = HexToRGBA(Instance.DeathMessagesConfig.UIConfig.RowColor)
}
,
}
}
);
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + i + "D", Parent = PANEL_NAME + "R" + i, Components = {
new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = $"325 -20", OffsetMax = $"385 40"
}
, new CuiRawImageComponent {
Color = HexToRGBA(Instance.DeathMessagesConfig.UIConfig.DistanceColor), Material = "assets/icons/iconmaterial.mat", Sprite = $"assets/icons/subtract.png",
}
,
}
}
);
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + i + "D" + "T", Parent = PANEL_NAME + "R" + i, Components = {
new CuiTextComponent {
Text = "", Color = HexToRGBA(Instance.DeathMessagesConfig.UIConfig.DistanceProperty.Color), Align = TextAnchor.MiddleCenter, FontSize = Instance.DeathMessagesConfig.UIConfig.DistanceProperty.Size, Font = "robotocondensed-bold.ttf",
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = $"325 0", OffsetMax = $"385 20"
}
}
}
);
if (Instance.DeathMessagesConfig.UIConfig.Outline) container[container.Count - 1].Components.Add(new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "-0.5 0.5"
}
);
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + i + "WP", Parent = PANEL_NAME + "R" + i, Components = {
new CuiScrollViewComponent {
Vertical = false, Horizontal = true, MovementType = UnityEngine.UI.ScrollRect.MovementType.Unrestricted, ContentTransform = new CuiRectTransform {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "0 0", OffsetMax = "113 20"
}
, HorizontalScrollbar = new CuiScrollbar {
Size = 0, HandleColor = "0 0 0 0", HighlightColor = "0 0 0 0", PressedColor = "0 0 0 0", TrackColor = "0 0 0 0",
}
, VerticalScrollbar = new CuiScrollbar {
Size = 0, HandleColor = "0 0 0 0", HighlightColor = "0 0 0 0", PressedColor = "0 0 0 0", TrackColor = "0 0 0 0",
}
}
, new CuiImageComponent {
Color = "0 0 0 0",
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = $"{192} 0", OffsetMax = $"{325} 20"
}
,
}
}
);
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + i + "I" + "W", Parent = PANEL_NAME + "R" + i + "WP", Components = {
new CuiImageComponent {
ItemId = 1545779598, Color = "1 1 1 1",
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = $"{1} 1", OffsetMax = $"{19} 19"
}
}
}
);
if (Instance.DeathMessagesConfig.UIConfig.ImageOutline) container[container.Count - 1].Components.Add(new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "-0.5 0.5"
}
);
for (int j = 0; j < 6; j++) {
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + i + "I" + "M" + j, Parent = PANEL_NAME + "R" + i + "WP", Components = {
new CuiImageComponent {
ItemId = 952603248, Color = "1 1 1 1",
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = $"{112 - j * 18} 2", OffsetMax = $"{128 - j * 18} 18"
}
}
}
);
if (Instance.DeathMessagesConfig.UIConfig.ImageOutline) container[container.Count - 1].Components.Add(new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "-0.5 0.5"
}
);
}
container.Add(new CuiElement {
Name = PANEL_NAME + "R" + i + "K", Parent = PANEL_NAME + "R" + i, Components = {
new CuiTextComponent {
Text = "", Color = HexToRGBA(Instance.DeathMessagesConfig.UIConfig.TextProperty.Color), Align = TextAnchor.MiddleRight, FontSize = Instance.DeathMessagesConfig.UIConfig.TextProperty.Size, Font = "robotocondensed-bold.ttf",
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = $"0 0", OffsetMax = $"190 20"
}
}
}
);
if (Instance.DeathMessagesConfig.UIConfig.Outline) container[container.Count - 1].Components.Add(new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "-0.5 0.5"
}
);
}
return container.ToJson();
}
private bool? SwitchHideMessages(BasePlayer player) {
if (PlayersData.TryGetValue(player.userID, out PlayerData playerData)) {
var nowSeconds = new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds();
if (playerData.LastConnectTime + 15000 > nowSeconds) {
SendReply(player, $"This option is not yet available for modification.It will be accessible in: {(playerData.LastConnectTime + 15000 - nowSeconds) / 1000} sec.");
return null;
}
playerData.HideMessages = !playerData.HideMessages;
playerData.LastConnectTime = nowSeconds;
if (playerData.HideMessages == false) {
AddTemplateUI(player);
AddUIRows(player);
}
else {
RemoveUITemplate(player);
}
}
else {
PlayersData[player.userID] = playerData = new PlayerData() {
HideMessages = true, HideMyName = false, LastConnectTime = new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds()
}
;
RemoveUITemplate(player);
}
return playerData.HideMessages;
}
private void Unload() {
foreach (var player in BasePlayer.activePlayerList) {
RemoveUITemplate(player);
RemoveUISettings(player);
}
Interface.Oxide.DataFileSystem.WriteObject("DeathMessages\\PlayersData", PlayersData);
DeathRow.DeathRows.Clear();
Instance = null;
}
private void CreateNote(string message, float distance, int weaponIcon, List<int> weaponMods) {
new DeathRow(message, distance.ToString("F1") + "m", weaponIcon, weaponMods).Run();
}
internal Dictionary<uint, int> Prefab2Item = new Dictionary<uint, int>();
internal const string PANEL_NAME = "DM";
[Obsolete]
private void CreateNote(string vName, string iName, float distance, string vColor, string iColor, string weaponName, string[] weaponMods, bool isHeadshot, bool needRenameVictim, bool needRenameInitiator) {
string message = $"<color={iColor}>{(needRenameInitiator ? Instance.GetNpcName(iName) : iName)}</color> убил <color={vColor}>{(needRenameVictim ? Instance.GetNpcName(vName) : vName)}</color>";
int weaponIcon = 1545779598;
List<int> weaponModsList = new List<int>(6);
if (ItemManager.itemDictionaryByName.TryGetValue(weaponName, out ItemDefinition itemDefinition)) weaponIcon = itemDefinition.itemid;
if (isHeadshot) weaponModsList.Add(996293980);
foreach (var weaponMod in weaponMods) {
if (ItemManager.itemDictionaryByName.TryGetValue(weaponMod, out ItemDefinition modDefinition)) weaponModsList.Add(modDefinition.itemid);
}
CreateNote(message, distance, weaponIcon, weaponModsList);
}
public class DeathRow {
public string Message {
get;
private set;
}
public string Distance {
get;
private set;
}
public int WeaponIcon {
get;
private set;
}
public List<int> WeaponModsIcons {
get;
private set;
}
public bool Initialized() => string.IsNullOrEmpty(this.Message) == false;
public static List<DeathRow> DeathRows = new List<DeathRow>();
public DeathRow(BasePlayer victim, BasePlayer initiator, HitInfo info) {
FillDistance(victim, initiator);
FillIcons(info);
string messageVariable = Instance.GetDeathMessage(info.damageTypes.GetMajorityDamageType());
if (string.IsNullOrEmpty(messageVariable) == false) this.Message = string.Format(messageVariable, GetNameString(victim), GetNameString(initiator));
}
public DeathRow(BasePlayer victim, NPCPlayer initiator, HitInfo info) {
if (Instance.DeathMessagesConfig.CoreConfig.PlayerKilledByNPC == false) return;
FillDistance(victim, initiator);
FillIcons(info);
string messageVariable = Instance.GetDeathMessage(info.damageTypes.GetMajorityDamageType());
if (string.IsNullOrEmpty(messageVariable) == false) this.Message = string.Format(messageVariable, GetNameString(victim), Instance.DeathMessagesConfig.CoreConfig.RenameNPC ? GetPrefabName(initiator.ShortPrefabName) : initiator.displayName);
}
public DeathRow(NPCPlayer victim, BasePlayer initiator, HitInfo info) {
if (Instance.DeathMessagesConfig.CoreConfig.NPC == false) return;
FillDistance(victim, initiator);
FillIcons(info);
string messageVariable = Instance.GetDeathMessage(info.damageTypes.GetMajorityDamageType());
if (string.IsNullOrEmpty(messageVariable) == false) this.Message = string.Format(messageVariable, Instance.DeathMessagesConfig.CoreConfig.RenameNPC ? GetPrefabName(victim.ShortPrefabName) : victim.displayName, GetNameString(initiator));
}
public DeathRow(BaseCombatEntity victim, BasePlayer initiator, HitInfo info) {
if (Instance.DeathMessagesConfig.CoreConfig.Animal == false) return;
FillDistance(victim, initiator);
FillIcons(info);
string messageVariable = Instance.GetDeathMessage(info.damageTypes.GetMajorityDamageType());
if (string.IsNullOrEmpty(messageVariable) == false && Instance.GetNpcName(victim.ShortPrefabName) != victim.ShortPrefabName) this.Message = string.Format(messageVariable, GetPrefabName(victim.ShortPrefabName), GetNameString(initiator));
}
public DeathRow(BasePlayer victim, BaseCombatEntity initiator, HitInfo info) {
if (Instance.DeathMessagesConfig.CoreConfig.PlayerKilledByAnimal == false) return;
FillDistance(victim, initiator);
FillIcons(info);
string messageVariable = Instance.GetDeathMessage(info.damageTypes.GetMajorityDamageType());
if (string.IsNullOrEmpty(messageVariable) == false && Instance.GetNpcName(initiator.ShortPrefabName) != initiator.ShortPrefabName) this.Message = string.Format(messageVariable, GetNameString(victim), GetPrefabName(initiator.ShortPrefabName));
}
public DeathRow(PatrolHelicopter victim, BasePlayer initiator, HitInfo info) {
if (Instance.DeathMessagesConfig.CoreConfig.Helicopter == false) return;
FillDistance(victim, initiator);
FillIcons(info);
string messageVariable = Instance.GetDeathMessage(info.damageTypes.GetMajorityDamageType());
if (string.IsNullOrEmpty(messageVariable) == false && Instance.GetNpcName(victim.ShortPrefabName) != victim.ShortPrefabName) this.Message = string.Format(messageVariable, GetPrefabName(victim.ShortPrefabName), GetNameString(initiator));
}
public DeathRow(BradleyAPC victim, BasePlayer initiator, HitInfo info) {
if (Instance.DeathMessagesConfig.CoreConfig.Bradley == false) return;
FillDistance(victim, initiator);
FillIcons(info);
string messageVariable = Instance.GetDeathMessage(info.damageTypes.GetMajorityDamageType());
if (string.IsNullOrEmpty(messageVariable) == false && Instance.GetNpcName(victim.ShortPrefabName) != victim.ShortPrefabName) this.Message = string.Format(messageVariable, GetPrefabName(victim.ShortPrefabName), GetNameString(initiator));
}
public DeathRow(BasePlayer victim, DecayEntity initiator, HitInfo info) {
if (Instance.DeathMessagesConfig.CoreConfig.PlayerKilledByEnv == false) return;
FillDistance(victim, initiator);
FillIcons(info, initiator);
string messageVariable = Instance.GetDeathMessage(info.damageTypes.GetMajorityDamageType());
if (string.IsNullOrEmpty(messageVariable) == false && Instance.GetNpcName(initiator.ShortPrefabName) != initiator.ShortPrefabName) this.Message = string.Format(messageVariable, GetNameString(victim), GetPrefabName(initiator.ShortPrefabName));
}
public DeathRow(BasePlayer victim, HitInfo info) {
if (Instance.DeathMessagesConfig.CoreConfig.PlayerKilledByEnv == false) return;
FillDistance(victim, null);
FillIcons(info, null);
string messageVariable = Instance.GetDeathMessage(info?.damageTypes?.GetMajorityDamageType() ?? DamageType.Generic);
if (string.IsNullOrEmpty(messageVariable) == false) this.Message = string.Format(messageVariable, GetNameString(victim), "");
}
public DeathRow(string message, string distance, int weaponIcon, List<int> weaponMods) {
this.Message = message;
this.Distance = distance;
this.WeaponIcon = weaponIcon;
this.WeaponModsIcons = weaponMods;
}
public void Run() {
if (Initialized()) {
if (DeathRows.Count == Instance.DeathMessagesConfig.UIConfig.Rows) DeathRows.RemoveAt(DeathRows.Count - 1);
DeathRows.Insert(0, this);
Instance.AddUIRow(this.Message, this.Distance, this.WeaponIcon, this.WeaponModsIcons);
}
}
private void FillDistance(BaseCombatEntity victim, BaseCombatEntity initiator = null) {
if (initiator != null) this.Distance = $"{Vector3.Distance(victim.transform.position, initiator.transform.position).ToString("F1")}m";
else this.Distance = "0m";
}
private void FillIcons(HitInfo info, BaseCombatEntity initiator = null) {
this.WeaponModsIcons = new List<int>(5);
if (info == null) {
this.WeaponIcon = 996293980;
return;
}
if (info.isHeadshot) this.WeaponModsIcons.Add(996293980);
if (initiator != null) {
ItemDefinition initiatorDefinition = GetInitiatorDefinition(initiator);
if (initiatorDefinition != null) {
this.WeaponIcon = initiatorDefinition.itemid;
Item attackItem = GetAttackItem(info);
if (attackItem == null) {
ItemDefinition attackDefinition = GetAttackDefinition(info);
if (attackDefinition != null && attackDefinition.itemid != this.WeaponIcon) this.WeaponModsIcons.Add(attackDefinition.itemid);
}
else {
this.WeaponModsIcons.Add(attackItem.info.itemid);
this.WeaponModsIcons.AddRange(attackItem.contents.itemList.Select(x => x.info.itemid).ToList());
}
}
}
else {
Item attackItem = GetAttackItem(info);
if (attackItem == null) {
ItemDefinition attackDefinition = GetAttackDefinition(info);
if (attackDefinition != null) {
this.WeaponIcon = attackDefinition.itemid;
}
else {
if (info.isHeadshot == false) this.WeaponIcon = 996293980;
}
}
else {
this.WeaponIcon = attackItem.info.itemid;
if (attackItem.contents != null) this.WeaponModsIcons.AddRange(attackItem.contents.itemList.Select(x => x.info.itemid).ToList());
}
}
}
private Item GetAttackItem(HitInfo info) {
Item attackItem = GetWeaponFromEntity(info.Weapon);
if (attackItem == null) attackItem = GetWeaponFromEntity(info.WeaponPrefab);
if (attackItem == null) attackItem = GetWeaponFromEntity(info.ProjectilePrefab?.sourceWeaponPrefab);
return attackItem;
}
private ItemDefinition GetAttackDefinition(HitInfo info) {
ItemDefinition attackDefinition = GetWeaponFromEntityName(info.Weapon);
if (attackDefinition == null) attackDefinition = GetWeaponFromEntityName(info.WeaponPrefab);
if (attackDefinition == null) attackDefinition = GetWeaponFromEntityName(info.ProjectilePrefab?.sourceWeaponPrefab);
if (attackDefinition == null) attackDefinition = GetWeaponFromEntityName(info.ProjectilePrefab?.sourceProjectilePrefab?.sourceWeaponPrefab);
return attackDefinition;
}
private ItemDefinition GetInitiatorDefinition(BaseCombatEntity entity) {
return GetWeaponFromEntityName(entity);
}
private Item GetWeaponFromEntity(BaseEntity attackEntity) {
if (attackEntity == null || attackEntity.GetItem() == null) return null;
return attackEntity.GetItem();
}
private ItemDefinition GetWeaponFromEntityName(BaseEntity attackEntity) {
if (attackEntity == null) return null;
if (!Instance.Prefab2Item.TryGetValue(attackEntity.prefabID, out int itemID)) {
if (!Instance.PrefabName2Item.TryGetValue(attackEntity.ShortPrefabName, out itemID)) {
return null;
}
}
if (!ItemManager.itemDictionary.TryGetValue(itemID, out ItemDefinition item)) return null;
return item;
}
private string GetNameString(BasePlayer player) {
string playerName = player.displayName;
if (player.IsNpc == false && Instance.PlayersData.TryGetValue(player.userID, out PlayerData playerData) && playerData.HideMyName) playerName = RandomUsernames.Get(player.userID + (ulong)((long)UnityEngine.Random.Range(0, 100000)));
return $"<size={Instance.DeathMessagesConfig.UIConfig.NameProperty.Size}><color={Instance.GetColorFor(player)}>{playerName.Substring(0, Math.Min(16, playerName.Length))}</color></size>";
}
private string GetPrefabName(string shortPrefabName) {
return $"<size={Instance.DeathMessagesConfig.UIConfig.NameProperty.Size}><color={Instance.DeathMessagesConfig.UIConfig.NameProperty.Color}>{Instance.GetNpcName(shortPrefabName)}</color></size>";
}
}
public class PlayerData {
public double LastConnectTime = 0;
public bool HideMessages = false;
public bool HideMyName = false;
}
private bool SwitchHideMyName(BasePlayer player) {
if (PlayersData.TryGetValue(player.userID, out PlayerData playerData)) {
playerData.HideMyName = !playerData.HideMyName;
}
else {
PlayersData[player.userID] = new PlayerData() {
HideMessages = false, HideMyName = true, LastConnectTime = new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds()
}
;
}
return playerData.HideMyName;
}
private void OnServerSave() {
Interface.Oxide.DataFileSystem.WriteObject("DeathMessages\\PlayersData", PlayersData);
}
private void OnPlayerConnected(BasePlayer player) {
AddTemplateUI(player);
AddUIRows(player);
if (PlayersData.TryGetValue(player.userID, out PlayerData playerData)) playerData.LastConnectTime = new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds();
if (Instance.DeathMessagesConfig.UIConfig.EnableUISettings && Instance.DeathMessagesConfig.UIConfig.EnableUISettingsButton) AddUISettings(player);
}
private void AddUISettingsWidget(BasePlayer player) {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = "DMUISettings", Parent = "DMUI", Components = {
new CuiRectTransformComponent {
AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = $"{5} {-43}", OffsetMax = $"{180} {5}"
}
, new CuiImageComponent {
Color = "1 0.95 0.85 0.2", Material = "assets/icons/iconmaterial.mat",
}
}
}
);
Instance.PlayersData.TryGetValue(player.userID, out PlayerData playerData);
container.Add(new CuiButton {
Button = {
Command = "deathmessages hidemyname", Color = "0 0 0 0",
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "5 3", OffsetMax = "170 23"
}
, Text = {
Text = playerData != null && playerData.HideMyName ? "☑ Hide my name in DeathMessages" : "☐ Hide my name in DeathMessages", Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.8", Font = "robotocondensed-bold.ttf", FontSize = 11
}
,
}
, "DMUISettings", "DMUISettings.HideMyName");
container.Add(new CuiButton {
Button = {
Command = "deathmessages hidemessages", Color = "0 0 0 0",
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "5 23", OffsetMax = "170 43"
}
, Text = {
Text = playerData != null && playerData.HideMessages ? "☑ Hide DeathMessages" : "☐ Hide DeathMessages", Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.8", Font = "robotocondensed-bold.ttf", FontSize = 11
}
,
}
, "DMUISettings", "DMUISettings.HideMessages");
CuiHelper.AddUi(player, container);
}
private bool IsPlayerNameHidden(BasePlayer player) {
return PlayersData.TryGetValue(player.userID, out PlayerData playerData) && playerData.HideMyName;
}
internal Dictionary<ulong, PlayerData> PlayersData = new Dictionary<ulong, PlayerData>();
private void OnPlayerDisconnected(BasePlayer player) {
}
private void UpdateUISettingsButton(BasePlayer player, string command) {
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiButton {
Button = {
Command = $"deathmessages {command}", Color = "0 0 0 0",
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1",
}
, Text = {
Text = "",
}
,
}
, "DMUI", "DMUI.Button", "DMUI.Button");
CuiHelper.AddUi(player, container);
}
private bool IsPlayerHideMessages(BasePlayer player) {
return PlayersData.TryGetValue(player.userID, out PlayerData playerData) && playerData.HideMessages;
}
private void SetDefaultConfig() {
DeathMessagesConfig = GetDefaultConfig();
Config.WriteObject(DeathMessagesConfig, true);
}
internal const string HUD = "Hud";
internal string GetDeathMessage(DamageType damageType) {
if (DeathMessagesConfig.CoreConfig.Messages.TryGetValue(damageType.ToString(), out List<string> variables)) return variables[UnityEngine.Random.Range(0, variables.Count)];
return null;
}
[ConsoleCommand("deathmessages")]
private void CMDMain(ConsoleSystem.Arg arg) {
if (Instance.DeathMessagesConfig.UIConfig.EnableUISettings == false || Instance.DeathMessagesConfig.UIConfig.EnableUISettingsButton == false) return;
BasePlayer player = arg.Player();
if (player != null && arg.HasArgs()) {
string command = arg.Args[0];
switch (command) {
case "show" : {
UpdateUISettingsButton(player, "hide");
AddUISettingsWidget(player);
break;
}
case "hide" : {
CuiHelper.DestroyUi(player, "DMUISettings");
UpdateUISettingsButton(player, "show");
break;
}
case "hidemyname" : {
SwitchHideMyName(player);
UpdateUISettingsWidget(player);
break;
}
case "hidemessages" : {
SwitchHideMessages(player);
UpdateUISettingsWidget(player);
break;
}
}
}
}
private void OnEntityDeath(BaseCombatEntity victim, HitInfo info) {
if (victim == null) return;
if (info == null) {
if (victim.IsNonNpcPlayer()) new DeathRow(victim as BasePlayer, null).Run();
return;
}
if (info.damageTypes == null) return;
DeathRow outputRow = null;
if (info.Initiator != null && info.Initiator is BaseCombatEntity) {
if (victim is BasePlayer && info.Initiator is BasePlayer && victim.net.ID.Value != info.Initiator.net.ID.Value) {
if (victim.IsNonNpcPlayer() && info.Initiator.IsNpcPlayer()) {
outputRow = new DeathRow(victim as BasePlayer, info.Initiator as NPCPlayer, info);
}
if (victim.IsNpcPlayer() && info.Initiator.IsNonNpcPlayer()) {
outputRow = new DeathRow(victim as NPCPlayer, info.Initiator as BasePlayer, info);
}
if (victim.IsNonNpcPlayer() && info.Initiator.IsNonNpcPlayer()) {
outputRow = new DeathRow(victim as BasePlayer, info.Initiator as BasePlayer, info);
}
}
if (victim is BaseAnimalNPC || victim is BaseNPC2 || victim is SimpleShark) {
if (info.Initiator.IsNonNpcPlayer()) {
outputRow = new DeathRow(victim, info.Initiator as BasePlayer, info);
}
}
if (victim is BradleyAPC bradleyAPC && info.Initiator.IsNonNpcPlayer()) {
outputRow = new DeathRow(bradleyAPC, info.Initiator as BasePlayer, info);
}
if (victim.IsNonNpcPlayer()) {
if (info.Initiator is BaseAnimalNPC || info.Initiator is BaseNPC2 || info.Initiator is SimpleShark) {
outputRow = new DeathRow(victim as BasePlayer, info.Initiator as BaseCombatEntity, info);
}
if (info.Initiator is DecayEntity) {
outputRow = new DeathRow(victim as BasePlayer, info.Initiator as DecayEntity, info);
}
}
}
if (info.Initiator == null || info.Initiator.net.ID.Value == victim.net.ID.Value) {
if (victim.IsNonNpcPlayer()) outputRow = new DeathRow(victim as BasePlayer, info);
}
outputRow?.Run();
}
public DeathMessagesConfiguration GetDefaultConfig() {
return new DeathMessagesConfiguration {
CoreConfig = new DeathMessagesConfiguration.CoreConfiguration() {
Names = Names, Messages = Messages, Animal = true, NPC = tru
// ... [Code preview truncated due to length. Full source in attached file] ...