RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
Overrides.java
1package com.osroyale.content.overrides;
2
3import com.osroyale.game.world.entity.combat.attack.FightStyle;
4import com.osroyale.game.world.entity.combat.attack.FightType;
5import com.osroyale.game.world.entity.combat.weapon.WeaponInterface;
6import com.osroyale.game.world.entity.mob.UpdateFlag;
7import com.osroyale.game.world.entity.mob.player.Player;
8import com.osroyale.game.world.items.Item;
9import com.osroyale.game.world.items.containers.equipment.Equipment;
10import com.osroyale.game.world.items.containers.equipment.EquipmentType;
11import com.osroyale.game.world.position.Area;
12import com.osroyale.net.packet.out.*;
13
14import java.util.*;
15
52
53public class Overrides {
54
55 private final Player player;
56 public Overrides(Player player) {
57 this.player = player;
58 }
59
60 public record OverridePreset(Item... items) {}
61 public Map<String, OverridePreset> presets = new HashMap<>();
62
63 public List<Integer> allOverrides = new ArrayList<>();
64 public Map<Integer, Item> currentOverrides = new HashMap<>();
65
66 final Map<Integer, Integer> buttons = new HashMap<>();
67 final Map<Integer, String> presetButtons = new HashMap<>();
68
69 EquipmentType filter = EquipmentType.NOT_WIELDABLE;
70 String filterName = "All";
71 boolean managingOverrides = false;
72
73 public void openInterface() {
74 if (Area.inWilderness(player)) {
75 player.message("You can't do this in the wilderness.");
76 return;
77 }
78 filter = EquipmentType.NOT_WIELDABLE;
79 filterName = "All";
80 drawText();
81 loadContainers();
82 player.interfaceManager.open(OVERRIDE_INTERFACE);
83 }
84
85 private void drawText() {
86 wipeInterface();
87 player.send(new SendString(filterName + " Overrides", 60113));
88
89 if (filterName.equals("Preset")) {
90 drawPresets();
91 return;
92 }
93
94 int slot = 0;
95 for (int i = 0; i < allOverrides.size(); i++) {
96 final var equipmentSlot = new Item(allOverrides.get(i)).getDefinition().getEquipmentType().getNewItemDefName();
97 if (!Objects.equals(equipmentSlot, filter.getNewItemDefName()) && filter != EquipmentType.NOT_WIELDABLE) {
98 continue;
99 }
100
101 final var itemName = new Item(allOverrides.get(i)).getName();
102 player.send(new SendString(itemName, 60146 + (slot * 2)));
103 buttons.put(-5391 + (slot * 2), allOverrides.get(i));
104 slot++;
105 }
106 }
107
108 private void drawPresets() {
109 for (int i = 0; i < presets.size(); i++) {
110 final var presetName = presets.keySet().toArray()[i].toString();
111 player.send(new SendString(presetName, 60146 + (i * 2)));
112 presetButtons.put(-5391 + (i * 2), presetName);
113 }
114 }
115
116 private void wipeInterface() {
117 for (int i = 0; i < allOverrides.size() + 1; i++) {
118 player.send(new SendString("", 60146 + (i * 2)));
119 }
120 buttons.clear();
121 presetButtons.clear();
122 }
123
124 public void addOverride(int itemId) {
125 final var item = new Item(itemId);
126 final var canEquipItem = item.isEquipable();
127 if (!canEquipItem) {
128 player.dialogueFactory.sendItem("Keepsake Overrides", "You can only keepsake equipable items.", itemId).execute();
129 return;
130 }
131 final var unallowedSlot = item.getEquipmentType() == EquipmentType.RING || item.getEquipmentType() == EquipmentType.ARROWS;
132 if (unallowedSlot) {
133 player.dialogueFactory.sendItem("Keepsake Overrides", "You cannot keepsake this item.", itemId).execute();
134 return;
135 }
136 if (allOverrides.contains(itemId)) {
137 player.dialogueFactory.sendItem("Keepsake Overrides", "You already have this as an override.", itemId).execute();
138 return;
139 }
140 if (allOverrides.size() > 44) {
141 player.dialogueFactory.sendItem("Keepsake Overrides", "You can only have 45 overrides.", itemId).execute();
142 return;
143 }
144 if (Area.inWilderness(player)) {
145 player.message("You can't do this in the wilderness.");
146 return;
147 }
148
149 player.dialogueFactory.sendStatement(
150 "Are you sure you want to keepsake the " + item.getName() + "?", "You will @red@not@bla@ be able to reclaim it.").sendOption(
151 "Yes, keepsake the " + item.getName(), () -> {
152 allOverrides.add(itemId);
153 player.inventory.remove(2399, 1);
154 player.inventory.remove(itemId, 1);
155 },
156 "Nevermind", () -> player.dialogueFactory.clear()).execute();
157 }
158
159 private void deleteOverride(Item item) {
160 if (!allOverrides.contains(item.getId())) {
161 player.message("Error deleting override.");
162 return;
163 }
164
165 allOverrides.remove(Integer.valueOf(item.getId()));
166
167 //Remove override if it is currently equipped
168 if (currentOverrides.containsValue(item)) {
169 removeOverride(item.getId());
170 }
171
172 //Remove preset if it contains the deleted override
173 for (int i = 0; i < presets.size(); i++) {
174 final var preset = presets.get(presets.keySet().toArray()[i].toString());
175 if (Arrays.stream(preset.items).anyMatch(presetItem -> presetItem != null && presetItem.getId() == item.getId())) {
176 presets.remove(presets.keySet().toArray()[i].toString());
177 player.message("A preset has been deleted as it contained a deleted override.");
178 }
179 }
180
181 drawText();
182 }
183
184 public boolean hasOverride(int slot) {
185 if (Area.inWilderness(player)) {
186 return false;
187 }
188 if (Area.inDuelArena(player)) {
189 return false;
190 }
191 if (!currentOverrides.containsKey(slot)) {
192 return false;
193 }
194
195 if (slot == Equipment.WEAPON_SLOT) {
196 return hasWeaponOverride();
197 /*if (player.equipment.get(Equipment.WEAPON_SLOT) != null) {
198 final var wornWeapon = player.equipment.get(Equipment.WEAPON_SLOT).getRangedDefinition();
199 final var overrideWeapon = currentOverrides.get(Equipment.WEAPON_SLOT).getRangedDefinition();
200 return (wornWeapon.isPresent() || overrideWeapon.isEmpty()) && (overrideWeapon.isPresent() || wornWeapon.isEmpty());
201 } else {
202 return true;
203 }*/
204 }
205
206 if (slot == Equipment.SHIELD_SLOT) {
207 return hasShieldOverride();
208 /* if (player.equipment.get(Equipment.WEAPON_SLOT) != null) {
209 final var wornWeapon = player.equipment.get(Equipment.WEAPON_SLOT);
210 if (currentOverrides.containsKey(Equipment.WEAPON_SLOT)) {
211 if (wornWeapon.getRangedDefinition().isPresent() && wornWeapon.isTwoHanded() && currentOverrides.get(Equipment.WEAPON_SLOT).getRangedDefinition().isEmpty()) {
212 return false;
213 }
214 return !currentOverrides.get(Equipment.WEAPON_SLOT).isTwoHanded();
215 }
216 return !wornWeapon.isTwoHanded();
217 } else if (currentOverrides.containsKey(Equipment.WEAPON_SLOT)) {
218 return !currentOverrides.get(Equipment.WEAPON_SLOT).isTwoHanded();
219 } else {
220 return true;
221 }*/
222 }
223
224 return currentOverrides.containsKey(slot);
225 }
226
227 private boolean hasWeaponOverride() {
228 final var hasWeapon = player.equipment.get(Equipment.WEAPON_SLOT) != null;
229 final var weaponIs2h = hasWeapon && player.equipment.get(Equipment.WEAPON_SLOT).isTwoHanded();
230 final var weaponIsRanged = hasWeapon && player.equipment.get(Equipment.WEAPON_SLOT).getRangedDefinition().isPresent();
231
232 final var hasOverride = currentOverrides.containsKey(Equipment.WEAPON_SLOT);
233 final var overrideIs2h = hasOverride && currentOverrides.get(Equipment.WEAPON_SLOT).isTwoHanded();
234 final var overrideIsRanged = hasOverride && currentOverrides.get(Equipment.WEAPON_SLOT).getRangedDefinition().isPresent();
235
236 if (hasWeapon) {
237 if (weaponIs2h && !overrideIs2h || overrideIs2h && !weaponIs2h) {
238 return false;
239 }
240 if (weaponIsRanged && !overrideIsRanged || overrideIsRanged && !weaponIsRanged) {
241 return false;
242 }
243 }
244
245 return hasOverride;
246 }
247
248 private boolean hasShieldOverride() {
249 final var hasWeapon = player.equipment.get(Equipment.WEAPON_SLOT) != null;
250 final var weaponIs2h = hasWeapon && player.equipment.get(Equipment.WEAPON_SLOT).isTwoHanded();
251
252 final var hasOverrideWeapon = currentOverrides.containsKey(Equipment.WEAPON_SLOT);
253 final var overrideIs2h = hasOverrideWeapon && currentOverrides.get(Equipment.WEAPON_SLOT).isTwoHanded();
254
255 if (weaponIs2h) {
256 return false;
257 }
258 if (overrideIs2h) {
259 return false;
260 }
261
262 return currentOverrides.containsKey(Equipment.SHIELD_SLOT);
263 }
264
265 public Item get(int slot) {
266 return currentOverrides.get(slot);
267 }
268
269 private void createPreset(String presetName) {
270 if (presets.containsKey(presetName)) {
271 player.message("You already have a preset named " + presetName + ".");
272 return;
273 }
274 Item[] presetItems = new Item[11];
275 currentOverrides.forEach((k, v) -> presetItems[k] = v);
276
277 presets.put(presetName, new OverridePreset(presetItems));
278 drawText();
279 }
280
281 private void loadPreset(String presetName) {
282 if (!presets.containsKey(presetName)) {
283 player.message("Error loading preset: " + presetName);
284 return;
285 }
286
287 removeAllOverrides();
288
289 for (Item item : presets.get(presetName).items) {
290 if (item == null) {
291 continue;
292 }
293 equipOverride(item);
294 }
295 }
296
297 private void renamePreset(String currentName, String newName) {
298 if (!presets.containsKey(currentName)) {
299 player.message("Error renaming preset: " + currentName);
300 return;
301 }
302 if (presets.containsKey(newName)) {
303 player.message("You already have a preset named " + newName + ".");
304 return;
305 }
306
307 presets.put(newName, presets.get(currentName));
308 presets.remove(currentName);
309 player.message("Preset renamed to " + newName + ".");
310 drawText();
311 }
312
313 private void deletePreset(String presetName) {
314 if (!presets.containsKey(presetName)) {
315 player.message("Error deleting preset: " + presetName);
316 return;
317 }
318
319 presets.remove(presetName);
320 player.message("Preset deleted.");
321 drawText();
322 }
323
324 public FightType getFightType(Item item) {
325 WeaponInterface weapon = item == null ? null : item.getWeaponInterface();
326 if (weapon == null) weapon = WeaponInterface.UNARMED;
327
328 FightType[] oldTypes = player.getWeapon().getFightTypes();
329 FightType[] newTypes = weapon.getFightTypes();
330 FightType result = null;
331
332 for (int index = 0; index < oldTypes.length; index++) {
333 if (newTypes.length == index) {
334 break;
335 }
336
337 if (newTypes[index].getStyle().equals(FightStyle.DEFENSIVE)
338 && player.getCombat().getFightType().getStyle().equals(FightStyle.DEFENSIVE)) {
339 result = newTypes[index];
340 break;
341 }
342
343 if (oldTypes[index] == player.getCombat().getFightType()) {
344 boolean oldControlled = oldTypes[index].getStyle().equals(FightStyle.CONTROLLED);
345 boolean newControlled = newTypes[index].getStyle().equals(FightStyle.CONTROLLED);
346 if (newControlled != oldControlled) {
347 continue;
348 }
349 result = newTypes[index];
350 break;
351 }
352 }
353
354 if (result == null) {
355 if (player.getCombat().getFightType().getStyle().equals(FightStyle.DEFENSIVE)) {
356 result = newTypes[newTypes.length - 1];
357 } else {
358 result = newTypes[1];
359 }
360 }
361 return result;
362 }
363
364 public boolean handleButtons(int button) {
365 if (presetButtons.containsKey(button)) {
366 final var presetName = presetButtons.get(button);
367 if (managingOverrides) {
368 managePresetDialogue(presetName);
369 return true;
370 }
371 loadPreset(presetName);
372 return true;
373 }
374 if (buttons.containsKey(button)) {
375 final var item = new Item(buttons.get(button));
376 if (managingOverrides) {
377 manageItemDialogue(item);
378 return true;
379 }
380 equipOverride(item);
381 return true;
382 }
383 switch (button) {
384 case INFO_BTN -> player.interfaceManager.open(INFO_INTERFACE);
385 case INFO_CLOSE_BTN -> player.interfaceManager.close();
386 case VIEW_ALL_BTN, INFO_GO_BACK_BTN, OPEN_OVERRIDE_BTN -> openInterface();
387 case HEAD_SLOT_BTN -> setFilter(EquipmentType.HELM, "Head");
388 case AMULET_SLOT_BTN -> setFilter(EquipmentType.AMULET, "Amulet");
389 case BODY_SLOT_BTN -> setFilter(EquipmentType.BODY, "Body");
390 case LEGS_SLOT_BTN -> setFilter(EquipmentType.LEGS, "Leg");
391 case BOOTS_SLOT_BTN -> setFilter(EquipmentType.BOOTS, "Boot");
392 case CAPE_SLOT_BTN -> setFilter(EquipmentType.CAPE, "Cape");
393 case WEAPON_SLOT_BTN -> setFilter(EquipmentType.WEAPON, "Weapon");
394 case GLOVES_SLOT_BTN -> setFilter(EquipmentType.GLOVES, "Glove");
395 case SHIELD_SLOT_BTN -> setFilter(EquipmentType.SHIELD, "Shield");
396 case VIEW_PRESET_BTN -> setFilter(EquipmentType.NOT_WIELDABLE, "Preset");
397 case MANAGE_BTN -> manageModeDialogue();
398
399 case SAVE_PRESET_BTN -> {
400 if (presets.size() > 4) {
401 player.message("You already have the maximum amount of presets saved.");
402 return true;
403 }
404 player.send(new SendInputMessage("Enter name for preset:", 30, this::createPreset));
405 return true;
406 }
407 }
408 return false;
409 }
410
411 private void manageModeDialogue() {
412 player.dialogueFactory.sendOption(
413 "Toggle manage mode to " + (managingOverrides ? "@red@off@bla@" : "@gre@on@bla@"), () -> managingOverrides = !managingOverrides,
414
415 "What is manage mode?", () -> player.dialogueFactory.sendStatement(
416 "Manage mode allows you to manage your overrides and presets.",
417 "When manage mode is on, clicking an override or preset will",
418 "open a menu allowing you to equip, delete, or rename it."),
419
420 "Nevermind", () -> player.dialogueFactory.clear()).execute();
421 }
422
423 private void manageItemDialogue(Item item) {
424 player.dialogueFactory.sendOption(
425 "Equip <col=255>" + item.getName()+"</col>", () -> equipOverride(item),
426
427 "@red@Delete " + item.getName(), () -> player.dialogueFactory.sendStatement(
428 "Are you sure you want to delete this override?", "The item will be @red@permanently lost@bla@.").sendOption(
429 "Yes, permanently delete " + item.getName(), () -> deleteOverride(item),
430 "Nevermind", () -> player.dialogueFactory.clear()),
431
432 "Nevermind", () -> player.dialogueFactory.clear()).execute();
433 }
434
435 private void managePresetDialogue(String presetName) {
436 player.dialogueFactory.sendOption(
437 "Equip <col=255>" + presetName + "</col>", () -> loadPreset(presetName),
438
439 "Rename preset", () -> {
440 player.dialogueFactory.clear();
441 player.dialogueFactory.onAction(() -> player.send(new SendInputMessage("Enter new preset name:", 30, input -> renamePreset(presetName, input))));
442 },
443
444 "@red@Delete " + presetName, () -> player.dialogueFactory.sendStatement(
445 "Are you sure you want to delete this preset?").sendOption(
446 "Yes, delete " + presetName, () -> deletePreset(presetName),
447 "Nevermind", () -> player.dialogueFactory.clear()),
448
449 "Nevermind", () -> player.dialogueFactory.clear()).execute();
450 }
451
452 private void setFilter(EquipmentType equipmentType, String name) {
453 filter = equipmentType;
454 filterName = name;
455 drawText();
456 }
457
458 public void removeOverride(int itemId) {
459 player.send(toggleConfig(itemId, "on"));
460 player.send(new SendItemOnInterface(determineContainer(itemId), new Item(-1)));
461
462 final var equipmentType = new Item(itemId).getDefinition().getEquipmentType();
463 currentOverrides.remove(equipmentType.getSlot());
464 player.updateFlags.add(UpdateFlag.APPEARANCE);
465 player.equipment.updateAnimation();
466 }
467
468 private void removeAllOverrides() {
469 while (!currentOverrides.isEmpty()) {
470 removeOverride(currentOverrides.get(currentOverrides.keySet().iterator().next()).getId());
471 }
472 }
473
474 private void equipOverride(Item item) {
475 player.send(toggleConfig(item.getId(), "off"));
476 player.send(new SendItemOnInterface(determineContainer(item.getId()), item));
477
478 final var equipmentType = item.getDefinition().getEquipmentType();
479 currentOverrides.remove(equipmentType.getSlot());
480 currentOverrides.put(equipmentType.getSlot(), item);
481 player.updateFlags.add(UpdateFlag.APPEARANCE);
482 player.equipment.updateAnimation();
483 }
484
485 /* This is used to reload the equipment config buttons & item containers. This is because if a player closes
486 * their client and reopens, the configs/items will not show even if they have overrides active. */
487 private void loadContainers() {
488 currentOverrides.forEach((slot, item) -> {
489 player.send(toggleConfig(item.getId(), "off"));
490 player.send(new SendItemOnInterface(determineContainer(item.getId()), item));
491 });
492 }
493
494 private SendConfig toggleConfig(int itemId, String toggle) {
495 final var configValue = toggle.equals("on") ? 0 : 1;
496 final var equipmentSlot = new Item(itemId).getDefinition().getEquipmentType();
497 return switch (equipmentSlot) {
498 case HAT, HELM, MASK, FACE -> new SendConfig(1300, configValue);
499 case CAPE -> new SendConfig(1301, configValue);
500 case AMULET -> new SendConfig(1302, configValue);
501 case WEAPON -> new SendConfig(1303, configValue);
502 case BODY, TORSO -> new SendConfig(1304, configValue);
503 case SHIELD -> new SendConfig(1305, configValue);
504 case LEGS -> new SendConfig(1306, configValue);
505 case BOOTS -> new SendConfig(1307, configValue);
506 case GLOVES -> new SendConfig(1308, configValue);
507 default -> null;
508 };
509 }
510
511 private int determineContainer(int itemId) {
512 final var equipmentSlot = new Item(itemId).getDefinition().getEquipmentType();
513 return switch (equipmentSlot) {
514 case HAT, HELM, MASK, FACE -> HEAD_CONTAINER;
515 case CAPE -> CAPE_CONTAINER;
516 case AMULET -> AMULET_CONTAINER;
517 case WEAPON -> WEAPON_CONTAINER;
518 case BODY, TORSO -> BODY_CONTAINER;
519 case SHIELD -> SHIELD_CONTAINER;
520 case LEGS -> LEGS_CONTAINER;
521 case GLOVES -> GLOVES_CONTAINER;
522 case BOOTS -> BOOTS_CONTAINER;
523 default -> -1;
524 };
525 }
526
527 //Constants - eliminate magic numbers
528 final int HEAD_CONTAINER = 60131;
529 final int BODY_CONTAINER = 60135;
530 final int LEGS_CONTAINER = 60137;
531 final int AMULET_CONTAINER = 60133;
532 final int CAPE_CONTAINER = 60132;
533 final int GLOVES_CONTAINER = 60138;
534 final int BOOTS_CONTAINER = 60139;
535 final int WEAPON_CONTAINER = 60134;
536 final int SHIELD_CONTAINER = 60136;
537 final int OVERRIDE_INTERFACE = 60106;
538 final int INFO_INTERFACE = 60260;
539 final int INFO_BTN = -5286;
540 final int INFO_CLOSE_BTN = -5270;
541 final int INFO_GO_BACK_BTN = -5267;
542 final int MANAGE_BTN = -5395;
543 final int HEAD_SLOT_BTN = -5415;
544 final int AMULET_SLOT_BTN = -5413;
545 final int BODY_SLOT_BTN = -5410;
546 final int LEGS_SLOT_BTN = -5408;
547 final int BOOTS_SLOT_BTN = -5407;
548 final int CAPE_SLOT_BTN = -5414;
549 final int WEAPON_SLOT_BTN = -5411;
550 final int GLOVES_SLOT_BTN = -5406;
551 final int SHIELD_SLOT_BTN = -5409;
552 final int VIEW_PRESET_BTN = -5417;
553 final int SAVE_PRESET_BTN = -5422;
554 final int VIEW_ALL_BTN = -5428;
555 final int OPEN_OVERRIDE_BTN = 27659;
556}