Thread: [Elvarg / OSRSPK] Woodcutting Skill

Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 26
  1. #11  
    Respected Member


    Kris's Avatar
    Join Date
    Jun 2016
    Age
    26
    Posts
    3,638
    Thanks given
    820
    Thanks received
    2,642
    Rep Power
    5000
    Didn't think it was possible but it just got a whole lot worse than your latest release.
    I don't think I need to even point out what you've done wrong considering how the others have already done a fairly thorough job on it, although I could definitely find more things to pick on.


    Quote Originally Posted by S C A P E View Post
    Arios used them and i got the respawn rates off of arios. They used alot of bitwise operators its quite odd.
    If you find it odd, why did you copy them? Just because a bunch of retards released a content-packed source doesn't necessarily mean their code is good, lol. Go off of your instincts.. And if your instincts suck, you can almost always find an answer to a question at StackOverflow.

    That enum just absolutely killed this lol.
    Attached image
    Reply With Quote  
     

  2. Thankful users:


  3. #12  
    Extreme Donator


    Join Date
    Oct 2010
    Posts
    2,853
    Thanks given
    1,213
    Thanks received
    1,622
    Rep Power
    5000
    I really admire how much you wish to contribute, it's really nice of you.

    I said it on your last release too, but I really think you should create some sort of abstract system for skilling.
    It just looks much cleaner and what's the point in having repetitive code?

    The actions for most skills:
    1. Click object
    2. Wait while your character does an animation
    3. Give player item and respawn the object

    Now, I quickly wrote an abstract class which handles the core things for most skills.

    Code:
    package com.elvarg.game.content.skill.skillable;
    
    import com.elvarg.game.entity.impl.player.Player;
    import com.elvarg.game.task.Task;
    
    /**
     * Acts as an interface for a skill which can be
     * trained.
     *  
     * @author Professor Oak
     */
    public interface Skillable {
    	
    	/**
    	 * Checks if the player has the requirements to start this skill.
    	 * @param player
    	 * @return
    	 */
    	public abstract boolean hasRequiremenets(Player player);
    	
    	/**
    	 * Handles the skill's execution. What should happen and
    	 * what not.
    	 * @param player
    	 */
    	public abstract void execute(Player player);
    	
    	/**
    	 * The success rate (in cycles) for this skill. Used for 
    	 * determing how long it takes for this skill to execute
    	 * before the player receives experience/rewards.
    	 */
    	public abstract int successRate(Player player);
    	
    	/**
    	 * Gives the player materials related to this skill.
    	 * @param player
    	 */
    	public abstract void harvestMaterial(Player player);
    	
    	/**
    	 * Finalizes thie skill, used for things
    	 * such as respawning objects.
    	 * @param player
    	 */
    	public abstract void finalize(Player player);
    	
    	/**
    	 * Often called upon stopping the skill.
    	 * Should be used for resetting attributes,
    	 * such as stopping ongoing {@link Task}s.
    	 * @param player
    	 */
    	public abstract void reset(Player player);
    }
    Now, using this base, I created something I call "DefaultSkillable" which is basically an implementation of this system for a default skill (such as wc, mining).
    Make sure to note the execute method.

    Code:
    package com.elvarg.game.content.skill.skillable.impl;
    
    import java.util.Optional;
    
    import com.elvarg.game.content.skill.skillable.Skillable;
    import com.elvarg.game.entity.impl.player.Player;
    import com.elvarg.game.model.Animation;
    import com.elvarg.game.task.Task;
    import com.elvarg.game.task.TaskManager;
    
    /**
     * Represents a default skillable.
     * A "default" skill is where the player simply animates
     * until a set amount of cycles have passed, and then
     * is rewarded with items.
     * 
     * @author Professor Oak
     *
     */
    public abstract class DefaultSkillable implements Skillable {
    
    	/**
    	 * The {@link Task} which is used to process
    	 * this skill in cycles.
    	 */
    	private Optional<Task> task = Optional.empty();
    
    	@Override
    	public void execute(Player player) {
    		//Start the anim..
    		player.performAnimation(animation());
    
    		//Start task..
    		task = Optional.of(new Task(1, player, false) {
    			int cycle = 0;
    			@Override
    			protected void execute() {
    				//Make sure we still have the requirements to keep skilling..
    				if(!hasRequiremenets(player)) {
    					reset(player);
    					return;
    				}
    				
    				//Loop animation..
    				player.performAnimation(animation());
    				
    				//Attempt to harvest material..
    				if(cycle++ >= successRate(player)) {
    					harvestMaterial(player);
    					cycle = 0;
    				}
    			}
    		});
    		TaskManager.submit(task.get());
    	}
    	
    	@Override
    	public void reset(Player player) {
    		//Stop task..
    		task.ifPresent(task -> task.stop());
    		task = Optional.empty();
    
    		//Reset animation..
    		player.performAnimation(Animation.DEFAULT_RESET_ANIMATION);
    	}
    	
    	@Override
    	public boolean hasRequiremenets(Player player) {
    		//Check inventory slots..
    		if(player.getInventory().getFreeSlots() == 0) {
    			player.getPacketSender().sendMessage("You don't have enough free inventory space.");
    			return false;
    		}
    		//Check busy..
    		if(player.busy()) {
    			return false;
    		}
    		return true;
    	}
    
    	@Override
    	public int successRate(Player player) {
    		return 0;
    	}
    
    	@Override
    	public void harvestMaterial(Player player) {
    		
    	}
    
    	@Override
    	public void finalize(Player player) {
    
    	}
    	
    	public abstract Animation animation();
    }
    Now we can use this "DefaultSkillable" to apply it for Woodcutting:
    Code:
    package com.elvarg.game.content.skill.skillable.impl;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Optional;
    
    import com.elvarg.game.collision.RegionClipping;
    import com.elvarg.game.entity.impl.object.GameObject;
    import com.elvarg.game.entity.impl.player.Player;
    import com.elvarg.game.model.Animation;
    import com.elvarg.game.model.Skill;
    import com.elvarg.game.model.container.impl.Equipment;
    import com.elvarg.game.task.TaskManager;
    import com.elvarg.game.task.impl.TimedObjectSpawnTask;
    import com.elvarg.util.Misc;
    
    /**
     * Represents the Woodcutting skill.
     * @author Professor Oak
     */
    public class Woodcutting extends DefaultSkillable {
    	
    	/**
    	 * Constructs a new {@link Woodcutting}.
    	 * @param treeObject		The tree to cut down.
    	 * @param tree				The tree's data
    	 */
    	public Woodcutting(GameObject treeObject, Tree tree) {
    		this.treeObject = treeObject;
    		this.tree = tree;
    	}
    	
    	/**
    	 * The {@link GameObject} to cut down.
    	 */
    	private final GameObject treeObject;
    
    	/**
    	 * The {@code treeObject} as an enumerated type
    	 * which contains information about it, such as
    	 * required level.
    	 */
    	private final Tree tree;
    
    	/**
    	 * The axe we're using to cut down the tree.
    	 */
    	private Optional<Axe> axe = Optional.empty();
    	
    	@Override
    	public boolean hasRequiremenets(Player player) {
    		//Attempt to find an axe..
    		axe = Optional.empty();
    		for (Axe a : Axe.values()) {
    			if (player.getEquipment().getItems()[Equipment.WEAPON_SLOT].getId() == a.getId()
    					|| player.getInventory().contains(a.getId())) {
    				
    				//If we have already found an axe,
    				//don't select others that are worse or can't be used
    				if(axe.isPresent()) {
    					if(player.getSkillManager().getMaxLevel(Skill.WOODCUTTING) < a .getRequiredLevel()) {
    						continue;
    					}
    					if(a.getRequiredLevel() < axe.get().getRequiredLevel()) {
    						continue;
    					}
    				}
    			
    				axe = Optional.of(a);
    			}
    		}
    
    		//Check if we found one..
    		if(!axe.isPresent()) {
    			player.getPacketSender().sendMessage("You don't have an axe which you can use.");
    			return false;
    		}
    
    		//Check if we have the required level to cut down this {@code tree} using the {@link Axe} we found..
    		if(player.getSkillManager().getCurrentLevel(Skill.WOODCUTTING) < axe.get().getRequiredLevel()) {
    			player.getPacketSender().sendMessage("You don't have an axe which you have the required Woodcutting level to use.");
    			return false;
    		}
    
    		//Check if we have the required level to cut down this {@code tree}..
    		if(player.getSkillManager().getCurrentLevel(Skill.WOODCUTTING) < tree.getRequiredLevel()) {
    			player.getPacketSender().sendMessage("You need a Woodcutting level of at least "+tree.getRequiredLevel()+" to cut this tree.");
    			return false;
    		}
    		
    		//Finally, check if the tree object remains there.
    		//Another player may have cut it down already.
    		if(!RegionClipping.getObject(treeObject.getId(), treeObject.getPosition()).isPresent()) {
    			return false;
    		}
    		
    		return super.hasRequiremenets(player);
    	}
    
    	@Override
    	public void execute(Player player) {
    		player.getPacketSender().sendMessage("You swing your axe at the tree..");
    		super.execute(player);
    	}
    
    	@Override
    	public void harvestMaterial(Player player) {
    		//Add logs..
    		player.getInventory().add(tree.getLogId(), 1);
    		player.getPacketSender().sendMessage("You get some logs.");
    		
    		//Add exp..
    		player.getSkillManager().addExperience(Skill.WOODCUTTING, tree.getXpReward());
    		
    		//Regular trees should always despawn.
    		//Multi trees are random.
    		if(!tree.isMulti() || Misc.getRandom(15) >= 2) {
    			finalize(player);
    		}
    	}
    
    	@Override
    	public void finalize(Player player) {
    		//Stop skilling..
    		reset(player);
    		
    		//Despawn object and respawn it after a short period of time..
    		TaskManager.submit(new TimedObjectSpawnTask(new GameObject(1343, treeObject.getPosition()), treeObject, false, tree.getRespawnTimer()));
    	}
    
    	@Override
    	public Animation animation() {
    		return axe.get().getAnimation();
    	}
    	
    	@Override
    	public int successRate(Player player) {
    		int cycles = tree.getCycles() - ((int)((player.getSkillManager().getMaxLevel(Skill.WOODCUTTING) * 0.07) * axe.get().getSpeed()));
    		if(cycles < 1) {
    			cycles = 1;
    		}
    		return cycles;
    	}
    	
    	public GameObject getTreeObject() {
    		return treeObject;
    	}
    	
    	/**
    	 * Holds data related to the axes
    	 * that can be used for this skill.
    	 */
    	public static enum Axe {
    		BRONZE_AXE(1351, 1, 1.0, new Animation(879)),
    		IRON_AXE(1349, 1, 1.05, new Animation(877)),
    		STEEL_AXE(1353, 6, 1.1, new Animation(875)),
    		BLACK_AXE(1361, 6, 1.15, new Animation(873)),
    		MITHRIL_AXE(1355, 21, 1.2, new Animation(871)),
    		ADAMANT_AXE(1357, 31, 1.33, new Animation(869)),
    		RUNE_AXE(1359, 41, 1.51, new Animation(867)),
    		DRAGON_AXE(6739, 61, 1.9, new Animation(2846)),
    		INFERNAL(13241,61, 2.2, new Animation(2117));
    		
    		private final int id;
    		private final int requiredLevel;
    		private final double speed;
    		private final Animation animation;
    		
    		private Axe(int id, int level, double speed, Animation animation) {
    			this.id = id;
    			this.requiredLevel = level;
    			this.speed = speed;
    			this.animation = animation;
    		}
    
    		public int getId() {
    			return id;
    		}
    
    		public int getRequiredLevel() {
    			return requiredLevel;
    		}
    
    		public double getSpeed() {
    			return speed;
    		}
    
    		public Animation getAnimation() {
    			return animation;
    		}
    	}
    
    	/**
    	 * Holds data related to the trees 
    	 * which can be used to train this skill.
    	 */
    	public static enum Tree {
    		NORMAL(1, 3655, 1511, new int[] { 1276, 1277, 1278, 1279, 1280, 1282, 1283, 1284, 1285, 1286, 1289, 1290, 1291, 1315, 1316, 1318, 1319, 1330, 1331, 1332, 1365, 1383, 1384, 3033, 3034, 3035, 3036, 3881, 3882, 3883, 5902, 5903, 5904 }, 5, 8, false),
    		ACHEY(1, 3655, 2862, new int[] { 2023 }, 5, 9, false),
    		OAK(15, 4684, 1521, new int[] { 1281, 3037 }, 6, 11, true),
    		WILLOW(30, 6346, 1519, new int[] { 1308, 5551, 5552, 5553 }, 9, 14, true),
    		TEAK(35, 6544, 6333, new int[] { 9036 }, 10, 16, true),
    		DRAMEN(36, 6581, 771, new int[] { 1292 }, 11, 17, true),
    		MAPLE(45, 7935, 1517, new int[] { 1307, 4677 }, 12, 18, true),
    		MAHOGANY(50, 8112, 6332, new int[] { 9034 }, 13, 20, true),
    		YEW(60, 8417, 1515, new int[] { 1309 }, 14, 28, true),
    		MAGIC(75, 9127, 1513, new int[] { 1306 }, 15, 40, true);
    
    		private final int[] objects;
    		private final int requiredLevel;
    		private final int xpReward;
    		private final int logId;
    		private final int cycles;
    		private final int respawnTimer;
    		private final boolean multi;
    
    		Tree(int req, int xp, int log, int[] obj, int cycles, int respawnTimer, boolean multi) {
    			this.requiredLevel = req;
    			this.xpReward = xp;
    			this.logId = log;
    			this.objects = obj;
    			this.cycles = cycles;
    			this.respawnTimer = respawnTimer;
    			this.multi = multi;
    		}
    
    		public boolean isMulti() {
    			return multi;
    		}
    		
    		public int getCycles() {
    			return cycles;
    		}
    
    		public int getRespawnTimer() {
    			return respawnTimer;
    		}
    
    		public int getLogId() {
    			return logId;
    		}
    
    		public int getXpReward() {
    			return xpReward;
    		}
    
    		public int getRequiredLevel() {
    			return requiredLevel;
    		}
    
    		private static final Map<Integer, Tree> trees = new HashMap<Integer, Tree>();
    
    		static {
    			for (Tree t : Tree.values()) {
    				for (int obj : t.objects) {
    					trees.put(obj, t);
    				}
    				trees.put(t.getLogId(), t);
    			}
    		}
    
    		public static Optional<Tree> forObjectId(int objectId) {
    			Tree tree = trees.get(objectId);
    			if(tree != null) {
    				return Optional.of(tree);
    			}
    			return Optional.empty();
    		}
    	}
    }
    This is much more efficient and allows me to use the same system for multiple skills. I wrote up this up very quickly. I'm sure it can be improved very much, feel free to do so.


    edit2: Added Mining in literally 15 minutes, woodcutting and mining are pretty much identical skills lol.
    Attached image

    Take a look yourself:
    Code:
    package com.elvarg.game.content.skill.skillable.impl;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Optional;
    
    import com.elvarg.game.collision.RegionClipping;
    import com.elvarg.game.entity.impl.object.GameObject;
    import com.elvarg.game.entity.impl.player.Player;
    import com.elvarg.game.model.Animation;
    import com.elvarg.game.model.Skill;
    import com.elvarg.game.model.container.impl.Equipment;
    import com.elvarg.game.task.TaskManager;
    import com.elvarg.game.task.impl.TimedObjectSpawnTask;
    
    /**
     * Represents the Mining skill.
     * @author Professor Oak
     */
    public class Mining extends DefaultSkillable {
    	
    	/**
    	 * Constructs a new {@link Mining}.
    	 * @param rockObject		The rock to mine.
    	 * @param rock				The rock's data
    	 */
    	public Mining(GameObject rockObject, Rock rock) {
    		this.rockObject = rockObject;
    		this.rock = rock;
    	}
    	
    	/**
    	 * The {@link GameObject} to mine.
    	 */
    	private final GameObject rockObject;
    
    	/**
    	 * The {@code rock} as an enumerated type
    	 * which contains information about it, such as
    	 * required level.
    	 */
    	private final Rock rock;
    
    	/**
    	 * The pickaxe we're using to mine.
    	 */
    	private Optional<Pickaxe> pickaxe = Optional.empty();
    	
    	@Override
    	public boolean hasRequiremenets(Player player) {
    		//Attempt to find a pickaxe..
    		pickaxe = Optional.empty();
    		for (Pickaxe a : Pickaxe.values()) {
    			if (player.getEquipment().getItems()[Equipment.WEAPON_SLOT].getId() == a.getId()
    					|| player.getInventory().contains(a.getId())) {
    				
    				//If we have already found a pickaxe,
    				//don't select others that are worse or can't be used
    				if(pickaxe.isPresent()) {
    					if(player.getSkillManager().getMaxLevel(Skill.MINING) < a .getRequiredLevel()) {
    						continue;
    					}
    					if(a.getRequiredLevel() < pickaxe.get().getRequiredLevel()) {
    						continue;
    					}
    				}
    				
    				pickaxe = Optional.of(a);
    			}
    		}
    
    		//Check if we found one..
    		if(!pickaxe.isPresent()) {
    			player.getPacketSender().sendMessage("You don't have a pickaxe which you can use.");
    			return false;
    		}
    
    		//Check if we have the required level to mine this {@code rock} using the {@link Pickaxe} we found..
    		if(player.getSkillManager().getCurrentLevel(Skill.MINING) < pickaxe.get().getRequiredLevel()) {
    			player.getPacketSender().sendMessage("You don't have a pickaxe which you have the required Mining level to use.");
    			return false;
    		}
    
    		//Check if we have the required level to mine this {@code rock}..
    		if(player.getSkillManager().getCurrentLevel(Skill.MINING) < rock.getRequiredLevel()) {
    			player.getPacketSender().sendMessage("You need a Mining level of at least "+rock.getRequiredLevel()+" to mine this rock.");
    			return false;
    		}
    		
    		//Finally, check if the rock object remains there.
    		//Another player may have mined it already.
    		if(!RegionClipping.getObject(rockObject.getId(), rockObject.getPosition()).isPresent()) {
    			return false;
    		}
    		
    		return super.hasRequiremenets(player);
    	}
    
    	@Override
    	public void execute(Player player) {
    		player.getPacketSender().sendMessage("You swing your pickaxe at the rock..");
    		super.execute(player);
    	}
    
    	@Override
    	public void harvestMaterial(Player player) {
    		//Add ores..
    		player.getInventory().add(rock.getOreId(), 1);
    		player.getPacketSender().sendMessage("You get some ores.");
    		
    		//Add exp..
    		player.getSkillManager().addExperience(Skill.MINING, rock.getXpReward());
    		
    		//Despawn rock..
    		finalize(player);
    	}
    
    	@Override
    	public void finalize(Player player) {
    		//Stop skilling..
    		reset(player);
    		
    		//Despawn object and respawn it after a short period of time..
    		TaskManager.submit(new TimedObjectSpawnTask(new GameObject(2704, rockObject.getPosition()), rockObject, false, rock.getRespawnTimer()));
    	}
    
    	@Override
    	public Animation animation() {
    		return pickaxe.get().getAnimation();
    	}
    	
    	@Override
    	public int successRate(Player player) {
    		int cycles = rock.getCycles() - ((int)((player.getSkillManager().getMaxLevel(Skill.MINING) * 0.07) * pickaxe.get().getSpeed()));
    		if(cycles < 1) {
    			cycles = 1;
    		}
    		return cycles;
    	}
    	
    	public GameObject getTreeObject() {
    		return rockObject;
    	}
    	
    	/**
    	 * Holds data related to the pickaxes
    	 * that can be used for this skill.
    	 */
    	public static enum Pickaxe {
    		BRONZE(1265, 1, new Animation(625), 1.0),
    		IRON(1267, 1, new Animation(626), 1.05),
    		STEEL(1269, 6, new Animation(627), 1.1),
    		MITHRIL(1273, 21, new Animation(628), 1.2),
    		ADAMANT(1271, 31, new Animation(629), 1.33),
    		RUNE(1275, 41, new Animation(624), 1.51),
    		DRAGON(15259, 61, new Animation(624), 1.9);
    
    		private final int id, requiredLevel;
    		private final Animation animation;
    		private final double speed;
    		
    		private Pickaxe(int id, int req, Animation animaion, double speed) {
    			this.id = id;
    			this.requiredLevel = req;
    			this.animation = animaion;
    			this.speed = speed;
    		}
    
    		public int getId() {
    			return id;
    		}
    		
    		public int getRequiredLevel() {
    			return requiredLevel;
    		}
    
    		public Animation getAnimation() {
    			return animation;
    		}
    		
    		public double getSpeed() {
    			return this.speed;
    		}
    	}
    
    	/**
    	 * Holds data related to the rocks 
    	 * which can be used to train this skill.
    	 */
    	public static enum Rock {
    		CLAY(new int[]{9711, 9712, 9713, 15503, 15504, 15505}, 1, 450, 434, 4, 2),
    		COPPER(new int[]{9708, 9709, 9710, 11936, 11960, 11961, 11962, 11189, 11190, 11191, 29231, 29230, 2090}, 1, 1550, 436, 5, 4),
    		TIN(new int[]{9714, 9715, 9716, 11933, 11957, 11958, 11959, 11186, 11187, 11188, 2094, 29227, 29229}, 1, 1550, 438, 5, 4),
    		IRON(new int[]{7455, 9717, 9718, 9719, 2093, 2092, 11954, 11955, 11956, 29221, 29222, 29223}, 15, 2450, 440, 6, 5),
    		SILVER(new int[]{2100, 2101, 29226, 29225, 11948, 11949}, 20, 2760, 442, 7, 7),
    		COAL(new int[]{2097, 5770, 29216, 29215, 29217, 11965, 11964, 11963, 11930, 11931, 11932}, 30, 3450, 453, 7, 7),
    		GOLD(new int[]{9720, 9721, 9722, 11951, 11183, 11184, 11185, 2099}, 40, 4580, 444, 8, 10),
    		MITHRIL(new int[]{25370, 25368, 5786, 5784, 11942, 11943, 11944, 11945, 11946, 29236, 11947, 11942, 11943}, 50, 6300, 447, 11, 11),
    		ADAMANTITE(new int[]{11941, 11939, 29233, 29235}, 70, 9560, 449, 13, 14),
    		RUNITE(new int[]{14859, 4860, 2106, 2107}, 85, 15122, 451, 15, 45),;
    
    		private int objects[];
    		private int oreId, requiredLevel, xpReward, cycles, respawnTimer;
    
    		private Rock(int[] objects, int requiredLevel, int xpReward, int oreId, int cycles, int respawnTimer) {
    			this.objects = objects;
    			this.requiredLevel = requiredLevel;
    			this.xpReward = xpReward;
    			this.oreId = oreId;
    			this.cycles = cycles;
    			this.respawnTimer = respawnTimer;
    		}
    
    		public int getRespawnTimer() {
    			return respawnTimer;
    		}
    
    		public int getRequiredLevel() {
    			return requiredLevel;
    		}
    
    		public int getXpReward(){
    			return xpReward;
    		}
    
    		public int getOreId() {
    			return oreId;
    		}
    
    		public int getCycles() {
    			return cycles;
    		}
    		
    		private static final Map<Integer, Rock> rocks = new HashMap<Integer, Rock>();
    
    		static {
    			for (Rock t : Rock.values()) {
    				for (int obj : t.objects) {
    					rocks.put(obj, t);
    				}
    				rocks.put(t.getOreId(), t);
    			}
    		}
    
    		public static Optional<Rock> forObjectId(int objectId) {
    			Rock rock = rocks.get(objectId);
    			if(rock != null) {
    				return Optional.of(rock);
    			}
    			return Optional.empty();
    		}
    	}
    }
    [Today 01:29 AM] RSTrials: Nice 0.97 Win/Loss Ratio luke. That's pretty bad.
    [Today 01:30 AM] Luke132: Ok u fucking moron i forgot i could influence misc.random
    Reply With Quote  
     


  4. #13  
    Ex Rune-Scaper

    Join Date
    Jun 2008
    Posts
    3,534
    Thanks given
    457
    Thanks received
    1,257
    Rep Power
    990
    Quote Originally Posted by Professor Oak View Post
    I really admire how much you wish to contribute, it's really nice of you.

    I said it on your last release too, but I really think you should create some sort of abstract system for skilling.
    It just looks much cleaner and what's the point in having repetitive code?

    The actions for most skills:
    1. Click object
    2. Wait while your character does an animation
    3. Give player item and respawn the object

    Now, I quickly wrote an abstract class which handles the core things for most skills.

    Code:
    /**
     * Acts as a parent for a skill which can be
     * trained.
     *  
     * @author Professor Oak
     */
    public abstract class Skillable {
    	
    	/**
    	 * Checks if the player has the requirements to start this skill.
    	 * @param player
    	 * @return
    	 */
    	public abstract boolean hasRequiremenets(Player player);
    	
    	/**
    	 * Handles the skill's execution. What should happen and
    	 * what not.
    	 * @param player
    	 */
    	public abstract void execute(Player player);
    	
    	/**
    	 * The success rate (in cycles) for this skill. Used for 
    	 * determing how long it takes for this skill to execute
    	 * before the player receives experience/rewards.
    	 */
    	public abstract int successRate(Player player);
    	
    	/**
    	 * Gives the player materials related to this skill.
    	 * @param player
    	 */
    	public abstract void harvestMaterial(Player player);
    	
    	/**
    	 * Finalizes thie skill, used for things
    	 * such as respawning objects.
    	 * @param player
    	 */
    	public abstract void finalize(Player player);
    	
    	/**
    	 * Often called upon stopping the skill.
    	 * Should be used for resetting attributes,
    	 * such as stopping ongoing {@link Task}s.
    	 * @param player
    	 */
    	public abstract void reset(Player player);
    If you're only going to have abstract method and no implementation in this class (which im assuming you're not) make this an interface instead of an abstract class so you can have multiple inheritance.
    Attached image
    Reply With Quote  
     

  5. #14  
    Extreme Donator


    Join Date
    Oct 2010
    Posts
    2,853
    Thanks given
    1,213
    Thanks received
    1,622
    Rep Power
    5000
    Quote Originally Posted by Freyr View Post
    If you're only going to have abstract method and no implementation in this class (which im assuming you're not) make this an interface instead of an abstract class so you can have multiple inheritance.
    edit: I did have an implementation but got rid of it. I'll do that
    edit2: modified my post and added mining
    [Today 01:29 AM] RSTrials: Nice 0.97 Win/Loss Ratio luke. That's pretty bad.
    [Today 01:30 AM] Luke132: Ok u fucking moron i forgot i could influence misc.random
    Reply With Quote  
     

  6. #15  
    Registered Member
    Andys1814's Avatar
    Join Date
    Feb 2013
    Posts
    974
    Thanks given
    688
    Thanks received
    455
    Rep Power
    727
    [SPOIL]
    Quote Originally Posted by Professor Oak View Post
    I really admire how much you wish to contribute, it's really nice of you.

    I said it on your last release too, but I really think you should create some sort of abstract system for skilling.
    It just looks much cleaner and what's the point in having repetitive code?

    The actions for most skills:
    1. Click object
    2. Wait while your character does an animation
    3. Give player item and respawn the object

    Now, I quickly wrote an abstract class which handles the core things for most skills.

    Code:
    package com.elvarg.game.content.skill.skillable;
    
    import com.elvarg.game.entity.impl.player.Player;
    import com.elvarg.game.task.Task;
    
    /**
     * Acts as an interface for a skill which can be
     * trained.
     *  
     * @author Professor Oak
     */
    public interface Skillable {
    	
    	/**
    	 * Checks if the player has the requirements to start this skill.
    	 * @param player
    	 * @return
    	 */
    	public abstract boolean hasRequiremenets(Player player);
    	
    	/**
    	 * Handles the skill's execution. What should happen and
    	 * what not.
    	 * @param player
    	 */
    	public abstract void execute(Player player);
    	
    	/**
    	 * The success rate (in cycles) for this skill. Used for 
    	 * determing how long it takes for this skill to execute
    	 * before the player receives experience/rewards.
    	 */
    	public abstract int successRate(Player player);
    	
    	/**
    	 * Gives the player materials related to this skill.
    	 * @param player
    	 */
    	public abstract void harvestMaterial(Player player);
    	
    	/**
    	 * Finalizes thie skill, used for things
    	 * such as respawning objects.
    	 * @param player
    	 */
    	public abstract void finalize(Player player);
    	
    	/**
    	 * Often called upon stopping the skill.
    	 * Should be used for resetting attributes,
    	 * such as stopping ongoing {@link Task}s.
    	 * @param player
    	 */
    	public abstract void reset(Player player);
    }
    Now, using this base, I created something I call "DefaultSkillable" which is basically an implementation of this system for a default skill (such as wc, mining).
    Make sure to note the execute method.

    Code:
    package com.elvarg.game.content.skill.skillable.impl;
    
    import java.util.Optional;
    
    import com.elvarg.game.content.skill.skillable.Skillable;
    import com.elvarg.game.entity.impl.player.Player;
    import com.elvarg.game.model.Animation;
    import com.elvarg.game.task.Task;
    import com.elvarg.game.task.TaskManager;
    
    /**
     * Represents a default skillable.
     * A "default" skill is where the player simply animates
     * until a set amount of cycles have passed, and then
     * is rewarded with items.
     * 
     * @author Professor Oak
     *
     */
    public abstract class DefaultSkillable implements Skillable {
    
    	/**
    	 * The {@link Task} which is used to process
    	 * this skill in cycles.
    	 */
    	private Optional<Task> task = Optional.empty();
    
    	@Override
    	public void execute(Player player) {
    		//Start the anim..
    		player.performAnimation(animation());
    
    		//Start task..
    		task = Optional.of(new Task(1, player, false) {
    			int cycle = 0;
    			@Override
    			protected void execute() {
    				//Make sure we still have the requirements to keep skilling..
    				if(!hasRequiremenets(player)) {
    					reset(player);
    					return;
    				}
    				
    				//Loop animation..
    				player.performAnimation(animation());
    				
    				//Attempt to harvest material..
    				if(cycle++ >= successRate(player)) {
    					harvestMaterial(player);
    					cycle = 0;
    				}
    			}
    		});
    		TaskManager.submit(task.get());
    	}
    	
    	@Override
    	public void reset(Player player) {
    		//Stop task..
    		task.ifPresent(task -> task.stop());
    		task = Optional.empty();
    
    		//Reset animation..
    		player.performAnimation(Animation.DEFAULT_RESET_ANIMATION);
    	}
    	
    	@Override
    	public boolean hasRequiremenets(Player player) {
    		//Check inventory slots..
    		if(player.getInventory().getFreeSlots() == 0) {
    			player.getPacketSender().sendMessage("You don't have enough free inventory space.");
    			return false;
    		}
    		//Check busy..
    		if(player.busy()) {
    			return false;
    		}
    		return true;
    	}
    
    	@Override
    	public int successRate(Player player) {
    		return 0;
    	}
    
    	@Override
    	public void harvestMaterial(Player player) {
    		
    	}
    
    	@Override
    	public void finalize(Player player) {
    
    	}
    	
    	public abstract Animation animation();
    }
    Now we can use this "DefaultSkillable" to apply it for Woodcutting:
    Code:
    package com.elvarg.game.content.skill.skillable.impl;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Optional;
    
    import com.elvarg.game.collision.RegionClipping;
    import com.elvarg.game.entity.impl.object.GameObject;
    import com.elvarg.game.entity.impl.player.Player;
    import com.elvarg.game.model.Animation;
    import com.elvarg.game.model.Skill;
    import com.elvarg.game.model.container.impl.Equipment;
    import com.elvarg.game.task.TaskManager;
    import com.elvarg.game.task.impl.TimedObjectSpawnTask;
    import com.elvarg.util.Misc;
    
    /**
     * Represents the Woodcutting skill.
     * @author Professor Oak
     */
    public class Woodcutting extends DefaultSkillable {
    	
    	/**
    	 * Constructs a new {@link Woodcutting}.
    	 * @param treeObject		The tree to cut down.
    	 * @param tree				The tree's data
    	 */
    	public Woodcutting(GameObject treeObject, Tree tree) {
    		this.treeObject = treeObject;
    		this.tree = tree;
    	}
    	
    	/**
    	 * The {@link GameObject} to cut down.
    	 */
    	private final GameObject treeObject;
    
    	/**
    	 * The {@code treeObject} as an enumerated type
    	 * which contains information about it, such as
    	 * required level.
    	 */
    	private final Tree tree;
    
    	/**
    	 * The axe we're using to cut down the tree.
    	 */
    	private Optional<Axe> axe = Optional.empty();
    	
    	@Override
    	public boolean hasRequiremenets(Player player) {
    		//Attempt to find an axe..
    		axe = Optional.empty();
    		for (Axe a : Axe.values()) {
    			if (player.getEquipment().getItems()[Equipment.WEAPON_SLOT].getId() == a.getId()
    					|| player.getInventory().contains(a.getId())) {
    				
    				//If we have already found an axe,
    				//don't select others that are worse or can't be used
    				if(axe.isPresent()) {
    					if(player.getSkillManager().getMaxLevel(Skill.WOODCUTTING) < a .getRequiredLevel()) {
    						continue;
    					}
    					if(a.getRequiredLevel() < axe.get().getRequiredLevel()) {
    						continue;
    					}
    				}
    			
    				axe = Optional.of(a);
    			}
    		}
    
    		//Check if we found one..
    		if(!axe.isPresent()) {
    			player.getPacketSender().sendMessage("You don't have an axe which you can use.");
    			return false;
    		}
    
    		//Check if we have the required level to cut down this {@code tree} using the {@link Axe} we found..
    		if(player.getSkillManager().getCurrentLevel(Skill.WOODCUTTING) < axe.get().getRequiredLevel()) {
    			player.getPacketSender().sendMessage("You don't have an axe which you have the required Woodcutting level to use.");
    			return false;
    		}
    
    		//Check if we have the required level to cut down this {@code tree}..
    		if(player.getSkillManager().getCurrentLevel(Skill.WOODCUTTING) < tree.getRequiredLevel()) {
    			player.getPacketSender().sendMessage("You need a Woodcutting level of at least "+tree.getRequiredLevel()+" to cut this tree.");
    			return false;
    		}
    		
    		//Finally, check if the tree object remains there.
    		//Another player may have cut it down already.
    		if(!RegionClipping.getObject(treeObject.getId(), treeObject.getPosition()).isPresent()) {
    			return false;
    		}
    		
    		return super.hasRequiremenets(player);
    	}
    
    	@Override
    	public void execute(Player player) {
    		player.getPacketSender().sendMessage("You swing your axe at the tree..");
    		super.execute(player);
    	}
    
    	@Override
    	public void harvestMaterial(Player player) {
    		//Add logs..
    		player.getInventory().add(tree.getLogId(), 1);
    		player.getPacketSender().sendMessage("You get some logs.");
    		
    		//Add exp..
    		player.getSkillManager().addExperience(Skill.WOODCUTTING, tree.getXpReward());
    		
    		//Regular trees should always despawn.
    		//Multi trees are random.
    		if(!tree.isMulti() || Misc.getRandom(15) >= 2) {
    			finalize(player);
    		}
    	}
    
    	@Override
    	public void finalize(Player player) {
    		//Stop skilling..
    		reset(player);
    		
    		//Despawn object and respawn it after a short period of time..
    		TaskManager.submit(new TimedObjectSpawnTask(new GameObject(1343, treeObject.getPosition()), treeObject, false, tree.getRespawnTimer()));
    	}
    
    	@Override
    	public Animation animation() {
    		return axe.get().getAnimation();
    	}
    	
    	@Override
    	public int successRate(Player player) {
    		int cycles = tree.getCycles() - ((int)((player.getSkillManager().getMaxLevel(Skill.WOODCUTTING) * 0.07) * axe.get().getSpeed()));
    		if(cycles < 1) {
    			cycles = 1;
    		}
    		return cycles;
    	}
    	
    	public GameObject getTreeObject() {
    		return treeObject;
    	}
    	
    	/**
    	 * Holds data related to the axes
    	 * that can be used for this skill.
    	 */
    	public static enum Axe {
    		BRONZE_AXE(1351, 1, 1.0, new Animation(879)),
    		IRON_AXE(1349, 1, 1.05, new Animation(877)),
    		STEEL_AXE(1353, 6, 1.1, new Animation(875)),
    		BLACK_AXE(1361, 6, 1.15, new Animation(873)),
    		MITHRIL_AXE(1355, 21, 1.2, new Animation(871)),
    		ADAMANT_AXE(1357, 31, 1.33, new Animation(869)),
    		RUNE_AXE(1359, 41, 1.51, new Animation(867)),
    		DRAGON_AXE(6739, 61, 1.9, new Animation(2846)),
    		INFERNAL(13241,61, 2.2, new Animation(2117));
    		
    		private final int id;
    		private final int requiredLevel;
    		private final double speed;
    		private final Animation animation;
    		
    		private Axe(int id, int level, double speed, Animation animation) {
    			this.id = id;
    			this.requiredLevel = level;
    			this.speed = speed;
    			this.animation = animation;
    		}
    
    		public int getId() {
    			return id;
    		}
    
    		public int getRequiredLevel() {
    			return requiredLevel;
    		}
    
    		public double getSpeed() {
    			return speed;
    		}
    
    		public Animation getAnimation() {
    			return animation;
    		}
    	}
    
    	/**
    	 * Holds data related to the trees 
    	 * which can be used to train this skill.
    	 */
    	public static enum Tree {
    		NORMAL(1, 3655, 1511, new int[] { 1276, 1277, 1278, 1279, 1280, 1282, 1283, 1284, 1285, 1286, 1289, 1290, 1291, 1315, 1316, 1318, 1319, 1330, 1331, 1332, 1365, 1383, 1384, 3033, 3034, 3035, 3036, 3881, 3882, 3883, 5902, 5903, 5904 }, 5, 8, false),
    		ACHEY(1, 3655, 2862, new int[] { 2023 }, 5, 9, false),
    		OAK(15, 4684, 1521, new int[] { 1281, 3037 }, 6, 11, true),
    		WILLOW(30, 6346, 1519, new int[] { 1308, 5551, 5552, 5553 }, 9, 14, true),
    		TEAK(35, 6544, 6333, new int[] { 9036 }, 10, 16, true),
    		DRAMEN(36, 6581, 771, new int[] { 1292 }, 11, 17, true),
    		MAPLE(45, 7935, 1517, new int[] { 1307, 4677 }, 12, 18, true),
    		MAHOGANY(50, 8112, 6332, new int[] { 9034 }, 13, 20, true),
    		YEW(60, 8417, 1515, new int[] { 1309 }, 14, 28, true),
    		MAGIC(75, 9127, 1513, new int[] { 1306 }, 15, 40, true);
    
    		private final int[] objects;
    		private final int requiredLevel;
    		private final int xpReward;
    		private final int logId;
    		private final int cycles;
    		private final int respawnTimer;
    		private final boolean multi;
    
    		Tree(int req, int xp, int log, int[] obj, int cycles, int respawnTimer, boolean multi) {
    			this.requiredLevel = req;
    			this.xpReward = xp;
    			this.logId = log;
    			this.objects = obj;
    			this.cycles = cycles;
    			this.respawnTimer = respawnTimer;
    			this.multi = multi;
    		}
    
    		public boolean isMulti() {
    			return multi;
    		}
    		
    		public int getCycles() {
    			return cycles;
    		}
    
    		public int getRespawnTimer() {
    			return respawnTimer;
    		}
    
    		public int getLogId() {
    			return logId;
    		}
    
    		public int getXpReward() {
    			return xpReward;
    		}
    
    		public int getRequiredLevel() {
    			return requiredLevel;
    		}
    
    		private static final Map<Integer, Tree> trees = new HashMap<Integer, Tree>();
    
    		static {
    			for (Tree t : Tree.values()) {
    				for (int obj : t.objects) {
    					trees.put(obj, t);
    				}
    				trees.put(t.getLogId(), t);
    			}
    		}
    
    		public static Optional<Tree> forObjectId(int objectId) {
    			Tree tree = trees.get(objectId);
    			if(tree != null) {
    				return Optional.of(tree);
    			}
    			return Optional.empty();
    		}
    	}
    }
    This is much more efficient and allows me to use the same system for multiple skills. I wrote up this up very quickly. I'm sure it can be improved very much, feel free to do so.


    edit2: Added Mining in literally 15 minutes, woodcutting and mining are pretty much identical skills lol.
    Attached image

    Take a look yourself:
    Code:
    package com.elvarg.game.content.skill.skillable.impl;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Optional;
    
    import com.elvarg.game.collision.RegionClipping;
    import com.elvarg.game.entity.impl.object.GameObject;
    import com.elvarg.game.entity.impl.player.Player;
    import com.elvarg.game.model.Animation;
    import com.elvarg.game.model.Skill;
    import com.elvarg.game.model.container.impl.Equipment;
    import com.elvarg.game.task.TaskManager;
    import com.elvarg.game.task.impl.TimedObjectSpawnTask;
    
    /**
     * Represents the Mining skill.
     * @author Professor Oak
     */
    public class Mining extends DefaultSkillable {
    	
    	/**
    	 * Constructs a new {@link Mining}.
    	 * @param rockObject		The rock to mine.
    	 * @param rock				The rock's data
    	 */
    	public Mining(GameObject rockObject, Rock rock) {
    		this.rockObject = rockObject;
    		this.rock = rock;
    	}
    	
    	/**
    	 * The {@link GameObject} to mine.
    	 */
    	private final GameObject rockObject;
    
    	/**
    	 * The {@code rock} as an enumerated type
    	 * which contains information about it, such as
    	 * required level.
    	 */
    	private final Rock rock;
    
    	/**
    	 * The pickaxe we're using to mine.
    	 */
    	private Optional<Pickaxe> pickaxe = Optional.empty();
    	
    	@Override
    	public boolean hasRequiremenets(Player player) {
    		//Attempt to find a pickaxe..
    		pickaxe = Optional.empty();
    		for (Pickaxe a : Pickaxe.values()) {
    			if (player.getEquipment().getItems()[Equipment.WEAPON_SLOT].getId() == a.getId()
    					|| player.getInventory().contains(a.getId())) {
    				
    				//If we have already found a pickaxe,
    				//don't select others that are worse or can't be used
    				if(pickaxe.isPresent()) {
    					if(player.getSkillManager().getMaxLevel(Skill.MINING) < a .getRequiredLevel()) {
    						continue;
    					}
    					if(a.getRequiredLevel() < pickaxe.get().getRequiredLevel()) {
    						continue;
    					}
    				}
    				
    				pickaxe = Optional.of(a);
    			}
    		}
    
    		//Check if we found one..
    		if(!pickaxe.isPresent()) {
    			player.getPacketSender().sendMessage("You don't have a pickaxe which you can use.");
    			return false;
    		}
    
    		//Check if we have the required level to mine this {@code rock} using the {@link Pickaxe} we found..
    		if(player.getSkillManager().getCurrentLevel(Skill.MINING) < pickaxe.get().getRequiredLevel()) {
    			player.getPacketSender().sendMessage("You don't have a pickaxe which you have the required Mining level to use.");
    			return false;
    		}
    
    		//Check if we have the required level to mine this {@code rock}..
    		if(player.getSkillManager().getCurrentLevel(Skill.MINING) < rock.getRequiredLevel()) {
    			player.getPacketSender().sendMessage("You need a Mining level of at least "+rock.getRequiredLevel()+" to mine this rock.");
    			return false;
    		}
    		
    		//Finally, check if the rock object remains there.
    		//Another player may have mined it already.
    		if(!RegionClipping.getObject(rockObject.getId(), rockObject.getPosition()).isPresent()) {
    			return false;
    		}
    		
    		return super.hasRequiremenets(player);
    	}
    
    	@Override
    	public void execute(Player player) {
    		player.getPacketSender().sendMessage("You swing your pickaxe at the rock..");
    		super.execute(player);
    	}
    
    	@Override
    	public void harvestMaterial(Player player) {
    		//Add ores..
    		player.getInventory().add(rock.getOreId(), 1);
    		player.getPacketSender().sendMessage("You get some ores.");
    		
    		//Add exp..
    		player.getSkillManager().addExperience(Skill.MINING, rock.getXpReward());
    		
    		//Despawn rock..
    		finalize(player);
    	}
    
    	@Override
    	public void finalize(Player player) {
    		//Stop skilling..
    		reset(player);
    		
    		//Despawn object and respawn it after a short period of time..
    		TaskManager.submit(new TimedObjectSpawnTask(new GameObject(2704, rockObject.getPosition()), rockObject, false, rock.getRespawnTimer()));
    	}
    
    	@Override
    	public Animation animation() {
    		return pickaxe.get().getAnimation();
    	}
    	
    	@Override
    	public int successRate(Player player) {
    		int cycles = rock.getCycles() - ((int)((player.getSkillManager().getMaxLevel(Skill.MINING) * 0.07) * pickaxe.get().getSpeed()));
    		if(cycles < 1) {
    			cycles = 1;
    		}
    		return cycles;
    	}
    	
    	public GameObject getTreeObject() {
    		return rockObject;
    	}
    	
    	/**
    	 * Holds data related to the pickaxes
    	 * that can be used for this skill.
    	 */
    	public static enum Pickaxe {
    		BRONZE(1265, 1, new Animation(625), 1.0),
    		IRON(1267, 1, new Animation(626), 1.05),
    		STEEL(1269, 6, new Animation(627), 1.1),
    		MITHRIL(1273, 21, new Animation(628), 1.2),
    		ADAMANT(1271, 31, new Animation(629), 1.33),
    		RUNE(1275, 41, new Animation(624), 1.51),
    		DRAGON(15259, 61, new Animation(624), 1.9);
    
    		private final int id, requiredLevel;
    		private final Animation animation;
    		private final double speed;
    		
    		private Pickaxe(int id, int req, Animation animaion, double speed) {
    			this.id = id;
    			this.requiredLevel = req;
    			this.animation = animaion;
    			this.speed = speed;
    		}
    
    		public int getId() {
    			return id;
    		}
    		
    		public int getRequiredLevel() {
    			return requiredLevel;
    		}
    
    		public Animation getAnimation() {
    			return animation;
    		}
    		
    		public double getSpeed() {
    			return this.speed;
    		}
    	}
    
    	/**
    	 * Holds data related to the rocks 
    	 * which can be used to train this skill.
    	 */
    	public static enum Rock {
    		CLAY(new int[]{9711, 9712, 9713, 15503, 15504, 15505}, 1, 450, 434, 4, 2),
    		COPPER(new int[]{9708, 9709, 9710, 11936, 11960, 11961, 11962, 11189, 11190, 11191, 29231, 29230, 2090}, 1, 1550, 436, 5, 4),
    		TIN(new int[]{9714, 9715, 9716, 11933, 11957, 11958, 11959, 11186, 11187, 11188, 2094, 29227, 29229}, 1, 1550, 438, 5, 4),
    		IRON(new int[]{7455, 9717, 9718, 9719, 2093, 2092, 11954, 11955, 11956, 29221, 29222, 29223}, 15, 2450, 440, 6, 5),
    		SILVER(new int[]{2100, 2101, 29226, 29225, 11948, 11949}, 20, 2760, 442, 7, 7),
    		COAL(new int[]{2097, 5770, 29216, 29215, 29217, 11965, 11964, 11963, 11930, 11931, 11932}, 30, 3450, 453, 7, 7),
    		GOLD(new int[]{9720, 9721, 9722, 11951, 11183, 11184, 11185, 2099}, 40, 4580, 444, 8, 10),
    		MITHRIL(new int[]{25370, 25368, 5786, 5784, 11942, 11943, 11944, 11945, 11946, 29236, 11947, 11942, 11943}, 50, 6300, 447, 11, 11),
    		ADAMANTITE(new int[]{11941, 11939, 29233, 29235}, 70, 9560, 449, 13, 14),
    		RUNITE(new int[]{14859, 4860, 2106, 2107}, 85, 15122, 451, 15, 45),;
    
    		private int objects[];
    		private int oreId, requiredLevel, xpReward, cycles, respawnTimer;
    
    		private Rock(int[] objects, int requiredLevel, int xpReward, int oreId, int cycles, int respawnTimer) {
    			this.objects = objects;
    			this.requiredLevel = requiredLevel;
    			this.xpReward = xpReward;
    			this.oreId = oreId;
    			this.cycles = cycles;
    			this.respawnTimer = respawnTimer;
    		}
    
    		public int getRespawnTimer() {
    			return respawnTimer;
    		}
    
    		public int getRequiredLevel() {
    			return requiredLevel;
    		}
    
    		public int getXpReward(){
    			return xpReward;
    		}
    
    		public int getOreId() {
    			return oreId;
    		}
    
    		public int getCycles() {
    			return cycles;
    		}
    		
    		private static final Map<Integer, Rock> rocks = new HashMap<Integer, Rock>();
    
    		static {
    			for (Rock t : Rock.values()) {
    				for (int obj : t.objects) {
    					rocks.put(obj, t);
    				}
    				rocks.put(t.getOreId(), t);
    			}
    		}
    
    		public static Optional<Rock> forObjectId(int objectId) {
    			Rock rock = rocks.get(objectId);
    			if(rock != null) {
    				return Optional.of(rock);
    			}
    			return Optional.empty();
    		}
    	}
    }
    [/SPOIL]

    This would definitely be preferable. Good job

    Even better yet though, a proper content plugin system. For example this allowed me to do 100% thieving in a concise way as seen below: (Kotlin code)

    Code:
    package plugins.skills.thieving
    
    import glory.engine.task.Task
    import glory.engine.task.TaskManager
    import glory.plugin.*
    import glory.world.model.Item
    import glory.world.model.Skill
    
    /**
     * Handles functionality for stall thieving.
     *
     * @author Andys1814.
     */
    enum class Stall(val id: Int, val levelRequired: Int, val reward: Int, val experience: Int) {
        BAKER(4875, 1, 1897, 30),
        GEM(2562, 20, 1635, 60),
        FUR(2563, 40, 950, 90),
        SPICE(2564, 60, 7650, 105),
        SCIMITAR(4878, 80, 1613, 135);
    }
    
    @PluginMain fun thieve(repo: PluginRepository) {
        Stall.values().forEach { stall ->
            repo.onfirstClickObject(stall.id) { thieve(it, stall) }
        }
    }
    
    fun thieve(plgn: Plugin, stall: Stall) {
        if (plgn.plr().skillManager.getCurrentLevel(Skill.THIEVING) < stall.levelRequired) {
            plgn.msg("This stall requires level ${stall.levelRequired} to steal from.")
            return
        }
    
        if (plgn.plr().inventory.freeSlots <= 0) {
            plgn.msg("You don't have enough inventory space to steal from this stall.")
            return
        }
    
        plgn.anim(881)
    
        TaskManager.submit(object : Task(3, plgn.plr(), false) {
            override fun execute() {
                plgn.plr().inventory + stall.reward
                plgn.msg("You steal some loot from the stall.")
                plgn.plr().skillManager.addExperience(Skill.THIEVING, stall.experience)
                stop()
            }
        })
    }
    Reply With Quote  
     

  7. Thankful users:


  8. #16  
    Extreme Donator


    Join Date
    Oct 2010
    Posts
    2,853
    Thanks given
    1,213
    Thanks received
    1,622
    Rep Power
    5000
    Quote Originally Posted by Andys1814 View Post
    [SPOIL][/SPOIL]

    This would definitely be preferable. Good job

    Even better yet though, a proper content plugin system. For example this allowed me to do 100% thieving in a concise way as seen below: (Kotlin code)

    Code:
    package plugins.skills.thieving
    
    import glory.engine.task.Task
    import glory.engine.task.TaskManager
    import glory.plugin.*
    import glory.world.model.Item
    import glory.world.model.Skill
    
    /**
     * Handles functionality for stall thieving.
     *
     * @author Andys1814.
     */
    enum class Stall(val id: Int, val levelRequired: Int, val reward: Int, val experience: Int) {
        BAKER(4875, 1, 1897, 30),
        GEM(2562, 20, 1635, 60),
        FUR(2563, 40, 950, 90),
        SPICE(2564, 60, 7650, 105),
        SCIMITAR(4878, 80, 1613, 135);
    }
    
    @PluginMain fun thieve(repo: PluginRepository) {
        Stall.values().forEach { stall ->
            repo.onfirstClickObject(stall.id) { thieve(it, stall) }
        }
    }
    
    fun thieve(plgn: Plugin, stall: Stall) {
        if (plgn.plr().skillManager.getCurrentLevel(Skill.THIEVING) < stall.levelRequired) {
            plgn.msg("This stall requires level ${stall.levelRequired} to steal from.")
            return
        }
    
        if (plgn.plr().inventory.freeSlots <= 0) {
            plgn.msg("You don't have enough inventory space to steal from this stall.")
        }
    
        plgn.anim(881)
    
        TaskManager.submit(object : Task(3, plgn.plr(), false) {
            override fun execute() {
                plgn.plr().inventory + stall.reward
                plgn.msg("You steal some loot from the stall.")
                plgn.plr().skillManager.addExperience(Skill.THIEVING, stall.experience)
                stop()
            }
        })
    }
    Yeah I gotta look into kotlin
    [Today 01:29 AM] RSTrials: Nice 0.97 Win/Loss Ratio luke. That's pretty bad.
    [Today 01:30 AM] Luke132: Ok u fucking moron i forgot i could influence misc.random
    Reply With Quote  
     

  9. #17  
    Registered Member
    Andys1814's Avatar
    Join Date
    Feb 2013
    Posts
    974
    Thanks given
    688
    Thanks received
    455
    Rep Power
    727
    Quote Originally Posted by Professor Oak View Post
    Yeah I gotta look into kotlin
    omg its amazing. haven't programmed in java since i learned kotlin a few weeks ago. Considering writing a framework in it. would reccommend.
    Reply With Quote  
     

  10. Thankful user:


  11. #18  
    (Official) Thanksgiver

    Arham's Avatar
    Join Date
    Jan 2013
    Age
    23
    Posts
    3,415
    Thanks given
    7,254
    Thanks received
    1,938
    Rep Power
    3905
    Quote Originally Posted by Andys1814 View Post
    omg its amazing. haven't programmed in java since i learned kotlin a few weeks ago. Considering writing a framework in it. would reccommend.
    Will look into and it seems like a Java developer's dream

    P.S: your function thieve is missing a return statement in the second if
    Attached image
    Attached image
    Quote Originally Posted by MrClassic View Post
    Arham is the official thanker!
    List of my work here!
    Reply With Quote  
     

  12. #19  
    Registered Member
    Andys1814's Avatar
    Join Date
    Feb 2013
    Posts
    974
    Thanks given
    688
    Thanks received
    455
    Rep Power
    727
    Quote Originally Posted by arham 4 View Post
    Will look into and it seems like a Java developer's dream

    P.S: your function thieve is missing a return statement in the second if
    hahaha I literally just realized that right before I read your comment, thanks

    You should definitely look into it, here's their complete docs: https://kotlinlang.org/docs/reference/basic-syntax.html
    Reply With Quote  
     

  13. Thankful user:


  14. #20  
    Registered Member Farage's Avatar
    Join Date
    Jan 2017
    Posts
    252
    Thanks given
    24
    Thanks received
    22
    Rep Power
    0
    Quote Originally Posted by Kris View Post
    Didn't think it was possible but it just got a whole lot worse than your latest release.
    I don't think I need to even point out what you've done wrong considering how the others have already done a fairly thorough job on it, although I could definitely find more things to pick on.




    If you find it odd, why did you copy them? Just because a bunch of retards released a content-packed source doesn't necessarily mean their code is good, lol. Go off of your instincts.. And if your instincts suck, you can almost always find an answer to a question at StackOverflow.

    That enum just absolutely killed this lol.
    I went for it cos i know its accurate.
    Have a nice day!
    Иди в пизду!
    Bonne journée!
    Einen schönen Tag noch!
    Hezký den!
    祝你今天愉快!
    Reply With Quote  
     

Page 2 of 3 FirstFirst 123 LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. [Elvarg / OSRSPK] Cooking Skill
    By Farage in forum Snippets
    Replies: 10
    Last Post: 07-22-2017, 09:32 PM
  2. [Elvarg / OSRSPK] Firemaking Skill
    By Farage in forum Snippets
    Replies: 32
    Last Post: 07-20-2017, 05:49 AM
  3. Replies: 9
    Last Post: 08-07-2016, 06:59 PM
  4. Need Help With Woodcutting Skill [718]
    By ItsStino in forum Help
    Replies: 9
    Last Post: 05-31-2014, 06:21 AM
  5. Replies: 3
    Last Post: 08-12-2011, 04:19 PM
Tags for this Thread

View Tag Cloud

Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •