Lunar spellbook work + easter event

This commit is contained in:
Ceikry 2021-03-31 21:20:42 -05:00
parent f7a0d2d567
commit d6114292b2
31 changed files with 749 additions and 718 deletions

View file

@ -9,7 +9,6 @@ import org.runite.client.*
import java.awt.event.KeyEvent
import java.text.SimpleDateFormat
import java.util.*
import org.runite.client.TextureOperation12
import java.util.LinkedList
@ -265,7 +264,7 @@ object DeveloperConsole {
" "
)
)
)
).also { println("Playing song ID: $it - ${clientCommand.joinToString("")}") }
)
} else {
args = clientCommand[1].toInt()

View file

@ -1,4 +1,4 @@
revision=530
subrevision=1
port=43593
cachePath=
cachePath=/home/ceik/IdeaProjects/rs09-remake/Server/data/cache

View file

@ -7154,6 +7154,18 @@
"weight": "100.0",
"id": "0",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "3.0",
"id": "6666",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "3.0",
"id": "6665",
"maxAmount": "1"
}
]
},

View file

@ -124686,7 +124686,7 @@
"attack_speed": "4",
"id": "13560",
"absorb": "0,0,0",
"bonuses": "0,0,0,1,0,0,0,0,0,0,0,0,0,1,0",
"bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0",
"equipment_slot": "12"
},
{
@ -124700,7 +124700,7 @@
"attack_speed": "4",
"id": "13561",
"absorb": "0,0,0",
"bonuses": "0,0,0,1,0,0,0,0,0,0,0,0,0,1,0",
"bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0",
"equipment_slot": "12"
},
{
@ -124714,7 +124714,7 @@
"attack_speed": "4",
"id": "13562",
"absorb": "0,0,0",
"bonuses": "0,0,0,1,0,0,0,0,0,0,0,0,0,1,0",
"bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0",
"equipment_slot": "12"
},
{

View file

@ -1247,6 +1247,12 @@
"indexId": "221",
"borders": ""
},
{
"id": "273",
"name": "Easter Jig",
"indexId": "475",
"borders": ""
},
{
"id": "277",
"name": "Haunted Mine",

View file

@ -42,7 +42,7 @@ public final class GnomeStrongholdPlugin extends OptionHandler {
case 9317:
final boolean scale = player.getLocation().getY() <= object.getLocation().getY();
final Location end = object.getLocation().transform(scale ? 3 : -3, scale ? 6 : -6, 0);
if (player.getSkills().hasLevel(Skills.AGILITY, 37)) {
if (!player.getSkills().hasLevel(Skills.AGILITY, 37)) {
player.getPacketDispatch().sendMessage("You must be level 37 agility or higher to climb down the rocks.");
break;
}

View file

@ -94,7 +94,7 @@ public enum CookableItems {
public static HashMap<Integer,CookableItems>cookingMap = new HashMap<>();
public static HashMap<Integer, CookableItems>intentionalBurnMap = new HashMap<>();
public int raw,cooked,level,burnLevel,burnt;
double experience;
public double experience;
double low,high;
CookableItems(int cooked, int raw, int burnt, int level, double experience, int burnLevel, double low, double high){
this.raw = raw;

View file

@ -1,14 +1,11 @@
package core.game.node.entity.skill.magic;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.equipment.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.entity.player.link.TeleportManager.TeleportType;
import core.game.node.entity.player.link.audio.Audio;
import core.game.node.item.Item;
import core.game.world.map.Location;
@ -58,24 +55,6 @@ public final class TeleotherSpells extends MagicSpell {
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
ComponentDefinition.put(326, new ComponentPlugin() {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
if (button == 5) {
player.lock(2);
if (player.getTeleporter().send(player.getAttribute("t-o_location", player.getLocation()), TeleportType.TELE_OTHER)) {
player.visualize(Animation.create(1816), Graphics.create(342));
}
}
player.getInterfaceManager().close();
return true;
}
});
SpellBook.MODERN.register(54, new TeleotherSpells(74, 84, "Lumbridge", Location.create(3222, 3217, 0), Runes.SOUL_RUNE.getItem(1), Runes.LAW_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(1)));
SpellBook.MODERN.register(59, new TeleotherSpells(82, 92, "Falador", Location.create(2965, 3378, 0), Runes.SOUL_RUNE.getItem(1), Runes.LAW_RUNE.getItem(1), Runes.WATER_RUNE.getItem(1)));
SpellBook.MODERN.register(62, new TeleotherSpells(90, 100, "Camelot", Location.create(2758, 3478, 0), Runes.SOUL_RUNE.getItem(2), Runes.LAW_RUNE.getItem(1)));

View file

@ -1,156 +0,0 @@
package core.game.node.entity.skill.magic.lunar;
import core.plugin.Initializable;
import core.game.node.entity.skill.SkillPulse;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.skill.cooking.CookableItems;
import core.game.node.entity.skill.magic.MagicSpell;
import core.game.node.entity.skill.magic.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.equipment.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
/**
* Represents the pie baking lunar spell.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class BakePieSpell extends MagicSpell {
/**
* Represents the animation of the spell.
*/
private static final Animation ANIMATION = Animation.create(4413);
/**
* Represents the graphics to use.
*/
private static final Graphics GRAPHIC = new Graphics(746, (150 << 16));
/**
* Constructs a new {@code BakePieSpell} {@code Object}.
*/
public BakePieSpell() {
super(SpellBook.LUNAR, 65, 60, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 1), new Item(Runes.FIRE_RUNE.getId(), 5), new Item(Runes.WATER_RUNE.getId(), 4) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(15, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
if (!super.meetsRequirements(player, true, false)) {
return false;
}
Item foodItem = target.asItem();
CookableItems food = null;
for (Item item : player.getInventory().toArray()) {
if (item == null) {
continue;
}
if (item.getName().toLowerCase().contains("pie") && item.getName().toLowerCase().contains("uncooked") || item.getName().toLowerCase().contains("raw")) {
food = CookableItems.forId(item.getId());
}
}
if (food == null) {
player.getPacketDispatch().sendMessage("You need a pie in order to cast this spell.");
return false;
}
player.getPulseManager().run(new LunarPiePulse(player, foodItem, food));
return true;
}
/**
* Represents the skill pulse used to cook a pie.
* @author 'Vexia
*/
public final class LunarPiePulse extends SkillPulse<Item> {
//the pie
private CookableItems pie;
/**
* Constructs a new {@code BakePieSpell} {@code Object}.
* @param player the player.
* @param node the node.
*/
public LunarPiePulse(final Player player, final Item node, final CookableItems pie) {
super(player, node);
this.pie = pie;
}
@Override
public boolean checkRequirements() {
if (player.getSkills().getLevel(Skills.COOKING) < pie.level) {
player.getDialogueInterpreter().sendDialogue("You need to have a Cooking level of " + pie.level + " to cook this pie.");
return false;
}
if (!player.getInventory().containsItem(new Item(pie.raw))) {
stop();
return false;
}
return true;
}
@Override
public void animate() {
player.animate(ANIMATION);
player.graphics(GRAPHIC);
}
@Override
public boolean reward() {
if (getDelay() == 1) {
setDelay(5);
return false;
}
if (player.getInventory().remove(new Item(pie.raw)) && meetsRequirements(player, true, true)) {
player.getInventory().add(new Item(pie.cooked));
} else {
return true;
}
return nextPie() == null;
}
@Override
public void stop() {
super.stop();
player.graphics(new Graphics(-1));
}
@Override
public void message(int type) {
}
/**
* Method used to get the next pie.
* @return the pie.
*/
public CookableItems nextPie() {
for (Item item : player.getInventory().toArray()) {
if (item == null) {
continue;
}
if (item.getName().toLowerCase().contains("pie") && item.getName().toLowerCase().contains("uncooked") || item.getName().toLowerCase().contains("raw")) {
if(CookableItems.cookingMap.get(item.getId()) == null){
pie = null;
}
pie = CookableItems.forId(item.getId());
node = item;
}
}
return pie;
}
}
}

View file

@ -1,85 +0,0 @@
package core.game.node.entity.skill.magic.lunar;
import core.plugin.Initializable;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.skill.magic.MagicSpell;
import core.game.node.entity.skill.magic.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.equipment.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.node.object.GameObject;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
import rs09.game.node.entity.skill.farming.FarmingPatch;
import rs09.game.node.entity.skill.farming.Patch;
/**
* Cures a diseased plant.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class CurePlantSpell extends MagicSpell {
/**
* Represents the animation of the spell.
*/
private final static Animation ANIMATION = Animation.create(4409);
/**
* Represents the graphics to use.
*/
private final static Graphics GRAPHIC = new Graphics(742, 100);
/**
* Constructs a new {@code CurePlantSpell} {@code Object}.
*/
public CurePlantSpell() {
super(SpellBook.LUNAR, 66, 60, ANIMATION, GRAPHIC, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 1), new Item(Runes.EARTH_RUNE.getId(), 8) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(32, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
if (!(target instanceof GameObject)) {
return false;
}
final GameObject object = ((GameObject) target);
FarmingPatch fPatch = FarmingPatch.forObject(object);
if(fPatch == null){
player.sendMessage("This spell is for plants... not whatever the heckies that is.");
return false;
}
Patch patch = fPatch.getPatchFor(player);
if(!patch.isDiseased() && !patch.isWeedy()){
player.sendMessage("It seems to be growing fine already, lad.");
return false;
}
if(patch.isWeedy()){
player.sendMessage("Trust me lad, the weeds are healthy enough as is.");
return false;
}
if(patch.isDead()){
player.sendMessage("It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.");
return false;
}
if (!super.meetsRequirements(player, true, true)) {
return false;
}
patch.cureDisease();
player.animate(ANIMATION);
player.graphics(GRAPHIC);
player.getSkills().addExperience(Skills.FARMING, 91.5, true);
return true;
}
}

View file

@ -1,154 +0,0 @@
package core.game.node.entity.skill.magic.lunar;
import core.game.component.Component;
import core.plugin.Initializable;
import core.game.node.entity.skill.magic.MagicSpell;
import core.game.node.entity.skill.magic.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.equipment.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.entity.player.link.TeleportManager.TeleportType;
import core.game.node.item.Item;
import core.game.world.map.Location;
import core.game.world.map.RegionManager;
import core.plugin.Plugin;
/**
* Represents the plugin to handle all teleport spells.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class LunarTeleportPlugin extends MagicSpell {
/**
* Represents the component used for group spells.
*/
private static final Component COMPONENT = new Component(326);
/**
* Represents the location to teleport to.
*/
private Location location;
/**
* Represents if it's a group teleport.
*/
private boolean group;
/**
* Constructs a new {@code LunarTeleportPlugin} {@code Object}.
*/
public LunarTeleportPlugin() {
/**
* empty.
*/
}
/**
* Constructs a new {@code LunarTeleportPlugin} {@code Object}.
* @param level the level.
* @param experience the experience.
* @param items the items.
*/
public LunarTeleportPlugin(final int level, final double experience, final Location location, boolean group, final Item... items) {
super(SpellBook.LUNAR, level, experience, null, null, null, items);
this.location = location;
this.group = group;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = (Player) entity;
if (player.getLocks().isTeleportLocked() || !meetsRequirements(player, true, false)) {
return false;
}
player.getTeleporter().send(location.transform(0, 0, 0), getSpellId() == 16 ? TeleportType.HOME : TeleportType.LUNAR);
if (!meetsRequirements(player, true, true)) {
return false;
}
entity.setAttribute("teleport:items", super.runes);
if (group) {
String destination = "Moonclan Island";
switch (getSpellId()) {
case 34:
destination = "Waterbirth Island";
break;
case 35:
destination = "Barbarian outpost";
break;
case 36:
destination = "Port Khazard";
break;
case 37:
destination = "Fishing guild";
break;
case 38:
destination = "Catherby";
break;
case 39:
destination = "Ice plateau";
break;
}
for (Player p : RegionManager.getLocalPlayers(player, 1)) {
if (p == player) {
continue;
}
if (!p.isActive() || p.getLocks().isTeleportLocked()) {
player.getPacketDispatch().sendMessage("The other player is currently busy.");
continue;
}
if (!p.getSettings().isAcceptAid()) {
player.getPacketDispatch().sendMessage("The player is not accepting any aid.");
continue;
}
visualize(entity, p);
p.setAttribute("t-o_location", location);
p.getPacketDispatch().sendString(player.getUsername(), 326, 1);
p.getPacketDispatch().sendString(destination, 326, 3);
p.getInterfaceManager().open(COMPONENT);
}
}
return true;
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
// home
SpellBook.LUNAR.register(16, new LunarTeleportPlugin(0, 0, Location.create(2100, 3914, 0), false));
// moonclan teleport
SpellBook.LUNAR.register(20, new LunarTeleportPlugin(69, 66, Location.create(2111, 3916, 0), false, new Item(Runes.LAW_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.EARTH_RUNE.getId(), 2)));
// moonclan group teleport
SpellBook.LUNAR.register(33, new LunarTeleportPlugin(70, 67, Location.create(2111, 3916, 0), true, new Item(Runes.LAW_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.EARTH_RUNE.getId(), 4)));
// ourina teleport
SpellBook.LUNAR.register(31, new LunarTeleportPlugin(71, 69, Location.create(2469, 3247, 0), false, new Item(Runes.LAW_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.EARTH_RUNE.getId(), 6)));
// waterbirth teleport
SpellBook.LUNAR.register(24, new LunarTeleportPlugin(72, 71, Location.create(2527, 3739, 0), false, new Item(Runes.LAW_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.WATER_RUNE.getId(), 1)));
// waterbirth group teleport
SpellBook.LUNAR.register(34, new LunarTeleportPlugin(73, 72, Location.create(2527, 3739, 0), true, new Item(Runes.LAW_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.WATER_RUNE.getId(), 5)));
// barbarian post teleport.
SpellBook.LUNAR.register(0, new LunarTeleportPlugin(75, 76, Location.create(2544, 3572, 0), false, new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.FIRE_RUNE.getId(), 3)));
// barbarian group teleport
SpellBook.LUNAR.register(35, new LunarTeleportPlugin(77, 77, Location.create(2544, 3572, 0), true, new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.FIRE_RUNE.getId(), 6)));
// khzard teleport
SpellBook.LUNAR.register(18, new LunarTeleportPlugin(78, 80, Location.create(2656, 3157, 0), false, new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.WATER_RUNE.getId(), 4)));
// khzard group teleport
SpellBook.LUNAR.register(36, new LunarTeleportPlugin(79, 81, Location.create(2656, 3157, 0), true, new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.WATER_RUNE.getId(), 8)));
// fishing guild teleport
SpellBook.LUNAR.register(17, new LunarTeleportPlugin(85, 89, Location.create(2611, 3393, 0), false, new Item(Runes.LAW_RUNE.getId(), 3), new Item(Runes.ASTRAL_RUNE.getId(), 3), new Item(Runes.WATER_RUNE.getId(), 10)));
// fishing guild group teleport
SpellBook.LUNAR.register(37, new LunarTeleportPlugin(86, 90, Location.create(2611, 3393, 0), true, new Item(Runes.LAW_RUNE.getId(), 3), new Item(Runes.ASTRAL_RUNE.getId(), 3), new Item(Runes.WATER_RUNE.getId(), 14)));
// catherby teleport
SpellBook.LUNAR.register(21, new LunarTeleportPlugin(87, 92, Location.create(2804, 3433, 0), false, new Item(Runes.LAW_RUNE.getId(), 3), new Item(Runes.ASTRAL_RUNE.getId(), 3), new Item(Runes.WATER_RUNE.getId(), 10)));
// catherby group teleport
SpellBook.LUNAR.register(38, new LunarTeleportPlugin(88, 93, Location.create(2804, 3433, 0), true, new Item(Runes.LAW_RUNE.getId(), 3), new Item(Runes.ASTRAL_RUNE.getId(), 3), new Item(Runes.WATER_RUNE.getId(), 12)));
// ice plateua teleport
SpellBook.LUNAR.register(28, new LunarTeleportPlugin(89, 96, Location.create(2972, 3873, 0), false, new Item(Runes.LAW_RUNE.getId(), 3), new Item(Runes.ASTRAL_RUNE.getId(), 3), new Item(Runes.WATER_RUNE.getId(), 8)));
// ice plateua group teleport
SpellBook.LUNAR.register(39, new LunarTeleportPlugin(90, 99, Location.create(2972, 3873, 0), true, new Item(Runes.LAW_RUNE.getId(), 3), new Item(Runes.ASTRAL_RUNE.getId(), 3), new Item(Runes.WATER_RUNE.getId(), 16)));
return this;
}
}

