Thread: [PI/Any] Skill Handling (Enum based)

Results 1 to 5 of 5
  1. #1 [PI/Any] Skill Handling (Enum based) 
    Registered Member -Syndicate's Avatar
    Join Date
    Jan 2015
    Posts
    77
    Thanks given
    46
    Thanks received
    15
    Rep Power
    37
    This is a snippet, although, also a question.
    For those of you that want to use the classes, feel free.

    Spoiler for SkillHandler:
    Code:
    package helios.world.players.skills;
    
    import helios.Config;
    import helios.world.players.Player;
    import helios.world.players.Restrictions;
    
    import java.util.Arrays;
    import java.util.Optional;
    
    @SuppressWarnings("unused")
    
    /**
     * @author -Syndicate
     */
    
    public class SkillHandler {
    	
    	private static final int EXPERIENCE_CAP = 200000000;
    	
    	private static final int [] LEVELS = new int [25];
    	public static final int levelForSkill(Player player, int skill) {
    		return LEVELS[skill];
    	}
    	public static void assign(Player player, int skill, int level) {
    		LEVELS[skill] = level;
    	}
    	public static void increase(Player player, int skill, int amount) {
    		LEVELS[skill] += amount;
    	}
    	public static void decrease(Player player, int skill, int amount) {
    		LEVELS[skill] -= amount;
    	}
    	public static final int skillArrayLength() {
    		return LEVELS.length;
    	}
    	
    	private static final int [] EXPERIENCE = new int [25];
    	public static final int expForSkill(Player player, int skill) {
    		return EXPERIENCE[skill];
    	}
    	public static void assignExp(Player player, int skill, int amount) {
    		EXPERIENCE[skill] = amount;
    	}
    	public static void increaseExp(Player player, int skill, int amount) {
    		EXPERIENCE[skill] += amount;
    	}
    	public static void decreaseExp(Player player, int skill, int amount) {
    		EXPERIENCE[skill] -= amount;
    	}
    	
    	public static int expForLevel(int level) {
    		int points = 0;
    		int output = 0;
    
    		for (int lvl = 1; lvl <= level; lvl++) {
    			points += Math.floor((double)lvl + 300.0 * Math.pow(2.0, (double)lvl / 7.0));
    			if (lvl >= level)
    				return output;
    			output = (int)Math.floor(points / 4);
    		}
    		return 0;
    	}
    	
    	public static int levelForExp(int exp) {
    		int points = 0;
    		int output = 0;
    		if (exp > 13034430)
    			return 99;
    		for (int lvl = 1; lvl <= 99; lvl++) {
    			points += Math.floor((double) lvl + 300.0 * Math.pow(2.0, (double) lvl / 7.0));
    			output = (int) Math.floor(points / 4);
    			if (output >= exp) {
    				return lvl;
    			}
    		}
    		return 1;
    	}
    	
    	public static int calculateCombat(Player player) {
    		int attack = levelForExp(expForSkill(player, 0));
    		int defence = levelForExp(expForSkill(player, 1));
    		int strength = levelForExp(expForSkill(player, 2));
    		int hitpoints = levelForExp(expForSkill(player, 3));
    		int prayer = levelForExp(expForSkill(player, 4));
    		int ranged = levelForExp(expForSkill(player, 5));
    		int magic = levelForExp(expForSkill(player, 6));
    		int combatLevel = 3;
    		combatLevel = (int) ((defence + hitpoints + Math.floor(prayer / 2)) * 0.25) + 1;
    		double melee = (attack + strength) * 0.325;
    		double ranger = Math.floor(ranged * 1.5) * 0.325;
    		double mage = Math.floor(magic * 1.5) * 0.325;
    		if (melee >= ranger && melee >= mage) {
    			combatLevel += melee;
    		} else if (ranger >= melee && ranger >= mage) {
    			combatLevel += ranger;
    		} else if (mage >= melee && mage >= ranger) {
    			combatLevel += mage;
    		}
    		return combatLevel;
    	}
    	
    	public static int calculateTotal(Player player) {
    		int total = 0;
    		for (int i = 0; i < 21; i++) {
    			total += levelForExp(expForSkill(player, i));
    		}
    		return total;
    	}
    	
    	public static void appendExp(Player player, int skill, int amount) {
    		if (amount+expForSkill(player, skill) == 0 || amount == 0)
    			return;
    		if (expForSkill(player, skill) == EXPERIENCE_CAP)
    			return;
    		
    		
    		final int experience = (amount *= Config.SERVER_EXP_BONUS);
    		final int currentLevel = levelForExp(expForSkill(player, skill));
    		increaseExp(player, skill, experience);
    		
    		if (currentLevel < levelForExp(expForSkill(player, skill))) {
    			if (levelForSkill(player, skill) < levelForExp(expForSkill(player, skill)) && skill != 3 && skill != 5) {
    				assign(player, skill, levelForExp(expForSkill(player, skill)));
    			}
    			levelUp(player, skill, currentLevel);
    			player.getPA().requestUpdates();
    			player.gfx100(199);
    		}
    		player.getPA().setSkillLevel(skill, levelForSkill(player, skill), expForSkill(player, skill));
    		refreshSkill(player, skill);
    	}
    	
    	private static void levelUp(Player player, int skill, int exp) {
    		player.getPA().sendFrame126("Level: "+calculateTotal(player), 13983);
    		player.getPA().sendFrame126("Combat Level: "+calculateCombat(player)+"", 3983);
    		
    		Optional<Skills> data = Skills.getSkill(skill);
    		
    		if(!data.isPresent())
    			return;
    					
    		player.sendMessage("Congratulations, you've advanced a level in "+data.get().toString()+"!");
    		player.getPA().sendFrame126("Congratulations, you've advanced a level in "+data.get().toString()+"!", data.get().getFrame2());
    		player.getPA().sendFrame126("Your " +data.get().toString()+ " level is now " + levelForExp(expForSkill(player, skill)) + ".", data.get().getFrame3());
    		player.getPA().sendFrame164(data.get().getFrame1());
    
    		player.dialogueAction = 0;
    		player.nextChat = 0;
    	}
    	
    	public static void refreshSkill(Player player, int skill) {
    		Optional<Skills> data = Skills.getSkill(skill);
    
    		if(!data.isPresent())
    			return;
    
    		player.getPA().sendFrame126("" + levelForSkill(player, skill) + "", data.get().getFrame4());
    		player.getPA().sendFrame126("" + levelForExp(expForSkill(player, skill)) + "", data.get().getFrame5());
    		player.getPA().sendFrame126("" + expForSkill(player, skill) + "", data.get().getFrame6());
    		player.getPA().sendFrame126("" + levelForExp(levelForExp(expForSkill(player, skill)) + 1) + "", data.get().getFrame7());
    	}
        
        public static void resetCombat(Player player) {
        	if (Restrictions.equipmentRestrict(player))
        		return;
    		for(int i = 0; i < 7; i++) {
    			int cb = i == 3 ? 10 : 1; 
    			assignExp(player, i, cb);
    			assign(player, i, cb);
    			resetSkill(player, i);
    		}
        }
        
        public static void resetSkill(Player player, int id) {
        	if (Restrictions.equipmentRestrict(player))
        		return;
        	int skill = id == Skills.CONSTITUTION.getId() ? 10 : 1;
        	assignExp(player, id, skill);
    		assign(player, id, skill);
    		refreshSkill(player, id);
        }
        
        public static void resetSkills(Player player) {
        	for (int i = 0; i > 21; i++) {
        		resetSkill(player, i);
        	}
        }
        
    }

    Note on SkillHandler class; I do realize the methods for the arrays are considerably redundant, but I don't want them public.
    Any tips? Completely down for criticism, thanks. Don't hurt my feels tho.

    Also, maybe I should instantiate the Player class within the main class, instead of for each method? Not sure.

    Spoiler for Skills:
    Code:
    package helios.world.players.skilling;
    
    import java.util.Arrays;
    import java.util.Optional;
    
    public enum Skills {
    	ATTACK(0, 6247, 6248, 6249, 4004, 4005, 4044, 4045),
    	DEFENCE(1, 6253, 6254, 6255, 4008, 4009, 4056, 4057),
    	STRENGTH(2, 6206, 6207, 6208, 4006, 4007, 4050, 4051),
    	CONSTITUTION(3, 6216, 6217, 6218, 4016, 4017, 4080, 4081),
    	RANGED(4, 4443, 5453, 6114, 4010, 4011, 4062, 4063),
    	PRAYER(5, 6242, 6243, 6244, 4012, 4013, 4068, 4069),
    	MAGIC(6, 6211, 6212, 6213, 4014, 4015, 4074, 4075),
    	COOKING(7, 6226, 6227, 6228, 4034, 4035, 4134, 4135),
    	WOODCUTTING(8, 4272, 4273, 4274, 4038, 4039, 4146, 4147),
    	FLETCHING(9, 6231, 6232, 6233, 4026, 4027, 4110, 4111),
    	FISHING(10, 6258, 6259, 6260, 4032, 4033, 4128, 4129),
    	FIREMAKING(11, 4282, 4283, 4284, 4036, 4037, 4140, 4141),
    	CRAFTING(12, 6263, 6264, 6265, 4024, 4025, 4104, 4105),
    	SMITHING(13, 6221, 6222, 6223, 4030, 4031, 4122, 4123),
    	MINING(14, 4416, 4417, 4438, 4028, 4029, 4116, 4117),
    	HERBLORE(15, 6237, 6238, 6239, 4020, 4021, 4092, 4093),
    	AGILITY(16, 4277, 4278, 4279, 4018, 4019, 4086, 4087),
    	THIEVING(17, 4261, 4263, 4264, 4022, 4023, 4098, 4099),
    	SLAYER(18, 12122, 12123, 12124, 12166, 12167, 12171, 12172),
    	FARMING(19, 12122, 12123, 12124, 13926, 13927, 13921, 13922),
    	RUNECRAFTING(20, 4267, 4268, 4269, 4152, 4153, 4157, 4158);
    
    	int skill, frame, frame2, frame3, frame4, frame5, frame6, frame7;
    	 
    	private Skills(int skill, int frame, int frame2,
    	int frame3, int frame4, int frame5, int frame6, int frame7) {
    		this.skill = skill;
    		this.frame = frame;
    		this.frame2 = frame2;
    		this.frame3 = frame3;
    		this.frame4 = frame4;
    		this.frame5 = frame5;
    		this.frame6 = frame6;
    		this.frame7 = frame7;
    	}
    
    	public final int getId() {
    		return skill;
    	}
    	public final int getFrame1() {
    		return frame;
    	}
    	public final int getFrame2() {
    		return frame2;
    	}
    	public final int getFrame3() {
    		return frame3;
    	}
    	public final int getFrame4() {
    		return frame4;
    	}
    	public final int getFrame5() {
    		return frame5;
    	}
    	public final int getFrame6() {
    		return frame6;
    	}
    	public final int getFrame7() {
    		return frame7;
    	}
    	public String toString() {
    		return name().charAt(0) + name().substring(1).toLowerCase();
    	}
    	public static Optional<Skills> getSkill(int identifier) {
    		return Arrays.stream(values()).filter(s -> s.skill == identifier).findFirst();
    	}
    }

    If you feel like using these classes, they are fully capable of replacing the old methods of handling skills in PI, and operational.
    (There might be a few things that need tweaking on your end.)

    Please note; no matter how you handle player saving, the variables EXPERIENCE, and LEVELS should NOT be re-wrote within the Player class.. If you are handling player saving in the same manner the original Project Insanity source does, you should simply call these variables in the PlayerSave class.

    I'm in the process of repackaging, and re-writing most of everything in Project Insanity, because, well, I feel like it.
    That's besides the point though, what I'm really posting this for is some constructive criticism.

    So, my fellow Rune-Server users, is this an acceptable way of handling 'skills'?
    What are some things I could do differently?
    Reply With Quote  
     

  2. Thankful user:


  3. #2  
    Software Developer

    Tyrant's Avatar
    Join Date
    Jul 2013
    Age
    24
    Posts
    1,562
    Thanks given
    678
    Thanks received
    423
    Rep Power
    1060
    You shouldn't be making

    private static final int [] LEVELS = new int [25];

    private static final int [] EXPERIENCE= new int [25];

    static since they are unique to each player, by making them static, that means basically every player will share the same levels / experience.
    Instead if you still wanted to do it that way you could instance the class and access the fields from there and make them nonstatic, although
    I don't really like that way... Wouldn't really recommend using this unless its been reworked out and fixed.

    However, this is a nice idea to have a skill handler for those miscellaneous methods, as they are easier to access and refer to,
    so good job on that.
    Reply With Quote  
     

  4. #3  
    Respected Member


    Kris's Avatar
    Join Date
    Jun 2016
    Age
    26
    Posts
    3,638
    Thanks given
    820
    Thanks received
    2,642
    Rep Power
    5000
    As Tyrant said, why is everything static here? Levels, experience etc etc are unique to every player. Pretty much nothing should be static here lol.
    Reply With Quote  
     

  5. #4  
    Registered Member -Syndicate's Avatar
    Join Date
    Jan 2015
    Posts
    77
    Thanks given
    46
    Thanks received
    15
    Rep Power
    37
    Well, it was saving the values separately for each player, so I was under the impression it would work.
    So, if I make them not static, obviously I need to instantiate it in a way that I don't have to constantly instantiate it in each class..

    If I do this is the Player class, would that be recommended? Also, should I instantiate it in a static manner?
    Code:
    	public SkillHandler skillHandler = new SkillHandler();
    	public SkillHandler handleSkills() {
    		return skillHandler;
    	}
    Or
    Code:
    	public static SkillHandler skillHandler = new SkillHandler();
    	public static SkillHandler handleSkills() {
    		return skillHandler;
    	}
    I only ask because then I wont have to instantiate the Player/Client in some way, each time I use the SkillHandler instance.
    Thanks for the notes.
    Reply With Quote  
     

  6. #5  
    need java lessons
    Eclipse's Avatar
    Join Date
    Aug 2012
    Posts
    4,436
    Thanks given
    686
    Thanks received
    898
    Rep Power
    490
    Quote Originally Posted by -Syndicate View Post
    Well, it was saving the values separately for each player, so I was under the impression it would work.
    So, if I make them not static, obviously I need to instantiate it in a way that I don't have to constantly instantiate it in each class..

    If I do this is the Player class, would that be recommended? Also, should I instantiate it in a static manner?
    Code:
    	public SkillHandler skillHandler = new SkillHandler();
    	public SkillHandler handleSkills() {
    		return skillHandler;
    	}
    Or
    Code:
    	public static SkillHandler skillHandler = new SkillHandler();
    	public static SkillHandler handleSkills() {
    		return skillHandler;
    	}
    I only ask because then I wont have to instantiate the Player/Client in some way, each time I use the SkillHandler instance.
    Thanks for the notes.
    you can make your methods static and call them that way, but when you call the skills you have to call them for each player via your player class or wherever you save your variables, making them static here will make everyone who accesses a method have the same exp or level value you set in the class

    Quote Originally Posted by jerryrocks317 View Post
    i am 14 and have my own laptop im on almost 24/7 currently creating rsps lol so please get off my thread lol
    Reply With Quote  
     


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. Replies: 15
    Last Post: 07-17-2014, 07:52 AM
  2. [PI/Any base]Easy and efficient quest system
    By Haskell Curry in forum Tutorials
    Replies: 6
    Last Post: 10-14-2013, 04:51 PM
  3. [PI/Any base]Clean command system
    By Haskell Curry in forum Tutorials
    Replies: 21
    Last Post: 09-21-2013, 03:45 AM
  4. Shard-Revolutions/PI/Any base - Basic skill menu system
    By Haskell Curry in forum Snippets
    Replies: 12
    Last Post: 07-13-2012, 05:22 PM
  5. [PI, any base, etc] Correct NPC spawns
    By Nirvana in forum Configuration
    Replies: 27
    Last Post: 12-16-2011, 02:39 AM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •