Mimic Hostile Warning

I'm working on a simple plugin that mimics the default hostile warning in rust and could use a little help. The code I have right now will send a player a message when hostile state is changed. Things I need to figure out are how to only print this once and not on every hostile update, and I don't know how to call/draw the warning symbol in the top right corner. I would also like to make the warning last the duration of the hostile timer but am unsure how I would go about that.

Here's what I got so far:

using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("HostileWarn", "Savage", "0.0.4")]
    [Description("Hostile Chat Warning.")]
    public class HostileWarn : RustPlugin
    {

        private void OnEntityMarkHostile(BasePlayer player, float duration)
        {
            if (player.IsValid() == true || player.IsHostile() == true)
            {
                SendMessage(player, "You Are Marked <color=red>Hostile</color>!");
                return;
            }

        
        }


        void SendMessage(BasePlayer player, string msg, params object[] args)
        {
            {
                PrintToChat(player, msg, args);
                return;
            }
        
        
        }



    }
}​

1 things I'll like to note.

  • OnEntityMarkHostilereturn type is an (object), not a void. Thus, you could return null to execute the hook normally, or anything other than null to prevent execution. (Most just return booleans to prevent executions)
Things I need to figure out are how to only print this once and not on every hostile update

It can be done this way

// This Hook is called before BasePlayer is marked hostile. So you want to your instructions inverted.
public object OnEntityMarkHostile(BasePlayer player, float duration)
{
    if(player.IsValid() && !player.IsHostile()) {
        // send message to player they've been marked hostile.
        SendMessage(player, "You Are Marked <color=red>Hostile</color>!");
    }else {
        // you can increase the player hostility timer. but lets make sure this wasn't their first time being hostile..
        if((int) player.State.unHostileTimestamp != 0) {
            // you can add/decrease timestamp here. (the highest timestamp or duration will be set as true timestamp)
            player.State.unHostileTimestamp += duration;
        }
    }
    return null;
}

 

I don't know how to call/draw the warning symbol in the top right corner

This can be called to mark on BasePlayer to make them hostile. 60f = 1minute in seconds. But if they're already hostile you can just increase the player unHostileTimestamp 

public override void MarkHostileFor(float duration = 60f)
{
	if (Interface.CallHook("OnEntityMarkHostile", this, duration) != null)
		return;
	double currentTimestamp = TimeEx.currentTimestamp;
	double val = currentTimestamp + (double)duration;
	this.State.unHostileTimestamp = Math.Max(this.State.unHostileTimestamp, val);
	this.DirtyPlayerState();
	double num = Math.Max(this.State.unHostileTimestamp - currentTimestamp, 0.0);
	base.ClientRPCPlayer<float>(null, this, "SetHostileLength", (float)num);
}

 

I would also like to make the warning last the duration of the hostile timer but am unsure how I would go about that.

Not 100% sure what you mean by this? 

LegitSoulja

1 things I'll like to note.

  • OnEntityMarkHostilereturn type is an (object), not a void. Thus, you could return null to execute the hook normally, or anything other than null to prevent execution. (Most just return booleans to prevent executions)

It can be done this way

// This Hook is called before BasePlayer is marked hostile. So you want to your instructions inverted.
public object OnEntityMarkHostile(BasePlayer player, float duration)
{
    if(player.IsValid() && !player.IsHostile()) {
        // send message to player they've been marked hostile.
        SendMessage(player, "You Are Marked <color=red>Hostile</color>!");
    }else {
        // you can increase the player hostility timer. but lets make sure this wasn't their first time being hostile..
        if((int) player.State.unHostileTimestamp != 0) {
            // you can add/decrease timestamp here. (the highest timestamp or duration will be set as true timestamp)
            player.State.unHostileTimestamp += duration;
        }
    }
    return null;
}

 

This can be called to mark on BasePlayer to make them hostile. 60f = 1minute in seconds. But if they're already hostile you can just increase the player unHostileTimestamp 

public override void MarkHostileFor(float duration = 60f)
{
	if (Interface.CallHook("OnEntityMarkHostile", this, duration) != null)
		return;
	double currentTimestamp = TimeEx.currentTimestamp;
	double val = currentTimestamp + (double)duration;
	this.State.unHostileTimestamp = Math.Max(this.State.unHostileTimestamp, val);
	this.DirtyPlayerState();
	double num = Math.Max(this.State.unHostileTimestamp - currentTimestamp, 0.0);
	base.ClientRPCPlayer<float>(null, this, "SetHostileLength", (float)num);
}

 

Not 100% sure what you mean by this? 

Thank you very much for your reply, in the time since making this post I ended up going about another method and found help from the rust admin discord. In the end, no plugin was needed as we discovered the fix this plugin was attempting to solve.

When using a custom safe zone prefab with existing safezones, the hostile marker will break and no longer show when with in 2 hex's of that safezone and no timer is displayed. Players walk into the area marked hostile but have no visual indicator or timer letting them know they are hostile and are killed by the safe zone turrets. The fix was learned only recently and has plagued many custom map users, you need to use all custom safe zones. You can't use any existing safe zone, they all have to be custom to work as vanilla.

So now our custom outpost works like vanilla, but the use of custom fishing/stables has brought a long it's own set of problems.