View file

@ -1,93 +0,0 @@
package core.game.node.entity.skill.magic.lunar;
import core.game.component.CloseEvent;
import core.game.component.Component;
import core.plugin.Initializable;
import core.game.node.entity.skill.magic.MagicSpell;
import core.game.node.entity.skill.magic.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.equipment.SpellType;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
/**
* Represents the monster examine spell.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class MonsterExamineSpell extends MagicSpell {
/**
* Represents the animation of this spell.
*/
private final static Animation ANIMATION = new Animation(6293);
/**
* Repesents the graphics of this spell.
*/
private static final Graphics GRAPHIC = new Graphics(738, 130);
/**
* Represents the graphics of the eye.
*/
private static final Graphics EYE = new Graphics(1059);
/**
* Represents the animation of the spell.
*/
private static final Component COMPONENT = new Component(522);
/**
* Constructs a new {@code CurePlantSpell} {@code Object}.
*/
public MonsterExamineSpell() {
super(SpellBook.LUNAR, 66, 61, ANIMATION, null, null, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 1), new Item(Runes.MIND_RUNE.getId(), 1) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(6, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
if (!(target instanceof NPC)) {
player.getPacketDispatch().sendMessage("You can only cast this spell on monsters.");
return false;
}
if (!super.meetsRequirements(player, true, true)) {
return false;
}
final NPC npc = ((NPC) target);
player.animate(ANIMATION);
player.face(npc);
player.getAudioManager().send(3621);
;
COMPONENT.setCloseEvent(new CloseEvent() {
@Override
public boolean close(Player player, Component c) {
player.getInterfaceManager().restoreTabs();
return true;
}
});
player.graphics(EYE);
npc.graphics(GRAPHIC);
npc.getSkills().updateCombatLevel();
player.getPacketDispatch().sendString("Monster name: " + npc.getName(), 522, 0);
player.getPacketDispatch().sendString("Combat level: " + npc.getDefinition().getCombatLevel(), 522, 1);
player.getPacketDispatch().sendString("Life points: " + npc.getSkills().getMaximumLifepoints(), 522, 2);
player.getPacketDispatch().sendString("Creature's max hit: " + npc.getSwingHandler(false).calculateHit(npc, npc, 1.0), 522, 3);
player.getPacketDispatch().sendString("", 522, 4);
player.getInterfaceManager().openSingleTab(COMPONENT);
return true;
}
}

