RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
Waypoint.java
1package com.osroyale.game.world.entity.mob.movement.waypoint;
2
3import com.osroyale.game.task.Task;
4import com.osroyale.game.world.Interactable;
5import com.osroyale.game.world.World;
6import com.osroyale.game.world.entity.mob.Mob;
7import com.osroyale.game.world.entity.mob.data.PacketType;
8import com.osroyale.game.world.entity.mob.npc.Npc;
9import com.osroyale.game.world.entity.mob.player.Player;
10import com.osroyale.game.world.object.GameObject;
11import com.osroyale.game.world.object.GameObjectDefinition;
12import com.osroyale.game.world.pathfinding.TraversalMap;
13import com.osroyale.game.world.position.Position;
14import com.osroyale.game.world.region.Region;
15import com.osroyale.net.packet.out.SendMessage;
16import com.osroyale.util.Utility;
17
18import java.util.Objects;
19
51
52public abstract class Waypoint extends Task {
53 protected final Mob mob;
54 protected Interactable target;
55 private Position lastPosition;
56
57 protected Waypoint(Mob mob, Interactable target) {
58 super(true, 0);
59 this.mob = mob;
60 this.target = target;
61 }
62
63 protected abstract void onDestination();
64
65 protected int getRadius() {
66 return 1;
67 }
68
69 protected boolean withinDistance() {
70 if (target instanceof final GameObject object) {
71 Position position = mob.getPosition();
72 int x = position.getX();
73 int y = position.getY();
74
75 GameObjectDefinition definition = object.getDefinition();
76 int walkingFlag = definition.getWalkingFlag();
77 int sizeX = definition.getWidth();
78 int sizeY = definition.getLength();
79 int rotation = object.getDirection().getId();
80 if (rotation % 2 != 0) {
81 sizeX = definition.getLength();
82 sizeY = definition.getWidth();
83 }
84 if (rotation != 0) {
85 walkingFlag = (walkingFlag << rotation & 0xF) + (walkingFlag >> 4 - rotation);
86 }
87 if (sizeX != 0 && sizeY != 0) {
88 Position targetPosition = target.getPosition();
89 int destX = targetPosition.getX();
90 int destY = targetPosition.getY();
91 int height = targetPosition.getHeight();
92
93 int flag = TraversalMap.getFlags(destX, destY, height);
94
95 int cornerX = destX + sizeX - 1;
96 int cornerY = destY + sizeY - 1;
97
98 if (destX <= x && cornerX >= x && y >= destY && y <= cornerY) {
99 return true;
100 }
101 if (x == destX - 1 && destY <= y && y <= cornerY && (0x8 & flag) == 0 && (0x8 & walkingFlag) == 0) {
102 return true;
103 }
104 if (x == cornerX + 1 && destY <= y && cornerY >= y && (flag & 0x80) == 0 && (0x2 & walkingFlag) == 0) {
105 return true;
106 }
107 if (y == destY - 1 && destX <= x && cornerX >= x && (0x2 & flag) == 0 && (0x4 & walkingFlag) == 0) {
108 return true;
109 }
110 if (y == cornerY + 1 && destX <= x && cornerX >= x && (flag & 0x20) == 0 && (0x1 & walkingFlag) == 0) {
111 return true;
112 }
113 }
114 }
115 return Utility.getDistance(mob, target) <= getRadius() && !mob.movement.needsPlacement();
116 }
117
118 @Override
119 protected void onSchedule() {
120 if (mob.locking.locked(PacketType.MOVEMENT)) {
121 return;
122 }
123
124 if (target instanceof Mob) {
125 mob.interact((Mob) target);
126 }
127
128 if (!withinDistance()) {
129 findRoute();
130 }
131 }
132
133 @Override
134 public void execute() {
135 if (target instanceof Mob && Utility.inside(mob, target)) {
136 if (!mob.locking.locked(PacketType.MOVEMENT)
137 && !mob.movement.needsPlacement()) {
138 Mob targetMob = (Mob) target;
139 if (targetMob.hasPriorityIndex(mob)
140 || (!targetMob.isFixingInside() && !targetMob.movement.needsPlacement())) {
141 Utility.fixInsidePosition(mob, target);
142 }
143 }
144 return;
145 } else {
146 mob.setFixingInside(false);
147 }
148
149 if (withinDistance()) {
150 onDestination();
151 return;
152 }
153
154 if (target instanceof GameObject gameObject && mob.isPlayer()) {
155 if (gameObject.distance() > 1 && withinDistance(mob.getPosition().getX(), mob.getPosition().getY(), target.getPosition().getX(), target.getPosition().getY(), target.width(), gameObject.length(), gameObject.distance())) {
156 onDestination();
157 return;
158 }
159 }
160
161 if (target.getPosition().equals(lastPosition)) {
162 return;
163 }
164
165 if (mob.locking.locked(PacketType.MOVEMENT)) {
166 return;
167 }
168
169 lastPosition = target.getPosition();
170 findRoute();
171 }
172
173 private void findRoute() {
174 if (target instanceof Player && mob.equals(((Player) target).pet)) {
175 int distance = Utility.getDistance(mob, target);
176 if (distance > Region.VIEW_DISTANCE) {
177 Npc pet = mob.getNpc();
178 pet.move(target.getPosition());
179 pet.instance = ((Player) target).instance;
180 World.schedule(1, () -> {
181 pet.interact((Player) target);
182 pet.follow((Player) target);
183 });
184 }
185 }
186
187// if (this instanceof CombatWaypoint) {
188// System.out.println(mob.getPosition());
189// System.out.println(target.getPosition());
190// System.out.println(Utility.getDelta(mob, target));
191// System.out.println();
192// }
193
194 boolean smart = mob.isPlayer() || (mob.isNpc() && !(this instanceof CombatWaypoint));
195
196 if (smart && mob.movement.dijkstraPath(target)) {
197 return;
198 }
199
200 if (mob.movement.simplePath(target)) {
201 return;
202 }
203
204 if (mob.isPlayer())
205 mob.getPlayer().send(new SendMessage("I can't reach that!"));
206
207 /* No path can be found, lets get out of here!!!! */
208 cancel();
209 }
210
211 @Override
212 protected void onCancel(boolean logout) {
213 mob.resetFace();
214
215 if (target instanceof Mob other) {
216 other.attributes.remove("mob-following");
217 }
218 }
219
220 @Override
221 public boolean equals(Object obj) {
222 if (obj == this) return true;
223 if (obj instanceof Waypoint other) {
224 return Objects.equals(mob, other.mob)
225 && Objects.equals(target, other.target);
226 }
227 return false;
228 }
229
230 @Override
231 public String toString() {
232 return getClass().getSimpleName() + "{" +
233 "target=" + target +
234 '}';
235 }
236
237 public Interactable getTarget() {
238 return target;
239 }
240
241 public void onChange() {
242 execute();
243// mob.movement.processNextMovement();
244 }
245
246 boolean withinDistance(int x, int y, int x2, int y2, int width, int height, int distance) {
247 if (x > x2) {
248 x2 += Math.min(width, x - x2) - 1;
249 }
250 if (y > y2) {
251 y2 += Math.min(height, y - y2) - 1;
252 }
253 return Math.abs(x - x2) <= distance && Math.abs(y - y2) <= distance;
254 }
255}
synchronized final void cancel()
Definition Task.java:147
Task(boolean instant, int delay)
Definition Task.java:75
static void schedule(Task task)
Definition World.java:284
void move(Position position)
Definition Mob.java:377