|
Hey there,
Feel free to give constructive criticism. I've created this whilst at work, so this code is untested for.
Data is EMPTY! Cuz i do not have access to this @ work.
The skill:
The data:Code:package com.venenatis.game.content.skills.runecrafting; import com.venenatis.game.action.impl.Skill; import com.venenatis.game.model.Item; import com.venenatis.game.model.Skills; import com.venenatis.game.model.definitions.ItemDefinition; import com.venenatis.game.model.entity.npc.pet.Follower; import com.venenatis.game.model.entity.npc.pet.Pet; import com.venenatis.game.model.entity.player.Player; import com.venenatis.game.model.entity.player.dialogue.SimpleDialogues; import com.venenatis.game.model.masks.Animation; import com.venenatis.game.model.masks.Graphic; import com.venenatis.game.world.World; import com.venenatis.game.world.object.GameObject; /** * This class represents the runecrafting skill and its functionality. * * @author <a href="http://www.rune-server.org/members/_Patrick_/">Patrick van Elderen</a> * */ public class Runecrafting extends Skill { /** * The talisman */ private Item talisman; /** * The altar. */ private GameObject object; public GameObject getObject() { return object; } /** * The runecrafting animation */ private Animation RUNECRAFTING_ANIMATION = Animation.create(791); /** * The runecrafting graphic */ private Graphic RUNECRAFTING_GRAPHIC = Graphic.create(186); public Runecrafting(Player player, GameObject object) { super(player); this.object = object; } /** * Teleports the player to the altar using the locate option on the talisman * @param player * The player teleporting * @return */ private boolean locateTalisman(Player player) { Talisman t = Talisman.forId(talisman.getId()); player.getTeleportAction().teleport(t.getOutsideLocation()); return true; } @Override public boolean start(Player player) { //Safety check, player should never be null if (player == null) { return false; } //Safety check if (talisman != null) { Talisman t = Talisman.forId(talisman.getId()); //Check if we have an talisman if we do we can use the locate option if (t != null) { return locateTalisman(player); } //If we're not locating the alter we are trying to craft runes } else { return true; } return false; } @Override public boolean execute(Player player) { //First check if we have the required level if (player.getSkills().getLevel(Skills.RUNECRAFTING) < Altar.getAltar(getObject().getId()).getLevelRequired()) { SimpleDialogues.sendStatement(player, "You need a " + Skills.RUNECRAFTING + " level of " + Altar.getAltar(getObject().getId()).getLevelRequired() + " to craft this rune."); stop(); return false; } //Then we can check if we have any essence if (!player.getInventory().contains(7936) && !player.getInventory().contains(1436)) { SimpleDialogues.sendStatement(player, "You do not have any rune essence to bind."); stop(); return false; } //And lastly check if we can only use pure essence if (Altar.getAltar(getObject().getId()).isPureEssenceOnly() && !player.getInventory().contains(7936)) { SimpleDialogues.sendStatement(player, "You do not have any pure essence to bind."); stop(); return false; } //Start animation and play the graphic player.playAnimation(RUNECRAFTING_ANIMATION); player.playGraphic(RUNECRAFTING_GRAPHIC); return true; } @Override public boolean finish(Player player) { Altar altar = Altar.getAltar(getObject().getId()); //The essence multiplier based on runecrafting level int multiplier = (int) Math.floor(player.getSkills().getLevel(Skills.RUNECRAFTING) / altar.getDoubleRunesLevel()); multiplier += 1; //The amount off essence we have in our inventory int essenceAmount = player.getInventory().getAmount(getEssType(player, altar)); player.message("You bind the temple's power into " + ItemDefinition.get(altar.getRune()).getName() + "s"); //Add experience based on the amount of runes we are crafting player.getSkills().addExperience(Skills.RUNECRAFTING, altar.getExperience() * essenceAmount); if (RANDOM.nextInt(altar.getBaseChance() - (player.getSkills().getLevel(Skills.RUNECRAFTING) * 25)) == 1) { Pet p = altar.petDrop(); //First check if we already have this pet if (player.alreadyHasPet(player, altar.petDrop().getItem()) || player.getPet() == p.getNpc()) { return false; } //spawn the pet if we passed all checks if (player.getPet() > -1) { player.getInventory().addOrSentToBank(player, new Item(altar.petDrop().getItem())); World.getWorld().sendWorldMessage("<col=7f00ff>" + player.getUsername() + " has just received "+ItemDefinition.get(altar.petDrop().getItem()).getName()+".", false); } else { Follower pet = new Follower(player, p.getNpc()); player.setPet(p.getNpc()); World.getWorld().register(pet); World.getWorld().sendWorldMessage("<col=7f00ff>" + player.getUsername() + " has just received "+ItemDefinition.get(altar.petDrop().getItem()).getName()+".", false); player.getActionSender().sendMessage("You have a funny feeling like you're being followed."); } } //Remove all essence player.getInventory().removeAll(new Item(getEssType(player, altar))); //Replace with the rune we just crafted player.getInventory().add(new Item(altar.getRune(), essenceAmount * multiplier)); return true; } /** * Starts the runecrafting task * * @param player * The player trying to activate the altar * @param object * The actual altar we're trying to craft runes from * @return */ public static boolean startAction(Player player, GameObject object) { if(Altar.alterIds(object.getId())) { Runecrafting runecrafting = new Runecrafting(player, object); //Activate the SkillAction task runecrafting.execute(); //And sent the task to the World aswell World.getWorld().schedule(runecrafting); return true; } return false; } /** * Checks which type off essence we should be using * * @param player * The player to check * @param altar * The altar to check * @return The essence type required */ private int getEssType(Player player, Altar altar) { if (player.getInventory().contains(7936)) { return 7936; } else if (player.getInventory().contains(1436) && !altar.isPureEssenceOnly()) { return 1436; } return -1; } }
Code:package com.venenatis.game.content.skills.runecrafting; import java.util.HashMap; import java.util.Map; import com.venenatis.game.model.entity.npc.pet.Pet; /** * This Enum holds all runecrafting data. * @author <a href="http://www.rune-server.org/members/_Patrick_/">Patrick van Elderen</a> * */ public enum Altar { AIR(14897, 14841, 1438, 5527, 1, 556, 5, 11, false, 100_000, Pet.RIFT_GUARDIAN_AIR), MIND(14898, 14842, 1448, 5529, 2, 558, 5.5, 14, false, 100_000, Pet.RIFT_GUARDIAN_MIND), WATER(14899, 14843, 1444, 5531, 5, 555, 6, 19, false, 100_000, Pet.RIFT_GUARDIAN_WATER), EARTH(14900, 14844, 1440, 5535, 9, 557, 6.5, 26, false, 100_000, Pet.RIFT_GUARDIAN_EARTH), FIRE(14901, 14845, 1442, 5537, 14, 554, 7, 35, false, 100_000, Pet.RIFT_GUARDIAN_FIRE), BODY(14902, 14846, 1446, 5533, 20, 559, 7.5, 46, false, 100_000, Pet.RIFT_GUARDIAN_BODY), COSMIC(14903, 14847, 1454, 5539, 27, 564, 8, 59, true, 100_000, Pet.RIFT_GUARDIAN_COSMIC), CHAOS(14906, 14893, 1452, 5543, 35, 562, 8.5, 74, true, 100_000, Pet.RIFT_GUARDIAN_CHAOS), ASTRAL(14911, -1, -1, 9106, 40, 9075, 8.7, 82, true, 100_000, Pet.RIFT_GUARDIAN_ASTRAL), NATURE(14905, 14892, 1462, 5541, 44, 561, 9, 91, true, 100_000, Pet.RIFT_GUARDIAN_NATURE), LAW(14904, 14848, 1458, 5545, 54, 563, 9.5, 95, true, 100_000, Pet.RIFT_GUARDIAN_LAW), DEATH(14907, 14894, 1456, 5547, 65, 560, 10, 99, true, 100_000, Pet.RIFT_GUARDIAN_DEATH), BLOOD(27978, -1, 1450, 5549, 77, 565, 10.5, 1, true, 50_000, Pet.RIFT_GUARDIAN_BLOOD), SOUL(27980, -1, 1450, 5549, 77, 565, 10.5, 1, true, 50_000, Pet.RIFT_GUARDIAN_SOUL); /** * The object id used for this altar */ private int altar; /** * The object id of the exit object */ private int exitObjectId; /** * The talisman item id */ private int talismanId; /** * The tiarra item id */ private int tiarraId; /** * The level required */ private int levelRequired; /** * The experience received per essence */ private double experience; /** * The rune */ private int rune; private int multiplier; /** * Can we only use pure essence? */ private boolean pureEssenceOnly; /** * The drop rate example 1/1000 */ private int baseChance; /** * The actual pet */ private Pet pet; /** * A map of all altars */ private static Map<Integer, Altar> altars = new HashMap<Integer, Altar>(); static{ for(Altar altar : Altar.values()){ altars.put(altar.getId(), altar); } } /** * The altar constructor * * @param altar * The altar id * @param exitObject * The exit object id * @param talisman * The talisman required * @param tiarraId * Or the tiarra required * @param level * The level requirement * @param rune * The rune we're crafting * @param experience * The experience we gain * @param multiplier * The rune multiplier * @param requirePureEss * Is pure essence required in order to make this rune * @param rate * The drop rate of the pet * @param petDrop * The pet id */ private Altar(int altar, int exitObject, int talisman, int tiarraId, int level, int rune, double experience, int multiplier, boolean requirePureEss, int rate, Pet petDrop) { this.altar = altar; this.exitObjectId = exitObject; this.talismanId = talisman; this.tiarraId = tiarraId; this.levelRequired = level; this.experience = experience; this.rune = rune; this.multiplier = multiplier; this.pureEssenceOnly = requirePureEss; this.baseChance = rate; this.pet = petDrop; } /** * Grab the altars by object id * * @param id * The altar * @return */ public static boolean alterIds(int id) { for(Altar altar : altars.values()) { if(altar.getAlterId() == id) { return true; } } return false; } /** * Grab a single altar by id * * @param id * The object to check * @return */ public static Altar getAltar(int id) { for(Altar a: altars.values()) { if(a.getAlterId() == id) { return a; } } return null; } /** * Gets the altar by id * * @return the alter Id */ public int getAlterId() { return altar; } /** * Gets the exit object * * @return the object id. */ public int getExitObject() { return exitObjectId; } /** * Gets the talisman id. * * @return The id. */ public int getId() { return talismanId; } /** * Gets the tiara id * * @return The id. */ public int getTiaraId() { return tiarraId; } /** * Gets the required level. * * @return The required level. */ public int getLevelRequired() { return levelRequired; } /** * The rune we're crafting * * @return The rune Id. */ public int getRune() { return rune; } /** * The experience we receive per rune * * @return the Experience. */ public double getExperience() { return experience; } public int getDoubleRunesLevel() { return multiplier; } /** * Can we only use pure essence here? * * @return True or false */ public boolean isPureEssenceOnly() { return pureEssenceOnly; } /** * Returns the drop rate example 1/1000 * * @return The drop rate. */ public int getBaseChance() { return baseChance; } /** * The pet we receive * * @return the pet Id. */ public Pet petDrop() { return pet; } }Abstract class: (Credits to Emperor for the Enum took it from a random Hyperion ages ago)Code:package com.venenatis.game.content.skills.runecrafting; import java.util.HashMap; import java.util.Map; import com.venenatis.game.location.Location; /** * This Enum holds all talisman teleporting data. * @author <a href="http://www.rune-server.org/members/_Patrick_/">Patrick van Elderen</a> * */ public enum Talisman { AIR_TALISMAN(1438, Location.create(2984, 3290, 0), Location.create(2841, 4829, 0)), MIND_TALISMAN(1448, Location.create(2983, 3516, 0), Location.create(2793, 4828, 0)), WATER_TALISMAN(1444, Location.create(3187, 3166, 0), Location.create(2726, 4832, 0)), EARTH_TALISMAN(1440, Location.create(3304, 3475, 0), Location.create(2656, 4829, 0)), FIRE_TALISMAN(1442, Location.create(3315, 3254, 0), Location.create(2576, 4845, 0)), BODY_TALISMAN(1446, Location.create(3051, 3447, 0), Location.create(2521, 4834, 0)), COSMIC_TALISMAN(1454, Location.create(2407, 4379, 0), Location.create(2122, 4833, 0)), CHAOS_TALISMAN(1452, Location.create(3058, 3591, 0), Location.create(2281, 4837, 0)), NATURE_TALISMAN(1462, Location.create(2869, 3021, 0), Location.create(2400, 4835, 0)), LAW_TALISMAN(1458, Location.create(2858, 3379, 0), Location.create(2464, 4818, 0)), DEATH_TALISMAN(1456, Location.create(3087, 3496, 0), Location.create(2208, 4830, 0)); /** * The id of the talisman */ private final int talismanId; /** * The outside location of the altar */ private final Location outsideLocation; /** * The inside location of the altar */ private final Location insideLocation; /** * A map of all talismans */ private static Map<Integer, Talisman> talismans = new HashMap<Integer, Talisman>(); /** * Gets a talisman by an item id. * * @param item The item id. * @return The talisman. */ public static Talisman forId(int item) { return talismans.get(item); } /** * The talisman constructor * * @param id * The talisman * @param outsideLocation * The outside coordinates of the altar * @param insideLocation * The inside coordinates of the altar */ private Talisman(int id, Location outsideLocation, Location insideLocation){ this.talismanId = id; this.outsideLocation = outsideLocation; this.insideLocation = insideLocation; } /** * Gets the id. * * @return The id. */ public int getTalisman() { return talismanId; } /** * Gets the outside location of the alter * * @return the location */ public Location getOutsideLocation() { return outsideLocation; } /** * Gets the inside location of the alter * * @return the location */ public Location getInsideLocation() { return insideLocation; } }
Code:package com.venenatis.game.action.impl; import java.util.Random; import com.venenatis.game.model.entity.player.Player; import com.venenatis.game.task.Task; import com.venenatis.game.util.CycleState; public abstract class Skill extends Task { /** * The random instance used. */ public static final Random RANDOM = new Random(); /** * The current cycle state. */ private CycleState cycleState = CycleState.START; /** * The player. */ private final Player player; /** * Constructs a new skill action. */ public Skill(Player player) { super(1); this.player = player; } @Override public void execute() { switch (cycleState) { case START: if (start(player)) { setCycleState(CycleState.EXECUTE); return; } stop(); return; case EXECUTE: if (execute(player)) { setCycleState(CycleState.FINALIZE); } return; case FINALIZE: if (finish(player)) { stop(); } return; default: break; } } /** * Attempts to start the actual skilling action. * * @param player The player. * @return {@code True} if the player can execute this action, {@code false} if not. */ public abstract boolean start(Player player); /** * Executes the skilling action. * * @param player The player. * @return {@code True} if we can finish the skilling action, {@code false} if not. */ public abstract boolean execute(Player player); /** * Attempts to finish the skilling action. * * @param player The player. * @return {@code True} if the action has finished, {@code false} if we should re-execute. */ public abstract boolean finish(Player player); /** * @param cycleState the cycleState to set */ public void setCycleState(CycleState cycleState) { this.cycleState = cycleState; } /** * @return the cycleState */ public CycleState getCycleState() { return cycleState; } /** * @return the player */ public Player getPlayer() { return player; } }Kind regards,Code:package com.venenatis.game.util; /** * An enum holding different kinds of cycle states. * * @author Emperor */ public enum CycleState { /** * The commencing of the cycle. */ START, /** * The executing of the cycle. */ EXECUTE, /** * The finalizing of the cycle. */ FINALIZE, /** * The cycle has finished. */ FINISHED; }
Patrick
Last edited by _Patrick_; 12-12-2017 at 04:11 PM. Reason: Updated
might want to use some switch statements here and there
getAmount() method is fairly useless. There's a strict pattern between the levels required. The way I did it on my OSRS is by adding the 'level required for 2x runes' variable to the data. It is simply repeated from there on.
14 -> 28 -> 42..etc.
Lv * 1 -> Lv * 2 -> Lv * 3 ^
As far as the locateTalisman method goes - You could also store all of that data within the enum. There's no point to separate it at all.
The design of the HarvestingAction class is a little iffy IMO. I'm noticing a lot of methods where in most cases, a lot of them will never be touched. I'd write a default method inside the abstract class for those - just to shorten the code from redundant crap. I'd simply add default values to a lot of those methods and if necessary, you can simply override a method to give it a different value.
The last thing I personally find a little iffy is the constant object recreation. I mean java is indeed OO language but I personally prefer to have constants and refer to constants whenever necessary, rather than recreate a variable every time a method/class is called/created which puts a bit extra pressure on GC and makes memory usage a bit more unstable from the prospectors point of view.
Fairly decent overall though.
tHANKS FOR SHARING
Thanks guys will read again when im behind a pc currently on my phone
If you use your altar to get the amount, you can simply do Altar.getAmount() instead. It will result in cleaner code.
Make a Talisman class, let it have a teleportLocation and an itemID. Let Runecrafting have a Map/HashMap that maps the itemID to a Talisman-class. Use these to teleport and to check if the player has a talisman. In this case it's probably good enough to just map the item IDs to a location though. But a Talisman class is great for extension and for readability.
Also you might want to check if the player has the correct talisman in the altar class (and return true/false to the skill).
I'm guessing you won't offer a chance to get to the altar if there are no talisman involved. But it could still be dropped, which technically would create a glitch in your current code.
Updated, followed advice. Still gota FIX the multiplier.
Add the multiplier level into the Altar enum and do something like this.
Code:int multiplier = (int) Math.floor(player.getSkills().getLevel(Skills.RUNECRAFTING) / runeData.getDoubleRunesLevel()); multiplier += 1; player.getInventory().getContainer().add(new Item(runeData.getRuneId(), runes * multiplier));
« Previous Thread | Next Thread » |
Thread Information |
Users Browsing this ThreadThere are currently 1 users browsing this thread. (0 members and 1 guests) |