View file

@ -1,183 +0,0 @@
package core.game.node.entity.skill.magic.lunar;
import core.game.component.Component;
import core.game.component.ComponentPlugin;
import core.plugin.Initializable;
import core.game.node.entity.skill.magic.MagicSpell;
import core.game.node.entity.skill.magic.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.equipment.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
import core.tools.RandomFunction;
/**
* Represents the npc contact spell.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public class NPContactSpell extends MagicSpell {
/**
* Represents the animation of this graphics.
*/
private static final Animation ANIMATION = new Animation(4413);
/**
* Represents the graphhcics of the spell.
*/
private static final Graphics GRAPHIC = new Graphics(730, 130);
/**
* Constructs a new {@code CurePlantSpell} {@code Object}.
*/
public NPContactSpell() {
super(SpellBook.LUNAR, 67, 63, ANIMATION, GRAPHIC, null, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 1), new Item(Runes.AIR_RUNE.getId(), 2) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(4, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
final Component component = new Component(429);
if (meetsRequirements(player, true, true)) {
player.getInterfaceManager().open(component);
component.setPlugin(new ComponentPlugin() {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
switch (button) {
case 51:
player.getInterfaceManager().close();
break;
default:
NPCContact contact = NPCContact.forId(button);
if (contact == NPCContact.RANDOM) {
contact = NPCContact.values()[RandomFunction.random(NPCContact.values().length)];
}
if (contact == null) {
return true;
}
if (player.getDialogueInterpreter().open(contact.getNpc(), contact.getNpc())) {
player.animate(ANIMATION);
player.graphics(GRAPHIC);
player.getAudioManager().send(3618);
player.getInterfaceManager().close();
} else {
player.getPacketDispatch().sendMessage("This npc is unable to be contacted at this moment.");
}
return true;
}
return true;
}
});
return true;
}
return false;
}
/**
* Represents the npc's to contact.
* @author 'Vexia
*/
public enum NPCContact {
HONEST_JIMM(10, 4362),
BERT_THE_SANDMAN(11, 3108),
ADVISOR_GHRIM(12, 1375),
TURAEL(13, 8273),
LANTHUS(17, 1526),
SUMONA(27, 7780),
MAZCHNA(18, 8274),
DURADEL(23, 8275),
VANNAKA(28, 1597),
MURPHY(30, 466),
CHAELDAR(29, 1598),
CYRISUS(32, 5893),
LARRY(34, 5425),
RANDOM(35, -1);
/**
* Constructs a new {@code NPContactSpell} {@code Object}.
* @param button the button.
* @param npc the npc.
*/
NPCContact(int button, int npc) {
this.button = button;
this.npc = npc;
}
/**
* Represents the button of the npc to contact.
*/
private int button;
/**
* Represents the npc to contact.
*/
private int npc;
/**
* Gets the button.
* @return The button.
*/
public int getButton() {
return button;
}
/**
* Sets the button.
* @param button The button to set.
*/
public void setButton(int button) {
this.button = button;
}
/**
* Gets the npc.
* @return The npc.
*/
public int getNpc() {
return npc;
}
/**
* Sets the npc.
* @param npc The npc to set.
*/
public void setNpc(int npc) {
this.npc = npc;
}
/**
* Gets the npc.
* @param id the id.
* @return the npc contact.
*/
public static NPCContact forId(int id) {
for (NPCContact npc : NPCContact.values()) {
if (npc.getButton() == id) {
return npc;
}
}
return null;
}
}
}

