Made the PulseManager capable of running multiple pulses simultaneously, in different slots (this makes it function a bit more like an entity queue, though not quite)

Fixed the dupe in the ectofuntus by demoting the action pulses for grinding bones from world pulses to individual pulses, and correcting a bit of the logic
Added function to remove multiple attributes at once to the ContentAPI
This commit is contained in:
Ceikry 2022-09-06 23:37:08 +00:00 committed by Ryan
parent 4ecdbbac7e
commit 785f72215f
45 changed files with 188 additions and 128 deletions

View file

@ -1,5 +1,6 @@
package core.game.content.activity.bountyhunter;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.skill.magic.MagicSpell;
import core.game.node.entity.skill.magic.Runes;
import core.game.interaction.MovementPulse;
@ -74,7 +75,7 @@ public final class BountyLocateSpell extends MagicSpell {
public boolean pulse() {
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
}
Location destination = RegionManager.getTeleportLocation(entry.getTarget().getLocation(), 5);

View file

@ -83,7 +83,6 @@ public final class ClanWarsActivityPlugin extends ActivityPlugin {
@Override
public boolean handle(Player player, Node node, String option) {
player.getPulseManager().clear("interaction:attack:" + node.hashCode());
player.getProperties().getCombatPulse().attack(node);
return true;
}

View file

@ -67,7 +67,6 @@ public class DuelArea extends MapZone {
@Override
public boolean handle(Player player, Node node, String option) {
player.getPulseManager().clear("interaction:attack:" + node.hashCode());
player.getProperties().getCombatPulse().attack(node);
return true;
}

View file

@ -4,6 +4,7 @@ import core.game.interaction.MovementPulse;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.AbstractNPC;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
@ -155,7 +156,7 @@ public class PCRavagerNPC extends AbstractNPC {
public boolean pulse() {
return true;
}
}, "movement");
}, PulseType.STANDARD);
}
/**

View file

@ -5,6 +5,7 @@ import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.ImpactHandler.HitsplatType;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.AbstractNPC;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
@ -72,7 +73,7 @@ public final class PCSpinnerNPC extends AbstractNPC {
public boolean pulse() {
return true;
}
}, "movement");
}, PulseType.STANDARD);
}
}
}

View file

@ -3,6 +3,7 @@ package core.game.content.activity.pyramidplunder;
import core.game.interaction.MovementPulse;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.AbstractNPC;
import core.game.node.entity.player.Player;
import rs09.game.world.GameWorld;
@ -150,7 +151,7 @@ public abstract class PyramidPlunderNPC extends AbstractNPC {
public boolean pulse() {
return false;
}
}, "movement");
}, PulseType.STANDARD);
face(player);
}

View file

@ -58,7 +58,6 @@ public final class DemonSlayerPlugin extends OptionHandler {
return true;
}
player.face(((NPC) node));
player.getPulseManager().clear("interaction:attack:" + node.hashCode());
player.getProperties().getCombatPulse().attack(node);
return true;
case DRAIN_ID:

View file

@ -141,7 +141,6 @@ public final class DragonSlayerPlugin extends OptionHandler {
player.getPacketDispatch().sendMessage("You have already slain Elvarg the dragon.");
return true;
}
player.getPulseManager().clear("interaction:attack:" + node.hashCode());
player.getProperties().getCombatPulse().attack(node);
player.face((Entity) node);
break;
@ -230,7 +229,6 @@ public final class DragonSlayerPlugin extends OptionHandler {
break;
case 745:
if (option.equals("attack")) {
player.getPulseManager().clear("interaction:attack:" + node.hashCode());
player.getProperties().getCombatPulse().attack(node);
return true;
}

View file

@ -2,6 +2,7 @@ package core.game.content.quest.members.fishingcontest;
import core.game.interaction.MovementPulse;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.Player;
import core.game.system.task.Pulse;
import rs09.game.world.GameWorld;
@ -29,7 +30,7 @@ public class FenceInteraction extends PluginInteraction {
GameWorld.getPulser().submit(new SqueezePulse(player));
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
}

View file

@ -2,6 +2,7 @@ package core.game.content.quest.members.fishingcontest;
import core.game.interaction.MovementPulse;
import core.game.node.entity.Entity;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.system.task.Pulse;
@ -140,7 +141,7 @@ public class FishingContestCutscene extends CutscenePlugin {
player.getWalkingQueue().setRunDisabled(true);
return true;
}
}, "movement");
}, PulseType.STANDARD);
break;
case 12:
stranger.sendChat("You're switching with me. Go.");
@ -152,7 +153,7 @@ public class FishingContestCutscene extends CutscenePlugin {
player.getDialogueInterpreter().sendDialogue("Your spot is now by the pipes.");
return true;
}
}, "movement");
}, PulseType.STANDARD);
break;
case 22:
stranger.getPulseManager().run(new MovementPulse(stranger, base.getLocation().transform(7, 43, 0)) {
@ -160,7 +161,7 @@ public class FishingContestCutscene extends CutscenePlugin {
public boolean pulse() {
return true;
}
}, "movement");
},PulseType.STANDARD);
GameWorld.getPulser().submit(new FishingPulse());
return true;
}

View file

@ -2,6 +2,7 @@ package core.game.content.quest.members.fishingcontest;
import core.game.interaction.MovementPulse;
import core.game.interaction.Option;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.world.map.Location;
@ -24,7 +25,7 @@ public class FishingSpotInteraction extends PluginInteraction {
player.getDialogueInterpreter().sendDialogues(3677, FacialExpression.NEUTRAL, "I think you will find that is","my spot.");
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
} else if (npc_loc.equals(2630, 3435, 0)){
player.getPulseManager().run(new MovementPulse(player, npc.getLocation().transform(1, 0, 0)) {
@ -33,7 +34,7 @@ public class FishingSpotInteraction extends PluginInteraction {
player.getDialogueInterpreter().sendDialogues(225, FacialExpression.NEUTRAL, "Hey, you need to pay to enter the", "competition first! Only 5gp entrance fee!");
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
} else if (npc_loc.equals(Location.create(2632, 3427, 0))){
player.getPulseManager().run(new MovementPulse(player, npc.getLocation().transform(1, 0, 0)) {
@ -42,7 +43,7 @@ public class FishingSpotInteraction extends PluginInteraction {
player.getDialogueInterpreter().sendDialogues(228, FacialExpression.NEUTRAL, "I think you will find that is my spot.");
return true;
}
}, "movement");
},PulseType.STANDARD);
return true;
} else if(npc_loc.equals(Location.create(2627,3415,0))) {
player.getPulseManager().run(new MovementPulse(player, npc.getLocation().transform(1, 0, 0)) {
@ -51,7 +52,7 @@ public class FishingSpotInteraction extends PluginInteraction {
player.getDialogueInterpreter().sendDialogues(228, FacialExpression.NEUTRAL, "I think you will find that is my spot.");
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
}
}

View file

@ -3,6 +3,7 @@ package core.game.content.quest.members.fishingcontest;
import core.game.interaction.MovementPulse;
import core.game.interaction.NodeUsageEvent;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.game.node.scenery.Scenery;
@ -39,7 +40,7 @@ public class GarlicPipeInteraction extends PluginInteraction {
player.setAttribute("fishing_contest:garlic",true);
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
}
}
@ -57,7 +58,7 @@ public class GarlicPipeInteraction extends PluginInteraction {
player.getDialogueInterpreter().sendDialogue("This is the pipe I stuffed that garlic into.");
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
}
}

View file

@ -2,6 +2,7 @@ package core.game.content.quest.members.fishingcontest;
import core.game.interaction.MovementPulse;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.Player;
import core.game.world.map.Location;
import core.plugin.Initializable;
@ -37,7 +38,7 @@ public class GateInteraction extends PluginInteraction {
}
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
} else {
if(!player.getInventory().containsItem(FishingContest.FISHING_ROD)){
@ -55,7 +56,7 @@ public class GateInteraction extends PluginInteraction {
player.getDialogueInterpreter().sendDialogue("This gate is locked.");
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
}
return false;

View file

@ -2,6 +2,7 @@ package core.game.content.quest.members.fishingcontest;
import core.game.interaction.MovementPulse;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.scenery.Scenery;
@ -35,7 +36,7 @@ public class StairInteraction extends PluginInteraction {
player.getDialogueInterpreter().open(npc_id,new NPC(npc_id));
return true;
}
}, "movement");
}, PulseType.STANDARD);
}
@Override

View file

@ -2,6 +2,7 @@ package core.game.content.quest.members.fishingcontest;
import core.game.interaction.MovementPulse;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.Player;
import core.game.node.scenery.Scenery;
import core.game.world.update.flag.context.Animation;
@ -36,7 +37,7 @@ public class VineInteraction extends PluginInteraction {
}
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
}
}

View file

@ -3,6 +3,7 @@ package core.game.content.quest.members.sheepherder;
import core.game.interaction.DestinationFlag;
import core.game.interaction.MovementPulse;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.Player;
import rs09.game.system.SystemLogger;
import core.plugin.Initializable;
@ -40,7 +41,7 @@ public class GateInteractionHandler extends PluginInteraction {
player.getDialogueInterpreter().sendDialogues(SheepHerder.FARMER_BRUMTY, FacialExpression.SUSPICIOUS, "You can't enter without your protective gear!", "Can't have you spreading the plague!");
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
}
return false;

View file

@ -4,6 +4,7 @@ import core.game.interaction.DestinationFlag;
import core.game.interaction.MovementPulse;
import core.game.interaction.Option;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import rs09.game.system.SystemLogger;
@ -30,7 +31,7 @@ public class ProdActionHandler extends PluginInteraction {
handleProd(player,n);
return true;
}
}, "movement");
}, PulseType.STANDARD);
return true;
}
return false;

View file

@ -2,6 +2,7 @@ package core.game.content.quest.members.witchshouse;
import core.game.interaction.MovementPulse;
import core.game.interaction.Option;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.game.world.map.Location;
@ -35,7 +36,7 @@ public class BallInteraction extends PluginInteraction {
public boolean pulse() {
return true;
}
}, "movement");
}, PulseType.STANDARD);
handleBall(player);
}
return handled;

View file

@ -3,6 +3,7 @@ package core.game.interaction;
import api.events.InteractionEvent;
import core.game.container.Container;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
@ -70,18 +71,17 @@ public class Interaction {
}
player.debug("Received interaction request " + option.getName());
boolean hasHandler = option.getHandler() != null;
String pulseType = "interaction:" + option.getName() + ":" + node.hashCode();
boolean walk = hasHandler && option.getHandler().isWalk();
if (!walk && hasHandler && option.getHandler().isWalk(player, node)) {
walk = true;
}
if (!hasHandler || walk) {
handleWalkOption(player, option, pulseType);
handleWalkOption(player, option, PulseType.STANDARD);
} else if (hasHandler) {
player.debug("Option handler being used=" + option.getHandler().getClass().getSimpleName());
handleDefaultOption(player, option, pulseType);
handleDefaultOption(player, option, PulseType.STANDARD);
} else {
player.getPulseManager().runUnhandledAction(player, pulseType);
player.getPulseManager().runUnhandledAction(player, PulseType.STANDARD);
}
player.dispatch(new InteractionEvent(node, option.getName().toLowerCase()));
} catch (Exception e){
@ -100,7 +100,7 @@ public class Interaction {
if (player.getLocks().isInteractionLocked()) {
return;
}
player.getPulseManager().clear("interaction:" + option.getName() + ":" + node.hashCode());
player.getPulseManager().clear(PulseType.STANDARD);
GameWorld.getPulser().submit(new Pulse(1, player) {
@Override
public boolean pulse() {
@ -154,9 +154,9 @@ public class Interaction {
}
return true;
}
}, "interaction:invalid:" + node.hashCode());
}, PulseType.STANDARD);
} else {
player.getPulseManager().runUnhandledAction(player, "interaction:invalid:" + node.hashCode());
player.getPulseManager().runUnhandledAction(player, PulseType.STANDARD);
}
}
@ -166,7 +166,7 @@ public class Interaction {
* @param option The option.
* @param pulseType The pulse type.
*/
private void handleWalkOption(final Player player, final Option option, String pulseType) {
private void handleWalkOption(final Player player, final Option option, PulseType pulseType) {
if (node.getLocation() == null) {
player.getPulseManager().runUnhandledAction(player, pulseType);
return;
@ -201,7 +201,7 @@ public class Interaction {
* @param option The option.
* @param pulseType The pulse type.
*/
private void handleDefaultOption(final Player player, final Option option, String pulseType) {
private void handleDefaultOption(final Player player, final Option option, PulseType pulseType) {
if (!option.getHandler().isDelayed(player)) {
if (player.getZoneMonitor().interact(node, option)) {
return;

View file

@ -3,6 +3,7 @@ package core.game.interaction;
import api.events.UseWithEvent;
import core.cache.def.impl.SceneryDefinition;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
@ -126,7 +127,7 @@ public abstract class UseWithHandler implements Plugin<Object> {
}
if (handler == null) {
if (n instanceof Item && !(event.getUsed() instanceof Player)) {
event.getPlayer().getPulseManager().runUnhandledAction(event.getPlayer());
event.getPlayer().getPulseManager().runUnhandledAction(event.getPlayer(), PulseType.STANDARD);
} else {
event.getPlayer().getPulseManager().run(new MovementPulse(event.getPlayer(), event.getUsedWith()) {
@Override
@ -135,7 +136,7 @@ public abstract class UseWithHandler implements Plugin<Object> {
event.getPlayer().getPacketDispatch().sendMessage("Nothing interesting happens.");
return true;
}
}, "movement");
}, PulseType.STANDARD);
}
return;
}
@ -164,7 +165,7 @@ public abstract class UseWithHandler implements Plugin<Object> {
}
return true;
}
});
}, PulseType.STANDARD);
return;
}
event.getPlayer().getPulseManager().run(new MovementPulse(event.getPlayer(), event.getUsedWith(), handler.get(0)) {
@ -188,7 +189,7 @@ public abstract class UseWithHandler implements Plugin<Object> {
}
return true;
}
}, "movement");
}, PulseType.STANDARD);
} catch (Exception e){
e.printStackTrace();
}

View file

@ -75,7 +75,6 @@ public final class PortSarimPlugin extends OptionHandler {
if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) != 20) {
player.getPacketDispatch().sendMessage("The goblin is already in prison. You have no reason to attack him.");
} else {
player.getPulseManager().clear("interaction:attack:" + node.hashCode());
player.getProperties().getCombatPulse().attack(node);
}
break;

View file

@ -58,7 +58,6 @@ public final class CanafisWereWolfPlugin extends OptionHandler {
}
});
} else {
player.getPulseManager().clear("interaction:attack:" + node.hashCode());
player.getProperties().getCombatPulse().attack(node);
}
return true;

View file

@ -5,6 +5,7 @@ import core.game.component.Component;
import core.game.interaction.MovementPulse;
import core.game.interaction.OptionHandler;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.Player;
import core.game.node.scenery.Scenery;
import core.plugin.Initializable;
@ -37,7 +38,7 @@ public final class WildernessDitchPlugin extends OptionHandler {
handleDitch(player, node);
return true;
}
}, "movement");
}, PulseType.STANDARD);
}
return true;
}

View file

@ -5,6 +5,7 @@ import core.game.interaction.MovementPulse;
import core.game.interaction.Option;
import core.game.interaction.OptionHandler;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.Player;
import core.plugin.Initializable;
import core.plugin.Plugin;
@ -38,7 +39,7 @@ public final class FollowOptionPlugin extends OptionHandler {
super.stop();
mover.face(null);
}
}, "movement");
}, PulseType.STANDARD);
return true;
}
}

