1. How would I see when a player has successfully finished farming a Metal/Sulfur Rock Node? I tried OnEntityDeath, but it displays nothing when I have finished the rock.

    I'd like to get the Rock's position and entity name/ID when it's empty/farmed.
    [DOUBLEPOST=1453717582,1453652809][/DOUBLEPOST]I'm trying something else: I spawn a Metal Resource Rock using code and when I print either entity.ToString() or entity.net.ID.ToString() upon spawning them, those numbers will be different from the entity.net.ID.ToString() when I check with OnDispenserGather.

    Code:
    PLAYER ran chat command: /createres
    = Entity Net ID: 19812114OnDispenserGather -> Puts( "Entity Net ID: " + entity.net.ID.ToString() );
    = Entity Net ID: 19803877
    Why are the IDs and entity 'names' different from each other?
     
  2. I'm just guessing but perhaps when it changes model as you mine it the instance of it changes also therefore changing its ID ?
     
    Last edited by a moderator: Jan 25, 2016
  3. It actually has the same Net ID all the time as I mine it.

    When I spawn it it has a Net ID of X, but when I mine it it has Y. I found an alternative to OnEntityDeath - I used OnDispenserGather and I checked how much was left, and I am able to see when it's the last hit, but I can't remove it from my List as it has a different ID.

    I am making a function similar to your CustomLootSpawns plugin, but I am just spawning resource rocks instead.

    I want to make sure that the rocks don't spawn inside each other, so I want to loop through my List and then delete the entities before spawning them again.
     
  4. To get around this issue you could create a MD5 sum (or similar) based on the Position XY and Z of the rock, then use that as an ID.

    Create a custom class that also houses the entity object of the rock as well as it's custom identifier.
     
  5. I have thought about using the position to add it to my List as well, but how would I then find the actual entity by looping through my List and then delete the entity?
     
  6. Create a class which firstly finds all entity types of X (rocks for this example), then holds it inside a custom List<> array.

    For example: (this code is just written here, sorry if it's slightly wrong)
    Code:
    private class RustRockHandler
    {
        private class RustRock
        {
            EntityType Rock;
            string ID;
           
            public RustRock(EntityType rock)
            {
                //Calculate MD5 here from POS
                var _md5 = calcmd5(rock.transform.position);
                Rock = rock;
                ID = _md5;
            }
        }
           
        private readonly List<RustRock> _rustRocks = new List<RustRock>();
       
        //Type maybe something like "sulphur", "metal", "stone", yadda....
        public void FindAllRocksOfType(string type)
        {
            switch ( type )
            {
                case "metal":
                    foreach ( var _entity in GameManager.FindEntities<Thing>() )
                    {
                        _rustRocks.Add(new RustRock(_entity)); //Adds a found rock into the rustRocks array.
                    }
                    break;
                   
                case "stone":
                    //do stuff.
                    break;
            }
        }
       
       
        //Allows a rock to be added manually
        public void AddRock(EntityType rock)
        {
            _rustRocks.Add(new RustRock(rock));
        }
       
        //Gets the RustRock class with a certain ID and returns it.
        public RustRock GetRockByPosition(vector3 position)
        {
            var _md5 = calcmd5(position);
            var _rock = _rustRocks.Where(x => x.ID == _md5).DefaultIfEmpty(null).FirstOrDefault();
            return _rock; //returns NULL if not found.
        }
       
        //Deletes a rock at a position in the array
        public void DeleteRockByPosition(vector3 position)
        {
            var _md5 = calcmd5(position);
            var _rock = _rustRocks.Where(x => x.ID == _md5).DefaultIfEmpty(null).FirstOrDefault();
           
            if ( _rock != null )
                _rustRocks.Remove(_rock);
        }
    }//Declare the new class instance.
    private RustRockHandler _rustRockHandler = new RustRockHandler;//Inside loaded method
    _rustRockHandler.FindAllRocksOfType("metal");//Inside the "hit rock" method hook
    var _myRock = _rustRockHandler.GetRockByPosition(_hitEntity.transform.position);
    if ( _myRock == null )
    {
        // Our array doesnt know about this rock, add it.
        _rustRockHandler.AddRock(_myRock);
    } else {
        if ( _hitInfo.AmountRemaining < 10 ) // Some sort of check to see if the rock is about to die?
        {
            //Delete the game object (unsure how to do this, work it out)
            //Example:
            _myRock.Rock.Remove();
        }
    }[code]
    [DOUBLEPOST=1453977428][/DOUBLEPOST]There is a much better way of doing the FindAllRocksOfType method by the way, using Linq, but without Visual Studio and the Oxide libs where i am currently, i cant write it as i am unsure of the calls to make off the top of my head.
     
  7. Thanks for the example.

    Won't looping through all entities greatly affect server performance?
     
  8. You don't have to do it that way, it would just fill the array when the plugin is loaded.
    You could just leave it as it is without firstly filling the loop, and having the rock add itself when it's first hit to keep the array size down.

    And no, it would only take a extremely short time to do string comparisons on the List array.
     
  9. Maybe I am misunderstanding you, but this function will happen once every 10-30 minutes whenever I have to check if the rocks exist and then delete them and respawn if they do. I have a place with resources that respawn every X minutes, but I don't want them to spawn inside each other thus stacking up to hundreds of rocks if they are left untouched for the day.
     
  10. Why not just spawn a new one randomly in the world as a current one is deemed dead?

    Kinda a one out one in kinda thing.
     
  11. It's a small spot where the resources spawn on the exact same location.
     
  12. Ah, i assume you have an area with custom coordinates where the ore nodes will spawn?

    If so, this will still work with near-zero affect to performance.
    [DOUBLEPOST=1453978173][/DOUBLEPOST]Instead of calculating an MD5, you could just chop up the Position vector and use each one as a string with is appended to the ID variable.
    That way, you have no complicated algorithm to work out.

    Example:
    Code:
    var _myStr = $"{vector.position.x}{vector.position.y}{vector.position.z}";
    Rock.ID == _myStr;
    
     
  13. That's correct.

    I have a very small house with 2 spots.

    Let's say: -3000, 50, -3000 and , -3010, 50, -3000

    When you teleport there there will be 1x Metal Rock and 1x Sulfur Rock in each side of the house.

    If you farm the resource then it's gone, but it will respawn 10 minutes after.

    Every 10 minutes it checks if the rocks are there - if they aren't there then they have been farmed and then can then be respawned - if they are there then the function will return and do nothing and check again in 10 minutes.
     
  14. Ah i see, that makes sense Mathias.
    The class provided will work well for that, expand on it to have their static spawn positions saved, the class itself could deal with everything then... From spawning the rock in the first instance, to the hook method calling a sub-method in the class, to detecting when it's dead and respawning it after x minutes.
     
  15. Thanks a lot for your help, I'll work on your example.
     
  16. No problem, if you need any more help either reply here again or drop me a PM :)