greg review comments

This commit is contained in:
Player Name 2026-07-27 08:51:03 +02:00
parent 0161a000b5
commit a356fef354
22 changed files with 242 additions and 348 deletions

View file

@ -10,7 +10,6 @@ import core.game.world.map.*;
import core.game.world.map.build.DynamicRegion;
import core.game.world.map.zone.ZoneBorders;
import core.game.world.map.zone.ZoneBuilder;
import core.game.world.repository.Repository;
import core.game.world.update.flag.context.Animation;
import core.tools.Log;
import org.jetbrains.annotations.NotNull;

View file

@ -11,14 +11,13 @@ import java.util.Arrays;
*
*/
public enum HousingStyle {
// open door ids are doorId + 1
BASIC_WOOD (1, 5000, 7503, 0, 13100, 13101, 13098, 13098, Decoration.BASIC_WOOD_WINDOW),
BASIC_STONE (10, 5000, 7503, 1, 13094, 13096, 1902, 13090, Decoration.BASIC_STONE_WINDOW),
WHITEWASHED_STONE (20, 7500, 7503, 2, 13006, 13007, 1415, 1415, Decoration.WHITEWASHED_STONE_WINDOW),
FREMENNIK_STYLE_WOOD(30, 10000, 7503, 3, 13109, 13107, 13111, 13111, Decoration.FREMENNIK_WINDOW),
TROPICAL_WOOD (40, 15000, 7759, 0, 13016, 13015, 13011, 13011, Decoration.TROPICAL_WOOD_WINDOW),
FANCY_STONE (50, 25000, 7759, 1, 13119, 13118, 13116, 13116, Decoration.FANCY_STONE_WINDOW);
BASIC_WOOD (1, 5000, 7503, 0, 13100, 13101, 13098, Decoration.BASIC_WOOD_WINDOW),
BASIC_STONE (10, 5000, 7503, 1, 13094, 13096, 1902, 13090, Decoration.BASIC_STONE_WINDOW),
WHITEWASHED_STONE (20, 7500, 7503, 2, 13006, 13007, 1415, Decoration.WHITEWASHED_STONE_WINDOW),
FREMENNIK_STYLE_WOOD(30, 10000, 7503, 3, 13109, 13107, 13111, Decoration.FREMENNIK_WINDOW),
TROPICAL_WOOD (40, 15000, 7759, 0, 13016, 13015, 13011, Decoration.TROPICAL_WOOD_WINDOW),
FANCY_STONE (50, 25000, 7759, 1, 13119, 13118, 13116, Decoration.FANCY_STONE_WINDOW);
/**
* Array of all Dungeon Wall IDs.
@ -107,6 +106,7 @@ public enum HousingStyle {
* @param secondDoorId The second-door object id used in this style.
* @param wallId The wall object id used in this style.
* @param secondWallId The second-wall object id used in this style.
* @param window The window decoration used in this style.
*/
HousingStyle(int level, int cost, int regionId, int plane, int doorId, int secondDoorId, int wallId, int secondWallId, Decoration window) {
this.levelRequirement = level;
@ -120,6 +120,29 @@ public enum HousingStyle {
this.window = window;
}
/**
* Constructs a new {@code HousingStyle} {@code Object} for housing styles that do not have a second wall id
* @param level The level required.
* @param cost The cost of the style.
* @param regionId The region id for this style.
* @param plane The plane for this style.
* @param doorId The door object id used in this style.
* @param secondDoorId The second-door object id used in this style.
* @param wallId The wall object id used in this style.
* @param window The window decoration used in this style.
*/
HousingStyle(int level, int cost, int regionId, int plane, int doorId, int secondDoorId, int wallId, Decoration window) {
this.levelRequirement = level;
this.cost = cost;
this.regionId = regionId;
this.plane = plane;
this.doorId = doorId;
this.secondDoorId = secondDoorId;
this.wallId = wallId;
this.secondWallId = wallId;
this.window = window;
}
/**
* Gets the level.
* @return the level

View file

@ -819,7 +819,7 @@ class LunarListeners : SpellListener("lunar"), Commands {
private fun sendGroupTeleport(player: Player, xp: Double, destName: String, loc: Location){
RegionManager.getLocalPlayers(player.location, 1).forEach {
if (it.name == player.name) return@forEach
if (it == player) return@forEach
if (it.isTeleBlocked) return@forEach
if (!it.isActive) return@forEach
if (!it.settings.isAcceptAid) return@forEach

View file

@ -28,7 +28,7 @@ public class StatRestoreSpell extends MagicSpell {
private static final Animation ANIMATION = new Animation(4413);
private static final Graphics GRAPHICS = new Graphics(733, 130);
private static final Consumables[] acceptedPotions = new Consumables[] { Consumables.RESTORE, Consumables.SUPER_RESTO, Consumables.PRAYER, Consumables.ENERGY, Consumables.SUPER_ENERGY };
private static final Consumables[] acceptedPotions = new Consumables[] { Consumables.RESTORE, Consumables.SUPER_RESTO, Consumables.PRAYER, Consumables.ENERGY, Consumables.SUPER_ENERGY };
public StatRestoreSpell() {
super(SpellBook.LUNAR, 81, 84, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.EARTH_RUNE.getId(), 10), new Item(Runes.WATER_RUNE.getId(), 10) });
@ -69,7 +69,7 @@ public class StatRestoreSpell extends MagicSpell {
if (!o.isActive() || o.getLocks().isInteractionLocked()) {
continue;
}
if (!o.getSettings().isAcceptAid() || (o instanceof AIPlayer)) {
if (!o.getSettings().isAcceptAid() && !(o instanceof AIPlayer)) {
continue;
}
o.graphics(GRAPHICS);
@ -98,10 +98,10 @@ public class StatRestoreSpell extends MagicSpell {
}
private boolean isRestore(Potion p) {
for (int i = 0; i < acceptedPotions.length; i++) {
if (p == acceptedPotions[i].getConsumable())
return true;
}
for (int i = 0; i < acceptedPotions.length; i++) {
if (p == acceptedPotions[i].getConsumable())
return true;
}
return false;
}

View file

@ -20,6 +20,7 @@ import static core.api.ContentAPIKt.*;
* @author Emperor
*/
public final class PestControlSession {
private static STRANGE_PHANTOM_OBJECT_THAT_SHARES_A_TILE_WITH_A_BARRICADE = 25636;
/**
* The barricade object offsets.
@ -274,7 +275,7 @@ public final class PestControlSession {
for (Scenery object : objectList) {
for (Point point : OBJECT_OFFSETS) {
if (object.getLocation().getLocalX() == point.getX() && object.getLocation().getLocalY() == point.getY()) {
if (object.getId() != 25636) { //strange phantom object that shares a tile with a barricade
if (object.getId() != STRANGE_PHANTOM_OBJECT_THAT_SHARES_A_TILE_WITH_A_BARRICADE) {
barricades.add(object);
}
}

View file

@ -46,7 +46,7 @@ public class SquireDialogue extends DialoguePlugin {
interpreter.sendDialogues(3781, FacialExpression.HALF_GUILTY, "Congratulations! You managed to destroy all the portals!", "We've awarded you " + points + " Void Knight Commendation", "points. Please also accept these coins as a reward.");
stage = 100;
} else {// won and not awarded.
interpreter.sendDialogues(3781, FacialExpression.HALF_GUILTY, "Congratulations! You managed to destroy all the portals!", "However, you did not succeed in reaching the required", "amount of damage dealt we cannot grant you a reward.");
interpreter.sendDialogues(3781, FacialExpression.HALF_GUILTY, "Congratulations! You managed to destroy all the portals!", "However, you did not succeed in reaching the required", "amount of damage delt we cannot grant you a reward.");
stage = 101;
}
return true;

View file

@ -372,7 +372,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
return scenery != null && SEED_LOCS.contains(scenery.location)
}
fun resetChunkIfBarren(chunk: RegionChunk) {
private fun resetChunkIfBarren(chunk: RegionChunk) {
val wipedHoles = ArrayList<Scenery>()
for (x in 0 until 8) {
for (y in 0 until 8) {
@ -392,10 +392,10 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
}
}
fun countFieldState(chunk: RegionChunk, emptyHoleList: ArrayList<Scenery>, seedHoleList: ArrayList<Scenery>) {
for (x in 0 until 8) {
for (y in 0 until 8) {
for (i in 0 until 4) {
private fun countFieldState(chunk: RegionChunk, emptyHoleList: ArrayList<Scenery>, seedHoleList: ArrayList<Scenery>) {
for (x in 0 until RegionChunk.SIZE) {
for (y in 0 until RegionChunk.SIZE) {
for (i in 0 until RegionChunk.ARRAY_SIZE) {
val obj = chunk.objects[x][y][i] ?: continue
if (obj.id in HOLES) {
if (obj.location in SEED_LOCS) {
@ -412,8 +412,8 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
fun populateSeeds() {
// First, see if there are any chunks that have been completely wiped out. These need to be restored first (GL #2400).
Region.load(VINESWEEPER_REGION)
for (cx in 0 until 8) {
for (cy in 0 until 8) {
for (cx in 0 until RegionChunk.SIZE) {
for (cy in 0 until RegionChunk.SIZE) {
val chunk = VINESWEEPER_REGION.chunks[cx][cy][0]
resetChunkIfBarren(chunk)
}

View file

@ -1,7 +1,6 @@
package content.region.misthalin.draynor.dialogue;
import content.region.misthalin.draynor.handlers.DBRCutscene;
import core.game.activity.ActivityManager;
import core.game.dialogue.DialoguePlugin;
import core.game.dialogue.FacialExpression;
import core.game.node.entity.npc.NPC;
@ -9,6 +8,8 @@ import core.game.node.entity.player.Player;
import core.plugin.Initializable;
import core.game.node.item.Item;
import static core.api.ContentAPIKt.getAttribute;
/**
* Represents the dialogue plugin used for the draynor bank guard npc.
* @author 'Vexia
@ -16,6 +17,7 @@ import core.game.node.item.Item;
*/
@Initializable
public final class DraynorBankGuard extends DialoguePlugin {
private final static String HAS_SEEN_RECORDING = "draynor-recording";
/**
* Represents the coins item needed to re-watch the recording.
@ -56,7 +58,7 @@ public final class DraynorBankGuard extends DialoguePlugin {
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
if (!player.getAttribute("draynor-recording", false)) {
if (!getAttribute(player, HAS_SEEN_RECORDING, false)) {
interpreter.sendOptions("Select an option", "Can I deposit my stuff here?", "That wall doesn't look very good.", "Sorry, I don't want anything.");
stage = 1;
} else {

View file

@ -1,5 +1,6 @@
package content.region.misthalin.draynor.handlers
import content.region.misthalin.draynor.dialogue.DraynorBankGuard
import core.api.*
import core.game.activity.Cutscene
import core.game.component.Component
@ -29,6 +30,8 @@ import org.rs09.consts.NPCs
class DBRCutscene(player: Player) : Cutscene(player) {
companion object {
const val HAS_SEEN_RECORDING = "draynor-recording"
// Animations
private val STEAL_ANIMATION = Animation(832)
private val CAST_ANIMATION = Animation(1167)
@ -46,11 +49,15 @@ class DBRCutscene(player: Player) : Cutscene(player) {
// Graphics
private val TELEKINETIC_GRAPHIC = Graphics(142, 96)
private val SHOCK_GRAPHIC = Graphics(432, 0, 0)
private val SHOCK_CAST = Graphics(433)
private val TELE_OTHER_CAST = Graphics(343)
private val TELE_OTHER_TARGET = Graphics(342)
private val PURPLE_GRAPHIC = Graphics(301, 100)
private val THUNDER_GRAPHIC = Graphics(76)
// Projectile ids
private const val SHOCK_PROJECTILE_ID = 434
// Components
private val CRACKED = Component(385)
}
@ -93,19 +100,17 @@ class DBRCutscene(player: Player) : Cutscene(player) {
)
}
private fun castShock(target: Entity) {
val wiseOldMan = getNPC(NPCs.WISE_OLD_MAN_2566)!!
private fun castShock(target: Entity, wiseOldMan: Entity) {
wiseOldMan.animate(CAST_ANIMATION)
wiseOldMan.graphics(Graphics(433))
val projectile = Projectile.create(wiseOldMan, target, 434)
wiseOldMan.graphics(SHOCK_CAST)
val projectile = Projectile.create(wiseOldMan, target, SHOCK_PROJECTILE_ID)
projectile.send()
}
private fun castShock(loc: Location) {
val wiseOldMan = getNPC(NPCs.WISE_OLD_MAN_2566)!!
private fun castShock(loc: Location, wiseOldMan: Entity) {
wiseOldMan.animate(CAST_ANIMATION)
wiseOldMan.graphics(Graphics(433))
val projectile = Projectile.create(wiseOldMan, null, 434, 30, 30, 41, 140, 0, 0)
wiseOldMan.graphics(SHOCK_CAST)
val projectile = Projectile.create(wiseOldMan, null, SHOCK_PROJECTILE_ID, 30, 30, 41, 140, 0, 0)
projectile.endLocation = loc
projectile.send()
}
@ -119,12 +124,6 @@ class DBRCutscene(player: Player) : Cutscene(player) {
SpellBookManager.SpellBook.MODERN.getSpell(19).cast(wiseOldMan, GroundItemManager.get(Item(Items.BLUE_PARTYHAT_2422).id, base.transform(20, 44, 0), player))
}
private fun castThunderShock() {
val wiseOldMan = getNPC(NPCs.WISE_OLD_MAN_2566)!!
wiseOldMan.animate(THUNDER_ANIMATION)
wiseOldMan.graphics(PURPLE_GRAPHIC)
}
private fun die(npc: NPC) {
npc.animator.reset()
npc.animate(DEATH_ANIMATION)
@ -135,8 +134,7 @@ class DBRCutscene(player: Player) : Cutscene(player) {
override fun runStage(stage: Int) {
when (stage) {
0 -> {
player.lock()
player.locks.lockMovement(10000000)
lock(player, 1000)
sendDialogue(player, "You close your eyes and watch the recording...")
fadeToBlack()
timedUpdate(3)
@ -220,7 +218,7 @@ class DBRCutscene(player: Player) : Cutscene(player) {
sendChat(qutieDoll, "Huh?")
qutieDoll.faceTemporary(wiseOldMan, 2)
sendChat(wiseOldMan, "Please don't block my line of fire!")
castShock(purePker)
castShock(purePker, wiseOldMan)
timedUpdate(1)
}
16 -> {
@ -270,7 +268,8 @@ class DBRCutscene(player: Player) : Cutscene(player) {
timedUpdate(3)
}
24 -> {
castShock(base.transform(16, 46, 0))
val wiseOldMan = getNPC(NPCs.WISE_OLD_MAN_2566)!!
castShock(base.transform(16, 46, 0), wiseOldMan)
timedUpdate(2)
}
25 -> {
@ -381,7 +380,7 @@ class DBRCutscene(player: Player) : Cutscene(player) {
38 -> {
val wiseOldMan = getNPC(NPCs.WISE_OLD_MAN_2566)!!
wiseOldMan.faceTemporary(getNPC(NPCs.ELFINLOCKS_2578)!!, 1)
castShock(getNPC(NPCs.ELFINLOCKS_2578)!!)
castShock(getNPC(NPCs.ELFINLOCKS_2578)!!, wiseOldMan)
timedUpdate(2)
}
39 -> {
@ -400,7 +399,8 @@ class DBRCutscene(player: Player) : Cutscene(player) {
timedUpdate(2)
}
42 -> {
castShock(getNPC(NPCs.SP34KR_1337_2577)!!)
val wiseOldMan = getNPC(NPCs.WISE_OLD_MAN_2566)!!
castShock(getNPC(NPCs.SP34KR_1337_2577)!!, wiseOldMan)
move(getNPC(NPCs.QUTIEDOLL_2576)!!, 21, 44)
timedUpdate(2)
}
@ -430,7 +430,8 @@ class DBRCutscene(player: Player) : Cutscene(player) {
timedUpdate(1)
}
48 -> {
castShock(getNPC(NPCs.QUTIEDOLL_2576)!!)
val wiseOldMan = getNPC(NPCs.WISE_OLD_MAN_2566)!!
castShock(getNPC(NPCs.QUTIEDOLL_2576)!!, wiseOldMan)
timedUpdate(3)
}
49 -> {
@ -501,7 +502,9 @@ class DBRCutscene(player: Player) : Cutscene(player) {
timedUpdate(2)
}
61 -> {
castThunderShock()
val wiseOldMan = getNPC(NPCs.WISE_OLD_MAN_2566)!!
wiseOldMan.animate(THUNDER_ANIMATION)
wiseOldMan.graphics(PURPLE_GRAPHIC)
timedUpdate(3)
}
62 -> {
@ -547,7 +550,7 @@ class DBRCutscene(player: Player) : Cutscene(player) {
}
69 -> end {
player.isInvisible = false
setAttribute(player, "/save:draynor-recording", true)
setAttribute(player, "/save:$HAS_SEEN_RECORDING", true)
sendDialogue(player, "End of recording.")
}
}

View file

@ -384,4 +384,4 @@ class TearsOfGuthixGlobalTick : TickListener {
}
}
}
}
}

View file

@ -14,18 +14,12 @@ open class FillChunkContract(var chunk: RegionChunk? = null) : ChunkSpecContract
var chunkDelegate: (Int, Int, Int, Region) -> RegionChunk? = {_,_,_,_ -> chunk}
override fun populateChunks(dyn: DynamicRegion) {
for(plane in planes) {
for(x in 0 until 8)
for(y in 0 until 8)
if(replaceCondition.invoke(x,y,plane)) {
for (plane in planes) {
for (x in 0 until 8)
for (y in 0 until 8)
if (replaceCondition.invoke(x,y,plane)) {
val chunk = getChunk(x,y,plane,dyn) ?: continue
dyn.replaceChunk(
plane,
x,
y,
chunk,
sourceRegion
)
dyn.replaceChunk(plane, x, y, chunk, sourceRegion)
afterSetting(chunk, x, y, plane, dyn)
}
}

View file

@ -141,7 +141,7 @@ class ScriptAPI(private val bot: Player) {
/**
* Gets the nearest node with matching id.
* @param id the id to look for
* @param object whether the node we are looking for is an object.
* @param isObject whether the node we are looking for is an object.
* @return the closest node with matching id or null.
* @author Ceikry
*/
@ -166,7 +166,7 @@ class ScriptAPI(private val bot: Player) {
/**
* Gets the nearest node with a matching name.
* @param name the name to look for.
* @param object whether the node we are looking for is an object.
* @param isObject whether the node we are looking for is an object.
* @return the nearest matching node or null.
* @author Ceikry
*/

View file

@ -7,6 +7,7 @@ import core.game.node.entity.npc.NPC;
import core.game.node.entity.npc.NPCBehavior;
import core.game.node.entity.player.Player;
import core.game.system.task.Pulse;
import core.game.world.GameWorld;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.map.Point;
@ -18,8 +19,11 @@ import core.net.packet.context.PlayerContext;
import core.net.packet.out.ClearMinimapFlag;
import kotlin.jvm.functions.Function2;
import kotlin.Pair;
import core.tools.SystemLogger;
import core.api.utils.Vector;
import content.region.wilderness.handlers.revenants.RevenantNPC;
import static core.api.ContentAPIKt.*;
import java.util.Deque;
@ -217,12 +221,12 @@ public abstract class MovementPulse extends Pulse {
clearInferiorScripts();
mover.face(null);
if (canInteractWithoutMoving()) {
if (interactImmediately()) {
stop();
return true;
}
}
if (canInteractWithoutMoving()) {
if (interactImmediately()) {
stop();
return true;
}
}
updatePath();
if (tryInteract()) {
@ -235,33 +239,28 @@ public abstract class MovementPulse extends Pulse {
private boolean tryInteract() {
Location ml = mover.getLocation();
if (ml == null) {
return false;
}
// Allow being within 1 square of moving entities to interact with them.
int radius = destination instanceof Entity && ((Entity) destination).getWalkingQueue().hasPath() ? 1 : 0;
int radius = destination instanceof Entity && ((Entity)destination).getWalkingQueue().hasPath() ? 1 : 0;
if (interactLocation == null)
return false;
boolean atInteractLocation = Math.max(Math.abs(ml.getX() - interactLocation.getX()), Math.abs(ml.getY() - interactLocation.getY())) <= radius;
// Check if already in a valid interaction position for entity destinations
boolean canInteractFromCurrentPosition = false;
if (!atInteractLocation && destination instanceof Entity) {
Entity target = (Entity) destination;
Location dl = target.getLocation();
if (dl == null) {
return false;
}
boolean onSameTile = ml.getX() == dl.getX() && ml.getY() == dl.getY() && ml.getZ() == dl.getZ();
if (!onSameTile) {
canInteractFromCurrentPosition = Pathfinder.canInteract(
ml.getX(), ml.getY(), mover.size(),
dl.getX(), dl.getY(), target.size(), target.size(),
0, // walkFlag - "can interact from any unblocked direction"
ml.getZ(),
RegionManager::getClippingFlag);
}
}
if (atInteractLocation || canInteractFromCurrentPosition) {
boolean atInteractLocation = Math.max(Math.abs(ml.getX() - interactLocation.getX()), Math.abs(ml.getY() - interactLocation.getY())) <= radius;
// Check if already in a valid interaction position for entity destinations
boolean canInteractFromCurrentPosition = false;
if (!atInteractLocation && destination instanceof Entity) {
Entity target = (Entity) destination;
Location dl = target.getLocation();
boolean onSameTile = ml.getX() == dl.getX() && ml.getY() == dl.getY() && ml.getZ() == dl.getZ();
if (!onSameTile) {
canInteractFromCurrentPosition = Pathfinder.canInteract(
ml.getX(), ml.getY(), mover.size(),
dl.getX(), dl.getY(), target.size(), target.size(),
0, // walkFlag - "can interact from any unblocked direction"
ml.getZ(),
RegionManager::getClippingFlag
);
}
}
if (atInteractLocation || canInteractFromCurrentPosition) {
try {
if (near || pulse()) {
if (mover instanceof Player) {
@ -273,7 +272,7 @@ public abstract class MovementPulse extends Pulse {
stop();
return true;
}
} catch (Exception e) {
} catch (Exception e){
e.printStackTrace();
stop();
}
@ -288,35 +287,34 @@ public abstract class MovementPulse extends Pulse {
* @return true if the mover can interact without moving
*/
private boolean canInteractWithoutMoving() {
if (!(destination instanceof Entity)) {
return false;
}
Entity target = (Entity) destination;
Location ml = mover.getLocation();
Location dl = target.getLocation();
if (ml == null || dl == null) {
return false;
}
if (ml.getX() == dl.getX() && ml.getY() == dl.getY() && ml.getZ() == dl.getZ()) {
return false;
}
if (isInsideEntity(ml)) {
return false;
}
if (target.getWalkingQueue().hasPath()) { // For moving entities, allow interaction from 1 tile away
int distance = Math.max(
Math.abs(ml.getX() - dl.getX()),
Math.abs(ml.getY() - dl.getY()));
if (distance <= target.size()) {
return true;
}
}
return Pathfinder.canInteract(
ml.getX(), ml.getY(), mover.size(),
dl.getX(), dl.getY(), target.size(), target.size(),
0, // walkFlag - "can interact from any unblocked direction"
ml.getZ(),
RegionManager::getClippingFlag);
if (!(destination instanceof Entity)) {
return false;
}
Entity target = (Entity) destination;
Location ml = mover.getLocation();
Location dl = target.getLocation();
if (ml.getX() == dl.getX() && ml.getY() == dl.getY() && ml.getZ() == dl.getZ()) {
return false;
}
if (isInsideEntity(mover.getLocation())) {
return false;
}
if (target.getWalkingQueue().hasPath()) { // For moving entities, allow interaction from 1 tile away
int distance = Math.max(
Math.abs(ml.getX() - dl.getX()),
Math.abs(ml.getY() - dl.getY())
);
if (distance <= target.size()) {
return true;
}
}
return Pathfinder.canInteract(
ml.getX(), ml.getY(), mover.size(),
dl.getX(), dl.getY(), target.size(), target.size(),
0, // walkFlag - "can interact from any unblocked direction"
ml.getZ(),
RegionManager::getClippingFlag
);
}
/**
@ -326,20 +324,20 @@ public abstract class MovementPulse extends Pulse {
* @return true if interaction was successful and pulse should stop
*/
private boolean interactImmediately() {
if (destination instanceof Entity) {
mover.face((Entity) destination);
}
try {
if (pulse()) {
if (mover instanceof Player) {
PacketRepository.send(ClearMinimapFlag.class, new PlayerContext((Player) mover));
}
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
if (destination instanceof Entity) {
mover.face((Entity) destination);
}
try {
if (pulse()) {
if (mover instanceof Player) {
PacketRepository.send(ClearMinimapFlag.class, new PlayerContext((Player) mover));
}
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private boolean validate() {
@ -466,49 +464,49 @@ public abstract class MovementPulse extends Pulse {
return canMove;
}
private Location checkForEntityPathInterrupt(Location loc) {
Location ml = mover.getLocation();
Location dl = destination.getLocation();
// Lead the target if they're walking/running, unless they're already within interaction range
if (loc != null && destination instanceof Entity) {
WalkingQueue wq = ((Entity) destination).getWalkingQueue();
if (wq.hasPath()) {
Point[] points = wq.getQueue().toArray(new Point[0]);
if (points.length > 0) {
Point p = points[0];
Point predictiveIntersection = null;
for (int i = 0; i < points.length; i++) {
Location closestBorder = getClosestBorderToPoint(points[i], loc.getZ());
private Location checkForEntityPathInterrupt(Location loc) {
Location ml = mover.getLocation();
Location dl = destination.getLocation();
// Lead the target if they're walking/running, unless they're already within interaction range
if (loc != null && destination instanceof Entity) {
WalkingQueue wq = ((Entity) destination).getWalkingQueue();
if (wq.hasPath()) {
Point[] points = wq.getQueue().toArray(new Point[0]);
if (points.length > 0) {
Point p = points[0];
Point predictiveIntersection = null;
for (int i = 0; i < points.length; i++) {
Location closestBorder = getClosestBorderToPoint(points[i], loc.getZ());
if (!RegionManager.isTeleportPermitted(closestBorder)) { // A nasty hack to discard invalid intersection points
continue;
}
int moverDist = Math.max(Math.abs(ml.getX() - closestBorder.getX()), Math.abs(ml.getY() - closestBorder.getY()));
float movementRatio = moverDist / (float) ((i + 1) / (mover.getWalkingQueue().isRunning() ? 2 : 1));
if (predictiveIntersection == null && movementRatio <= 1.0) { //try to predict an intersection point on the path if possible
predictiveIntersection = points[i];
break;
}
// Otherwise, we target the farthest point along target's planned movement that's within 1 tick's running,
// this ensures the player will run to catch up to the target if able.
if (moverDist <= 2) {
p = points[i];
}
}
if (predictiveIntersection != null)
p = predictiveIntersection;
if (!RegionManager.isTeleportPermitted(closestBorder)) { // A nasty hack to discard invalid intersection points
continue;
}
int moverDist = Math.max(Math.abs(ml.getX() - closestBorder.getX()), Math.abs(ml.getY() - closestBorder.getY()));
float movementRatio = moverDist / (float) ((i + 1) / (mover.getWalkingQueue().isRunning() ? 2 : 1));
if (predictiveIntersection == null && movementRatio <= 1.0) { //try to predict an intersection point on the path if possible
predictiveIntersection = points[i];
break;
}
// Otherwise, we target the farthest point along target's planned movement that's within 1 tick's running,
// this ensures the player will run to catch up to the target if able.
if (moverDist <= 2) {
p = points[i];
}
}
if (predictiveIntersection != null)
p = predictiveIntersection;
Location endLoc = getClosestBorderToPoint(p, loc.getZ());
Location endLoc = getClosestBorderToPoint(p, loc.getZ());
if (!RegionManager.isTeleportPermitted(endLoc)) { // Basically a prayer
return loc;
}
return endLoc;
}
}
}
return loc;
}
if (!RegionManager.isTeleportPermitted(endLoc)) { // Basically a prayer
return loc;
}
return endLoc;
}
}
}
return loc;
}
private Location getClosestBorderToPoint (Point p, int plane) {
Vector pathDiff = Vector.betweenLocs (destination.getLocation(), Location.create(p.getX(), p.getY(), plane));
@ -597,9 +595,6 @@ public abstract class MovementPulse extends Pulse {
* @return {@code True} if so.
*/
private boolean isInsideEntity(Location l) {
if (l == null) {
return false;
}
if (!(destination instanceof Entity)) {
return false;
}
@ -607,9 +602,6 @@ public abstract class MovementPulse extends Pulse {
return false;
}
Location loc = destination.getLocation();
if (loc == null) {
return false;
}
int size = destination.size();
return Pathfinder.isStandingIn(l.getX(), l.getY(), mover.size(), mover.size(), loc.getX(), loc.getY(), size, size);
}

View file

@ -112,11 +112,11 @@ public abstract class CombatSpell extends MagicSpell {
* Gets a list of valid targets for a multihitting spell.
* @param entity The caster of the spell.
* @param target The primary victim.
* @param max The maximum number of extra victims that may be hit.
* @param max The maximum number of extra victims that may be hit.
* @return The list of targets (the primary target is always at index 0).
*/
public List<Entity> getMultihitTargets(Entity entity, Entity target, int max) {
List<Entity> victims = new ArrayList<>(20);
List<Entity> victims = new ArrayList<>(max+1);
victims.add(target);
List<Entity> surrounding = RegionManager.getLocalEntities(target.getLocation(), 1);
@ -249,4 +249,4 @@ public abstract class CombatSpell extends MagicSpell {
return SPLASH_GRAPHIC;
}
}
}

View file

@ -20,7 +20,6 @@ import static core.api.ContentAPIKt.*;
* @author Emperor
*/
public final class WalkingQueue {
/**
* The walking queue.
*/
@ -57,7 +56,7 @@ public final class WalkingQueue {
*/
private Location footPrint;
public ArrayList<GroundItem> routeItems = new ArrayList<GroundItem>();
public ArrayList<GroundItem> routeItems = new ArrayList<GroundItem>();
/**
* Constructs a new {@code WalkingQueue} {@code Object}.
@ -85,20 +84,21 @@ public final class WalkingQueue {
if (isPlayer && updateRegion(prevLocation, entity.getLocation(), true)) {
return;
}
if (hasTimerActive(entity, "frozen"))
return;
if (hasTimerActive(entity, "frozen")) {
return;
}
Point point = walkingQueue.poll();
boolean drawPath = entity.getAttribute("routedraw", false);
boolean drawPath = entity.getAttribute("routedraw", false);
if (point == null) {
updateRunEnergy(false);
if (isPlayer && drawPath) {
for (GroundItem item : routeItems) {
if (item != null) {
RegionManager.getRegionChunk(item.getLocation()).remove(item);
}
}
routeItems.clear();
}
if (isPlayer && drawPath) {
for (GroundItem item : routeItems) {
if (item != null) {
RegionManager.getRegionChunk(item.getLocation()).remove(item);
}
}
routeItems.clear();
}
return;
}
if (isPlayer && ((Player) entity).getSettings().getRunEnergy() < 1.0) {
@ -308,13 +308,13 @@ public final class WalkingQueue {
if (point == null) {
return;
}
boolean drawRoute = entity.getAttribute("routedraw", false);
if (drawRoute && entity instanceof Player) {
Player p = (Player) entity;
GroundItem item = new GroundItem(new Item(13444), Location.create(x, y, p.getLocation().getZ()), p);
routeItems.add (item);
RegionManager.getRegionChunk(item.getLocation()).add(item);
}
boolean drawRoute = entity.getAttribute("routedraw", false);
if (drawRoute && entity instanceof Player) {
Player p = (Player) entity;
GroundItem item = new GroundItem(new Item(13444), Location.create(x, y, p.getLocation().getZ()), p);
routeItems.add (item);
RegionManager.getRegionChunk(item.getLocation()).add(item);
}
int diffX = x - point.getX(), diffY = y - point.getY();
int max = Math.max(Math.abs(diffX), Math.abs(diffY));
for (int i = 0; i < max; i++) {
@ -351,9 +351,7 @@ public final class WalkingQueue {
/**
* Checks if the entity is running.
* @return {@code True} if a ctrl + click reward was performed, <br> the
* player has the run option enabled or the NPC is a familiar, <p>
* {@code false} if not.
* @return {@code True} if a ctrl + click reward was performed, the player has the run option enabled or the NPC is a familiar, {@code False} if not.
*/
public boolean isRunningBoth() {
if (isRunDisabled()) return false;
@ -392,7 +390,6 @@ public final class WalkingQueue {
*/
public void reset(boolean running) {
Location loc = entity.getLocation();
if (loc == null) {
log(this.getClass(), Log.ERR,
"The entity location provided was null."

View file

@ -1,6 +1,5 @@
package core.game.node.entity.npc;
import core.ServerConstants;
import core.game.event.NPCKillEvent;
import core.cache.def.impl.NPCDefinition;
import core.game.dialogue.DialoguePlugin;

View file

@ -25,7 +25,6 @@ import core.game.world.repository.Repository;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Holds and handles the NPC drop tables.

View file

@ -1,11 +1,9 @@
package core.game.node.entity.player.info.login;
import core.Server;
import core.game.component.Component;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.emote.Emotes;
import core.game.node.item.Item;
import core.game.world.map.Location;
import core.game.world.map.RegionManager;
import core.net.packet.PacketRepository;
import core.net.packet.context.InterfaceContext;

View file

@ -50,9 +50,9 @@ public final class PacketDispatch {
PacketRepository.send(Config.class, new ConfigContext(player, index, value));
}
public void sendVarcUpdate(short index, int value) {
PacketRepository.send(VarcUpdate.class, new VarcUpdateContext(player, index, value));
}
public void sendVarcUpdate(short index, int value) {
PacketRepository.send(VarcUpdate.class, new VarcUpdateContext(player, index, value));
}
/**
* Send a game message.
@ -312,7 +312,7 @@ public final class PacketDispatch {
* @param id The animation id.
*/
public void sendAnimation(int id) {
player.getUpdateMasks().register(EntityFlag.Animate, new Animation(id));
player.getUpdateMasks().register(EntityFlag.Animate, new Animation(id));
}
/**
@ -321,7 +321,7 @@ public final class PacketDispatch {
* @param delay The animation delay.
*/
public void sendAnimation(int id, int delay) {
player.getUpdateMasks().register(EntityFlag.Animate, new Animation(id, delay));
player.getUpdateMasks().register(EntityFlag.Animate, new Animation(id, delay));
}
/**
@ -329,7 +329,7 @@ public final class PacketDispatch {
* @param id The graphic id.
*/
public void sendGraphic(int id) {
player.getUpdateMasks().register(EntityFlag.SpotAnim, new Graphics(id));
player.getUpdateMasks().register(EntityFlag.SpotAnim, new Graphics(id));
}
/**
@ -395,7 +395,7 @@ public final class PacketDispatch {
* @param height The graphic height.
*/
public void sendGraphic(int id, int height) {
player.getUpdateMasks().register(EntityFlag.SpotAnim, new Graphics(id, height));
player.getUpdateMasks().register(EntityFlag.SpotAnim, new Graphics(id, height));
}
public void sendVarClient(int id, int value, boolean cs2) {
PacketRepository.send(Config.class, new ConfigContext(player, id, value, cs2));

View file

@ -41,11 +41,6 @@ public final class Skills {
*/
public double experienceMultiplier = 1.0;
/**
* The maximum experience multiplier.
*/
public static final double MAX_EXPERIENCE_MOD = 60.0;
/**
* Represents an array of skill names.
*/
@ -252,9 +247,9 @@ public final class Skills {
staticLevels[slot] = newLevel;
if (entity instanceof Player) {
player.updateAppearance();
player.updateAppearance();
LevelUp.levelup(player, slot, amount);
updateCombatLevel();
updateCombatLevel();
}
}
if (entity instanceof Player) {
@ -288,46 +283,6 @@ public final class Skills {
//Keywords for people ctrl + Fing the project
//xprate xp rate xp multiplier skilling rate
return experienceMultiplier;
/*if (!(entity instanceof Player)) {
return 1.0;
}
double mod = multiplyer ? (EXPERIENCE_MULTIPLIER) : 1;
Player p = (Player) entity;
if (p.getIronmanManager().getMode() == IronmanMode.ULTIMATE) {
mod /= 4;
} else if (p.getIronmanManager().getMode() == IronmanMode.STANDARD) {
mod /= 2;
}
//A boost for combat skills that are under level 65.
if(entity instanceof Player && !this.hasLevel(slot, 65) && isCombat(slot)){
mod *= 1.5;
}
//Grand Exchange region XP boost.
if(entity.getLocation().getRegion().getRegionId() == 12598){
mod += 1.5;
}
// Pest control, XP halved during the game
if (entity.getLocation().getRegion().getRegionId() == 10536) {
mod *= .5;
}
if (SystemManager.getSystemConfig().isDoubleExp()) {
mod *= 2;
}
if (HolidayEvent.getCurrent() != null) {
HolidayEvent.getCurrent().addExperience(p, slot, experience);
}
p.getAntiMacroHandler().registerExperience(slot, experience);
if (TutorialSession.getExtension(p).getStage() < TutorialSession.MAX_STAGE) {
mod = 1.0;
} else {
if (playerMod && p.getExperienceMod() != 0.0) {
mod *= p.getExperienceMod();
}
}
if (mod > MAX_EXPERIENCE_MOD ) {
return MAX_EXPERIENCE_MOD;
}
return mod;*/
}
/**
@ -721,9 +676,6 @@ public final class Skills {
if (prayerPoints < 0) {
prayerPoints = 0;
}
// if (prayerPoints > staticLevels[PRAYER]) {
// prayerPoints = staticLevels[PRAYER];
// }
if (entity instanceof Player) {
PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, PRAYER));
}

View file

@ -15,15 +15,12 @@ import static core.api.ContentAPIKt.log;
/**
* An aiding class for object constructing/removing.
*
* @author Emperor
*/
public final class SceneryBuilder {
/**
* Replaces a scenery.
*
* @param remove The object to remove.
* @param remove The object to remove.
* @param construct The object to add.
* @return {@code True} if successful.
*/
@ -34,9 +31,9 @@ public final class SceneryBuilder {
/**
* Replaces a scenery.
*
* @param remove The object to remove.
* @param remove The object to remove.
* @param construct The object to add.
* @param clip If clipping should be adjusted.
* @param clip If clipping should be adjusted.
* @return {@code True} if successful.
*/
public static boolean replace(Scenery remove, Scenery construct, boolean clip, boolean permanent) {
@ -71,9 +68,8 @@ public final class SceneryBuilder {
/**
* Replaces the object client sided alone.
*
* @param remove The object to remove.
* @param construct The object to replace with.
* @param remove The object to remove.
* @param construct The object to replace with.
* @param restoreTicks The restoration ticks.
* @return {@code True} if successful.
*/
@ -93,9 +89,8 @@ public final class SceneryBuilder {
/**
* Replaces a scenery temporarily.
*
* @param remove The object to remove.
* @param construct The object to add.
* @param remove The object to remove.
* @param construct The object to add.
* @param restoreTicks The amount of ticks before the object gets restored.
* @return {@code True} if successful.
*/
@ -105,9 +100,8 @@ public final class SceneryBuilder {
/**
* Replaces a scenery temporarily.
*
* @param remove The object to remove.
* @param construct The object to add.
* @param remove The object to remove.
* @param construct The object to add.
* @param restoreTicks The amount of ticks before the object gets restored.
* @return {@code True} if successful.
*/
@ -151,7 +145,6 @@ public final class SceneryBuilder {
/**
* Adds a scenery.
*
* @param object The object to add.
* @return {@code True} if successful.
*/
@ -161,10 +154,8 @@ public final class SceneryBuilder {
/**
* Adds a scenery.
*
* @param object The object to add.
* @param ticks The amount of ticks this object should last for (-1 for
* permanent).
* @param ticks The amount of ticks this object should last for (-1 for permanent).
* @return {@code True} if successful.
*/
public static Constructed add(Scenery object, int ticks, final GroundItem... items) {
@ -191,7 +182,6 @@ public final class SceneryBuilder {
/**
* Removes a scenery.
*
* @param object The object to remove.
* @return {@code True} if successful.
*/
@ -210,21 +200,18 @@ public final class SceneryBuilder {
/**
* Removes a scenery.
*
* @param object the object.
* @param object the object.
* @param respawnTicks the respawn ticks.
* @return {@code True}if removed.
*/
public static boolean remove(final Scenery object, int respawnTicks) {
if (remove(object)) {
GameWorld.getPulser().submit(new Pulse(respawnTicks) {
@Override
public boolean pulse() {
add(object);
return true;
}
});
return true;
}
@ -233,8 +220,7 @@ public final class SceneryBuilder {
/**
* Updates the scenery on all the player's screen.
*
* @param objects The scenerys.
* @param objects The sceneries.
*/
public static void update(Scenery... objects) {
for (Scenery o : objects) {

View file

@ -156,10 +156,6 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) {
sendMessage(player, "Job cleared successfully.")
}
define("region", Privilege.STANDARD, "", "Prints your current Region ID.") {player, args ->
sendMessage(player, "Region ID: ${player.location.regionId}")
}
define("spellbook", Privilege.ADMIN, "::spellbook <lt>book ID<gt> (0 = MODERN, 1 = ANCIENTS, 2 = LUNARS)", "Swaps your spellbook to the given book ID."){player, args ->
if(args.size < 2){
reject(player,"Usage: ::spellbook [int]. 0 = MODERN, 1 = ANCIENTS, 2 = LUNARS")
@ -377,28 +373,6 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) {
player.dialogueInterpreter.sendDialogues(player, id, "Expression ID: $id")
}
define("tileinfo", Privilege.ADMIN, "::tileinfo", "Prints out your current tile's clipping flags and entities on it.") { player, args ->
if (args.size != 1) reject(player, "::tileinfo doesn't take arguments.")
sendMessage(player, "Location: ${player.location}")
sendMessage(player, "Clipping: ${RegionManager.getClippingFlag(player.location, false)}")
sendMessage(player, "Projectile: ${RegionManager.getClippingFlag(player.location, true)}")
sendMessage(player, "${player.location.chunk.players.size} players and ${player.location.chunk.npcs.size} npcs on this chunk.")
sendMessage(player, "Entities on this tile:")
for (p in RegionManager.getLocalPlayers(player.location, 0)) {
sendMessage(player, " player ${player.username}")
}
for (npc in RegionManager.getLocalNPCs(player.location, 0)) {
sendMessage(player, " npc ${npc.name}")
}
sendMessage(player, "Entities within render distance:")
for (p in RegionManager.getLocalPlayers(player.location)) {
sendMessage(player, " player ${player.username} at ${player.location}")
}
for (npc in RegionManager.getLocalNPCs(player.location)) {
sendMessage(player, " npc ${npc.name} at ${npc.location}}")
}
}
define("timers", Privilege.ADMIN, "::timers", "Print out timers") { player, args ->
player.sendMessage("Active timers:")
for(timer in player.timers.activeTimers) {
@ -483,31 +457,6 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) {
target.skills.addExperience(skill, xp!!)
}
define("renewpenguins", Privilege.ADMIN, "", "Generates a fresh set of weekly penguins") { player, _ ->
val spawnedOrdinals = (PenguinHNSEvent.getStoreFile()["spawned-penguins"] as JSONArray).map { it.toString().toInt() }
val penguinNPCs = arrayListOf(NPCs.BARREL_8104, NPCs.BUSH_8105,NPCs.CACTUS_8107,NPCs.CRATE_8108,NPCs.ROCK_8109,NPCs.TOADSTOOL_8110)
spawnedOrdinals.forEach {
val peng = Penguin.values()[it]
val nearNPCs = getLocalEntities(peng.location,1)
nearNPCs.forEach { npc ->
if (npc.id in penguinNPCs) {
poofClear(npc as NPC)
}
}
}
penguins = spawner.spawnPenguins(10)
PenguinHNSEvent.getStoreFile()["spawned-penguins"] = penguins.toJSONArray()
tagMapping.clear()
for (p in penguins) {
tagMapping.put(p, JSONArray())
val pengCoord = Penguin.values()[p].location
player.debug("Penguin spawned at:$pengCoord")
}
updateStoreFile()
player.debug("Penguin positions have been renewed")
}
define("spawnpenguin",Privilege.ADMIN,"::spawnPenguin <lt>Ordinal<gt>","Adds a new Penguin spawn to this weeks list based on the ordinal provided 0-64"){player,args->
if (args.size!=2) reject (player,"Usage: ::spawnpenguin Ordinal")
val ordinal = args[1].toIntOrNull()