RuneHive-Game
Loading...
Searching...
No Matches
PlayerRangedStrategy.java
Go to the documentation of this file.
1package com.runehive.game.world.entity.combat.strategy.player;
2
3import com.runehive.content.itemaction.impl.CrawsBow;
4import com.runehive.content.prestige.PrestigePerk;
5import com.runehive.game.Animation;
6import com.runehive.game.UpdatePriority;
7import com.runehive.game.world.entity.combat.CombatImpact;
8import com.runehive.game.world.entity.combat.CombatType;
9import com.runehive.game.world.entity.combat.attack.FightType;
10import com.runehive.game.world.entity.combat.effect.impl.CombatPoisonEffect;
11import com.runehive.game.world.entity.combat.hit.CombatHit;
12import com.runehive.game.world.entity.combat.hit.Hit;
13import com.runehive.game.world.entity.combat.ranged.RangedAmmunition;
14import com.runehive.game.world.entity.combat.ranged.RangedWeaponType;
15import com.runehive.game.world.entity.combat.strategy.basic.RangedStrategy;
16import com.runehive.game.world.entity.mob.Mob;
17import com.runehive.game.world.entity.mob.UpdateFlag;
18import com.runehive.game.world.entity.mob.player.Player;
19import com.runehive.game.world.entity.mob.player.PlayerRight;
20import com.runehive.game.world.items.Item;
21import com.runehive.game.world.items.containers.equipment.Equipment;
22import com.runehive.game.world.items.ground.GroundItem;
23import com.runehive.game.world.position.Area;
24import com.runehive.game.world.position.Position;
25import com.runehive.net.packet.out.SendMessage;
26import com.runehive.util.RandomUtils;
27
28import java.util.Collections;
29import java.util.LinkedList;
30import java.util.List;
31import java.util.function.Consumer;
32import java.util.function.Predicate;
33
34public class PlayerRangedStrategy extends RangedStrategy<Player> {
35
37
39 }
40
41 @Override
42 public boolean canAttack(Player attacker, Mob defender) {
44
45 if (weapon == null) {
46 attacker.getCombat().reset();
47 return false;
48 }
49
50 if(weapon.getId() == CrawsBow.CRAWS_CHARGED_ID && attacker.crawsBowCharges < 1) {
51 attacker.send(new SendMessage("Your Craw's bow is out of charges!"));
52 attacker.getCombat().reset();
53 return false;
54 }
55
56 if (attacker.rangedDefinition == null) {
57 return false;
58 }
59
60 int bowsWithNoArrowsRequired [] = {22550, 25865, 25867, 25884, 25886, 25890, 25892, 25894, 25896, 25888};
61 Item ammo = attacker.equipment.get(attacker.rangedDefinition.getSlot());
62 if (ammo != null && attacker.rangedAmmo != null && ammo.getAmount() >= attacker.rangedAmmo.getRemoval()) {
63 if (attacker.rangedDefinition.isValid(attacker.rangedAmmo)) {
64 return true;
65 }
66 attacker.send(new SendMessage("You can't use this ammunition with this weapon."));
67 } else if
68 (attacker.equipment.contains(bowsWithNoArrowsRequired)) {
69 return true;
70 } else {
71 attacker.send(new SendMessage("You need some ammunition to use this weapon!"));
72 }
73 attacker.getCombat().reset();
74 return false;
75 }
76
77 protected void sendStuff(Player attacker, Mob defender) {
78 int id = attacker.equipment.get(attacker.rangedDefinition.getSlot()).getId();
79 Animation animation = attacker.rangedAmmo.getAnimation(id).orElse(getAttackAnimation(attacker, defender));
80 attacker.animate(animation, true);
81 attacker.rangedAmmo.getStart(id).ifPresent(attacker::graphic);
82 attacker.rangedAmmo.sendProjectile(attacker, defender);
83 }
84
85 @Override
86 public void start(Player attacker, Mob defender, Hit[] hits) {
87 if (attacker.isSpecialActivated()) {
88 attacker.getCombatSpecial().drain(attacker);
89 }
90
91 if (attacker.getCombat().getDefender() == defender) {
92 sendStuff(attacker, defender);
93
94 int id = attacker.equipment.get(attacker.rangedDefinition.getSlot()).getId();
95 if (attacker.rangedAmmo.getEffect(id).isPresent()) {
96 List<Hit> extra = new LinkedList<>();
97 for (Hit hit : hits) {
98 Predicate<CombatImpact> filter = effect -> effect.canAffect(attacker, defender, hit);
99 Consumer<CombatImpact> execute = effect -> effect.impact(attacker, defender, hit, extra);
100 attacker.rangedAmmo.getEffect(id).filter(filter).ifPresent(execute);
101 }
102 if (!defender.isPlayer() || !PlayerRight.isIronman(attacker)) {
103 if (extra.isEmpty()) {
104 Collections.addAll(extra, hits);
105 addCombatExperience(attacker, extra.toArray(new Hit[0]));
106 } else {
107 addCombatExperience(attacker, hits);
108 }
109 }
110 } else if (!defender.isPlayer() || !PlayerRight.isIronman(attacker)) {
111 addCombatExperience(attacker, hits);
112 }
113 }
114 }
115
116 @Override
117 public void attack(Player attacker, Mob defender, Hit hit) {
118 removeAmmunition(attacker, defender, attacker.rangedDefinition.getType());
119 if (hit.getDamage() > 1 && attacker.rangedDefinition != null) {
120 Item item = attacker.equipment.get(attacker.rangedDefinition.getSlot());
121 CombatPoisonEffect.getPoisonType(item).ifPresent(defender::poison);
122 }
123
125 if(weapon != null) {
126 switch(weapon.getId()) {
128 attacker.crawsBowCharges--;
129 }
130 }
131 }
132 }
133
134 @Override
135 public void hit(Player attacker, Mob defender, Hit hit) {
136 if (attacker.rangedAmmo != null && attacker.rangedDefinition != null) {
137 int id = attacker.equipment.retrieve(attacker.rangedDefinition.getSlot()).map(Item::getId).orElse(-1);
138 attacker.rangedAmmo.getEnd(id).ifPresent(defender::graphic);
139 }
140 }
141
142 @Override
143 public Animation getAttackAnimation(Player attacker, Mob defender) {
144 int animation = attacker.getCombat().getFightType().getAnimation();
145
146 if (attacker.equipment.hasShield()) {
147 Item weapon = attacker.equipment.getShield();
148 FightType fightType = attacker.getCombat().getFightType();
149 animation = weapon.getAttackAnimation(fightType).orElse(animation);
150 }
151
152 if (attacker.equipment.hasWeapon()) {
153 Item weapon = attacker.equipment.getWeapon();
154 FightType fightType = attacker.getCombat().getFightType();
155 animation = weapon.getAttackAnimation(fightType).orElse(animation);
156 }
157
159 final var item = attacker.overrides.get(Equipment.WEAPON_SLOT);
160 animation = attacker.overrides.getFightType(item).getAnimation();
161 }
162
163 return new Animation(animation, UpdatePriority.HIGH);
164 }
165
166 @Override
167 public int getAttackDelay(Player attacker, Mob defender, FightType fightType) {
168 return attacker.getCombat().getFightType().getDelay();
169 }
170
171 @Override
172 public int getAttackDistance(Player attacker, FightType fightType) {
173 return fightType.getDistance();
174 }
175
176 @Override
177 public CombatHit[] getHits(Player attacker, Mob defender) {
178 RangedAmmunition ammo = attacker.rangedAmmo;
179 CombatHit[] hits = new CombatHit[ammo.getRemoval()];
180 for (int index = 0; index < hits.length; index++) {
181 hits[index] = nextRangedHit(attacker, defender);
182 }
183 return hits;
184 }
185
186 @Override
188 return CombatType.RANGED;
189 }
190
191 private void removeAmmunition(Player attacker, Mob defender, RangedWeaponType type) {
192 Item next = attacker.equipment.get(type.getSlot());
193 if (next == null) return;
194
195 if (attacker.rangedAmmo.isDroppable()) {
196 Item dropItem = new Item(next.getId());
197
198 boolean canBreak = !dropItem.getName().contains("arrow") || !attacker.prestige.hasPerk(PrestigePerk.ARROWHEAD);
199
200 if (!canBreak || RandomUtils.success(0.80)) {
201 if (Equipment.hasAssembler(attacker) /* AKA 100% */) {
202 return;
203 }
204
205 if (Equipment.hasAccumulator(attacker) && RandomUtils.success(0.90)) {
206 return;
207 }
208
209 if (Equipment.hasAttractor(attacker) && RandomUtils.success(0.80)) {
210 return;
211 }
212
213 Position dropPoisition = defender.getPosition();
214
215 if (Area.inKraken(attacker) || Area.inZulrah(attacker)) {
216 dropPoisition = attacker.getPosition();
217 }
218
219 GroundItem.create(attacker, dropItem, dropPoisition);
220 }
221 }
222 final int bowsWithNoArrowsRequired [] = {22550, 25865, 25867, 25884, 25886, 25890, 25892, 25894, 25896, 25888};
223 if (attacker.equipment.contains(bowsWithNoArrowsRequired)) {
224 return;
225 } else {
226 next.decrementAmount();
227 }
228
229
230 if (next.getAmount() == 0 && !attacker.equipment.contains(bowsWithNoArrowsRequired)) {
231 attacker.send(new SendMessage("That was the last of your ammunition!"));
232 next = null;
233 }
234
235 attacker.equipment.set(type.getSlot(), next, false);
236 attacker.equipment.refresh();
237 attacker.updateFlags.add(UpdateFlag.APPEARANCE);
238 }
239
240 public static PlayerRangedStrategy get() {
241 return INSTANCE;
242 }
243
244}
boolean hasPerk(PrestigePerk perk)
Class that models a single animation used by an entity.
The combat effect applied when a character needs to be poisoned.
static Optional< PoisonType > getPoisonType(Item item)
Gets the PoisonType for item wrapped in an optional.
A wrapper for a Hit object, adding additional variables for hit and hitsplat delays.
A Hit object holds the damage amount and hitsplat data.
Definition Hit.java:10
final CombatHit nextRangedHit(T attacker, Mob defender)
void removeAmmunition(Player attacker, Mob defender, RangedWeaponType type)
int getAttackDelay(Player attacker, Mob defender, FightType fightType)
Handles the mob class.
Definition Mob.java:66
final EnumSet< UpdateFlag > updateFlags
Definition Mob.java:94
final boolean isPlayer()
Check if an entity is a player.
Definition Mob.java:564
This class represents a character controlled by a player.
Definition Player.java:125
Combat< Player > getCombat()
The combat of the mob.
Definition Player.java:759
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 void decrementAmount()
Decrements the amount by 1.
Definition Item.java:284
final int getAmount()
Gets the quantity of this item.
Definition Item.java:342
final Item get(int index)
Gets the Item located on index.
final Optional< Item > retrieve(int index)
Retrieves the item located on index.
The container that manages the equipment for a player.
boolean contains(int[] bowsWithNoArrowsRequired)
void refresh()
Forces a refresh of Equipment items to the EQUIPMENT_DISPLAY_ID widget.
Represents a single Ground item on the world map.
static GroundItem create(Player player, Item item)
Creates a new GroundItem object for a player and an item.
Handles checking if mobs are in a certain area.
Definition Area.java:13
static boolean inZulrah(Interactable entity)
Definition Area.java:320
static boolean inKraken(Interactable entity)
Definition Area.java:237
Represents a single tile on the game world.
Definition Position.java:14
The OutgoingPacket that sends a message to a Players chatbox in the client.
A static-util class that provides additional functionality for generating pseudo-random numbers.
static boolean success(double value)
Determines if a pseudorandomly generated double rounded to two decimal places is below or equal to va...
Handles the perk rewards from prestiging.
Represents different priorities for updating.
The enumerated type whose elements represent the fighting types.
final int getAnimation()
Gets the animation executed when this type is active.
void drain(Player player)
Drains the special bar for player.
static boolean isIronman(Player player)
Checks if the player is an ironman.