View file

@ -358,7 +358,6 @@ public abstract class Entity extends Node {
* @param node the node.
*/
public void attack(final Node node) {
getPulseManager().clear("interaction:attack:" + node.hashCode());
getProperties().getCombatPulse().attack(node);
}

View file

@ -6,6 +6,7 @@ import core.game.container.ContainerType;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.impl.Animator;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.IronmanMode;
@ -152,13 +153,11 @@ public final class DeathTask extends NodeTask {
@SuppressWarnings("deprecation")
public static void startDeath(Entity entity, Entity killer) {
if (!isDead(entity)) {
entity.getPulseManager().clear();
if (killer == null) {
killer = entity;
}
Pulse pulse = SINGLETON.schedule(entity, killer);
pulse.start();
entity.getPulseManager().set(pulse);
entity.getPulseManager().run(pulse, PulseType.STRONG);
}
}

View file

@ -8,6 +8,9 @@ import core.game.system.task.Pulse;
import rs09.game.node.entity.combat.CombatPulse;
import rs09.game.world.GameWorld;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Represents an entity's pulse manager.
* @author Emperor
@ -17,47 +20,61 @@ public final class PulseManager {
/**
* The movement pulse.
*/
private Pulse current;
private final HashMap<PulseType, Pulse> currentPulses = new HashMap<>();
public void run(Pulse pulse) {
run(pulse, PulseType.STANDARD);
}
/**
* Runs a pulse.
* @param pulse The pulse.
* @param pulseType The pulse type we're trying to run.
*/
public void run(Pulse pulse, String... pulseType) {
run(pulse, false, pulseType);
}
public void run(Pulse pulse, PulseType pulseType) {
ArrayList<PulseType> toRemove = new ArrayList<>(currentPulses.size());
currentPulses.forEach((key, value) -> {
if (value != null && !value.isRunning()) {
toRemove.add(key);
}
});
for (PulseType t : toRemove) currentPulses.remove(t);
if (currentPulses.get(PulseType.STRONG) != null) {
//strong pulses cannot be interrupted or ran alongside anything else. They are the ONLY pulse type when they are present.
return;
}
public void run(Pulse pulse, boolean fast, String... pulseType) {
if (!clear(pulseType)) {
return;
}
if (pulseType == PulseType.STRONG) {
clear();
}
currentPulses.put(pulseType, pulse);
pulse.start();
if (pulse.isRunning()) {
if (fast) {
GameWorld.getPulser().submit(current = pulse);
} else {
GameWorld.getPulser().submit(current = pulse);
}
GameWorld.getPulser().submit(pulse);
}
}
public void clear() {
currentPulses.forEach((type, pulse) -> {
if (type != PulseType.STRONG && pulse != null) pulse.stop();
});
}
/**
* Clears the pulses.
*/
public boolean clear(String... pulseType) {
if (current != null && current.isRunning()) {
if (pulseType.length > 0) {
int length = pulseType.length;
for (int i = 0; i < length; i++) {
if (!current.removeFor(pulseType[i])) {
return false;
}
}
} else if (!current.removeFor("unspecified")) {
return false;
}
current.stop();
public boolean clear(PulseType pulseType) {
Pulse pulse = currentPulses.get(pulseType);
if (pulse != null) {
pulse.stop();
currentPulses.remove(pulseType);
}
return true;
}
@ -68,7 +85,7 @@ public final class PulseManager {
* @return The pulse.
* @param pulseType The pulse type.
*/
public Pulse runUnhandledAction(final Player player, String... pulseType) {
public Pulse runUnhandledAction(final Player player, PulseType pulseType) {
Pulse pulse = new Pulse(1, player) {
@Override
public boolean pulse() {
@ -85,13 +102,12 @@ public final class PulseManager {
* @return {@code True} if so.
*/
public boolean isMovingPulse() {
if (current != null && !current.isRunning()) {
if (!hasPulseRunning()) {
return false;
}
if (current instanceof CombatPulse) {
return true;
}
return current instanceof MovementPulse;
Pulse current = getCurrent();
return current instanceof MovementPulse || current instanceof CombatPulse;
}
/**
@ -99,7 +115,7 @@ public final class PulseManager {
* @return {@code True} if so.
*/
public boolean hasPulseRunning() {
return current != null && current.isRunning();
return getCurrent() != null && getCurrent().isRunning();
}
/**
@ -107,20 +123,10 @@ public final class PulseManager {
* @param e The entity.
*/
public static void cancelDeathTask(Entity e) {
if (!DeathTask.isDead(e) || e.getPulseManager().current == null) {
if (!DeathTask.isDead(e) || e.getPulseManager().getCurrent() == null) {
return;
}
e.getPulseManager().current.stop();
}
/**
* Sets the current pulse.
* @deprecated This should only be used by death pulse, use
* {@link #run(Pulse, String...)} instead.
*/
@Deprecated
public void set(Pulse schedule) {
this.current = schedule;
e.getPulseManager().getCurrent().stop();
}
/**
@ -128,6 +134,14 @@ public final class PulseManager {
* @return The current.
*/
public Pulse getCurrent() {
return current;
PulseType[] types = PulseType.values();
for (PulseType type : types) {
if (currentPulses.get(type) != null) {
return currentPulses.get(type);
}
}
return null;
}
}
}

View file

@ -0,0 +1,11 @@
package core.game.node.entity.impl;
//facilitating pseudo-entity-queues in a clean manner with minimal disruption to existing code.
//this is NOT perfect.
//bit shit, really.
public enum PulseType {
STANDARD, //standard pulse slot, should be interrupted/replaced by most things
STRONG, //enforces itself as the only that can run
CUSTOM_1, //custom slots for extra tasks that should run alongside standard tasks.
CUSTOM_2
}

View file

@ -5,6 +5,7 @@ import java.util.List;
import core.game.interaction.DestinationFlag;
import core.game.interaction.MovementPulse;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.AbstractNPC;
import core.game.node.entity.player.Player;
import core.game.world.map.Location;
@ -71,7 +72,7 @@ public class StrayDogNPC extends AbstractNPC {
players = RegionManager.getLocalPlayers(this, 7);
if (players.size() != 0) {
target = players.get(RandomFunction.random(players.size()));
getPulseManager().run(getFollowPulse(target), "movement");
getPulseManager().run(getFollowPulse(target), PulseType.STANDARD);
delay = System.currentTimeMillis() + 150000;
}
}

View file

@ -1,6 +1,8 @@
package core.game.node.entity.skill.agility;
import static api.ContentAPIKt.*;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.link.TeleportManager;
import core.game.node.entity.skill.Skills;
import core.game.interaction.MovementPulse;
@ -267,7 +269,7 @@ public final class AgilityHandler {
walk(player, courseIndex, start, end, animation, experience, message, infiniteRun);
return true;
}
}, "movement");
}, PulseType.STANDARD);
return;
}
player.getWalkingQueue().reset();

View file

@ -1,6 +1,7 @@
package core.game.node.entity.skill.agility.shortcuts;
import core.game.content.activity.ActivityManager;
import core.game.node.entity.impl.PulseType;
import core.plugin.Initializable;
import core.game.node.entity.skill.agility.AgilityShortcut;
import core.game.interaction.MovementPulse;
@ -39,7 +40,7 @@ public class StileShortcut extends AgilityShortcut {
climb(player, object);
return true;
}
}, "movement");
}, PulseType.STANDARD);
}
/**

View file

@ -3,6 +3,7 @@ package core.game.node.entity.skill.construction.npc;
import core.game.content.dialogue.DialoguePlugin;
import core.game.content.dialogue.FacialExpression;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.skill.construction.HouseManager;
import core.game.node.entity.skill.construction.Servant;
@ -172,7 +173,7 @@ public class HouseServantDialogue extends DialoguePlugin {
case 3:
player("Stop following me.");
if (servant.getPulseManager().isMovingPulse()) {
servant.getPulseManager().clear("movement");
servant.getPulseManager().clear(PulseType.STANDARD);
}
stage = 100;
break;
@ -562,6 +563,6 @@ public class HouseServantDialogue extends DialoguePlugin {
public boolean pulse() {
return false;
}
}, "movement");
}, PulseType.STANDARD);
}
}

View file

@ -7,6 +7,7 @@ import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.equipment.WeaponInterface;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.entity.skill.SkillBonus;
@ -517,7 +518,7 @@ public abstract class Familiar extends NPC implements Plugin<Object> {
public boolean pulse() {
return false;
}
}, "movement");
}, PulseType.STANDARD);
face(owner);
}

View file

@ -12,7 +12,7 @@ public abstract class Pulse implements Runnable {
/**
* If the task is still running.
*/
private boolean running = true;
public boolean running = true;
/**
* The amount of game-ticks to wait before execution.

View file

@ -8,6 +8,7 @@ import core.game.interaction.MovementPulse;
import core.game.interaction.Option;
import core.game.interaction.SpecialGroundItems;
import core.game.node.Node;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.item.GroundItem;
@ -243,7 +244,7 @@ public final class InteractionPacket implements IncomingPacket {
player.getDialogueInterpreter().addAction((player1, buttonId) -> player1.teleport(new Location(3140, 4230, 2)));
return true;
}
}, "movement");
}, PulseType.STANDARD);
return;
}
if (objectId == 6898) {

View file

@ -1,5 +1,6 @@
package core.net.packet.in;
import core.game.node.entity.impl.PulseType;
import rs09.ServerConstants;
import core.game.node.entity.skill.magic.MagicSpell;
import core.game.node.entity.skill.summoning.familiar.FamiliarSpecial;
@ -81,7 +82,7 @@ public class InterfaceUseOnPacket implements IncomingPacket {
MagicSpell.castSpell(player, SpellBookManager.SpellBook.MODERN, spell, groundItem);
return true;
}
}, "movement");
}, PulseType.STANDARD);
}
break;
case 195: // Interface On Player

View file

@ -2,6 +2,7 @@ package core.net.packet.in;
import core.game.interaction.MovementPulse;
import core.game.node.entity.Entity;
import core.game.node.entity.impl.PulseType;
import core.game.node.entity.player.Player;
import rs09.game.ai.AIPlayer;
import core.game.world.map.Location;
@ -60,7 +61,7 @@ public final class WalkPacket implements IncomingPacket {
}
return true;
}
}, true, "movement");
}, PulseType.STANDARD);
if (opcode == 39) {
buffer.get(); // The x-coordinate of where we clicked on the
// minimap.

View file

@ -1,5 +1,6 @@
package rs09.game.ai;
import core.game.node.entity.impl.PulseType;
import rs09.ServerConstants;
import core.game.container.impl.EquipmentContainer;
import core.game.interaction.DestinationFlag;
@ -287,7 +288,7 @@ public class AIPlayer extends Player {
face(e);
return false;
}
}, "movement");
}, PulseType.STANDARD);
}
public void randomWalkAroundPoint(Location point, int radius) {

View file

@ -788,7 +788,11 @@ fun <T> setAttribute(entity: Entity, attribute: String, value: T) {
}
fun removeAttribute(entity: Entity, attribute: String) {
entity.removeAttribute(attribute)
entity.removeAttribute(attribute.replace("/save:",""))
}
fun removeAttributes(entity: Entity, vararg attributes: String) {
for (attribute in attributes) removeAttribute(entity, attribute)
}
/**

View file

@ -277,7 +277,7 @@ class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Scr
override fun canSwing(entity: Entity, victim: Entity): InteractionType? {
if(victim is Player || victim.name.contains("revenant", ignoreCase = true)) {
script.state = State.RUNNING
script.bot.pulseManager.current.stop()
script.bot.pulseManager.clear()
}
return super.canSwing(entity, victim)
}

View file

@ -2,6 +2,7 @@ package rs09.game.content.ame
import api.poofClear
import core.game.interaction.MovementPulse
import core.game.node.entity.impl.PulseType
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.item.Item
@ -36,7 +37,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
open fun terminate() {
finalized = true
pulseManager.clear("amemovement")
pulseManager.clear(PulseType.STANDARD)
RandomEventManager.getInstance(player)?.event = null
if (initialized) {
poofClear(this)
@ -49,7 +50,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
face(player)
return false
}
}), "amemovement")
}), PulseType.STANDARD)
}
override fun tick() {

View file

@ -2,6 +2,7 @@ package rs09.game.content.ame.events.certer
import api.addItemOrDrop
import core.game.component.Component
import core.game.node.entity.impl.PulseType
import core.game.node.entity.player.link.emote.Emotes
import rs09.game.content.ame.RandomEventManager
import rs09.game.content.dialogue.DialogueFile
@ -47,7 +48,7 @@ class CerterDialogue(val initial: Boolean) : DialogueFile() {
super.end()
if (player!!.getAttribute("certer:reward", false)) {
// Remove movement pulse to stop following player
npc!!.pulseManager.clear("amemovement")
npc!!.pulseManager.clear(PulseType.STANDARD)
// Wave goodbye
npc!!.animate(Emotes.WAVE.animation)
// Terminate the event

View file

@ -3,6 +3,7 @@ package rs09.game.content.zone.phasmatys.bonegrinder
import api.Container
import api.*
import core.game.content.global.Bones
import core.game.node.entity.impl.PulseType
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
@ -146,7 +147,7 @@ class BoneGrinderListener : InteractionListener {
}
})
} else {
Pulser.submit(fillPulse)
player.pulseManager.run(fillPulse, PulseType.CUSTOM_1)
}
return true
}
@ -162,7 +163,7 @@ class BoneGrinderListener : InteractionListener {
return true
}
Pulser.submit(object : Pulse(){
player.pulseManager.run(object : Pulse(){
var stage = 0
override fun pulse(): Boolean {
when(stage++){
@ -181,7 +182,7 @@ class BoneGrinderListener : InteractionListener {
}
return false
}
})
}, PulseType.CUSTOM_1)
return true
}
@ -199,14 +200,18 @@ class BoneGrinderListener : InteractionListener {
return true
}
fun handleEmpty(player: Player): Boolean{
if(!getAttribute(player,BONE_BIN_KEY,false)){
sendMessage(player,"You have no bonemeal to collect.")
return true
}
fun handleEmpty(player: Player): Boolean {
val inHopper = getAttribute(player, BONE_HOPPER_KEY, false)
val boneType = getAttribute(player, LOADED_BONE_KEY, -1)
val hasMeal = getAttribute(player, BONE_BIN_KEY, false) && boneType != -1
if(getAttribute(player,BONE_HOPPER_KEY,false) && !getAttribute(player,BONE_BIN_KEY,false)){
sendMessage(player,"You need to wind the wheel to grind the bones.")
if(!hasMeal){
if (inHopper)
sendMessage(player,"You need to wind the wheel to grind the bones.")
else if (boneType == -1)
sendMessage(player, "You need to load some bones in the hopper first.")
else
sendMessage(player,"You have no bonemeal to collect.")
return true
}
@ -215,31 +220,29 @@ class BoneGrinderListener : InteractionListener {
return true
}
val bone = Bones.values()[getAttribute(player,LOADED_BONE_KEY,-1)]
val bone = Bones.values()[boneType]
removeAttributes(player, BONE_HOPPER_KEY, BONE_BIN_KEY, LOADED_BONE_KEY)
lock(player, SCOOP_ANIM.duration + 1)
Pulser.submit(object : Pulse(){
player.pulseManager.run(object : Pulse(){
var stage = 0
override fun pulse(): Boolean {
when(stage++){
0 -> {
face(player,Location(3658, 3525, 1))
lock(player, SCOOP_ANIM.duration)
animate(player,SCOOP_ANIM)
}
SCOOP_ANIM.duration -> {
if(removeItem(player,Item(Items.EMPTY_POT_1931),Container.INVENTORY)){
addItem(player,bone.boneMeal.id)
setAttribute(player,BONE_BIN_KEY,false)
setAttribute(player,BONE_HOPPER_KEY,false)
setAttribute(player,LOADED_BONE_KEY,-1)
}
return true
}
}
return false
}
})
}, PulseType.CUSTOM_1)
return true
}

View file

@ -3,6 +3,7 @@ package rs09.game.interaction.item
import api.openDialogue
import api.sendMessage
import core.game.node.Node
import core.game.node.entity.impl.PulseType
import core.game.node.entity.player.Player
import core.game.node.item.Item
import rs09.game.content.dialogue.DialogueFile
@ -29,7 +30,7 @@ class EnchantedJewelleryListener : InteractionListener {
}
}
private fun handle(player: Player, node: Node, isEquipped: Boolean) {
player.pulseManager.current.stop()
player.pulseManager.clear(PulseType.STANDARD)
val item = node.asItem()
val jewellery = EnchantedJewellery.idMap[item.id]
if (jewellery != null) {

View file

@ -29,7 +29,7 @@ class CombatPulse(
/**
* The entity.
*/
private val entity: Entity?) : Pulse(1, entity, null) {
val entity: Entity?) : Pulse(1, entity, null) {
/**
* The victim.
@ -108,6 +108,11 @@ class CombatPulse(
* The last attack recieved.
*/
var lastReceivedAttack = 0
init {
running = false
}
override fun pulse(): Boolean {
if (victim == null || DeathTask.isDead(entity) || DeathTask.isDead(victim)) {
return true
@ -179,7 +184,7 @@ class CombatPulse(
}
}
if (!victim.pulseManager.isMovingPulse) {
victim.pulseManager.clear("combat")
victim.pulseManager.clear()
}
victim.setAttribute("combat-time", System.currentTimeMillis() + 10000)
victim.setAttribute("combat-attacker", entity)
@ -291,7 +296,9 @@ class CombatPulse(
}
setVictim(victim)
entity.onAttack(victim as Entity?)
entity.pulseManager.run(this)
if (!isAttacking)
entity.pulseManager.run(this)
}
/**