Solved How to spawn an Entity without triggering an EntitySpawnEvent

Discussion in 'Plugin Development' started by FilBuild, May 26, 2020.

Thread Status:
Not open for further replies.
  1. Hey!
    So I'm writing a plugin, where every spawned mob gets replaced with a random mob (/Entity).
    The Problem is after I removed the originally spawned Entity and spawned a new Entity, the Entity spawn event gets called again ( and again and again...). I can't figure out how to prevent that. Maybe someone can help me!

    Here is my Code for the Listener:
    Code:
        @EventHandler
        public void onMobSpawn(EntitySpawnEvent e) {
            if (arst == 1) {
    // you can ignore that, just a simple check if the mobs should get replaced at all (activated through commands)
            Entity ent = e.getEntity();
            Location loc = ent.getLocation();
            if (ent.getType() == EntityType.EXPERIENCE_ORB) {
                return;
            }
    // here are following even more entities that should not trigger the replace
            ent.remove();
            EntityType entrnd = null;
            while (entrnd == null) {
                entrnd = EntityType.values()[rnd.nextInt((EntityType.values()).length)];
                if (entrnd == EntityType.ENDER_DRAGON) {
                    entrnd = null;
                }
    //here are following even more Entities that shouldn't be the replacement
            }
            ent.getWorld().spawnEntity(loc, entrnd);
            entrnd = null;
            }
    Thanks in advance!
     
  2. Offline

    BrittleMind

    You could have something like
    Code:
    List<UUID> spawnedEntities = new ArrayList<>();
    
    @EventHandler
    public void onMobSpawn(EntitySpawnEvent e) {
        UUID id = event.getEntity().getUniqueId();
        if(spawnedEntities.contains(id)){
            spawnedEntities.remove(id);
            return;
        }
        ....Your stuff...
       spawnedEntities.add(ent.getWorld().spawnEntity(loc, entrnd).getUniqueId());
    }
    
     
  3. I added your idea, but it still not worked :c

    Here is my Code, did I do something wrong?

    Code:
    @EventHandler
        public void onMobSpawn(EntitySpawnEvent e) {
            if (arst == 1) {
    //You can ignore that.
            Entity ent = e.getEntity();
            Location loc = ent.getLocation();
            if (ent.getType() == EntityType.EXPERIENCE_ORB) {
                return;
            }
    //many more entities following, that should not be replaced
            ent.remove();
            EntityType entrnd = null;
            while (entrnd == null) {
                entrnd = EntityType.values()[rnd.nextInt((EntityType.values()).length)];
                if (entrnd == EntityType.ENDER_DRAGON) {
                    entrnd = null;
                }
    // and more entities that shouldn't be used for replacing following
            }
            spawnedEntities.add(ent.getWorld().spawnEntity(loc, entrnd).getUniqueId());
            entrnd = null;
            }
        }
    Edit: It's still creates a loop
     
  4. Online

    KarimAKL

    @FilBuild I belive you can add a boolean outside of your event to prevent this.
    Code:Java
    1. private boolean spawn = true;
    2.  
    3. @EventHandler
    4. public void onMobSpawn(EntitySpawnEvent event) {
    5. if (!spawn) {
    6. spawn = true;
    7. return;
    8. }
    9. spawn = false;
    10.  
    11. // Your code here
    12. }

    I believe this should work because Minecraft is single-threaded.
     
  5. Offline

    BrittleMind

    T̵r̵u̵e̵,̵ ̵b̵u̵t̵ ̵m̵u̵l̵t̵i̵p̵l̵e̵ ̵E̵n̵t̵i̵t̵y̵S̵p̵a̵w̵n̵E̵v̵e̵n̵t̵ ̵c̵a̵n̵ ̵b̵e̵ ̵t̵r̵i̵g̵g̵e̵r̵e̵d̵ ̵p̵e̵r̵ ̵t̵i̵c̵k̵.̵
    ̵M̵e̵a̵n̵i̵n̵g̵ ̵t̵h̵i̵s̵ ̵d̵o̵e̵s̵n̵'̵t̵ ̵g̵u̵a̵r̵a̵n̵t̵e̵e̵ ̵t̵h̵e̵ ̵v̵e̵r̵y̵ ̵n̵e̵x̵t̵ ̵t̵r̵i̵g̵g̵e̵r̵ ̵i̵s̵ ̵t̵h̵e̵ ̵e̵n̵t̵i̵t̵y̵ ̵j̵u̵s̵t̵ ̵s̵p̵a̵w̵n̵e̵d̵
     
    Last edited by a moderator: May 27, 2020
  6. Online

    KarimAKL

    You're calling the event using World#spawnEntity(...), which means that it'll run next.
     
  7. Offline

    BrittleMind

    #̵T̵i̵c̵k̵ ̵1̵ ̵>̵
    ̵-̵-̵>̵ ̵S̵p̵a̵w̵n̵e̵d̵ ̵C̵r̵e̵e̵p̵e̵r̵ ̵-̵>̵ ̵S̵p̵a̵w̵n̵ ̵e̵n̵t̵i̵t̵y̵ ̵&̵ ̵s̵e̵t̵ ̵b̵o̵o̵l̵e̵a̵n̵ ̵t̵o̵ ̵f̵a̵l̵s̵e̵;̵
    ̵-̵-̵>̵ ̵S̵p̵a̵w̵n̵e̵d̵ ̵Z̵o̵m̵b̵i̵e̵ ̵-̵>̵ ̵b̵o̵o̵l̵e̵a̵n̵ ̵i̵s̵ ̵f̵a̵l̵s̵e̵,̵ ̵s̵e̵t̵ ̵b̵o̵o̵l̵e̵a̵n̵ ̵t̵r̵u̵e̵ ̵d̵o̵ ̵n̵o̵t̵h̵i̵n̵g̵ ̵e̵l̵s̵e̵.̵
    ̵#̵T̵i̵c̵k̵ ̵2̵>̵
    ̵-̵-̵>̵ ̵S̵p̵a̵w̵n̵e̵d̵ ̵E̵n̵t̵i̵t̵y̵ ̵(̵f̵r̵o̵m̵ ̵t̵h̵e̵ ̵f̵i̵r̵s̵t̵ ̵c̵r̵e̵e̵p̵e̵r̵ ̵e̵v̵e̵n̵t̵)̵ ̵-̵>̵ ̵r̵e̵p̵l̵a̵c̵e̵ ̵t̵h̵i̵s̵ ̵e̵n̵t̵i̵t̵y̵ ̵t̵o̵o̵ ̵b̵e̵c̵a̵u̵s̵e̵ ̵b̵o̵o̵l̵e̵a̵n̵ ̵i̵s̵ ̵t̵r̵u̵e̵;̵

    ̵E̵v̵e̵n̵ ̵i̵f̵ ̵t̵h̵e̵ ̵n̵e̵w̵ ̵e̵n̵t̵i̵t̵y̵ ̵w̵a̵s̵ ̵s̵p̵a̵w̵n̵e̵d̵ ̵i̵n̵ ̵t̵h̵e̵ ̵s̵a̵m̵e̵ ̵t̵i̵c̵k̵ ̵(̵w̵h̵i̵c̵h̵ ̵I̵ ̵d̵o̵n̵'̵t̵ ̵t̵h̵i̵n̵k̵ ̵i̵t̵ ̵i̵s̵)̵,̵ ̵i̵t̵ ̵w̵o̵u̵l̵d̵ ̵s̵t̵i̵l̵l̵ ̵b̵e̵ ̵q̵u̵e̵u̵e̵d̵ ̵a̵f̵t̵e̵r̵ ̵t̵h̵e̵ ̵Z̵o̵m̵b̵i̵e̵,̵ ̵w̵h̵e̵r̵e̵ ̵'̵s̵p̵a̵w̵n̵'̵ ̵w̵o̵u̵l̵d̵ ̵b̵e̵ ̵t̵r̵u̵e̵ ̵a̵g̵a̵i̵n̵.̵

    I'm wrong

    ̵A̵n̵d̵ ̵w̵e̵'̵r̵e̵ ̵g̵e̵t̵t̵i̵n̵g̵ ̵o̵f̵f̵ ̵t̵o̵p̵i̵c̵.̵
    It didn't work @FilBuild b̵e̵c̵a̵u̵s̵e̵ ̵y̵o̵u̵ ̵m̵i̵s̵s̵e̵d̵ ̵t̵h̵e̵ ̵i̵f̵ ̵s̵t̵a̵t̵e̵m̵e̵n̵t̵ ̵i̵n̵ ̵m̵y̵ ̵f̵i̵r̵s̵t̵ ̵e̵x̵a̵m̵p̵l̵e̵ :)
     
    Last edited by a moderator: May 27, 2020
  8. Online

    KarimAKL

    The "Spawned Entity" in your example would be spawned before the "Spawned Creeper", not in the next tick.
    This has nothing to do with the Bukkit API, this is just how it works with a single thread.

    Not quite; we're talking about the problem @FilBuild is having.

    No, the World#spawnEntity(...) method calls the new EntitySpawnEvent before adding the entity to the list, which is causing the infinite loop.
     
  9. That would make sense! But how can I prevent that?


    I didn't missed it, I just forgot to paste it in here, my error. It still didn't work :c

    Code:
    @EventHandler
        public void onMobSpawn(EntitySpawnEvent e) {
            if (arst == 1) {
    //You can ignore that.
            Entity ent = e.getEntity();
            Location loc = ent.getLocation();
            if (ent.getType() == EntityType.EXPERIENCE_ORB) {
                return;
            }
    
    //many more entities following, that should not be replaced
    
             UUID id = e.getEntity().getUniqueId();
                if(spawnedEntities.contains(id)){
                    spawnedEntities.remove(id);
                    return;
                }
    
            ent.remove();
            EntityType entrnd = null;
            while (entrnd == null) {
                entrnd = EntityType.values()[rnd.nextInt((EntityType.values()).length)];
                if (entrnd == EntityType.ENDER_DRAGON) {
                    entrnd = null;
                }
    // and more entities that shouldn't be used for replacing following
            }
            spawnedEntities.add(ent.getWorld().spawnEntity(loc, entrnd).getUniqueId());
            entrnd = null;
            }
        }
    And just for it to be complete ( in the case i did another paste error) here is the full code:

    Full Code (open)

    Code:
    package me.filip.rm.cmd;
    
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.UUID;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.EntityType;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntitySpawnEvent;
    
    import me.filip.rm.Main;
    import me.filip.rm.utils.Utils;
    
    public class Rmobs implements CommandExecutor, Listener{
        static int arst = 0;
        List<UUID> spawnedEntities = new ArrayList<>(); 
        static String chck = "rnd";
        Random rnd = new Random();
        @SuppressWarnings("unused")
        private Main plugin;
        public Rmobs(Main plugin) {
            this.plugin = plugin;
            plugin.getCommand("startrm").setExecutor(this);
            Bukkit.getPluginManager().registerEvents(this, plugin);
    }
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String string, String[] args) {
            if (arst == 1) {
                Bukkit.broadcastMessage(Utils.chat("&4Random Mobs has already started!"));
                return false;
            }
            arst = 1;
            Bukkit.broadcastMessage(Utils.chat("&3Random Mobs got started by " + sender.getName()));
            return false;
        }
        @EventHandler
        public void onMobSpawn(EntitySpawnEvent e) {
            if (arst == 1) {
            Entity ent = e.getEntity();
            Location loc = ent.getLocation();
            if (ent.getType() == EntityType.EXPERIENCE_ORB) {
                return;
            }
            if (ent.getType() == EntityType.DROPPED_ITEM) {
                return;
            }
            if (ent.getType() == EntityType.PLAYER) {
                return;
            }
            if (ent.getType() == EntityType.SPLASH_POTION) {
                return;
            }
            if (ent.getType() == EntityType.UNKNOWN) {
                return;
            }
            if (ent.getType() == EntityType.ARROW) {
                return;
            }
            if (ent.getType() == EntityType.COMPLEX_PART) {
                return;
            }
            if (ent.getType() == EntityType.FALLING_BLOCK) {
                return;
            }
            if (ent.getType() == EntityType.MINECART) {
                return;
            }
            if (ent.getType() == EntityType.MINECART_CHEST) {
                return;
            }
            if (ent.getType() == EntityType.THROWN_EXP_BOTTLE) {
                return;
            }
            if (ent.getType() == EntityType.FISHING_HOOK) {
                return;
            }
            if (ent.getType() == EntityType.LEASH_HITCH) {
                return;
            }
            if (ent.getType() == EntityType.BOAT) {
                return;
            }
            if (ent.getType() == EntityType.PAINTING) {
                return;
            }
            if (ent.getType() == EntityType.WITHER_SKULL) {
                return;
            }
            if (ent.getType() == EntityType.ENDER_DRAGON) {
                return;
            }
            if (ent.getType() == EntityType.WITHER) {
                return;
            }
            if (ent.getType() == EntityType.SILVERFISH) {
                return;
            }
            if (ent.getType() == EntityType.WEATHER) {
                return;
            }
             UUID id = e.getEntity().getUniqueId();
                if(spawnedEntities.contains(id)){
                    spawnedEntities.remove(id);
                    return;
                }
            ent.remove();
            EntityType entrnd = null;
            while (entrnd == null) {
                entrnd = EntityType.values()[rnd.nextInt((EntityType.values()).length)];
                if (entrnd == EntityType.ENDER_DRAGON) {
                    entrnd = null;
                }
                if (entrnd == EntityType.COMPLEX_PART) {
                    entrnd = null;
                }
                if (entrnd == EntityType.ENDER_PEARL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.FISHING_HOOK) {
                    entrnd = null;
                }
                if (entrnd == EntityType.FALLING_BLOCK) {
                    entrnd = null;
                }
                if (entrnd == EntityType.ITEM_FRAME) {
                    entrnd = null;
                }
                if (entrnd == EntityType.ENDER_SIGNAL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.LEASH_HITCH) {
                    entrnd = null;
                }
                if (entrnd == EntityType.MINECART_COMMAND) {
                    entrnd = null;
                }
                if (entrnd == EntityType.DROPPED_ITEM) {
                    entrnd = null;
                }
                if (entrnd == EntityType.PLAYER) {
                    entrnd = null;
                }
                if (entrnd == EntityType.UNKNOWN) {
                    entrnd = null;
                }
                if (entrnd == EntityType.WITHER_SKULL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.WITHER) {
                    entrnd = null;
                }
                if (entrnd == EntityType.SMALL_FIREBALL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.FIREBALL) {
                    entrnd = null;
                }
                if (ent.getType() == EntityType.PAINTING) {
                    entrnd = null;
                }
                if (ent.getType() == EntityType.WEATHER) {
                    entrnd = null;
                }
                if (ent.getType() == EntityType.MINECART_MOB_SPAWNER) {
                    entrnd = null;
                }
                if (ent.getType() == EntityType.SNOWBALL) {
                    entrnd = null;
                }
                if (ent.getType() == EntityType.SPLASH_POTION) {
                    entrnd = null;
                }
            }
            spawnedEntities.add(ent.getWorld().spawnEntity(loc, entrnd).getUniqueId());
            entrnd = null;
            }
        }
     
    }
    
     
  10. Offline

    BrittleMind

    @BrittleMind is a moron :)

    @FilBuild , @KarimAKL 's solution should work just fine.
    I didn't realize World#spawnEntity(...) would end up being recursive, therefore Entity#
    getUniqueId() would never return :p
     
    Last edited by a moderator: May 27, 2020
  11. I did some testing too, this works like ~75% of the time. Which for my fun plugin is enough, but it still would be great, if we could get it to 100%.

    Just to throw some ideas in, maybe if you can give the entity some form of tag, before it's gets spawned and then just check in the first part for it? I tried this already, but I only found a way to "tag" the entity after it got spawned, which of course is to late, because than the spawnevent is already triggered.




    Then i did something wrong, here is my code:


    Code:
    package me.filip.rm.cmd;
    
    
    import java.util.Random;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.EntityType;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntitySpawnEvent;
    
    import me.filip.rm.Main;
    import me.filip.rm.utils.Utils;
    
    public class Rmobs implements CommandExecutor, Listener{
        static int arst = 0;
        static boolean pls = false;
        static String chck = "rnd";
        Random rnd = new Random();
        @SuppressWarnings("unused")
        private Main plugin;
        public Rmobs(Main plugin) {
            this.plugin = plugin;
            plugin.getCommand("startrm").setExecutor(this);
            Bukkit.getPluginManager().registerEvents(this, plugin);
    }
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String string, String[] args) {
            if (arst == 1) {
                Bukkit.broadcastMessage(Utils.chat("&4Random Mobs has already started!"));
                return false;
            }
            arst = 1;
            Bukkit.broadcastMessage(Utils.chat("&3Random Mobs got started by " + sender.getName()));
            return false;
        }
        @EventHandler
        public void onMobSpawn(EntitySpawnEvent e) {
            if (arst == 1) {
            Entity ent = e.getEntity();
            Location loc = ent.getLocation();
            if (ent.getType() == EntityType.EXPERIENCE_ORB) {
                return;
            }
            if (ent.getType() == EntityType.DROPPED_ITEM) {
                return;
            }
            if (ent.getType() == EntityType.PLAYER) {
                return;
            }
            if (ent.getType() == EntityType.SPLASH_POTION) {
                return;
            }
            if (ent.getType() == EntityType.UNKNOWN) {
                return;
            }
            if (ent.getType() == EntityType.ARROW) {
                return;
            }
            if (ent.getType() == EntityType.COMPLEX_PART) {
                return;
            }
            if (ent.getType() == EntityType.FALLING_BLOCK) {
                return;
            }
            if (ent.getType() == EntityType.MINECART) {
                return;
            }
            if (ent.getType() == EntityType.MINECART_CHEST) {
                return;
            }
            if (ent.getType() == EntityType.THROWN_EXP_BOTTLE) {
                return;
            }
            if (ent.getType() == EntityType.FISHING_HOOK) {
                return;
            }
            if (ent.getType() == EntityType.LEASH_HITCH) {
                return;
            }
            if (ent.getType() == EntityType.BOAT) {
                return;
            }
            if (ent.getType() == EntityType.PAINTING) {
                return;
            }
            if (ent.getType() == EntityType.WITHER_SKULL) {
                return;
            }
            if (ent.getType() == EntityType.ENDER_DRAGON) {
                return;
            }
            if (ent.getType() == EntityType.WITHER) {
                return;
            }
            if (ent.getType() == EntityType.SILVERFISH) {
                return;
            }
            if (ent.getType() == EntityType.WEATHER) {
                return;
            }
            if (pls == true) {
                pls = false;
                return;
            }
            ent.remove();
            EntityType entrnd = null;
            while (entrnd == null) {
                entrnd = EntityType.values()[rnd.nextInt((EntityType.values()).length)];
                if (entrnd == EntityType.ENDER_DRAGON) {
                    entrnd = null;
                }
                if (entrnd == EntityType.COMPLEX_PART) {
                    entrnd = null;
                }
                if (entrnd == EntityType.ENDER_PEARL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.FISHING_HOOK) {
                    entrnd = null;
                }
                if (entrnd == EntityType.FALLING_BLOCK) {
                    entrnd = null;
                }
                if (entrnd == EntityType.ITEM_FRAME) {
                    entrnd = null;
                }
                if (entrnd == EntityType.ENDER_SIGNAL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.LEASH_HITCH) {
                    entrnd = null;
                }
                if (entrnd == EntityType.MINECART_COMMAND) {
                    entrnd = null;
                }
                if (entrnd == EntityType.DROPPED_ITEM) {
                    entrnd = null;
                }
                if (entrnd == EntityType.PLAYER) {
                    entrnd = null;
                }
                if (entrnd == EntityType.UNKNOWN) {
                    entrnd = null;
                }
                if (entrnd == EntityType.WITHER_SKULL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.WITHER) {
                    entrnd = null;
                }
                if (entrnd == EntityType.SMALL_FIREBALL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.FIREBALL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.PAINTING) {
                    entrnd = null;
                }
                if (entrnd == EntityType.WEATHER) {
                    entrnd = null;
                }
                if (entrnd == EntityType.MINECART_MOB_SPAWNER) {
                    entrnd = null;
                }
                if (entrnd == EntityType.SNOWBALL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.SPLASH_POTION) {
                    entrnd = null;
                }
                if (entrnd == EntityType.EXPERIENCE_ORB) {
                    entrnd = null;
                }
                if (entrnd == EntityType.DROPPED_ITEM) {
                    entrnd = null;
                }
                if (entrnd == EntityType.PLAYER) {
                    entrnd = null;
                }
                if (entrnd == EntityType.SPLASH_POTION) {
                    entrnd = null;
                }
                if (entrnd == EntityType.UNKNOWN) {
                    entrnd = null;
                }
                if (entrnd == EntityType.ARROW) {
                    entrnd = null;
                }
                if (entrnd == EntityType.COMPLEX_PART) {
                    entrnd = null;
                }
                if (entrnd == EntityType.FALLING_BLOCK) {
                    entrnd = null;
                }
                if (entrnd == EntityType.MINECART) {
                    entrnd = null;
                }
                if (entrnd == EntityType.MINECART_CHEST) {
                    entrnd = null;
                }
                if (entrnd == EntityType.THROWN_EXP_BOTTLE) {
                    entrnd = null;
                }
                if (entrnd == EntityType.FISHING_HOOK) {
                    entrnd = null;
                }
                if (entrnd == EntityType.LEASH_HITCH) {
                    entrnd = null;
                }
                if (entrnd == EntityType.BOAT) {
                    entrnd = null;
                }
                if (entrnd == EntityType.PAINTING) {
                    entrnd = null;
                }
                if (entrnd == EntityType.WITHER_SKULL) {
                    entrnd = null;
                }
                if (entrnd == EntityType.ENDER_DRAGON) {
                    entrnd = null;
                }
                if (entrnd == EntityType.WITHER) {
                    entrnd = null;
                }
                if (entrnd == EntityType.SILVERFISH) {
                    entrnd = null;
                }
                if (entrnd == EntityType.WEATHER) {
                    entrnd = null;
                }
                if (entrnd == ent.getType()) {
                    entrnd = null;
                }
            }
            pls = true;
            ent.getWorld().spawnEntity(loc, entrnd);
            entrnd = null;
            }
        }
       
    }
    
     
    Last edited: May 27, 2020
  12. Online

    KarimAKL

    What do you mean by that? What part of it is not working? What is happening instead?

    I haven't worked with this in quite a while but, i think this is possible by creating an entity using NMS and then adding it to the world.

    A few suggestions:
    1. You might want to create a list of entity types you want to have replaced.
    2. 'arst' seems to be used as a toggle, why is it an integer instead of a boolean?
    3. 'arst' and 'pls' doesn't need to be static.
    4. Setting 'entrnd' to null at the end of the event method is not needed, it'll be out of scope anyway.
    5. You might also want to name your variables something clearer. You don't have to give them all short names.
    6. Booleans can be compared using '!' instead of '==' so, for your 'pls' check, you can use "if (pls)" instead of "if (pls == true)", if you're checking for 'false', you can do "if (!pls)".
    7. You can cancel the event instead of removing the entity. Removing the entity might actually not even work.
     
    FilBuild likes this.

  13. Thanks for your tips, it seems like it's working now! Thank you all, i will mark this thread as solved!
     
    KarimAKL likes this.
Thread Status:
Not open for further replies.

Share This Page