diff --git a/Server/data/configs/ammo_configs.json b/Server/data/configs/ammo_configs.json index fef8c7d5e..c0f6437e0 100644 --- a/Server/data/configs/ammo_configs.json +++ b/Server/data/configs/ammo_configs.json @@ -1726,5 +1726,45 @@ "darkbow_graphic": "", "projectile": "1839,40,36,32,32,15,0", "poison_damage": "0" + }, + { + "itemId": "14202", + "name": "Arrows (class 1)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "14203", + "name": "Arrows (class 2)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "14204", + "name": "Arrows (class 3)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "14205", + "name": "Arrows (class 4)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "14206", + "name": "Arrows (class 5)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" } ] diff --git a/Server/data/configs/interface_configs.json b/Server/data/configs/interface_configs.json index a5f64ee10..bb3d2219d 100644 --- a/Server/data/configs/interface_configs.json +++ b/Server/data/configs/interface_configs.json @@ -712,5 +712,17 @@ "interfaceType": "3", "walkable": "false", "tabIndex": "-1" + }, + { + "id": "804", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "809", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" } ] diff --git a/Server/data/configs/item_configs.json b/Server/data/configs/item_configs.json index 559e30ae3..0b59a5f7f 100644 --- a/Server/data/configs/item_configs.json +++ b/Server/data/configs/item_configs.json @@ -134119,7 +134119,7 @@ "attack_speed": "4", "id": "14202", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,15,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,15", "equipment_slot": "13" }, { @@ -134133,7 +134133,7 @@ "attack_speed": "4", "id": "14203", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,30,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,30", "equipment_slot": "13" }, { @@ -134147,7 +134147,7 @@ "attack_speed": "4", "id": "14204", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,45,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,45", "equipment_slot": "13" }, { @@ -134161,7 +134161,7 @@ "attack_speed": "4", "id": "14205", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,60,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", "equipment_slot": "13" }, { @@ -134175,7 +134175,7 @@ "attack_speed": "4", "id": "14206", "absorb": "0,0,0", - "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,75,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", "equipment_slot": "13" }, { @@ -135431,6 +135431,8 @@ "destroy_message": "Drop", "name": "Scimitar (class 1)", "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", "id": "14287", "bonuses": "0,55,0,0,0,0,0,0,0,0,0,15,0,0,0" }, @@ -135459,6 +135461,8 @@ "destroy_message": "Drop", "name": "Scimitar (class 2)", "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", "id": "14289", "bonuses": "0,90,0,0,0,0,0,0,0,0,0,30,0,0,0" }, @@ -135487,6 +135491,8 @@ "destroy_message": "Drop", "name": "Scimitar (class 3)", "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", "id": "14291", "bonuses": "0,145,0,0,0,0,0,0,0,0,0,45,0,0,0" }, @@ -135515,6 +135521,8 @@ "destroy_message": "Drop", "name": "Scimitar (class 4)", "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", "id": "14293", "bonuses": "0,180,0,0,0,0,0,0,0,0,0,60,0,0,0" }, @@ -135543,6 +135551,8 @@ "destroy_message": "Drop", "name": "Scimitar (class 5)", "archery_ticket_price": "0", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,0,2517,0", "id": "14295", "bonuses": "0,225,0,0,0,0,0,0,0,0,0,75,0,0,0" }, @@ -135570,6 +135580,8 @@ "destroy_message": "Drop", "name": "Dagger (class 1)", "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", "id": "14297", "bonuses": "41,0,0,0,0,0,0,0,0,0,0,15,0,0,0" }, @@ -135597,6 +135609,8 @@ "destroy_message": "Drop", "name": "Dagger (class 2)", "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", "id": "14299", "bonuses": "68,0,0,0,0,0,0,0,0,0,0,30,0,0,0" }, @@ -135624,6 +135638,8 @@ "destroy_message": "Drop", "name": "Dagger (class 3)", "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", "id": "14301", "bonuses": "101,0,0,0,0,0,0,0,0,0,0,45,0,0,0" }, @@ -135651,6 +135667,8 @@ "destroy_message": "Drop", "name": "Dagger (class 4)", "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", "id": "14303", "bonuses": "135,0,0,0,0,0,0,0,0,0,0,60,0,0,0" }, @@ -135678,6 +135696,8 @@ "destroy_message": "Drop", "name": "Dagger (class 5)", "archery_ticket_price": "0", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", "id": "14305", "bonuses": "168,0,0,0,0,0,0,0,0,0,0,75,0,0,0" }, diff --git a/Server/data/configs/music_configs.json b/Server/data/configs/music_configs.json index cbfa322d3..f9b48736b 100644 --- a/Server/data/configs/music_configs.json +++ b/Server/data/configs/music_configs.json @@ -2296,5 +2296,11 @@ "name": "Charmin' Farmin'", "indexId": "516", "borders": "{1600,4672,1663,4735}" + }, + { + "id": "578", + "name": "Stealing Creation", + "indexId": "620", + "borders": "" } ] diff --git a/Server/data/configs/ranged_weapon_configs.json b/Server/data/configs/ranged_weapon_configs.json index b04138c0b..a2790b612 100644 --- a/Server/data/configs/ranged_weapon_configs.json +++ b/Server/data/configs/ranged_weapon_configs.json @@ -1564,5 +1564,50 @@ "animation": "426", "drop_ammo": "true", "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,11212,11227,11228,11229,11217,78,4160" + }, + { + "itemId": "14192", + "name": "Bow (class 1)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" + }, + { + "itemId": "14194", + "name": "Bow (class 2)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" + }, + { + "itemId": "14196", + "name": "Bow (class 3)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" + }, + { + "itemId": "14198", + "name": "Bow (class 4)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" + }, + { + "itemId": "14200", + "name": "Bow (class 5)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" } ] diff --git a/Server/src/main/java/core/game/content/consumable/Consumables.java b/Server/src/main/java/core/game/content/consumable/Consumables.java index 5c0c68a13..c8d294904 100644 --- a/Server/src/main/java/core/game/content/consumable/Consumables.java +++ b/Server/src/main/java/core/game/content/consumable/Consumables.java @@ -348,7 +348,17 @@ public enum Consumables { FISH_MIX(new BarbarianMix(new int[] {11477, 11479}, new MultiEffect(new SkillEffect(Skills.FISHING, 3, 0), new HealingEffect(6)))), SUPER_ENERGY_MIX(new BarbarianMix(new int[] {11481, 11483}, new MultiEffect(new EnergyEffect(20), new HealingEffect(6)))), HUNTING_MIX(new BarbarianMix(new int[] {11517, 11519}, new MultiEffect(new SkillEffect(Skills.HUNTER, 3, 0), new HealingEffect(6)))), - SUPER_STR_MIX(new BarbarianMix(new int[] {11485, 11487}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 5, 0.15), new HealingEffect(6)))); + SUPER_STR_MIX(new BarbarianMix(new int[] {11485, 11487}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 5, 0.15), new HealingEffect(6)))), + + /** Stealing creation potions */ + SC_PRAYER(new Potion(new int[] {14207, 14209, 14211, 14213, 14215}, new PrayerEffect(7, 0.25))), + SC_ENERGY(new Potion(new int[] {14217, 14219, 14221, 14223, 14225}, new EnergyEffect(20))), + SC_ATTACK(new Potion(new int[] {14227, 14229, 14231, 14233, 14235}, new SkillEffect(Skills.ATTACK, 3, 0.2))), + SC_STRENGTH(new Potion(new int[] {14237, 14239, 14241, 14243, 14245}, new SkillEffect(Skills.STRENGTH, 3, 0.2))), + SC_RANGE(new Potion(new int[] {14247, 14249, 14251, 14253, 14255}, new SkillEffect(Skills.RANGE, 3, 0.1))), + SC_DEFENCE(new Potion(new int[] {14257, 14259, 14261, 14263, 14265}, new SkillEffect(Skills.DEFENCE, 3, 0.1))), + SC_MAGIC(new Potion(new int[] {14267, 14269, 14271, 14273, 14275}, new SkillEffect(Skills.MAGIC, 3, 0.1))), + SC_SUMMONING(new Potion(new int[] {14277, 14279, 14281, 14283, 14285}, new SummoningEffect(7, 0.25))); public static HashMap consumables = new HashMap<>(); diff --git a/Server/src/main/java/core/game/interaction/Option.java b/Server/src/main/java/core/game/interaction/Option.java index 37b85c9ba..9e5a47065 100644 --- a/Server/src/main/java/core/game/interaction/Option.java +++ b/Server/src/main/java/core/game/interaction/Option.java @@ -28,6 +28,9 @@ public final class Option { * The player trade option. */ public static final Option _P_TRADE = new Option("Trade with", 3); + public static final Option _P_GIVETO = new Option("Give-to", 3); + + public static final Option _P_PICKPOCKET = new Option("Pickpocket", 4); public static final Option _P_EXAMINE = new Option("Examine", 7); @@ -122,4 +125,4 @@ public final class Option { this.handler = handler; return this; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/node/entity/player/link/PacketDispatch.java b/Server/src/main/java/core/game/node/entity/player/link/PacketDispatch.java index ec8e26a23..0f48882e5 100644 --- a/Server/src/main/java/core/game/node/entity/player/link/PacketDispatch.java +++ b/Server/src/main/java/core/game/node/entity/player/link/PacketDispatch.java @@ -49,6 +49,10 @@ public final class PacketDispatch { PacketRepository.send(Config.class, new ConfigContext(player, varp.getIndex(), varp.getValue())); } + public void sendVarcUpdate(short index, int value) { + PacketRepository.send(VarcUpdate.class, new VarcUpdateContext(player, index, value)); + } + /** * Send a game message. * @param message The game message. diff --git a/Server/src/main/java/core/game/node/entity/skill/agility/shortcuts/StileShortcut.java b/Server/src/main/java/core/game/node/entity/skill/agility/shortcuts/StileShortcut.java index 2efb7745d..01b87715b 100644 --- a/Server/src/main/java/core/game/node/entity/skill/agility/shortcuts/StileShortcut.java +++ b/Server/src/main/java/core/game/node/entity/skill/agility/shortcuts/StileShortcut.java @@ -24,7 +24,7 @@ public class StileShortcut extends AgilityShortcut { * Constructs a new {@Code StileShortcut} {@Code Object} */ public StileShortcut() { - super(new int[] { 993, 3730, 7527, 12982, 19222, 22302, 29460, 33842, 34776 }, 1, 0.0, false, 0.0, new String[] { "climb-over" }); + super(new int[] { 993, 3730, 7527, 12982, 19222, 22302, 29460, 33842, 34776, 39508, 39509, 39510 }, 1, 0.0, false, 0.0, new String[] { "climb-over" }); } diff --git a/Server/src/main/java/core/game/node/entity/skill/construction/HouseManager.java b/Server/src/main/java/core/game/node/entity/skill/construction/HouseManager.java index 017e43efb..9a33ee84f 100644 --- a/Server/src/main/java/core/game/node/entity/skill/construction/HouseManager.java +++ b/Server/src/main/java/core/game/node/entity/skill/construction/HouseManager.java @@ -389,17 +389,16 @@ public final class HouseManager { for (int x = 0; x < 8; x++) { for (int y = 0; y < 8; y++) { if(z == 3){ - region.replaceChunk(z, x, y, defaultSkyChunk.copy(region.getPlanes()[z]), from); - continue; + region.replaceChunk(z, x, y, defaultSkyChunk/*.copy(region.getPlanes()[z])*/, from); + continue; } Room room = rooms[z][x][y]; if (room != null) { if (room.getProperties().isRoof() && buildingMode) { continue; } - BuildRegionChunk copy = room.getChunk().copy(region.getPlanes()[z]); - region.replaceChunk(z, x, y, copy, from); - room.loadDecorations(z, copy, this); + region.replaceChunk(z, x, y, room.getChunk(), from); + room.loadDecorations(z, (BuildRegionChunk)region.getPlanes()[z].getChunks()[x][y], this); } else { region.replaceChunk(z, x, y, z != 0 ? defaultSkyChunk.copy(region.getPlanes()[z]) : defaultChunk.copy(region.getPlanes()[0]), from); } @@ -831,4 +830,4 @@ public final class HouseManager { public HouseZone getZone() { return zone; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/node/entity/skill/gather/SkillingTool.java b/Server/src/main/java/core/game/node/entity/skill/gather/SkillingTool.java index 1c153c29c..a77366987 100644 --- a/Server/src/main/java/core/game/node/entity/skill/gather/SkillingTool.java +++ b/Server/src/main/java/core/game/node/entity/skill/gather/SkillingTool.java @@ -1,15 +1,15 @@ package core.game.node.entity.skill.gather; -import core.game.node.entity.skill.Skills; import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Items; /** * Represents a skilling tool (such as knife, axe, needle, ...) * @author Emperor */ public enum SkillingTool { - /** * Represents a bronze axe (woodcutting). */ @@ -88,7 +88,29 @@ public enum SkillingTool { /** * Represents the Inferno Adze (mining) */ - INFERNO_ADZE2(13661, 61, 1.0D, new Animation(10222)); + INFERNO_ADZE2(13661, 61, 1.0D, new Animation(10222)), + + HATCHET_CLASS1(Items.HATCHET_CLASS_1_14132, 1, 0.1, new Animation(10603)), + HATCHET_CLASS2(Items.HATCHET_CLASS_2_14134, 20, 0.3, new Animation(10604)), + HATCHET_CLASS3(Items.HATCHET_CLASS_3_14136, 40, 0.65, new Animation(10605)), + HATCHET_CLASS4(Items.HATCHET_CLASS_4_14138, 60, 0.85, new Animation(10606)), + HATCHET_CLASS5(Items.HATCHET_CLASS_5_14140, 80, 1.0, new Animation(10607)), + PICKAXE_CLASS1(Items.PICKAXE_CLASS_1_14122, 1, 0.1, new Animation(10608)), + PICKAXE_CLASS2(Items.PICKAXE_CLASS_2_14124, 20, 0.3, new Animation(10609)), + PICKAXE_CLASS3(Items.PICKAXE_CLASS_3_14126, 40, 0.65, new Animation(10610)), + PICKAXE_CLASS4(Items.PICKAXE_CLASS_4_14128, 60, 0.85, new Animation(10611)), + PICKAXE_CLASS5(Items.PICKAXE_CLASS_5_14130, 80, 1.0, new Animation(10612)), + HARPOON_CLASS1(Items.HARPOON_CLASS_1_14142, 1, 0.1, new Animation(10613)), + HARPOON_CLASS2(Items.HARPOON_CLASS_2_14144, 20, 0.3, new Animation(10614)), + HARPOON_CLASS3(Items.HARPOON_CLASS_3_14146, 40, 0.65, new Animation(10615)), + HARPOON_CLASS4(Items.HARPOON_CLASS_4_14148, 60, 0.85, new Animation(10616)), + HARPOON_CLASS5(Items.HARPOON_CLASS_5_14150, 80, 1.0, new Animation(10617)), + BUTTERFLY_NET_CLASS1(Items.BUTTERFLY_NET_CLASS_1_14152, 1, 0.1, new Animation(10618)), + BUTTERFLY_NET_CLASS2(Items.BUTTERFLY_NET_CLASS_2_14154, 20, 0.3, new Animation(10619)), + BUTTERFLY_NET_CLASS3(Items.BUTTERFLY_NET_CLASS_3_14156, 40, 0.65, new Animation(10620)), + BUTTERFLY_NET_CLASS4(Items.BUTTERFLY_NET_CLASS_4_14158, 60, 0.85, new Animation(10621)), + BUTTERFLY_NET_CLASS5(Items.BUTTERFLY_NET_CLASS_5_14160, 80, 1.0, new Animation(10622)); + /** * The tool id. @@ -145,23 +167,28 @@ public enum SkillingTool { */ public static SkillingTool getHatchet(Player player) { SkillingTool tool = null; - if (checkTool(player, Skills.WOODCUTTING, SkillingTool.DRAGON_AXE)) { - tool = SkillingTool.DRAGON_AXE; - } else if (checkTool(player, Skills.WOODCUTTING, SkillingTool.RUNE_AXE)) { - tool = SkillingTool.RUNE_AXE; - } else if (checkTool(player, Skills.WOODCUTTING, SkillingTool.ADAMANT_AXE)) { - tool = SkillingTool.ADAMANT_AXE; - } else if (checkTool(player, Skills.WOODCUTTING, SkillingTool.MITHRIL_AXE)) { - tool = SkillingTool.MITHRIL_AXE; - } else if (checkTool(player, Skills.WOODCUTTING, SkillingTool.BLACK_AXE)) { - tool = SkillingTool.BLACK_AXE; - } else if (checkTool(player, Skills.WOODCUTTING, SkillingTool.STEEL_AXE)) { - tool = SkillingTool.STEEL_AXE; - } else if (checkTool(player, Skills.WOODCUTTING, SkillingTool.IRON_AXE)) { - tool = SkillingTool.IRON_AXE; - } else if (checkTool(player, Skills.WOODCUTTING, SkillingTool.BRONZE_AXE)) { - tool = SkillingTool.BRONZE_AXE; - } else if (checkTool(player, Skills.WOODCUTTING, SkillingTool.INFERNO_ADZE)) { + SkillingTool[] hatchetPriority = new SkillingTool[] { + SkillingTool.HATCHET_CLASS5, + SkillingTool.HATCHET_CLASS4, + SkillingTool.DRAGON_AXE, + SkillingTool.HATCHET_CLASS3, + SkillingTool.RUNE_AXE, + SkillingTool.ADAMANT_AXE, + SkillingTool.HATCHET_CLASS2, + SkillingTool.MITHRIL_AXE, + SkillingTool.BLACK_AXE, + SkillingTool.STEEL_AXE, + SkillingTool.HATCHET_CLASS1, + SkillingTool.IRON_AXE, + SkillingTool.BRONZE_AXE + }; + for(SkillingTool hatchet : hatchetPriority) { + if (checkTool(player, Skills.WOODCUTTING, hatchet)) { + tool = hatchet; + break; + } + } + if (checkTool(player, Skills.WOODCUTTING, SkillingTool.INFERNO_ADZE)) { if(player.getSkills().getLevel(Skills.FIREMAKING) >= 92) { tool = SkillingTool.INFERNO_ADZE; } @@ -176,26 +203,84 @@ public enum SkillingTool { */ public static SkillingTool getPickaxe(Player player) { SkillingTool tool = null; + SkillingTool[] pickaxePriority = new SkillingTool[] { + SkillingTool.PICKAXE_CLASS5, + SkillingTool.PICKAXE_CLASS4, + SkillingTool.RUNE_PICKAXE, + SkillingTool.PICKAXE_CLASS3, + SkillingTool.ADAMANT_PICKAXE, + SkillingTool.PICKAXE_CLASS2, + SkillingTool.MITHRIL_PICKAXE, + SkillingTool.STEEL_PICKAXE, + SkillingTool.PICKAXE_CLASS1, + SkillingTool.IRON_PICKAXE, + SkillingTool.BRONZE_PICKAXE, + }; + for(SkillingTool pickaxe : pickaxePriority) { + if (checkTool(player, Skills.MINING, pickaxe)) { + tool = pickaxe; + break; + } + } if (checkTool(player, Skills.MINING, SkillingTool.INFERNO_ADZE2)) { if (player.getSkills().getLevel(Skills.FIREMAKING) >= 92) { tool = SkillingTool.INFERNO_ADZE2; } - } else if (checkTool(player, Skills.MINING, SkillingTool.RUNE_PICKAXE)) { - tool = SkillingTool.RUNE_PICKAXE; - } else if (checkTool(player, Skills.MINING, SkillingTool.ADAMANT_PICKAXE)) { - tool = SkillingTool.ADAMANT_PICKAXE; - } else if (checkTool(player, Skills.MINING, SkillingTool.MITHRIL_PICKAXE)) { - tool = SkillingTool.MITHRIL_PICKAXE; - } else if (checkTool(player, Skills.MINING, SkillingTool.STEEL_PICKAXE)) { - tool = SkillingTool.STEEL_PICKAXE; - } else if (checkTool(player, Skills.MINING, SkillingTool.IRON_PICKAXE)) { - tool = SkillingTool.IRON_PICKAXE; - } else if (checkTool(player, Skills.MINING, SkillingTool.BRONZE_PICKAXE)) { - tool = SkillingTool.BRONZE_PICKAXE; } return tool; } + public static SkillingTool getHarpoon(Player player) { + SkillingTool tool = null; + SkillingTool[] harpoonPriority = new SkillingTool[] { + SkillingTool.BUTTERFLY_NET_CLASS5, + SkillingTool.BUTTERFLY_NET_CLASS4, + SkillingTool.BUTTERFLY_NET_CLASS3, + SkillingTool.BUTTERFLY_NET_CLASS2, + SkillingTool.BUTTERFLY_NET_CLASS1, + }; + for(SkillingTool harpoon : harpoonPriority) { + if (checkTool(player, Skills.FISHING, harpoon)) { + tool = harpoon; + break; + } + } + return tool; + } + + public static SkillingTool getButterflyNet(Player player) { + SkillingTool tool = null; + SkillingTool[] butterflyNetPriority = new SkillingTool[] { + SkillingTool.BUTTERFLY_NET_CLASS5, + SkillingTool.BUTTERFLY_NET_CLASS4, + SkillingTool.BUTTERFLY_NET_CLASS3, + SkillingTool.BUTTERFLY_NET_CLASS2, + SkillingTool.BUTTERFLY_NET_CLASS1, + }; + for(SkillingTool butterflyNet : butterflyNetPriority) { + if (checkTool(player, Skills.HUNTER, butterflyNet)) { + tool = butterflyNet; + break; + } + } + return tool; + } + + public static SkillingTool getToolForSkill(Player player, int skill) { + switch(skill) { + case Skills.MINING: + return getPickaxe(player); + case Skills.WOODCUTTING: + return getHatchet(player); + case Skills.FISHING: + return getHarpoon(player); + case Skills.HUNTER: + return getButterflyNet(player); + default: + return null; + } + } + /** * Checks if the player has a tool and if he can use it. * @param tool The tool. @@ -242,4 +327,4 @@ public enum SkillingTool { public Animation getAnimation() { return animation; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/node/entity/skill/magic/CombinationRune.java b/Server/src/main/java/core/game/node/entity/skill/magic/CombinationRune.java index a5d351c23..cab977fa0 100644 --- a/Server/src/main/java/core/game/node/entity/skill/magic/CombinationRune.java +++ b/Server/src/main/java/core/game/node/entity/skill/magic/CombinationRune.java @@ -9,8 +9,9 @@ public enum CombinationRune { MIST_RUNE(4695,Runes.WATER_RUNE,Runes.AIR_RUNE), DUST_RUNE(4696, Runes.AIR_RUNE,Runes.EARTH_RUNE), SMOKE_RUNE(4697,Runes.FIRE_RUNE,Runes.AIR_RUNE), - MUD_RUNE(4698,Runes.EARTH_RUNE,Runes.WATER_RUNE); - + MUD_RUNE(4698,Runes.EARTH_RUNE,Runes.WATER_RUNE), + ELEMENTAL_RUNE(12850, Runes.AIR_RUNE, Runes.WATER_RUNE, Runes.EARTH_RUNE, Runes.FIRE_RUNE), + CATALYTIC_RUNE(12851, Runes.MIND_RUNE, Runes.CHAOS_RUNE, Runes.DEATH_RUNE, Runes.BLOOD_RUNE, Runes.SOUL_RUNE, Runes.ASTRAL_RUNE); public Runes[] types; public int id; diff --git a/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningPouch.java b/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningPouch.java index 5c10a3b89..2bd087aae 100644 --- a/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningPouch.java +++ b/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningPouch.java @@ -399,7 +399,13 @@ public enum SummoningPouch { /** * Represents a steel titan pouch. */ - STEEL_TITAN_POUCH(76, 12790, 99, 435.2, 7343, 4.9, 10, new Item(12160), new Item(1119), new Item(12155), new Item(12183, 178)); + STEEL_TITAN_POUCH(76, 12790, 99, 435.2, 7343, 4.9, 10, new Item(12160), new Item(1119), new Item(12155), new Item(12183, 178)), + + SACRED_CLAY_POUCH_1(-1, 14422, 1, 0, 8240, 0, 1, new Item(14182)), + SACRED_CLAY_POUCH_2(-1, 14424, 20, 0, 8242, 0, 3, new Item(14184)), + SACRED_CLAY_POUCH_3(-1, 14426, 40, 0, 8244, 0, 5, new Item(14186)), + SACRED_CLAY_POUCH_4(-1, 14428, 60, 0, 8246, 0, 7, new Item(14188)), + SACRED_CLAY_POUCH_5(-1, 14430, 80, 0, 8248, 0, 9, new Item(14190)); /** * The mapping. @@ -564,4 +570,4 @@ public enum SummoningPouch { return slot; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningScroll.java b/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningScroll.java index a1b7d5520..4a217bec7 100644 --- a/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningScroll.java +++ b/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningScroll.java @@ -7,7 +7,12 @@ package core.game.node.entity.skill.summoning; public enum SummoningScroll { HOWL_SCROLL(0, 12425, 0.1, 1, 12047), DREADFOWL_STRIKE_SCROLL(1, 12445, 0.1, 4, 12043), EGG_SPAWN_SCROLL(2, 12428, 0.2, 10, 12059), SLIME_SPRAY_SCROLL(3, 12459, 0.2, 13, 12019), STONY_SHELL_SCROLL(4, 12533, 0.2, 16, 12009), PESTER_SCROLL(5, 12838, 0.5, 17, 12778), ELECTRIC_LASH_SCROLL(6, 12460, 0.4, 18, 12049), VENOM_SHOT_SCROLL(7, 12432, 0.9, 19, 12055), FIREBALL_ASSAULT_SCROLL(8, 12839, 1.1, 22, 12808), CHEESE_FEAST_SCROLL(9, 12430, 2.3, 23, 12067), SANDSTORM_SCROLL(10, 12446, 2.5, 25, 12063), GENERATE_COMPOST_SCROLL(11, 12440, 0.6, 28, 12091), EXPLODE_SCROLL(12, 12834, 2.9, 29, 12800), VAMPYRE_TOUCH_SCROLL(13, 12447, 1.5, 31, 12053), INSANE_FEROCITY_SCROLL(14, 12433, 1.6, 32, 12065), MULTICHOP_SCROLL(15, 12429, 0.7, 33, 12021), CALL_TO_ARMS_SCROLL1(16, 12443, 0.7, 34, 12818), CALL_TO_ARMS_SCROLL2(17, 12443, 0.7, 34, 12814), CALL_TO_ARMS_SCROLL3(18, 12443, 0.7, 34, 12780), CALL_TO_ARMS_SCROLL4(19, 12443, 0.7, 34, 12798), BRONZE_BULL_RUSH_SCROLL(64, 12461, 3.6, 36, 12073), UNBURDEN_SCROLL(20, 12431, 0.6, 40, 12087), HERBCALL_SCROLL(21, 12422, 0.8, 41, 12071), EVIL_FLAMES_SCROLL(22, 12448, 2.1, 42, 12051), PETRIFYING_GAZE_SCROLL1(23, 12458, 0.9, 43, 12095), PETRIFYING_GAZE_SCROLL2(24, 12458, 0.9, 43, 12097), PETRIFYING_GAZE_SCROLL3(25, 12458, 0.9, 43, 12099), PETRIFYING_GAZE_SCROLL4(26, 12458, 0.9, 43, 12101), PETRIFYING_GAZE_SCROLL5(27, 12458, 0.9, 43, 12103), PETRIFYING_GAZE_SCROLL6(28, 12458, 0.9, 43, 12105), PETRIFYING_GAZE_SCROLL7(29, 12458, 0.9, 43, 12107), IRON_BULL_RUSH_SCROLL(65, 12462, 4.6, 46, 12075), IMMENSE_HEAT_SCROLL(30, 12829, 2.3, 46, 12816), THIEVING_FINGERS_SCROLL(31, 12426, 47, 167, 12041), BLOOD_DRAIN_SCROLL(32, 12444, 2.4, 49, 12061), TIRELESS_RUN_SCROLL(33, 12441, 0.8, 52, 12007), ABYSSAL_DRAIN_SCROLL(34, 12454, 1.1, 54, 12035), DISSOLVE_SCROLL(35, 12453, 5.5, 55, 12027), STEEL_BULL_RUSH_SCROLL(66, 12463, 5.6, 56, 12077), FISH_RAIN_SCROLL(36, 12424, 1.1, 56, 12531), AMBUSH_SCROLL(37, 12836, 5.7, 57, 12812), RENDING_SCROLL(38, 12840, 5.7, 57, 12784), GOAD_SCROLL(39, 12835, 5.7, 57, 12810), DOOMSPHERE_SCROLL(40, 12455, 5.8, 58, -1), DUST_CLOUD_SCROLL(41, 12468, 3.0, 61, 12085), ABYSSAL_STEALTH_SCROLL(42, 12427, 1.9, 62, 12037), OPHIDIAN_INCUBATION_SCROLL(43, 12436, 3.1, 63, 12015), POISONOUS_BLAST_SCROLL(44, 12467, 3.2, 64, 12045), MITHRIL_BULL_RUSH_SCROLL(67, 12464, 6.6, 66, 12079), TOAD_BARK_SCROLL(45, 12452, 1.0, 66, 12123), TESTUDO_SCROLL(46, 12439, 0.7, 67, 12031), SWALLOW_WHOLE_SCROLL(47, 12438, 1.4, 68, 12029), FRUITFALL_SCROLL(48, 12423, 1.4, 69, 12033), FAMINE_SCROLL(49, 12830, 1.5, 70, 12820), ARCTIC_BLAST_SCROLL(50, 12451, 1.1, 71, 12057), // RISE_FROM_THE_ASHES_SCROLL(51, 14622, 8.0, 277, -1), - VOLCANIC_STRENGTH_SCROLL(51, 12826, 7.3, 73, 12792), CRUSHING_CLAW_SCROLL(52, 12449, 3.7, 74, 12069), MANTIS_STRIKE_SCROLL(53, 12450, 3.7, 75, 12011), INFERNO_SCROLL(54, 12841, 1.5, 76, 12782), ADAMANT_BULL_RUSH_SCROLL(68, 12465, 7.6, 76, 12081), DEADLY_CLAW_SCROLL(55, 12831, 11.0, 77, 12162), ACORN_MISSILE_SCROLL(56, 12457, 1.6, 78, 12013), TITANS_CONSTITUTION_SCROLL1(57, 12824, 7.9, 79, 12802), TITANS_CONSTITUTION_SCROLL2(58, 12824, 7.9, 79, 12806), TITANS_CONSTITUTION_SCROLL3(59, 12824, 7.9, 79, 12804), REGROWTH_SCROLL(60, 12442, 1.6, 80, 12025), SPIKE_SHOT_SCROLL(61, 12456, 4.1, 83, 12017), EBON_THUNDER_SCROLL(62, 12837, 8.3, 83, 12788), SWAMP_PLAGUE_SCROLL(63, 12832, 4.1, 85, 12776), RUNE_BULL_RUSH_SCROLL(69, 12466, 8.6, 86, 12083), HEALING_AURA_SCROLL(70, 12434, 1.8, 88, 12039), BOIL_SCROLL(71, 12833, 8.9, 89, 12786), MAGIC_FOCUS_SCROLL(72, 12437, 4.6, 92, 12089), ESSENCE_SHIPMENT_SCROLL(73, 12827, 1.9, 93, 12796), IRON_WITHIN_SCROLL(74, 12828, 4.7, 95, 12822), WINTER_STORAGE_SCROLL(75, 12435, 4.8, 96, 12093), STEEL_OF_LEGENDS_SCROLL(76, 12825, 4.9, 99, 12790); + VOLCANIC_STRENGTH_SCROLL(51, 12826, 7.3, 73, 12792), CRUSHING_CLAW_SCROLL(52, 12449, 3.7, 74, 12069), MANTIS_STRIKE_SCROLL(53, 12450, 3.7, 75, 12011), INFERNO_SCROLL(54, 12841, 1.5, 76, 12782), ADAMANT_BULL_RUSH_SCROLL(68, 12465, 7.6, 76, 12081), DEADLY_CLAW_SCROLL(55, 12831, 11.0, 77, 12162), ACORN_MISSILE_SCROLL(56, 12457, 1.6, 78, 12013), TITANS_CONSTITUTION_SCROLL1(57, 12824, 7.9, 79, 12802), TITANS_CONSTITUTION_SCROLL2(58, 12824, 7.9, 79, 12806), TITANS_CONSTITUTION_SCROLL3(59, 12824, 7.9, 79, 12804), REGROWTH_SCROLL(60, 12442, 1.6, 80, 12025), SPIKE_SHOT_SCROLL(61, 12456, 4.1, 83, 12017), EBON_THUNDER_SCROLL(62, 12837, 8.3, 83, 12788), SWAMP_PLAGUE_SCROLL(63, 12832, 4.1, 85, 12776), RUNE_BULL_RUSH_SCROLL(69, 12466, 8.6, 86, 12083), HEALING_AURA_SCROLL(70, 12434, 1.8, 88, 12039), BOIL_SCROLL(71, 12833, 8.9, 89, 12786), MAGIC_FOCUS_SCROLL(72, 12437, 4.6, 92, 12089), ESSENCE_SHIPMENT_SCROLL(73, 12827, 1.9, 93, 12796), IRON_WITHIN_SCROLL(74, 12828, 4.7, 95, 12822), WINTER_STORAGE_SCROLL(75, 12435, 4.8, 96, 12093), STEEL_OF_LEGENDS_SCROLL(76, 12825, 4.9, 99, 12790), + CLAY_DEPOSIT_SCROLL_1(-1, 14421, 0, 1, 14422), + CLAY_DEPOSIT_SCROLL_2(-1, 14421, 0, 20, 14424), + CLAY_DEPOSIT_SCROLL_3(-1, 14421, 0, 40, 14426), + CLAY_DEPOSIT_SCROLL_4(-1, 14421, 0, 60, 14428), + CLAY_DEPOSIT_SCROLL_5(-1, 14421, 0, 80, 14430); /** * The level required. @@ -131,4 +136,4 @@ public enum SummoningScroll { return null; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/node/scenery/SceneryBuilder.java b/Server/src/main/java/core/game/node/scenery/SceneryBuilder.java index 4db5c619a..eb97c1ab6 100644 --- a/Server/src/main/java/core/game/node/scenery/SceneryBuilder.java +++ b/Server/src/main/java/core/game/node/scenery/SceneryBuilder.java @@ -270,4 +270,4 @@ public final class SceneryBuilder { RegionManager.getRegionChunk(o.getLocation()).flag(new ObjectUpdateFlag(o, !o.isActive())); } } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/world/map/BuildRegionChunk.java b/Server/src/main/java/core/game/world/map/BuildRegionChunk.java index 197011b42..1d1a24e38 100644 --- a/Server/src/main/java/core/game/world/map/BuildRegionChunk.java +++ b/Server/src/main/java/core/game/world/map/BuildRegionChunk.java @@ -278,4 +278,4 @@ public class BuildRegionChunk extends RegionChunk { public Scenery[][] getObjects(int index) { return objects[index]; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/world/map/Region.java b/Server/src/main/java/core/game/world/map/Region.java index 78b580d7c..707684a85 100644 --- a/Server/src/main/java/core/game/world/map/Region.java +++ b/Server/src/main/java/core/game/world/map/Region.java @@ -4,6 +4,8 @@ import core.cache.Cache; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.music.MusicZone; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; import core.game.system.task.Pulse; import core.game.world.map.build.DynamicRegion; import core.game.world.map.build.LandscapeParser; @@ -19,6 +21,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.concurrent.TimeUnit; +import kotlin.Pair; /** * Represents a region. @@ -45,7 +48,7 @@ public class Region { /** * The region planes. */ - private final RegionPlane[] planes = new RegionPlane[4]; + protected final RegionPlane[] planes = new RegionPlane[4]; /** * The activity pulse. @@ -226,6 +229,15 @@ public class Region { return true; } + public void sendUpdateSceneGraph(boolean login) { + for (int z = 0; z < 4; z++) { + for (Player p : this.getPlanes()[z].getPlayers()) { + p.updateSceneGraph(login); + } + } + } + + /** * Checks if this region has the inactivity flagging pulse running. * @return {@code True} if so. @@ -546,4 +558,10 @@ public class Region { public void setUpdateAllPlanes(boolean updateAllPlanes) { this.updateAllPlanes = updateAllPlanes; } -} \ No newline at end of file + + public void transformAllSceneryById(Pair[] ids, boolean clip, boolean permanent) { + for(RegionPlane rp : getPlanes()) { + rp.transformAllSceneryById(ids, clip, permanent); + } + } +} diff --git a/Server/src/main/java/core/game/world/map/RegionChunk.java b/Server/src/main/java/core/game/world/map/RegionChunk.java index 4deaabbab..3c15c2965 100644 --- a/Server/src/main/java/core/game/world/map/RegionChunk.java +++ b/Server/src/main/java/core/game/world/map/RegionChunk.java @@ -4,6 +4,7 @@ import core.game.node.entity.player.Player; import core.game.node.item.GroundItem; import core.game.node.item.Item; import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; import rs09.game.system.SystemLogger; import core.game.world.map.build.DynamicRegion; import core.game.world.map.build.LandscapeParser; @@ -15,7 +16,9 @@ import core.net.packet.out.ConstructScenery; import core.net.packet.out.UpdateAreaPosition; import java.util.ArrayList; +import java.util.function.Function; import java.util.List; +import kotlin.Pair; /** * Represents a region chunk. @@ -365,4 +368,38 @@ public class RegionChunk { this.currentBase = currentBase; } -} \ No newline at end of file + public void transformAllSceneryById(Pair[] ids, boolean clip, boolean permanent) { + /*for(int i = 0; i < 8; i++) { + for(int j = 0; j < 8; j++) { + for(Scenery s : getObjects(i, j)) { + for(Pair id : ids) { + if(s != null && s.getId() == id.getFirst()) { + SceneryBuilder.replace(s, s.transform(id.getSecond()), clip, permanent); + } + } + } + } + }*/ + transformAllSceneryByFunction(clip, permanent, (Scenery s) -> { + for(Pair id : ids) { + if(s != null && s.getId() == id.getFirst()) { + return s.transform(id.getSecond()); + } + } + return s; + }); + } + + public void transformAllSceneryByFunction(boolean clip, boolean permanent, Function f) { + for(int i = 0; i < 8; i++) { + for(int j = 0; j < 8; j++) { + for(Scenery s : getObjects(i, j)) { + Scenery t = f.apply(s); + if(s != t) { + SceneryBuilder.replace(s, t, clip, permanent); + } + } + } + } + } +} diff --git a/Server/src/main/java/core/game/world/map/RegionPlane.java b/Server/src/main/java/core/game/world/map/RegionPlane.java index 15b68bc03..733023d13 100644 --- a/Server/src/main/java/core/game/world/map/RegionPlane.java +++ b/Server/src/main/java/core/game/world/map/RegionPlane.java @@ -19,6 +19,7 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; +import kotlin.Pair; /** * Represents one of the 4 planes of a region. @@ -418,4 +419,12 @@ public final class RegionPlane { return chunks; } -} \ No newline at end of file + public void transformAllSceneryById(Pair[] ids, boolean clip, boolean permanent) { + for(int x = 0; x < 8; x++) { + for(int y = 0; y < 8; y++) { + RegionChunk rc = getChunks()[x][y]; + rc.transformAllSceneryById(ids, clip, permanent); + } + } + } +} diff --git a/Server/src/main/java/core/game/world/map/Viewport.java b/Server/src/main/java/core/game/world/map/Viewport.java index 8489b40c0..d563b0357 100644 --- a/Server/src/main/java/core/game/world/map/Viewport.java +++ b/Server/src/main/java/core/game/world/map/Viewport.java @@ -152,4 +152,4 @@ public final class Viewport { this.currentPlane = currentPlane; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/world/map/build/DynamicRegion.java b/Server/src/main/java/core/game/world/map/build/DynamicRegion.java index bbfef5458..c2cabb55a 100644 --- a/Server/src/main/java/core/game/world/map/build/DynamicRegion.java +++ b/Server/src/main/java/core/game/world/map/build/DynamicRegion.java @@ -34,11 +34,6 @@ public final class DynamicRegion extends Region { */ private final int regionId; - /** - * The region chunks. - */ - private final RegionChunk[][][] chunks; - /** * The zone borders. */ @@ -75,7 +70,6 @@ public final class DynamicRegion extends Region { public DynamicRegion(int regionId, int x, int y) { super(x, y); this.regionId = regionId; - this.chunks = new RegionChunk[4][SIZE >> 3][SIZE >> 3]; } /** @@ -95,12 +89,12 @@ public final class DynamicRegion extends Region { * @param regionTwo The second/last region. * @return The new region. */ - public static DynamicRegion create(int regionOne, int regionTwo) { + public static DynamicRegion[] create(int regionOne, int regionTwo) { int x = (regionOne >> 8) << 6; int y = (regionOne & 0xFF) << 6; int x1 = (regionTwo >> 8) << 6; int y1 = (regionTwo & 0xFF) << 6; - return create(new ZoneBorders(x, y, x1 + SIZE, y1 + SIZE))[0]; + return create(new ZoneBorders(x, y, x1 + SIZE, y1 + SIZE)); } /** @@ -134,11 +128,7 @@ public final class DynamicRegion extends Region { } } for (Region r : regions) { - for (int z = 0; z < 4; z++) { - for (Player p : r.getPlanes()[z].getPlayers()) { - p.updateSceneGraph(false); - } - } + r.sendUpdateSceneGraph(false); } return regions.toArray(new DynamicRegion[regions.size()]); } @@ -211,12 +201,13 @@ public final class DynamicRegion extends Region { int x = regionX + (offsetX << 3); int y = regionY + (offsetY << 3); for (int plane = 0; plane < 4; plane++) { - RegionChunk c = region.chunks[plane][offsetX][offsetY]; + RegionChunk c = region.planes[plane].getChunks()[offsetX][offsetY]; if (c == null) { - region.chunks[plane][offsetX][offsetY] = c = new RegionChunk(Location.create(0, 0, 0), 0, region.getPlanes()[plane]); + region.planes[plane].getChunks()[offsetX][offsetY] = c = new RegionChunk(Location.create(0, 0, 0), 0, region.getPlanes()[plane]); } c.setRotation(0); c.setBase(Location.create(x, y, plane)); + c.setCurrentBase(region.getBaseLocation().transform(offsetX << 3, offsetY << 3, 0)); } } } @@ -267,10 +258,10 @@ public final class DynamicRegion extends Region { */ public void rotate() { for (int z = 0; z < 4; z++) { - RegionChunk[][] c = Arrays.copyOf(chunks[z], 8); + RegionChunk[][] c = Arrays.copyOf(planes[z].getChunks(), 8); for (int x = 0; x < 8; x++) { for (int y = 0; y < 8; y++) { - RegionChunk r = chunks[z][x][y] = c[8 - y - 1][x]; + RegionChunk r = planes[z].getChunks()[x][y] = c[8 - y - 1][x].copy(planes[z]); if (r != null) { r.setRotation(r.getRotation() + 1); } @@ -287,8 +278,7 @@ public final class DynamicRegion extends Region { * @param chunk The chunk to set. */ public void setChunk(int z, int x, int y, RegionChunk chunk) { - chunks[z][x][y] = chunk; - getPlanes()[z].getChunks()[x][y] = chunk; + planes[z].getChunks()[x][y] = chunk.copy(planes[z]); if (chunk != null) { chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, 0)); } @@ -303,16 +293,18 @@ public final class DynamicRegion extends Region { * @param fromRegion The region the chunk is copied from. */ public void replaceChunk(int z, int x, int y, RegionChunk chunk, Region fromRegion) { + if(fromRegion instanceof DynamicRegion) { + fromRegion = RegionManager.forId(fromRegion.getRegionId()); + } Region.load(DynamicRegion.this); - RegionPlane p = getPlanes()[z]; - chunks[z][x][y] = chunk; - p.getChunks()[x][y] = chunk; + RegionPlane p = planes[z]; if (chunk == null) { + p.getChunks()[x][y] = null; for (int i = x << 3; i < (x + 1) << 3; i++) { for (int j = y << 3; j < (y + 1) << 3; j++) { p.getFlags().getClippingFlags()[i][j] = -1; p.getProjectileFlags().getClippingFlags()[i][j] = -1; - Scenery object = p.getObjects()[i][j]; + Scenery object = p.getChunkObject(i, j); if (object != null) { LandscapeParser.removeScenery(object); } else { @@ -321,10 +313,11 @@ public final class DynamicRegion extends Region { } } } else { - chunk.clear(); + RegionChunk newChunk = p.getChunks()[x][y] = chunk.copy(p); + newChunk.clear(); Region.load(fromRegion); - Location l = chunk.getBase(); - chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, 0)); + Location l = newChunk.getBase(); + newChunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, 0)); Location regionBase = fromRegion.getBaseLocation(); RegionPlane rp = fromRegion.getPlanes()[l.getZ()]; for (int i = 0; i < 8; i++) { @@ -379,7 +372,7 @@ public final class DynamicRegion extends Region { NPC npc = plane.getNpcs().get(0); npc.clear(); } - for (RegionChunk[] chunks : getChunks()[plane.getPlane()]) { + for (RegionChunk[] chunks : getPlanes()[plane.getPlane()].getChunks()) { for (RegionChunk chunk : chunks) { if (chunk != null) { for (Iterator it = chunk.getItems().iterator(); it.hasNext();) { @@ -406,14 +399,6 @@ public final class DynamicRegion extends Region { return regionId; } - /** - * Gets the chunks. - * @return The chunks. - */ - public RegionChunk[][][] getChunks() { - return chunks; - } - /** * Gets the borders. * @return The borders. @@ -476,4 +461,4 @@ public final class DynamicRegion extends Region { } NPCs.clear(); } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/world/map/build/LandscapeParser.java b/Server/src/main/java/core/game/world/map/build/LandscapeParser.java index 703e3907b..8b130833a 100644 --- a/Server/src/main/java/core/game/world/map/build/LandscapeParser.java +++ b/Server/src/main/java/core/game/world/map/build/LandscapeParser.java @@ -75,7 +75,8 @@ public final class LandscapeParser { */ public static void addScenery(Scenery object, boolean landscape) { Location l = object.getLocation(); - flagScenery(RegionManager.getRegionPlane(l), l.getLocalX(), l.getLocalY(), object, landscape, false); + RegionPlane rp = RegionManager.getRegionPlane(l); + flagScenery(rp, l.getLocalX(), l.getLocalY(), object, landscape, false); } /** @@ -214,4 +215,4 @@ public final class LandscapeParser { } return current; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/world/update/flag/chunk/ObjectUpdateFlag.java b/Server/src/main/java/core/game/world/update/flag/chunk/ObjectUpdateFlag.java index 5b1d4ee18..6eb210c89 100644 --- a/Server/src/main/java/core/game/world/update/flag/chunk/ObjectUpdateFlag.java +++ b/Server/src/main/java/core/game/world/update/flag/chunk/ObjectUpdateFlag.java @@ -52,4 +52,4 @@ public class ObjectUpdateFlag extends UpdateFlag { return 0; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/net/packet/PacketRepository.java b/Server/src/main/java/core/net/packet/PacketRepository.java index 6cb4e3e60..0f872f18f 100644 --- a/Server/src/main/java/core/net/packet/PacketRepository.java +++ b/Server/src/main/java/core/net/packet/PacketRepository.java @@ -78,6 +78,7 @@ public final class PacketRepository { OUTGOING_PACKETS.put(InstancedLocationUpdate.class, new InstancedLocationUpdate()); // OUTGOING_PACKETS.put(CSConfigPacket.class, new CSConfigPacket()); // OUTGOING_PACKETS.put(Varbit.class, new Varbit()); + OUTGOING_PACKETS.put(VarcUpdate.class, new VarcUpdate()); INCOMING_PACKETS.put(22, new ClientFocusPacket()); INCOMING_PACKETS.put(93, new PingPacketHandler()); INCOMING_PACKETS.put(44, new CommandPacket()); @@ -204,4 +205,4 @@ public final class PacketRepository { public static IncomingPacket getIncoming(int opcode) { return INCOMING_PACKETS.get(opcode); } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/net/packet/context/VarcUpdateContext.java b/Server/src/main/java/core/net/packet/context/VarcUpdateContext.java new file mode 100644 index 000000000..4a4d9edb2 --- /dev/null +++ b/Server/src/main/java/core/net/packet/context/VarcUpdateContext.java @@ -0,0 +1,23 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +public class VarcUpdateContext implements Context { + + Player player; + public int varcId; + public int value; + + public VarcUpdateContext(Player player, int varcId, int value){ + this.player = player; + this.varcId = varcId; + this.value = value; + } + + @Override + public Player getPlayer() { + return player; + } +} + diff --git a/Server/src/main/java/core/net/packet/out/BuildDynamicScene.java b/Server/src/main/java/core/net/packet/out/BuildDynamicScene.java index 8337471a8..4b8e0ebc5 100644 --- a/Server/src/main/java/core/net/packet/out/BuildDynamicScene.java +++ b/Server/src/main/java/core/net/packet/out/BuildDynamicScene.java @@ -39,7 +39,7 @@ public final class BuildDynamicScene implements OutgoingPacket> 3) << 8 | (y >> 3)); if (r instanceof DynamicRegion) { DynamicRegion dr = (DynamicRegion) r; - chunks[z][x - baseX][y - baseY] = dr.getChunks()[z][x - (dr.getX() << 3)][y - (dr.getY() << 3)]; + chunks[z][x - baseX][y - baseY] = dr.getPlanes()[z].getChunks()[x - (dr.getX() << 3)][y - (dr.getY() << 3)]; } } } @@ -75,4 +75,4 @@ public final class BuildDynamicScene implements OutgoingPacket { + @Override + public void send(VarcUpdateContext varcUpdateContext) { + Player player = varcUpdateContext.getPlayer(); + if(varcUpdateContext.value <= 255) { + IoBuffer buffer = new IoBuffer(65); + buffer.putLEShort(player.getInterfaceManager().getPacketCount(1)); + buffer.putC((byte) varcUpdateContext.value); + buffer.putLEShortA(varcUpdateContext.varcId); + player.getSession().write(buffer); + } else { + IoBuffer buffer = new IoBuffer(69); + buffer.putLEShortA(player.getInterfaceManager().getPacketCount(1)); + buffer.putInt(varcUpdateContext.value); + buffer.putShortA(varcUpdateContext.varcId); + player.getSession().write(buffer); + } + } +} diff --git a/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt b/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt index e252b41cb..691893fb3 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt @@ -120,7 +120,9 @@ class EquipHandler : InteractionListener() { return } } - InteractionListeners.run(itemId,player,item,false) + if(!InteractionListeners.run(itemId,player,item,false)) { + return + } if (player.equipment.remove(item)) { player.audioManager.send(Audio(2238, 10, 1)) player.dialogueInterpreter.close() @@ -132,4 +134,4 @@ class EquipHandler : InteractionListener() { } } } -} \ No newline at end of file +} diff --git a/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt b/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt index 3e4cdc5bf..6a55379fa 100644 --- a/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt +++ b/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt @@ -427,6 +427,19 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){ player.varpManager.get(index!!).setVarbit(offset!!, value!!).send(player) } + define("setvarc", Command.Privilege.ADMIN) { player, args -> + if(args.size < 3){ + reject(player,"Usage: ::setvarc index value") + } + val index = args[1].toShortOrNull() + val value = args[2].toIntOrNull() + + if(index == null || value == null) { + reject(player,"Usage ::setvarc index value") + } + + player.packetDispatch.sendVarcUpdate(index!!, value!!) + } define("grow",Command.Privilege.ADMIN){player,_ -> val state: FarmingState = player.states.get("farming") as FarmingState? ?: return@define diff --git a/Server/src/main/kotlin/rs09/game/system/command/sets/SpawnCommandSet.kt b/Server/src/main/kotlin/rs09/game/system/command/sets/SpawnCommandSet.kt index 9f26c7e78..df371d8b2 100644 --- a/Server/src/main/kotlin/rs09/game/system/command/sets/SpawnCommandSet.kt +++ b/Server/src/main/kotlin/rs09/game/system/command/sets/SpawnCommandSet.kt @@ -70,5 +70,27 @@ class SpawnCommandSet : CommandSet(Command.Privilege.ADMIN){ SceneryBuilder.add(`object`) SystemLogger.logInfo("object = $`object`") } + + define("objectgrid") { player, args -> + if(args!!.size != 5) { + reject(player, "Usage: objectgrid beginId endId type rotation") + return@define + } + val beginId = args[1].toIntOrNull() ?: return@define + val endId = args[2].toIntOrNull() ?: return@define + val type = args[3].toIntOrNull() ?: return@define + val rotation = args[4].toIntOrNull() ?: return@define + for(i in 0..10) { + SceneryBuilder.add(Scenery(29447 + i, player.location.transform(i, -1, 0))) + } + for(i in beginId..endId) { + val j = i - beginId + val scenery = Scenery(i, player.location.transform(j % 10, j / 10, 0), type, rotation) + SceneryBuilder.add(scenery) + if(j % 10 == 0) { + SceneryBuilder.add(Scenery(29447 + (j / 10) % 10, player.location.transform(-1, j/10, 0))) + } + } + } } -} \ No newline at end of file +}