View file

@ -22,6 +22,7 @@ import core.net.packet.context.PlayerContext;
import core.net.packet.out.ClearMinimapFlag;
import rs09.ServerConstants;
import rs09.game.ai.AIPlayer;
import rs09.game.interaction.InteractionListener;
import rs09.game.interaction.InteractionListeners;
import rs09.game.world.repository.Repository;
@ -339,6 +340,9 @@ public final class InteractionPacket implements IncomingPacket {
player.debug("Handled by quest interaction manager.");
return;
}
if(InteractionListeners.run(item.getId(), InteractionListener.Companion.getITEM(),option.getName(),player,item)){
return;
}
item.getInteraction().handle(player, option);
}

View file

@ -51,9 +51,13 @@ public final class WalkPacket implements IncomingPacket {
player.face((Entity) null);
player.faceLocation((Location) null);
//player.getWalkingQueue().reset(running);
player.getPulseManager().run(new MovementPulse(player, Location.create(x, y, player.getLocation().getZ()), running) {
Player finalPlayer = player;
player.getPulseManager().run(new MovementPulse(finalPlayer, Location.create(x, y, player.getLocation().getZ()), running) {
@Override
public boolean pulse() {
if(running){
finalPlayer.getWalkingQueue().setRunning(false);
}
return true;
}
}, true, "movement");

View file

@ -0,0 +1,103 @@
package rs09.game.content.global.worldevents.holiday.easter
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.player.link.emote.Emotes
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import org.rs09.consts.Items
import rs09.game.content.dialogue.DialogueFile
import rs09.game.content.global.worldevents.WorldEvents
import rs09.tools.END_DIALOGUE
class EasterBunnyDialogueFile(val NEED_BASKET : Boolean) : DialogueFile() {
val EGG_ATTRIBUTE = "/save:easter:eggs"
override fun handle(componentID: Int, buttonID: Int) {
if(NEED_BASKET){
when(stage++){
0 -> npc("Hello, adventurer! Thank goodness you're here!")
1 -> player(FacialExpression.THINKING,"Thanks goodness I'M here?")
2 -> npc("Yes, yes, I need your help, you see!")
3 -> npc("I have lost ALL of my eggs. What a terrible thing.")
4 -> npc("Us easter bunnies rely on EGG to live.")
5 -> npc("Take this basket, please, and do me a kindness.")
6 -> player(FacialExpression.THINKING,"What kindness might that be?")
7 -> npc("I need you to try and gather up as many of my","lost eggs as you can.")
8 -> npc("Please, for me? I will reward you for your time.")
9 -> player("Fine, I suppose I will.")
10 -> {
player!!.inventory.add(Item(Items.BASKET_OF_EGGS_4565))
player!!.dialogueInterpreter.sendItemMessage(Items.BASKET_OF_EGGS_4565,"The Easter Bunny gives you a basket.")
stage = END_DIALOGUE
}
}
} else {
when (stage) {
0 -> options("Ask about rewards", "Ask about egg location").also { stage++ }
1 -> when (buttonID) {
1 -> player(FacialExpression.THINKING, "What kind of rewards can I claim?").also { stage = 10 }
2 -> player(FacialExpression.THINKING, "Where were some eggs last seen?").also { stage = 20 }
}
10 -> {
if (!player!!.emoteManager.isUnlocked(Emotes.BUNNY_HOP)) {
options("A credit (5 eggs)", "A Book of Knowledge (20 eggs)", "Bunny Hop Emote (30 eggs)")
} else {
options("A credit (5 eggs)", "A Book of Knowledge (20 eggs)")
}
stage++
}
11 -> {
end()
when (buttonID) {
1 -> {
if (player!!.getAttribute(EGG_ATTRIBUTE, 0) < 5) {
player!!.dialogueInterpreter.sendDialogue("You need 5 eggs to afford that.")
} else {
player!!.incrementAttribute(EGG_ATTRIBUTE, -5)
player!!.details.credits += 1
player!!.dialogueInterpreter.sendDialogue(
"You turn in 5 eggs in exchange for a credit.",
"You now have ${player!!.getAttribute(EGG_ATTRIBUTE, 0)} eggs."
)
}
}
2 -> {
if (player!!.getAttribute(EGG_ATTRIBUTE, 0) < 20) {
player!!.dialogueInterpreter.sendDialogue("You need 20 eggs to afford that.")
} else {
player!!.incrementAttribute(EGG_ATTRIBUTE, -20)
val item = Item(Items.BOOK_OF_KNOWLEDGE_11640)
if (!player!!.inventory.add(item)) {
GroundItemManager.create(item, player)
}
player!!.dialogueInterpreter.sendDialogue("You spend 20 eggs on a Book of Knowledge.")
}
}
3 -> {
if (player!!.getAttribute(EGG_ATTRIBUTE, 0) < 30) {
player!!.dialogueInterpreter.sendDialogue("You need 30 eggs to afford that.")
} else {
player!!.incrementAttribute(EGG_ATTRIBUTE, -30)
player!!.emoteManager.unlock(Emotes.BUNNY_HOP)
player!!.dialogueInterpreter.sendDialogue(
"The Easter Bunny teaches you how to bunny hop in exchange",
"for 30 eggs."
)
}
}
}
}
20 ->{
val event = WorldEvents.get("easter") as EasterEvent
npc("The last known location of some eggs is ${event.recentLoc}.").also { stage = END_DIALOGUE }
}
}
}
}
}

View file

@ -0,0 +1,117 @@
package rs09.game.content.global.worldevents.holiday.easter
import core.game.node.entity.npc.NPC
import core.game.node.item.GroundItem
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.map.Direction
import core.game.world.map.Location
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import rs09.game.content.global.worldevents.WorldEvent
import rs09.game.system.config.GroundSpawnLoader
import rs09.game.world.GameWorld
import rs09.game.world.repository.Repository
import rs09.tools.secondsToTicks
import java.util.*
class EasterEvent : WorldEvent("easter") {
val LUMBRIDGE_SPOTS = arrayOf(Location.create(3190, 3240, 0),
Location.create(3219, 3204, 0),Location.create(3212, 3201, 0),Location.create(3205, 3209, 0),
Location.create(3205, 3217, 0),Location.create(3211, 3213, 0),Location.create(3206, 3229, 0),
Location.create(3212, 3226, 0),Location.create(3212, 3244, 0),Location.create(3202, 3252, 0),
Location.create(3197, 3220, 0),Location.create(3189, 3207, 0),Location.create(3229, 3200, 0),
Location.create(3228, 3205, 0),Location.create(3251, 3212, 0),Location.create(3232, 3237, 0))
val DRAYNOR_SPOTS = arrayOf(Location.create(3085, 3242, 0),Location.create(3083, 3236, 0),Location.create(3093, 3224, 0),
Location.create(3099, 3241, 0),Location.create(3095, 3255, 0),Location.create(3089, 3264, 0),Location.create(3089, 3265, 0),
Location.create(3088, 3268, 0),Location.create(3090, 3274, 0),Location.create(3100, 3281, 0),Location.create(3116, 3265, 0),
Location.create(3123, 3272, 0),Location.create(3079, 3261, 0))
val FALADOR_SPOTS = arrayOf(
Location.create(2961, 3332, 0),Location.create(2967, 3336, 0),Location.create(2974, 3329, 0),
Location.create(2979, 3346, 0),Location.create(2970, 3348, 0),Location.create(2955, 3375, 0),Location.create(2942, 3386, 0),
Location.create(2937, 3385, 0),Location.create(3005, 3370, 0),Location.create(3006, 3383, 0),Location.create(3007, 3387, 0),
Location.create(2985, 3391, 0),Location.create(2984, 3381, 0),Location.create(2980, 3384, 0),Location.create(3025, 3345, 0),
Location.create(3060, 3389, 0),Location.create(3052, 3385, 0))
val EDGEVILLE_SPOTS = arrayOf(Location.create(3077, 3487, 0),Location.create(3082, 3487, 0),
Location.create(3089, 3481, 0),Location.create(3084, 3479, 0),Location.create(3108, 3499, 0),
Location.create(3110, 3517, 0),Location.create(3091, 3512, 0),Location.create(3092, 3507, 0),
Location.create(3081, 3513, 0),Location.create(3079, 3513, 1),Location.create(3080, 3508, 1),
Location.create(3108, 3499, 0),Location.create(3093, 3467, 0))
val TREE_GNOME_STRONGHOLD_SPOTS = arrayOf(
Location.create(2480, 3507, 0),Location.create(2486, 3513, 0),Location.create(2453, 3512, 0),
Location.create(2442, 3484, 0),Location.create(2438, 3486, 0),Location.create(2441, 3506, 0),
Location.create(2471, 3482, 0),Location.create(2482, 3478, 0),Location.create(2480, 3469, 0),
Location.create(2489, 3440, 0),Location.create(2470, 3417, 0),Location.create(2478, 3402, 0),
Location.create(2486, 3407, 0),Location.create(2492, 3404, 0),Location.create(2493, 3413, 0),
Location.create(2446, 3395, 0),Location.create(2422, 3398, 0),Location.create(2421, 3402, 0),Location.create(2418, 3398, 0),
Location.create(2401, 3415, 0),Location.create(2397, 3436, 0),Location.create(2409, 3448, 0),Location.create(2482, 3391, 0))
val locations = arrayOf("Lumbridge","Draynor Village","Falador","Edgeville","Tree Gnome Stronghold")
val spawnedItems = ArrayList<GroundItem>()
val eggs = arrayOf(Items.EASTER_EGG_11027,Items.EASTER_EGG_11028,Items.EASTER_EGG_11029,Items.EASTER_EGG_11030)
var recentLoc = ""
override fun checkActive(): Boolean {
val isApril = Calendar.getInstance().get(Calendar.MONTH) == Calendar.APRIL
val isBefore9th = Calendar.getInstance().get(Calendar.DAY_OF_MONTH) < 9
return (isApril && isBefore9th)
}
override fun initialize() {
super.initialize()
val easterBunny = NPC(NPCs.EASTER_BUNNY_7197)
easterBunny.isNeverWalks = true
easterBunny.direction = Direction.WEST
easterBunny.location = Location.create(3225, 3212, 0)
for(i in 0 until 5){
val bunny = NPC(NPCs.EASTER_BUNNY_3688)
bunny.location = Location.create(3223, 3213, 0)
bunny.isWalks = true
bunny.walkRadius = 4
bunny.init()
}
easterBunny.init()
GameWorld.settings?.message_model = 715
GameWorld.settings?.message_string = "Happy Easter!"
GameWorld.Pulser.submit(object : Pulse(){
override fun pulse(): Boolean {
if(delay == 1){
delay = secondsToTicks(if(GameWorld.settings?.isDevMode == true) 60 else 3600)
}
for(item in spawnedItems){
GroundItemManager.destroy(item)
}
spawnedItems.clear()
val locName = locations.random()
val locs = when(locName){
"Lumbridge" -> LUMBRIDGE_SPOTS
"Draynor Village" -> DRAYNOR_SPOTS
"Falador" -> FALADOR_SPOTS
"Edgeville" -> EDGEVILLE_SPOTS
"Tree Gnome Stronghold" -> TREE_GNOME_STRONGHOLD_SPOTS
else -> LUMBRIDGE_SPOTS
}.toMutableList()
Repository.sendNews("A bunch of eggs have been spotted in $locName!")
recentLoc = locName
val itemLocs = ArrayList<Location>()
for(i in 0 until locs.size / 2){
val loc = locs.random()
locs.remove(loc)
itemLocs.add(loc)
}
for(i in itemLocs){
spawnedItems.add(GroundSpawnLoader.GroundSpawn(-1, Item(eggs.random()),i).init())
}
return false
}
})
}
}

View file

@ -0,0 +1,50 @@
package rs09.game.content.global.worldevents.holiday.easter
import core.game.interaction.DestinationFlag
import core.game.interaction.MovementPulse
import core.game.node.item.GroundItemManager
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import rs09.game.interaction.InteractionListener
class EasterEventListeners : InteractionListener() {
val EGG_ATTRIBUTE = "/save:easter:eggs"
val eggs = intArrayOf(Items.EASTER_EGG_11027, Items.EASTER_EGG_11028, Items.EASTER_EGG_11029, Items.EASTER_EGG_11030)
override fun defineListeners() {
on(eggs,ITEM,"take"){player, node ->
player.pulseManager.run(object : MovementPulse(player,node, DestinationFlag.ITEM){
override fun pulse(): Boolean {
if(player.inventory.contains(Items.BASKET_OF_EGGS_4565,1) || player.equipment.contains(Items.BASKET_OF_EGGS_4565,1)){
val item = GroundItemManager.get(node.id,node.location,null)
GroundItemManager.destroy(item)
player.incrementAttribute(EGG_ATTRIBUTE)
player.sendMessage("You place the egg in the basket. You now have ${player.getAttribute<Int>(EGG_ATTRIBUTE,0)} eggs!")
} else {
player.sendMessage("You need to have your egg basket with you to collect these.")
}
return true
}
})
return@on true
}
on(Items.BASKET_OF_EGGS_4565,ITEM,"operate"){player, node ->
val numEggs = player.getAttribute<Int>(EGG_ATTRIBUTE) ?: 0
player.dialogueInterpreter.sendDialogue("You have $numEggs eggs in the basket.")
return@on true
}
on(NPCs.EASTER_BUNNY_7197,NPC,"talk-to"){player, node ->
val npc = node.asNpc()
npc.faceLocation(player.location)
val NEED_BASKET = !(player!!.inventory.contains(Items.BASKET_OF_EGGS_4565,1) || player!!.equipment.contains(Items.BASKET_OF_EGGS_4565,1) || player!!.bank.contains(Items.BASKET_OF_EGGS_4565,1))
player.dialogueInterpreter.open(EasterBunnyDialogueFile(NEED_BASKET),npc)
return@on true
}
}
}

View file

@ -97,11 +97,11 @@ class KingRoaldAFUDialogue(val questStage: Int) : DialogueFile() {
START_DIALOGUE -> player("I'm happy to report that the beacon network seems to", "be working as expected.").also { stage++ }
1 -> npc("Excellent! I'm delighted to hear it.").also { stage++ }
2 -> player("So, about that reward you promised?").also { stage++ }
4 -> npc("What happened to the days when adventurers felt", "rewarded in full by the knowledge of a job well done?").also { stage++ }
5 -> player("Well before my time, I'm afraid.")
6 -> npc("Hmph. Well, I suppose a king must stick to his word.", "Mind you, let me stress how grateful we are - and how", "grateful we'd be if you could continue helping us test", "the beacons.").also { stage++ }
7 -> npc("There is much more to be done and this is but a", "pittance compared to what I'm willing to offer for", "further assistance!").also { stage = END_DIALOGUE }
END_DIALOGUE -> {
3 -> npc("What happened to the days when adventurers felt", "rewarded in full by the knowledge of a job well done?").also { stage++ }
4 -> player("Well before my time, I'm afraid.").also { stage++ }
5 -> npc("Hmph. Well, I suppose a king must stick to his word.", "Mind you, let me stress how grateful we are - and how", "grateful we'd be if you could continue helping us test", "the beacons.").also { stage++ }
6 -> npc("There is much more to be done and this is but a", "pittance compared to what I'm willing to offer for", "further assistance!").also { stage++ }
7 -> {
end()
player!!.questRepository.getQuest("All Fired Up").finish(player)
}

View file

@ -0,0 +1,85 @@
package rs09.game.interaction.inter
import core.game.node.entity.npc.NPC
import core.tools.RandomFunction
import rs09.game.content.dialogue.DialogueFile
import rs09.game.interaction.InterfaceListener
class NPCContactInterface : InterfaceListener() {
val NPCs = arrayOf(org.rs09.consts.NPCs.HONEST_JIMMY_4362, org.rs09.consts.NPCs.BERT_3108, org.rs09.consts.NPCs.ADVISOR_GHRIM_1375, org.rs09.consts.NPCs.TURAEL_8273, org.rs09.consts.NPCs.LANTHUS_1526, org.rs09.consts.NPCs.SUMONA_7780, org.rs09.consts.NPCs.MAZCHNA_8274, org.rs09.consts.NPCs.DURADEL_8275, org.rs09.consts.NPCs.VANNAKA_1597, org.rs09.consts.NPCs.MURPHY_463, org.rs09.consts.NPCs.CHAELDAR_1598, org.rs09.consts.NPCs.CYRISUS_432, org.rs09.consts.NPCs.LARRY_5424)
val DialogueFiles = arrayOf<DialogueFile?>(
/*TODO("Honest Jimmy"),
TODO("Bert"),
TODO("ADVISOR GHRIM"),
TODO("Turael"),
TODO("LANTHUS"),
TODO("Sumona"),
TODO("Mazchna"),
TODO("Duradel"),
TODO("Vannaka"),
TODO("Murphy"),
TODO("Chaeldar"),
TODO("Cyrisus"),
TODO("Larry")*/
)
val INTER = 429
override fun defineListeners() {
//Remove a bunch of the buttons/heads so that people don't
//waste runes on spells that aren't implemented
//TODO: Re-enable NPCs as their respective content gets added
onOpen(INTER){player, component ->
//Honest Jimmy: Trouble Brewing
player.packetDispatch.sendInterfaceConfig(429,10,true)
player.packetDispatch.sendInterfaceConfig(429,38,true)
//Bert the Sandman: Hand in the Sand quest
player.packetDispatch.sendInterfaceConfig(429,11,true)
player.packetDispatch.sendInterfaceConfig(429,39,true)
//Advisor Ghrim: Kingdoms of Miscellania
player.packetDispatch.sendInterfaceConfig(429,12,true)
player.packetDispatch.sendInterfaceConfig(429,40,true)
//Lanthus: Castle Wars
player.packetDispatch.sendInterfaceConfig(429,17,true)
player.packetDispatch.sendInterfaceConfig(429,43,true)
//Sumona: Completion of Smoking Kills
player.packetDispatch.sendInterfaceConfig(429,27,true)
player.packetDispatch.sendInterfaceConfig(429,42,true)
return@onOpen true
}
on(INTER){player, _, _, buttonID, _, _ ->
var index = when(buttonID){
10,38 -> 0
11,39 -> 1
12,40 -> 2
13,41 -> 3
17,43 -> 4
27,42 -> 5
18,44 -> 6
23,45 -> 7
28,46 -> 8
30,47 -> 9
29,48 -> 10
32,33 -> 11
34,49 -> 12
else -> -1
}
if(index == -1) index = RandomFunction.random(NPCs.size)
val dialogueFile = DialogueFiles.getOrNull(index)
player.getAttribute<() -> Unit>("contact-caller")?.invoke()
player.interfaceManager.close()
if(dialogueFile != null){
player.dialogueInterpreter.open(dialogueFile, NPC(NPCs[index]))
} else {
player.dialogueInterpreter.open(NPCs[index])
}
return@on true
}
}
}

View file

@ -0,0 +1,23 @@
package rs09.game.interaction.inter
import core.game.node.entity.player.link.TeleportManager.TeleportType
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Components
import rs09.game.interaction.InterfaceListener
class TeleotherInterface : InterfaceListener() {
val IFACE = Components.TELEPORT_OTHER_326
override fun defineListeners() {
on(IFACE){player, _, _, button, _, _ ->
if(button == 5){
player.lock(2)
if (player.teleporter.send(player.getAttribute("t-o_location", player.location), TeleportType.TELE_OTHER)) {
player.visualize(Animation.create(1816), Graphics.create(342))
}
}
player.interfaceManager.close()
}
}
}

View file

@ -23,8 +23,10 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
} else if(patch.type == PatchType.HOPS){
harvestAmt = RandomFunction.random(3,35)
} else {
harvestAmt = RandomFunction.random(1,4)
harvestAmt = RandomFunction.random(3,5)
}
if(compost == CompostType.NORMAL) harvestAmt += 1
if(compost == CompostType.SUPER) harvestAmt += 2
}
fun isWeedy(): Boolean {

View file

@ -123,6 +123,9 @@ object UseWithPatchHandler{
override fun pulse(): Boolean {
if(player.inventory.remove(event.usedItem,false)){
p.compost = if(usedItem.id == Items.SUPERCOMPOST_6034) CompostType.SUPER else CompostType.NORMAL
if(p.plantable != null){
p.harvestAmt += if(p.compost == CompostType.NORMAL) 1 else if(p.compost == CompostType.SUPER) 2 else 0
}
player.inventory.add(Item(Items.BUCKET_1925))
}
return true

View file

@ -0,0 +1,255 @@
package rs09.game.node.entity.skill.magic
import core.game.component.Component
import core.game.node.`object`.GameObject
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.node.entity.skill.Skills
import core.game.node.entity.skill.cooking.CookableItems
import core.game.node.item.Item
import core.game.system.task.Pulse
import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Components
import org.rs09.consts.Items
import rs09.game.node.entity.skill.farming.FarmingPatch
import rs09.game.node.entity.skill.magic.spellconsts.Lunar
import rs09.game.system.config.NPCConfigParser
class LunarListeners : SpellListener("lunar") {
val BAKE_PIE_ANIM = Animation(4413)
val BAKE_PIE_GFX = Graphics(746,75)
val STATSPY_ANIM = Animation(6293)
val STATSPY_GFX = Graphics(1059)
val CURE_PLANT_ANIM = Animation(4409)
val CURE_PLANT_GFX = Graphics(742,100)
val NPC_CONTACT_ANIM = Animation(4413)
val NPC_CONTACT_GFX = Graphics(730,130)
override fun defineListeners() {
onCast(Lunar.HOME_TELEPORT,NONE){player, _ ->
requires(player)
sendTeleport(player,0.0, Location.create(2100, 3914, 0))
}
onCast(Lunar.MOONCLAN_TELEPORT,NONE){player, _ ->
requires(player,69, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,1), Item(Items.EARTH_RUNE_557,2)))
sendTeleport(player,66.0, Location.create(2111, 3916, 0))
}
onCast(Lunar.MOONCLAN_GR_TELEPORT,NONE){player, _ ->
requires(player,70, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,1), Item(Items.EARTH_RUNE_557,4)))
sendGroupTeleport(player,67.0,"Moonclan Island",Location.create(2111, 3916, 0))
}
onCast(Lunar.OURANIA_TELEPORT,NONE){player,_ ->
requires(player,71, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,1), Item(Items.EARTH_RUNE_557,6)))
sendTeleport(player,69.0, Location.create(2469, 3247, 0))
}
onCast(Lunar.WATERBIRTH_TELEPORT,NONE){player, _ ->
requires(player,72, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563), Item(Items.WATER_RUNE_555)))
sendTeleport(player,71.0, Location.create(2527, 3739, 0))
}
onCast(Lunar.WATERBIRTH_GR_TELEPORT,NONE){player,_ ->
requires(player,73, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563), Item(Items.WATER_RUNE_555,5)))
sendGroupTeleport(player,72.0,"Waterbirth Island", Location.create(2527, 3739, 0))
}
onCast(Lunar.BARBARIAN_TELEPORT,NONE){player,_ ->
requires(player,75, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,2), Item(Items.FIRE_RUNE_554,3)))
sendTeleport(player,76.0, Location.create(2544, 3572, 0))
}
onCast(Lunar.BARBARIAN_GR_TELEPORT,NONE){player,_ ->
requires(player,77, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,2), Item(Items.FIRE_RUNE_554,6)))
sendGroupTeleport(player,77.0,"Barbarian Outpost", Location.create(2544, 3572, 0))
}
onCast(Lunar.KHAZARD_TELEPORT,NONE){player,_ ->
requires(player,78, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,2), Item(Items.WATER_RUNE_555,4)))
sendTeleport(player,80.0, Location.create(2656, 3157, 0))
}
onCast(Lunar.KHAZARD_GR_TELEPORT,NONE){player,_ ->
requires(player,79, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,2), Item(Items.WATER_RUNE_555,8)))
sendGroupTeleport(player,81.0, "Port Khazard", Location.create(2656, 3157, 0))
}
onCast(Lunar.FISHING_GUILD_TELEPORT,NONE){player,_ ->
requires(player,85, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,10)))
sendTeleport(player,89.0, Location.create(2611, 3393, 0))
}
onCast(Lunar.FISHING_GUILD_GR_TELEPORT,NONE){player,_ ->
requires(player,86, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,14)))
sendGroupTeleport(player,90.0,"Fishing Guild", Location.create(2611, 3393, 0))
}
onCast(Lunar.CATHERBY_TELEPORT,NONE){player,_ ->
requires(player,87, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,10)))
sendTeleport(player,92.0, Location.create(2804, 3433, 0))
}
onCast(Lunar.CATHERBY_GR_TELEPORT,NONE){player,_ ->
requires(player,88, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,15)))
sendGroupTeleport(player,93.0,"Catherby", Location.create(2804, 3433, 0))
}
onCast(Lunar.ICE_PLATEAU_TELEPORT,NONE){player,_ ->
requires(player,89, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,8)))
sendTeleport(player,96.0, Location.create(2972, 3873, 0))
}
onCast(Lunar.ICE_PLATEAU_GR_TELEPORT,NONE){player,_ ->
requires(player,90, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,16)))
sendGroupTeleport(player,99.0, "Ice Plateau", Location.create(2972, 3873, 0))
}
onCast(Lunar.BAKE_PIE,NONE){player,_ ->
requires(player,65, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.FIRE_RUNE_554,5), Item(Items.WATER_RUNE_555,4)))
bakePie(player)
}
onCast(Lunar.MONSTER_EXAMINE,NPC){player,node ->
requires(player,66, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.MIND_RUNE_558), Item(Items.COSMIC_RUNE_564)))
examineMonster(player,node!!.asNpc())
}
onCast(Lunar.CURE_PLANT,OBJECT){player,node ->
requires(player,66, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.EARTH_RUNE_557,8)))
curePlant(player,node!!.asObject())
}
onCast(Lunar.NPC_CONTACT,NONE){player,node ->
requires(player,67, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.COSMIC_RUNE_564), Item(Items.AIR_RUNE_556,2)))
player.interfaceManager.open(Component(429))
player.setAttribute("contact-caller"){
removeRunes(player)
addXP(player,63.0)
setDelay(player,false)
visualizeSpell(player,NPC_CONTACT_ANIM,NPC_CONTACT_GFX)
}
}
}
fun curePlant(player: Player, obj: GameObject){
val fPatch = FarmingPatch.forObject(obj)
if(fPatch == null){
player.sendMessage("You attempt to cast Cure Plant on ${obj.definition.name}!")
player.sendMessage("It's not very effective....")
return
}
val patch = fPatch.getPatchFor(player)
if(!patch.isDiseased && !patch.isWeedy()){
player.sendMessage("This patch is already growing fine.")
return
}
if(patch.isWeedy()){
player.sendMessage("Trust me lad, the weeds are healthy enough as is.")
return
}
if(patch.isDead){
player.sendMessage("It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.")
return
}
patch.cureDisease()
removeRunes(player)
addXP(player,60.0)
visualizeSpell(player,CURE_PLANT_ANIM,CURE_PLANT_GFX)
setDelay(player,false)
}
fun examineMonster(player: Player, npc: NPC){
if(!npc.location.withinDistance(player.location)){
player.sendMessage("You must get closer to use this spell.")
return
}
player.faceLocation(npc.location)
visualizeSpell(player,STATSPY_ANIM,STATSPY_GFX)
removeRunes(player)
addXP(player,66.0)
setDelay(player,false)
player.interfaceManager.openSingleTab(Component(Components.DREAM_MONSTER_STAT_522))
player.packetDispatch.sendString("Monster name : " + npc.definition.name,Components.DREAM_MONSTER_STAT_522,0)
player.packetDispatch.sendString("Combat Level : ${npc.definition.combatLevel}",Components.DREAM_MONSTER_STAT_522,1)
player.packetDispatch.sendString("Hitpoints : ${npc.definition.handlers.get(NPCConfigParser.LIFEPOINTS) ?: 0}",Components.DREAM_MONSTER_STAT_522,2)
player.packetDispatch.sendString("Max hit : ${npc.getSwingHandler(false).calculateHit(npc,player,1.0)}",Components.DREAM_MONSTER_STAT_522,3)
val poisonStatus = if(npc.definition.handlers.getOrDefault(NPCConfigParser.POISON_IMMUNE,false) == true){
"This creature is immune to poison."
} else "This creature is not immune to poison."
player.packetDispatch.sendString(poisonStatus,Components.DREAM_MONSTER_STAT_522,4)
}
fun bakePie(player: Player){
val playerPies = ArrayList<Item>()
for(item in player.inventory.toArray()){
if(item == null) continue
val pie = CookableItems.forId(item.id) ?: continue
if(!pie.name.toLowerCase().contains("pie")) continue
if(player.skills.getLevel(Skills.COOKING) < pie.level) continue
playerPies.add(item)
}
if(playerPies.isEmpty()){
player.sendMessage("You have no pies which you have the level to cook.")
return
}
player.pulseManager.run(object : Pulse(){
var counter = 0
override fun pulse(): Boolean {
if(playerPies.isEmpty()) return true
if(counter == 0) delay = BAKE_PIE_ANIM.definition.durationTicks + 1
val item = playerPies.get(0)
val pie = CookableItems.forId(item.id)
player.visualize(BAKE_PIE_ANIM,BAKE_PIE_GFX)
addXP(player,60.0)
player.skills.addExperience(Skills.COOKING,pie.experience)
setDelay(player,false)
player.inventory.remove(item)
player.inventory.add(Item(pie.cooked))
playerPies.remove(item)
if(playerPies.isNotEmpty()) removeRunes(player,false) else removeRunes(player,true)
return false
}
})
}
fun sendTeleport(player: Player, xp: Double, loc: Location){
if(player.locks.isTeleportLocked){
player.sendMessage("A magical force prevents you from teleporting.")
return
}
player.teleporter.send(loc,TeleportManager.TeleportType.LUNAR)
addXP(player,xp)
removeRunes(player)
setDelay(player,true)
}
fun sendGroupTeleport(player: Player,xp: Double,destName: String,loc: Location){
RegionManager.getLocalPlayers(player,1).forEach {
if(it == player) return@forEach
if(it.locks.isTeleportLocked) return@forEach
if(!it.isActive) return@forEach
if(!it.settings.isAcceptAid) return@forEach
if(it.ironmanManager.isIronman) return@forEach
it.setAttribute("t-o_location",loc)
it.interfaceManager.open(Component(Components.TELEPORT_OTHER_326))
it.packetDispatch.sendString(player.username,Components.TELEPORT_OTHER_326,1)
it.packetDispatch.sendString(destName,Components.TELEPORT_OTHER_326,3)
}
sendTeleport(player,xp,loc)
}
}

