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:
And here is where the code above that is brought in: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);
Below is my attempts at trying to figure it out. I got frustrated and stopped so it might look incomplete: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(); }
And again, the other portion with my edits: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);
This is the error I get: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(); }
[Oxide] 7:20 PM [Error] RemoverTool.cs(218,23): error CS1525: Unexpected symbol `>'
Solved Remove Tool with hammer swing using OnHammerHit
Discussion in 'Rust Development' started by Solis.Randy, Mar 8, 2016.
-
Wulf Community Admin
What is on line 218? Your error is pointing to that.
-
Line 218: {info = <BaseEntity>.list; -
<BaseEntity>
Not sure what you try to do in that line. -
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:
-
-
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); } } }
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 -
-
You are a godsend lol. Hook me up with some PayPal info I'll send some $ for your work
-
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); }
-
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?
-
info.HitEntity.GetComponent<Deployable>() ?
-
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. -
-
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 -
-
Thanks again in advance.
Config File:
Code:"Remove - Access - Use ToolCupboards": false,
-
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>"; }
-
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" -
Last edited by a moderator: Jun 12, 2016