RuneHive-Game
Loading...
Searching...
No Matches
Fletching.java
Go to the documentation of this file.
1package com.runehive.content.skill.impl.fletching;
2
3import com.runehive.Config;
4import com.runehive.content.achievement.AchievementHandler;
5import com.runehive.content.achievement.AchievementKey;
6import com.runehive.content.activity.randomevent.RandomEventHandler;
7import com.runehive.content.clanchannel.content.ClanTaskKey;
8import com.runehive.content.event.impl.ClickButtonInteractionEvent;
9import com.runehive.content.event.impl.ItemOnItemInteractionEvent;
10import com.runehive.content.skill.impl.firemaking.FiremakingData;
11import com.runehive.content.skill.impl.fletching.impl.Arrow;
12import com.runehive.content.skill.impl.fletching.impl.Carvable;
13import com.runehive.content.skill.impl.fletching.impl.Stringable;
14import com.runehive.content.skillcape.SkillCape;
15import com.runehive.game.Animation;
16import com.runehive.game.Graphic;
17import com.runehive.game.action.Action;
18import com.runehive.game.action.policy.WalkablePolicy;
19import com.runehive.game.world.entity.mob.player.Player;
20import com.runehive.game.world.entity.skill.Skill;
21import com.runehive.game.world.items.Item;
22import com.runehive.net.packet.out.*;
23import com.runehive.util.Utility;
24import org.apache.logging.log4j.LogManager;
25import org.apache.logging.log4j.Logger;
26
27import java.util.HashMap;
28
29/**
30 * Handles the fletching skill.
31 *
32 * @author Daniel
33 */
34public class Fletching extends Skill {
35
36 private static final Logger logger = LogManager.getLogger(Fletching.class);
37
38 private static final String FLETCHABLE_KEY = "FLETCHABLE_KEY";
39
40 private final static HashMap<Integer, Fletchable> FLETCHABLES = new HashMap<>();
41
42 public Fletching(int level, double experience) {
43 super(Skill.FLETCHING, level, experience);
44 }
45
46 public static void addFletchable(Fletchable fletchable) {
47 if (FLETCHABLES.put(fletchable.getWith().getId(), fletchable) != null) {
48 System.out.println("[Fletching] Conflicting item values: " + fletchable.getWith().getId() + " Type: " + fletchable.getClass().getSimpleName());
49 }
50 }
51
52 private Fletchable getFletchable(int use, int with) {
53 return FLETCHABLES.getOrDefault(use, FLETCHABLES.get(with));
54 }
55
56 @Override
57 protected double modifier() {
59 }
60
61 @Override
62 protected boolean useItem(Player player, ItemOnItemInteractionEvent event) {
63 Item first = event.getFirst();
64 Item second = event.getSecond();
65
66 if (FiremakingData.forId(first.getId()).isPresent() && FiremakingData.forId(second.getId()).isPresent()) {
67 return false;
68 }
69
70 Fletchable fletchable = getFletchable(first.getId(), second.getId());
71
72 if (fletchable == null || first.getId() == 590 || second.getId() == 590 || first.getId() == 8792 || second.getId() == 8792) {
73 return false;
74 }
75
76 if (!fletchable.getUse().equalIds(first) && !fletchable.getUse().equalIds(second)) {
77 player.message("You need to use this with " + Utility.getAOrAn(fletchable.getUse().getName()) + " " + fletchable.getUse().getName().toLowerCase() + " to fletch this item.");
78 return true;
79 }
80
81 String prefix = fletchable.getWith().getName().split(" ")[0];
82
83 switch (fletchable.getFletchableItems().length) {
84
85 case 1:
86 player.attributes.set(FLETCHABLE_KEY, fletchable);
87 player.send(new SendString("\\n \\n \\n \\n" + fletchable.getFletchableItems()[0].getProduct().getName(), 2799));
88 player.send(new SendItemOnInterfaceZoom(1746, 170, fletchable.getFletchableItems()[0].getProduct().getId()));
89 player.send(new SendChatBoxInterface(4429));
90 return true;
91 case 2:
92 player.attributes.set(FLETCHABLE_KEY, fletchable);
93 player.send(new SendItemOnInterfaceZoom(8869, 170, fletchable.getFletchableItems()[0].getProduct().getId()));
94 player.send(new SendItemOnInterfaceZoom(8870, 170, fletchable.getFletchableItems()[1].getProduct().getId()));
95 player.send(new SendString("\\n \\n \\n \\n".concat(prefix + " Short Bow"), 8874));
96 player.send(new SendString("\\n \\n \\n \\n".concat(prefix + " Long Bow"), 8878));
97 player.send(new SendChatBoxInterface(8866));
98 return true;
99 case 3:
100 player.attributes.set(FLETCHABLE_KEY, fletchable);
101 player.send(new SendItemOnInterfaceZoom(8883, 170, fletchable.getFletchableItems()[0].getProduct().getId()));
102 player.send(new SendItemOnInterfaceZoom(8884, 170, fletchable.getFletchableItems()[1].getProduct().getId()));
103 player.send(new SendItemOnInterfaceZoom(8885, 170, fletchable.getFletchableItems()[2].getProduct().getId()));
104 player.send(new SendString("\\n \\n \\n \\n".concat("Arrow heads"), 8889));
105 player.send(new SendString("\\n \\n \\n \\n".concat(prefix + " Short Bow"), 8893));
106 player.send(new SendString("\\n \\n \\n \\n".concat(prefix + " Long Bow"), 8897));
107 player.send(new SendChatBoxInterface(8880));
108 return true;
109 case 4:
110 player.attributes.set(FLETCHABLE_KEY, fletchable);
111 player.send(new SendItemOnInterfaceZoom(8902, 170, fletchable.getFletchableItems()[0].getProduct().getId()));
112 player.send(new SendItemOnInterfaceZoom(8903, 170, fletchable.getFletchableItems()[1].getProduct().getId()));
113 player.send(new SendItemOnInterfaceZoom(8904, 170, fletchable.getFletchableItems()[2].getProduct().getId()));
114 player.send(new SendItemOnInterfaceZoom(8905, 170, fletchable.getFletchableItems()[3].getProduct().getId()));
115
116 String[] productNames;
117 if (fletchable == Carvable.AMETHYST) {
118 productNames = new String[]{"Arrowtips", "Bolt tips", "Javelin heads", "Dart tips"};
119 } else {
120 productNames = new String[]{"Arrow Shafts", "Short Bow", "Long Bow", "Crossbow Stock"};
121 }
122
123 player.send(new SendString("\\n \\n \\n \\n".concat(productNames[0]), 8909));
124 player.send(new SendString("\\n \\n \\n \\n".concat(productNames[1]), 8913));
125 player.send(new SendString("\\n \\n \\n \\n".concat(productNames[2]), 8917));
126 player.send(new SendString("\\n \\n \\n \\n".concat(productNames[3]), 8921));
127 player.send(new SendChatBoxInterface(8899));
128 return true;
129 default:
130 return false;
131 }
132 }
133
134 @Override
136 if (player.attributes.get(FLETCHABLE_KEY, Fletchable.class) == null) {
137 return false;
138 }
139
140 Fletchable fletchable = player.attributes.get(FLETCHABLE_KEY, Fletchable.class);
141
142 int button = event.getButton();
143
144 switch (button) {
145
146 /* Option 1 - Make all */
147 case 1747:
148 start(player, fletchable, 0, 15);
149 return true;
150
151 /* Option 1 - Make 1 */
152 case 2799:
153 case 8909:
154 case 8874:
155 case 8889:
156 start(player, fletchable, 0, 1);
157 return true;
158
159 /* Option 1 - Make 5 */
160 case 2798:
161 case 8908:
162 case 8873:
163 case 8888:
164 start(player, fletchable, 0, 5);
165 return true;
166
167 /* Option 1 - Make 10 */
168 case 8907:
169 case 8872:
170 case 8887:
171 start(player, fletchable, 0, 10);
172 return true;
173 //TODO: Make X limited to 150.
174
175 /* Option 1 - Make X */
176 case 1748:
177 case 8906:
178 case 8871:
179 case 8886:
180 case 6212:
181 try {
182 player.send(new SendInputAmount("Enter amount", 3, input ->
183 start(player, fletchable, 0, Integer.parseInt(input))));
184
185 } catch (Exception ex) {
186 logger.error(String.format("player=%s error fletching option1: make-x", player.getName()), ex);
187 }
188 return true;
189
190 /* Option 2 - Make 1 */
191 case 8913:
192 case 8878:
193 case 8893:
194 start(player, fletchable, 1, 1);
195 return true;
196
197 /* Option 2 - Make 5 */
198 case 8912:
199 case 8877:
200 case 8892:
201 start(player, fletchable, 1, 5);
202 return true;
203
204 /* Option 2 - Make 10 */
205 case 8911:
206 case 8876:
207 case 8891:
208 start(player, fletchable, 1, 10);
209 return true;
210
211 /* Option 2 - Make X */
212 case 8910:
213 case 8875:
214 case 8890:
215 try {
216 player.send(new SendInputAmount("Enter amount", 2, input -> start(player, fletchable, 1, Integer.parseInt(input))));
217 } catch (Exception ex) {
218 logger.error(String.format("player=%s error fletching option2: make-x", player.getName()), ex);
219 }
220 return true;
221
222 /* Option 3 - Make 1 */
223 case 8917:
224 case 8897:
225 start(player, fletchable, 2, 1);
226 return true;
227
228 /* Option 3 - Make 5 */
229 case 8916:
230 case 8896:
231 start(player, fletchable, 2, 5);
232 return true;
233
234 /* Option 3 - Make 10 */
235 case 8915:
236 case 8895:
237 start(player, fletchable, 2, 10);
238 return true;
239
240 /* Option 3 - Make X */
241 case 8914:
242 case 8894:
243 try {
244 player.send(new SendInputAmount("Enter amount", 2, input -> start(player, fletchable, 2, Integer.parseInt(input))));
245 } catch (Exception ex) {
246 logger.error(String.format("player=%s error fletching option3: make-x", player.getName()), ex);
247 }
248 return true;
249
250 /* Option 4 - Make 1 */
251 case 8921:
252 start(player, fletchable, 3, 1);
253 return true;
254
255 /* Option 4 - Make 5 */
256 case 8920:
257 start(player, fletchable, 3, 5);
258 return true;
259
260 /* Option 4 - Make 10 */
261 case 8919:
262 start(player, fletchable, 3, 10);
263 return true;
264
265 /* Option 4 - Make X */
266 case 8918:
267 try {
268
269 player.send(new SendInputAmount("Enter amount", 2, input -> start(player, fletchable, 3, Integer.parseInt(input))));
270 } catch (Exception ex) {
271 logger.error(String.format("player=%s error fletching option3: make-x", player.getName()), ex);
272 }
273 return true;
274
275 default:
276 return false;
277 }
278 }
279
280 public boolean fletch(Player player, int index, int amount) {
281 Fletchable fletchable = player.attributes.get(FLETCHABLE_KEY);
282
283 if (fletchable == null) {
284 return false;
285 }
286
287 return start(player, fletchable, index, amount);
288
289 }
290
291 public boolean start(Player player, Fletchable fletchable, int index, int amount) {
292 if (fletchable == null) {
293 return false;
294 }
295
297 FletchableItem item = fletchable.getFletchableItems()[index];
298 player.interfaceManager.close();
299
300 if (player.skills.getLevel(Skill.FLETCHING) < item.getLevel()) {
301 player.dialogueFactory.sendStatement("<col=369>You need a Fletching level of " + item.getLevel() + " to do that.").execute();
302 return true;
303 }
304
305 if (!(player.inventory.containsAll(fletchable.getIngredients()))) {
306 String firstName = fletchable.getUse().getName().toLowerCase();
307 String secondName = fletchable.getWith().getName().toLowerCase();
308
309 if (fletchable.getUse().getAmount() > 1 && !firstName.endsWith("s")) {
310 firstName = firstName.concat("s");
311 }
312
313 if (fletchable.getWith().getAmount() > 1 && !secondName.endsWith("s")) {
314 secondName = secondName.concat("s");
315 }
316
317 if (fletchable.getUse().getAmount() == 1 && firstName.endsWith("s")) {
318 firstName = firstName.substring(0, firstName.length() - 1);
319 }
320
321 if (fletchable.getWith().getAmount() == 1 && secondName.endsWith("s")) {
322 secondName = secondName.substring(0, secondName.length() - 1);
323 }
324
325 final String firstAmount;
326
327 if (fletchable.getUse().getAmount() == 1) {
328 firstAmount = Utility.getAOrAn(fletchable.getUse().getName());
329 } else {
330 firstAmount = String.valueOf(fletchable.getUse().getAmount());
331 }
332
333 final String secondAmount;
334
335 if (fletchable.getWith().getAmount() == 1) {
336 secondAmount = Utility.getAOrAn(fletchable.getWith().getName());
337 } else {
338 secondAmount = String.valueOf(fletchable.getWith().getAmount());
339 }
340
341 String firstRequirement = firstAmount + " " + firstName;
342 String secondRequirement = secondAmount + " " + secondName;
343 player.send(new SendMessage("You need " + firstRequirement + " and " + secondRequirement + " to do that."));
344 return true;
345 }
346
347 player.action.execute(fletch(player, fletchable, item, amount), true);
348 return true;
349 }
350
351 private Action<Player> fletch(Player player, Fletchable fletchable, FletchableItem item, int amount) {
352 return new Action<Player>(player, 2, true) {
353 int iterations = 0;
354
355 @Override
356 public void execute() {
357 ++iterations;
358 player.animate(new Animation(fletchable.getAnimation()));
359 player.graphic(new Graphic(fletchable.getGraphics()));
360 final boolean saveMaterial = SkillCape.isEquipped(player, SkillCape.FLETCHING) && Utility.random(1, 3) == 1;
361
362 if (fletchable == Carvable.AMETHYST) {
363 player.skills.addExperience(Skill.CRAFTING, item.getExperience() * modifier());
364 } else {
365 player.skills.addExperience(Skill.FLETCHING, item.getExperience() * modifier());
366 }
367
368 if (!saveMaterial) {
369 player.inventory.removeAll(fletchable.getIngredients());
370 }
371
372 player.inventory.addOrDrop(item.getProduct());
375
376 if (fletchable.getProductionMessage() != null) {
377 player.send(new SendMessage(fletchable.getProductionMessage()));
378 }
379
380 if (fletchable == Stringable.MAGIC_SHORTBOWS) {
381 getMob().forClan(channel -> channel.activateTask(ClanTaskKey.MAGIC_SHORTBOW, getMob().getName()));
382 } else if (fletchable == Stringable.YEW_SHORTBOWS) {
383 getMob().forClan(channel -> channel.activateTask(ClanTaskKey.YEW_SHORTBOW, getMob().getName()));
384 } else if (fletchable instanceof Arrow) {
386 }
387
388 if (iterations == amount || iterations > 28 || !(player.inventory.containsAll(fletchable.getIngredients()))) {
389 cancel();
390 if (!(player.inventory.containsAll(fletchable.getIngredients()))) {
391 player.send(new SendMessage("<col=369>You have run out of materials."));
392 }
393 return;
394 }
395 }
396
397
398 @Override
399 public String getName() {
400 return "Fletching";
401 }
402
403 @Override
404 public boolean prioritized() {
405 return false;
406 }
407
408 @Override
409 public WalkablePolicy getWalkablePolicy() {
411 }
412 };
413 }
414}
The class that contains setting-related constants for the server.
Definition Config.java:24
static final double FLETCHING_MODIFICATION
The experience modification for fletching.
Definition Config.java:259
static void activate(Player player, AchievementKey achievement)
Activates the achievement for the individual player.
final DialogueFactory execute()
Retrieves the next dialogue in the chain and executes it.
final DialogueFactory sendStatement(String... lines)
Appends a StatementDialogue to the current dialogue chain.
boolean useItem(Player player, ItemOnItemInteractionEvent event)
boolean clickButton(Player player, ClickButtonInteractionEvent event)
boolean fletch(Player player, int index, int amount)
Action< Player > fletch(Player player, Fletchable fletchable, FletchableItem item, int amount)
boolean start(Player player, Fletchable fletchable, int index, int amount)
static void addFletchable(Fletchable fletchable)
static final HashMap< Integer, Fletchable > FLETCHABLES
Class that models a single animation used by an entity.
Represents a single graphic that can be used by entities.
Definition Graphic.java:10
Represents an action an entity can execute.
Definition Action.java:12
public< A extends Action<?> > void execute(A action)
final GenericAttributes attributes
Definition Mob.java:95
Optional< Graphic > graphic
Definition Mob.java:91
This class represents a character controlled by a player.
Definition Player.java:125
String getName()
Gets the name of this entity.
Definition Player.java:774
static String getName(int skill)
Gets the name for a skill id.
Definition Skill.java:465
double experience
The current skill experience.
Definition Skill.java:179
int level
The current level of the skill.
Definition Skill.java:173
Skill(int skill, int level, double experience)
Constructs a new Skill.
Definition Skill.java:184
void addExperience(int id, double experience)
Adds experience to a given skill.
int getLevel(int id)
Gets the level of a skill.
The container class that represents an item that can be interacted with.
Definition Item.java:21
final int getId()
Gets the identification of this item.
Definition Item.java:324
final int getAmount()
Gets the quantity of this item.
Definition Item.java:342
boolean equalIds(Item other)
Definition Item.java:461
boolean removeAll(Collection<? extends Item > items)
Attempts to withdraw items in bulk from this container.
final boolean containsAll(int... identifiers)
Determines if this container contains all identifiers.
void addOrDrop(List< Item > items)
Attempts to deposit an item to the players inventory, if there is no space it'll bank the item instea...
Handles sending the SendItemOnInterfaceZoom packet.
The OutgoingPacket that sends a message to a Players chatbox in the client.
The OutgoingPacket that sends a string to a Players itemcontainer in the client.
Handles miscellaneous methods.
Definition Utility.java:27
static int random(int bound)
Definition Utility.java:239
static String getAOrAn(String nextWord)
A or an.
Definition Utility.java:116
public< K, E > E get(K key)
Gets a generic attribute.
public< K > void remove(K key)
Removes a generic attribute.
public< K, E > void set(K key, E attribute)
Sets a generic attribute.
static Optional< FiremakingData > forId(int id)
static boolean isEquipped(Player player, SkillCape cape)
A queue policy determines whether the action can occur while walking.
NON_WALKABLE
This indicates actions cannot occur while walking.