View file

@ -243,6 +243,10 @@ class ModernListeners : SpellListener("modern"){
}
private fun sendTeleport(player: Player, xp: Double, location: Location){
if(player.locks.isTeleportLocked){
player.sendMessage("A magical force prevents you from teleporting.")
return
}
player.teleporter.send(location,TeleportManager.TeleportType.NORMAL)
removeRunes(player)
addXP(player,xp)
@ -250,6 +254,10 @@ class ModernListeners : SpellListener("modern"){
}
private fun attemptHouseTeleport(player: Player){
if(player.locks.isTeleportLocked){
player.sendMessage("A magical force prevents you from teleporting.")
return
}
val loc = player.houseManager.location.exitLocation
if(loc == null){
player.sendMessage("You do not have a house whose portal you can teleport to.")

View file

@ -58,10 +58,12 @@ abstract class SpellListener(val bookName: String) : Listener {
}
}
fun removeRunes(player: Player){
fun removeRunes(player: Player,removeAttr: Boolean = true){
player.inventory.remove(*player.getAttribute("spell:runes",ArrayList<Item>()).toTypedArray())
player.removeAttribute("spell:runes")
player.removeAttribute("tablet-spell")
if(removeAttr) {
player.removeAttribute("spell:runes")
player.removeAttribute("tablet-spell")
}
}
fun addXP(player: Player,amount:Double){

View file

@ -0,0 +1,24 @@
package rs09.game.node.entity.skill.magic.spellconsts
object Lunar {
const val BARBARIAN_TELEPORT = 0
const val NPC_CONTACT = 4
const val MONSTER_EXAMINE = 6
const val BAKE_PIE = 15
const val HOME_TELEPORT = 16
const val FISHING_GUILD_TELEPORT = 17
const val KHAZARD_TELEPORT = 18
const val MOONCLAN_TELEPORT = 20
const val CATHERBY_TELEPORT = 21
const val WATERBIRTH_TELEPORT = 24
const val ICE_PLATEAU_TELEPORT = 28
const val OURANIA_TELEPORT = 31
const val CURE_PLANT = 32
const val MOONCLAN_GR_TELEPORT = 33
const val WATERBIRTH_GR_TELEPORT = 34
const val BARBARIAN_GR_TELEPORT = 35
const val KHAZARD_GR_TELEPORT = 36
const val FISHING_GUILD_GR_TELEPORT = 37
const val CATHERBY_GR_TELEPORT = 38
const val ICE_PLATEAU_GR_TELEPORT = 39
}

View file

@ -32,7 +32,7 @@ abstract class CommandSet(val defaultPrivilege: Command.Privilege) : Plugin<Any?
*/
fun reject(player: Player, vararg message: String){
for(msg in message) {
player.sendMessage(colorize("%R$msg"))
player.sendMessage(colorize("-->%R$msg"))
}
throw IllegalStateException()
}

View file

@ -1,6 +1,7 @@
package rs09.game.system.command.sets
import core.cache.def.impl.ItemDefinition
import core.cache.def.impl.NPCDefinition
import core.cache.def.impl.ObjectDefinition
import core.cache.def.impl.VarbitDefinition
import core.game.component.Component
@ -15,6 +16,8 @@ import core.game.world.map.RegionManager
import core.game.world.map.build.DynamicRegion
import core.plugin.Initializable
import core.tools.StringUtils
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.rs09.consts.Components
import rs09.ServerConstants
import rs09.game.content.activity.fishingtrawler.TrawlerLoot
@ -465,5 +468,27 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
define("resetmistag",Command.Privilege.STANDARD){player,_ ->
player.removeAttribute("mistag-greeted")
}
define("getnpcparent"){player,args ->
if(args.size < 2){
reject(player,"Usage: ::getnpcparent npcid")
}
val npcid = args[1].toIntOrNull() ?: reject(player,"Invalid NPC ID.")
GlobalScope.launch {
for(def in NPCDefinition.getDefinitions().values){
def ?: continue
def.childNPCIds ?: continue
for(id in def.childNPCIds){
if(id == npcid){
notify(player,"Parent NPC: ${def.id}")
return@launch
}
}
}
notify(player,"No parent NPC found.")
}
}
}
}

View file

@ -1,17 +1,17 @@
package rs09.game.system.config
import rs09.ServerConstants
import core.game.node.item.GroundItem
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import rs09.game.system.SystemLogger
import core.game.system.task.Pulse
import rs09.game.world.GameWorld
import core.game.world.map.Location
import rs09.game.world.repository.Repository
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser
import rs09.ServerConstants
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
import rs09.game.world.repository.Repository
import java.io.FileReader
import java.nio.ByteBuffer
@ -69,8 +69,8 @@ class GroundSpawnLoader {
/**
* Method used to initialize this spawn.
*/
fun init() {
GroundItemManager.create(this)
fun init(): GroundItem {
return GroundItemManager.create(this)
}
override fun isActive(): Boolean {

View file

@ -12,7 +12,8 @@ import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser
import java.io.FileReader
class NPCConfigParser {
class
NPCConfigParser {
companion object{
const val WEAKNESS = "weakness"