1. What I am trying to do:

    I am trying to edit the R-Remover tool to make it so instead of using a RayHit to determine what is being Removed, to use a OnHammerHit to determine that.

    What I know:

    Now I know with the OnHammerHit you don't even need to have anything regarding Distance or Ray, but I don't know what I need to change.

    Here is the code it determines what being Removed:

    Code:
    static BaseEntity FindRemoveObject(Ray ray, float distance)
            {
                RaycastHit hit;
                if (!UnityEngine.Physics.Raycast(ray, out hit, distance, constructionColl))
                    return null;
                return hit.GetEntity();
            } ///
            /// class Tool Remover
    ///        class ToolRemover : MonoBehaviour
            {
                public BasePlayer player;
                public int endTime;
                public int timeLeft;
                public RemoveType removeType;
                public BasePlayer playerActivator;
                public float distance;
                public float lastUpdate;            public InputState inputState;            void Awake()
                {
                    player = GetComponent<BasePlayer>();
                    lastUpdate = UnityEngine.Time.realtimeSinceStartup;
                }            public void RefreshDestroy()
                {
                    timeLeft = endTime;
                    CancelInvoke("DoDestroy");
                    CancelInvoke("RefreshRemoveGui");
                    Invoke("DoDestroy", endTime);
                    InvokeRepeating("RefreshRemoveGui", 1, 1);
                    DestroyGUI(player);
                    NewGUI(this);
                }            void DoDestroy()
                {
                    GameObject.Destroy(this);
                }            void RefreshRemoveGui()
                {
                    timeLeft--;
                    RefreshGUI(this);
                }            void FixedUpdate()
                {
                    if (!player.IsConnected() || player.IsDead()) { GameObject.Destroy(this); return; }
                    inputState = serverinput.GetValue(player) as InputState;
                    if (inputState.WasJustPressed(BUTTON.FIRE_PRIMARY))
                    {
                        float currentTime = UnityEngine.Time.realtimeSinceStartup;
                        if (lastUpdate + 0.5f < currentTime)
                        {
                            lastUpdate = currentTime;
                            if (player.GetActiveItem() != null)
                            {
                                PrintToChat(player, MessageErrorCantUseRemoveWithItem);
                                return;
                            }
                            Ray ray = new Ray(player.eyes.position, Quaternion.Euler(inputState.current.aimAngles) * Vector3.forward);
                            TryRemove(player, ray, removeType, distance);
                        }
                    }
                }            void OnDestroy()
                {
                    DestroyGUI(player);
                    if (playerActivator != player)
                    {
                        if (playerActivator.IsConnected())
                            PrintToChat(playerActivator, string.Format(MessageTargetRemoveEnded, player.displayName));
                    }
                }
            }
            void EndRemoverTool(BasePlayer player)
            {
                ToolRemover toolremover = player.GetComponent<ToolRemover>();
                if (toolremover == null) return;
                GameObject.Destroy(toolremover);
    And here is where the code above that is brought in:

    Code:
    static void TryRemove(BasePlayer player, Ray ray, RemoveType removeType, float distance)
            {
                BaseEntity removeObject = FindRemoveObject(ray, distance);
                if (removeObject == null)
                {
                    PrintToChat(player, MessageErrorNothingToRemove);
                    return;
                }
                var success = CanRemoveEntity(player, removeObject, removeType);
                if (success is string)
                {
                    PrintToChat(player, (string)success);
                    return;
                }
                if (usePay && !CanPay(player, removeObject, removeType))
                {
                    PrintToChat(player, MessageErrorNotEnoughPay);
                    return;
                }
                if (removeType == RemoveType.All)
                {
                    Interface.Call("RemoveAllFrom", removeObject.transform.position);
                    return;
                }
                if (usePay)
                    Pay(player, removeObject, removeType);
                if (useRefund)
                    Refund(player, removeObject, removeType);
                DoRemove(removeObject);        }        List<Vector3> removeFrom = new List<Vector3>();
            int currentRemove = 0;
            void RemoveAllFrom(Vector3 pos)
            {
                removeFrom.Add(pos);
                DelayRemoveAll();
            }        List<BaseEntity> wasRemoved = new List<BaseEntity>();
            void DelayRemoveAll()
            {
                if (currentRemove >= removeFrom.Count)
                {
                    currentRemove = 0;
                    removeFrom.Clear();
                    wasRemoved.Clear();
                    return;
                }
                List<BaseEntity> list = Pool.GetList<BaseEntity>();
                Vis.Entities<BaseEntity>(removeFrom[currentRemove], 3f, list, constructionColl);
                for(int i = 0; i < list.Count; i++)
                {
                    BaseEntity ent = list[i];
                    if (wasRemoved.Contains(ent)) continue;
                    if (!removeFrom.Contains(ent.transform.position))
                        removeFrom.Add(ent.transform.position);
                    wasRemoved.Add(ent);
                    DoRemove(ent);
                }
                currentRemove++;
                timer.Once(0.01f, () => DelayRemoveAll());
            }        static void DoRemove(BaseEntity removeObject)
            {
                if (removeObject == null) return;
                removeObject.KillMessage();
            }
    Below is my attempts at trying to figure it out. I got frustrated and stopped so it might look incomplete:

    Code:
            static BaseEntity OnHammerHit(BasePlayer player, HitInfo info)
            {       
                    OnHammerHit; 
                    if (info(player, info));       
                    return null;
                    return info.BaseEntity.ent;
                   
            }    ////
            /// class Tool Remover
     ////               class ToolRemover : MonoBehaviour
            {
                public BasePlayer player;
                public int endTime;
                public int timeLeft;
                public RemoveType removeType;
                public float distance;
                public float lastUpdate;
                public HitInfo info;
               
                void Awake()
                {
                    player = GetComponent<BasePlayer>();
                    lastUpdate = UnityEngine.Time.realtimeSinceStartup;
                }
               
                void OnHammerHit(BasePlayer player, HitInfo info)
                {
                    {info = <BaseEntity>.list;
                       
                        {
                        TryRemove(player, removeType, info);
                        }   
                    }       
                }
                   
            }
            void EndRemoverTool(BasePlayer player)
            {
                ToolRemover toolremover = player.GetComponent<ToolRemover>();
                if (toolremover == null) return;
                GameObject.Destroy(toolremover);
    
    And again, the other portion with my edits:

    Code:
    static void TryRemove(BasePlayer player, RemoveType removeType, HitInfo info)
            {
                BaseEntity removeObject = OnHammerHit(player, info);
                if (removeObject == null)
                {
                    PrintToChat(player, MessageErrorNothingToRemove);
                    return;
                }
                var success = CanRemoveEntity(player, removeObject, removeType);
                if (success is string)
                {
                    PrintToChat(player, (string)success);
                    return;
                }
                if (removeType == RemoveType.All)
                {
                    Interface.Call("RemoveAllFrom", removeObject.transform.position);
                    return;
                }
                if (useRefund)
                    Refund(player, removeObject, removeType);
                DoRemove(removeObject);        }        List<Vector3> removeFrom = new List<Vector3>();
            int currentRemove = 0;
            void RemoveAllFrom(Vector3 pos)
            {
                removeFrom.Add(pos);
                DelayRemoveAll();
            }        List<BaseEntity> wasRemoved = new List<BaseEntity>();
            void DelayRemoveAll()
            {
                if (currentRemove >= removeFrom.Count)
                {
                    currentRemove = 0;
                    removeFrom.Clear();
                    wasRemoved.Clear();
                    return;
                }
                List<BaseEntity> list = Pool.GetList<BaseEntity>();
                Vis.Entities<BaseEntity>(removeFrom[currentRemove], 3f, list, constructionColl);
                for(int i = 0; i < list.Count; i++)
                {
                    BaseEntity ent = list[i];
                    if (wasRemoved.Contains(ent)) continue;
                    if (!removeFrom.Contains(ent.transform.position))
                        removeFrom.Add(ent.transform.position);
                    wasRemoved.Add(ent);
                    DoRemove(ent);
                }
                currentRemove++;
                timer.Once(0.01f, () => DelayRemoveAll());
            }        static void DoRemove(BaseEntity removeObject)
            {
                if (removeObject == null) return;
                removeObject.KillMessage();
            }
    
    This is the error I get:

    [Oxide] 7:20 PM [Error] RemoverTool.cs(218,23): error CS1525: Unexpected symbol `>'
     
    Last edited by a moderator: Mar 8, 2016
  2. Wulf

    Wulf Community Admin

    What is on line 218? Your error is pointing to that.
     
  3. Jesus, I hit the 10,0000 character limit. Sorry had to trim down the stuff that wasn't code. I made Edits to the code on the original Wulf and the code you needed was added.

    Line 218: {info = <BaseEntity>.list;
     
  4. From what I can tell there is nothing like
    <BaseEntity>
    Not sure what you try to do in that line.
     
  5. I know I posted earlier, but looking back, it was bad and I have made some changes to my file.

    What I am trying to do:

    Remove on the hit of the hammer; instead of the current method where you have to be looking at your object and be within a certain distance.

    I know this is possible. I have seen servers that have it (Rusty Servers).

    Attached is my Remover Tool file. There are no attempts on me trying to figure it out this time. All I have done is trimmed a lot of code fat for stuff I don't use (GUI, RemoveAll, Different Tiers, etc.) So the code is significantly less that the original and should be better to sift through.

    I'd be willing to throw a few $$ on Thursday to someone who can solve this for me (and explain how you did it if you can so I can learn). I just don't like the responsiveness of how it works right now. With a Hammer hit its easy: you must hit the object. No distance calculations or nothing.
     

    Attached Files:

  6. Not completely sure if I got all types of BaseEntities the plugin removes but I think I covered most of them (deployables, signs, building blocks, doors, etc.)
    Disregarding the possibilities that I might have missed some BaseEntities, which I think I didn't, it should function exactly the same as the old RemoveTool just that you actually remove stuff by hitting them with the hammer after you enter the remove command. I also removed some unnecessary code.
    [DOUBLEPOST=1457544711][/DOUBLEPOST]As far as the explanation how I did this goes, I simply got rid of the FixedUpdate() function inside the ToolRemover class which wasn't needed anymore since we won't handle removing with casting a ray anymore.
    Then I removed all the code and values which weren't used as a result. A handy way to instantly tell which values never get used is to look at the compiler log inside .../server/<identity>/oxide/logs!
    Then I simply included the OnHammerHit(...) hook below:
    Code:
    void OnHammerHit(BasePlayer player, HitInfo info)
    {
        if (player.GetComponent<ToolRemover>()) // this is a shorthand for if(player.GetComponent<ToolRemover>() != null)
        {
            if (info.HitEntity.name.Contains("assets/prefabs/deployable") || info.HitEntity is BuildingBlock || info.HitEntity is SimpleBuildingBlock || info.HitEntity is Door)
            {
                TryRemove(player, info.HitEntity);
            }
        }
    }
    The TryRemove(...) function is the one that was already inside the plugin. I just changed the parameters and remove one line of code right at the start of the function.
    I guess the best thing to do would be just using something like Text Compare! - An online diff tool that can find the difference between two texts and pasting both files in there and then simply comparing them.
     

    Attached Files:

    Last edited by a moderator: Mar 9, 2016
  7. You are a godsend lol. Hook me up with some PayPal info I'll send some $ for your work
     
  8. Apk

    Apk

    I'm curious what other kinds of baseentities I can use in this... I decompiled the c# assembly file but I think I'm missing something. With your code a few odds and ends are missing, namely autoturrets, ladders, holiday junk, and locks.

    I fixed part of the problem by just looking for the name, but I'm a little stumped on locks...

    Code:
    if (info.HitEntity.name.Contains("assets/prefabs/deployable") || info.HitEntity is BuildingBlock || info.HitEntity is SimpleBuildingBlock || info.HitEntity is Door || info.HitEntity.name.Contains("autoturret") || info.HitEntity.name.Contains("ladder"))
                    {
                        TryRemove(player, info.HitEntity);
                    }
    I tried info.HitEntity.name.Contains("lock") and info.HitEntity is CodeLock (tried BaseLock as well) but that didn't get me anywhere. I'd swing my hammer as if it was passing through the lock.
     
  9. Same problem with detecting entity. So remove work fine, but refund can't work. Maybe info.HitEntity was not much right variant of detect entity who had hitted by hammer?
     
  10. info.HitEntity.GetComponent<Deployable>() ?
     
  11. For this remover tool, I wonder. How can you make it so that when you remove something it resets the timer back to 30 seconds?
    Should be pretty easy but I'm not very fluent in Java.
     
  12. I saw this plugin on many servers. Maybe this is private plugin wroted by any user of this community for $$
     
  13. Magic Hammer for Rust | Oxide
     
  14. Replace old function with this:

    Code:
    object OnHammerHit(BasePlayer player, HitInfo info)
    {
                if (player.GetComponent<ToolRemover>())
                {
                    if (info.HitEntity.GetComponent<Deployable>() || info.HitEntity is BuildingBlock)
                    {
                        TryRemove(player, info.HitEntity);                    ToolRemover RemoverClass = player.GetComponent<ToolRemover>();
                        RemoverClass.CancelInvoke("DoDestroy");
                        RemoverClass.Invoke("DoDestroy", RemoverClass.endTime);                    return false;
                    }
                }            return null;
    }
     
    Last edited by a moderator: Mar 18, 2016
  15. May be, but this is not remover plugin that i and, i think, many other people saw at the rust servers.
     
  16. Thanks mate, this works perfectly, but one more question. When I change the following to false so that you don't need to place cupboards to remove things in a non-blocked area, it just stops letting me /remove altogether (whether you're authorized to all cupboards or none exist nearby). How can I make it so you don't need to place a cupboard just so you can /remove somewhere where there are no cupboards blocking/authorizing you?

    Thanks again in advance.

    Config File:
    Code:
    "Remove - Access - Use ToolCupboards": false,
     
  17. I'm just give access to players remove only their entity's without any cupboard checks:

    Code:
    object CanRemoveEntity(BasePlayer player, BaseEntity entity)
    {
                if (entity.isDestroyed) return "Object already destroyed."; // possible with hammer hit?
               
                if (player.userID == entity.OwnerID) return true;
               
                if (player.net.connection.authLevel > 0) return true;            return "<color=red>You are not the owner of object.</color>";
    }
     
  18. Nice and useless code, thx much more.

    And now other question guys, on the plugin on this thread, edited by someone, when tryin to remove anything all going well, but
    Refund don't work, in console with yellow color of message wrote: "Effect.Init - invalid entity"
     
  19. Maybe you wanted to say 'useful'? :)
     
    Last edited by a moderator: Jun 12, 2016