Util On-Tick Checker

Discussion in 'Resources' started by mine2012craft, Apr 26, 2018.

Thread Status:
Not open for further replies.
  1. Offline

    mine2012craft

    So, one of the many things I have problems with is finding out how to check if a specific custom action (Usually for things that don't have their own events) happened on this specific tick, usually the tick it just happened on.

    Well, one of my friends, IGN is Combustible, actually solved this for me! I thought this was a decent workaround to this problem, and wasn't fair to keep it to ourselves, so I decided to post it here.


    PHP:
        /** This method can be used to wrap code that should only execute once per tick
         * for a given metadata object (block, entity, etc.).
         * <br>
         * If this function returns true, the program should proceed - this is the
         * first time it has been invoked on this particular tick
         * <br>
         * If this function returns false, then it has been called already this tick
         * for this entity / metakey pair. When returning false, the code should not
         * be executed.
         * @param plugin The class extending JavaPlugin
         * @param entity The entity being checked
         * @param metakey A unique key that will be checked
         * @return A true/false. If true, this is the first time it has been called. If false, it has been called before.
         */
        
    public static boolean checkOnceThisTick(Core pluginEntity entityString metakey) {
            if (
    entity.hasMetadata(metakey)
                && 
    entity.getMetadata(metakey).get(0).asInt() == entity.getTicksLived()) {
                return 
    false;
            }

            
    entity.setMetadata(metakey, new FixedMetadataValue(pluginentity.getTicksLived()));
            return 
    true;
        }
      
        
    /**
         * This is just another way to check if a certain metakey has been called (This one was made by me)
         * <br>
         * Comes with the ability to offset the tick amount being checked if ever needed (I used mine for BukkitRunnables)
         * @param plugin The class extending JavaPlugin
         * @param entity The entity being checked
         * @param metakey A unique key that will be checked
         * @param tickOffset Offsets the tick amount checked
         * @return A true/false. If true, this has been called already. If false, it has not been called.
         */
        
    public static boolean happenedThisTick(Core pluginEntity entityString metakeyint tickOffset) {
            if (
    entity.hasMetadata(metakey)
                    && 
    entity.getMetadata(metakey).get(0).asInt() == entity.getTicksLived() + tickOffset) {
                    return 
    true;
                }
            return 
    false;
        }
    I edited the code a bit to give explanations on what parameters are used, what returns, and how it works (The first section of explanation was made by the author)

    Big-ol shoutout to Combustible for this good code!
     
  2. Offline

    PhantomUnicorns

    • You're formatting is a little off.
    • You don't even use the reference to Core (JavaPlugin) in the second method.
    • You referenced it as Core instead of JavaPlugin (abstraction based code is better anyways).
    • Also you said for entities, blocks ,ect.. but you only have compatibility for entities.
    • I think you should return the ticks since the last check, that way it has varied application (if not tag is found return 0).
    • It's not really a custom event (something that has no event) it just if they have lived for 0 ticks since the last check?
    It seems pretty useless, when would you use this?

    Edit: In any case (I may be overseeing the usefulness or something) you could make a method that takes a Metadatable or something, it's the interface that allows for metadata.
     
    Last edited: Apr 30, 2018
  3. Offline

    mine2012craft

    I said before, this is not my code, this is my friends. And ya I should've probably made it done so for blocks.

    For me, I use it to create custom death messages if a player is killed in a custom way (ex. Custom Damage Bolts).
    Also I said it can be used to create custom events. I used it to create a SpellDeathEvent, which detects if a player died by a spell. I couldn't detect death via EntityDamageByEntityEvent because it had to come from a spell, and that event detects any source of damage by entity.

    Also used it for small organization purposes. It allows me to check if a player hit something on a tick when they have an ability active. I could've put it in the EntityDamageByEntity event, but I used the above Util to both be able to cancel the runnable when they do, and also so that way I don't have to go and make code elsewhere.

    You may be overlooking its usefulness, and true, it may not be useful to some people, but I think it's a great tool for me for some of my projects.
     
  4. Offline

    PhantomUnicorns

    Just a thought
    Revamp (open)

    Code:
    import org.bukkit.metadata.FixedMetadataValue;
    import org.bukkit.metadata.Metadatable;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Checker {
    
        private static final String _TIME_KEY, _DAMAGE_KEY;
    
        static {
            _TIME_KEY = "timeData";
            _DAMAGE_KEY = "damageData";
        }
    
        private static JavaPlugin _main;
    
        public static void setMain(JavaPlugin main) {
            _main = main;
        }
    
        private String _masterKey;
    
        /**
        * Default masterKey is nothing; this will make it universal
        */
        public Checker() {
            this._masterKey = "";
        }
    
        /**
        * @param masterKey The masterkey to use when setting each MetaData
        */
        public Checker(String masterKey) {
            this._masterKey = masterKey + ".";
        }
    
        /**
        * Gets the time that this method was ran with the Metadatable
        *
        * @param meta
        *            The Metadatable object
        * @param update
        *            If you would like to update the time
        * @return The amount of time it has been in milliseconds
        */
        public long time(Metadatable meta, boolean update) {
            String key = this._masterKey + _TIME_KEY;
            if (meta.hasMetadata(key)) {
                long time = System.currentTimeMillis() - meta.getMetadata(key).get(0).asLong();
                if (update) {
                    meta.getMetadata(key).remove(0);
                    meta.setMetadata(key, new FixedMetadataValue(_main, System.currentTimeMillis()));
                }
                return time;
            } else {
                meta.setMetadata(key, new FixedMetadataValue(_main, System.currentTimeMillis()));
                return 0;
            }
        }
    
        /**
        * Gets the last damage on the Metadatable
        *
        * @param meta
        *            The Metadatable object
        * @param damage
        *            The damage done; use 0 if you none (it will not update if 0)
        * @return The last damage inputed with this Metadatable
        */
        public double lastDamage(Metadatable meta, double damage) {
            String key = this._masterKey + _DAMAGE_KEY;
            if (meta.hasMetadata(key)) {
                double time = meta.getMetadata(key).get(0).asDouble();
                if (damage != 0) {
                    meta.getMetadata(key).remove(0);
                    meta.setMetadata(key, new FixedMetadataValue(_main, damage));
                }
                return time;
            } else {
                if (damage != 0) {
                    meta.setMetadata(key, new FixedMetadataValue(_main, damage));
                }
                return 0;
            }
        }
    
        /**
        * Sets a custom tag to a Metadatable
        *
        * @param meta
        *            The Metadatable
        * @param customKey
        *            The custom key associated with this custom MetaData
        * @param value
        *            The value you would like to set it as; put as null if you don't
        *            want to change it
        * @return The Object that was previously placed with the meta and customKey; if
        *         value was not set before will return null
        */
        public Object customTag(Metadatable meta, String customKey, Object value) {
            String key = this._masterKey + customKey;
            if (meta.hasMetadata(key)) {
                Object object = meta.getMetadata(key).get(0).value();
                if (value != null) {
                    meta.getMetadata(key).remove(0);
                    meta.setMetadata(key, new FixedMetadataValue(_main, value));
                }
                return object;
            } else {
                if (value != null) {
                    meta.setMetadata(key, new FixedMetadataValue(_main, value));
                }
                return null;
            }
        }
    }
    

    It seems better as it has more features and stuff but the lastDamage one is redundant (I think bukkit already stores last damage) but if it doesn't or if you want to make something like it, just replace the names. If you were to make your util in to an API or a fully developed util, it would make for an awesome thing :D

    This would be useful for custom arrows (sounds almost perfect to use the customTag on the arrow entity and when they land test for it)

    EDIT: If you don't want to, I'll do it.
     
    Last edited: Apr 30, 2018
Thread Status:
Not open for further replies.

Share This Page