Repository reorganisation

Unified kotlin and java into just src/main
Unified the rs09 and core packages
Took all content out of the core package, and placed it into the new content package
Reorganised all source code relating to content to be easier to find and explore
This commit is contained in:
Ceikry
2023-01-26 13:59:28 +00:00
committed by Ryan
parent e4b799c44a
commit a100affda2
3156 changed files with 24205 additions and 30585 deletions
@@ -0,0 +1,98 @@
package content.global.skill.magic
import core.api.setAttribute
import core.cache.def.impl.ItemDefinition
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.game.node.item.Item
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import core.game.interaction.Listener
import core.game.world.GameWorld
abstract class SpellListener(val bookName: String) : Listener {
companion object {
@JvmField
val NPC = -1
@JvmField
val OBJECT = -2
@JvmField
val ITEM = -3
@JvmField
val PLAYER = -4
@JvmField
val NONE = -5
@JvmField
val GROUND_ITEM = -6
}
fun onCast(spellID: Int,type: Int,method: (player: Player, node: Node?) -> Unit){
SpellListeners.add(spellID,type,bookName,method)
}
fun onCast(spellID: Int, type: Int, vararg ids: Int, method: (player: Player, node: Node?) -> Unit){
SpellListeners.add(spellID,type,ids,bookName,method)
}
fun requires(player: Player, magicLevel: Int = 0, runes: Array<Item> = arrayOf<Item>(), specialEquipment: IntArray = intArrayOf()) {
if(player.getAttribute("magic-delay",0) > GameWorld.ticks){
throw IllegalStateException()
}
if(player.getAttribute("tablet-spell",false)){
return
}
if(player.skills.getLevel(Skills.MAGIC) < magicLevel){
player.sendMessage("You need a magic level of $magicLevel to cast this spell.")
throw IllegalStateException()
}
for(rune in runes){
if(!SpellUtils.hasRune(player,rune)){
player.sendMessage("You don't have enough ${rune.definition.name.lowercase()}s to cast this spell.")
throw IllegalStateException()
}
}
for(item in specialEquipment){
if(!player.equipment.contains(item,1)){
player.sendMessage("You need a ${ItemDefinition.forId(item).name} to cast this.")
throw IllegalStateException()
}
}
}
fun removeRunes(player: Player,removeAttr: Boolean = true){
player.inventory.remove(*player.getAttribute("spell:runes",ArrayList<Item>()).toTypedArray())
if(removeAttr) {
player.removeAttribute("spell:runes")
player.removeAttribute("tablet-spell")
}
}
fun addXP(player: Player,amount:Double){
if(player.getAttribute("tablet-spell",false)) return
player.skills.addExperience(Skills.MAGIC,amount)
}
fun visualizeSpell(player: Player,anim:Animation,gfx: Graphics,soundID: Int = -1){
if(player.getAttribute("tablet-spell",false)) return
player.visualize(anim,gfx)
if(soundID != -1){
player.audioManager.send(soundID)
}
}
fun setDelay(player: Player, isTeleport: Boolean = false){
if(!isTeleport) player.setAttribute("magic-delay", GameWorld.ticks + 3) else player.setAttribute("magic-delay", GameWorld.ticks + 5)
}
fun setDelay(player: Player, delay: Int) {
setAttribute(player, "magic-delay", GameWorld.ticks + delay)
}
fun interrupt(player: Player){
player.pulseManager.clear()
}
fun showMagicTab(player: Player){
player.interfaceManager.setViewedTab(6)
}
}
@@ -0,0 +1,40 @@
package content.global.skill.magic
import core.game.node.Node
import core.game.node.entity.player.Player
import core.tools.SystemLogger
object SpellListeners {
val castMap = HashMap<String,(Player, Node?) -> Unit>()
fun add(spellID: Int, type: Int, book: String, method: (Player,Node?) -> Unit){
castMap["$book:$spellID:$type"] = method
}
fun add(spellID: Int, type: Int, ids: IntArray, book: String, method: (Player, Node?) -> Unit){
for(id in ids) {
castMap["$book:$spellID:$type:$id"] = method
}
}
fun get(spellID: Int, type: Int, book: String): ((Player,Node?) -> Unit)?{
SystemLogger.logInfo(this::class.java, "Getting $book:$spellID:$type")
return castMap["$book:$spellID:$type"]
}
fun get(spellID: Int, type: Int, id: Int, book: String): ((Player,Node?) -> Unit)?{
SystemLogger.logInfo(this::class.java, "Getting $book:$spellID:$type:$id")
return castMap["$book:$spellID:$type:$id"]
}
@JvmStatic
fun run(button: Int, type: Int, book: String, player: Player, node: Node? = null){
val method = get(button,type,node?.id ?: 0,book) ?: get(button,type,book) ?: return
try {
method.invoke(player, node)
} catch (e: IllegalStateException){
player.removeAttribute("spell:runes")
return
}
}
}
@@ -0,0 +1,38 @@
package content.global.skill.magic
import content.global.skill.magic.spellconsts.Modern
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.world.update.flag.context.Animation
import org.rs09.consts.Items
import core.game.interaction.InteractionListener
import core.game.interaction.IntType
class SpellTablets : InteractionListener {
val B2P_TABLET = Items.BONES_TO_PEACHES_8015
val B2B_TABLET = Items.BONES_TO_BANANAS_8014
override fun defineListeners() {
on(B2B_TABLET, IntType.ITEM, "break"){ player, node ->
breakTablet(player)
SpellListeners.run(Modern.BONES_TO_BANANAS,SpellListener.NONE,"modern",player)
player.inventory.remove(Item(node.id))
return@on true
}
on(B2P_TABLET, IntType.ITEM, "break"){ player, node ->
breakTablet(player)
SpellListeners.run(Modern.BONES_TO_PEACHES,SpellListener.NONE,"modern",player)
player.inventory.remove(Item(node.id))
return@on true
}
}
fun breakTablet(player: Player){
player.audioManager.send(979)
player.animator.forceAnimation(Animation(4069))
player.lock(5)
player.setAttribute("tablet-spell",true)
}
}
@@ -0,0 +1,98 @@
package content.global.skill.magic
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.combat.spell.CombinationRune
import core.game.node.entity.combat.spell.MagicStaff
import core.game.node.entity.combat.spell.Runes
import core.game.node.item.Item
object SpellUtils {
fun usingStaff(p: Player, rune: Int): Boolean {
val weapon = p.equipment[3] ?: return false
val staff = MagicStaff.forId(rune) ?: return false
val staves = staff.staves
for (id in staves) {
if (weapon.id == id) {
return true
}
}
return false
}
fun hasRune(p:Player,rune:Item):Boolean{
val removeItems = p.getAttribute("spell:runes",ArrayList<Item>())
if(usingStaff(p,rune.id)) return true
if(p.inventory.containsItem(rune)){
removeItems.add(rune)
p.setAttribute("spell:runes",removeItems)
}
val baseAmt = p.inventory.getAmount(rune.id)
var amtRemaining = rune.amount - baseAmt
val possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(rune.id))
for (r in possibleComboRunes) {
if (p.inventory.containsItem(Item(r.id)) && amtRemaining > 0) {
val amt = p.inventory.getAmount(r.id)
if (amtRemaining <= amt) {
removeItems.add(Item(r.id,amtRemaining))
amtRemaining = 0
break
}
removeItems.add(Item(r.id,p.inventory.getAmount(r.id)))
amtRemaining -= p.inventory.getAmount(r.id)
}
}
p.setAttribute("spell:runes",removeItems)
return amtRemaining <= 0
}
fun hasRune(p: Player, item: Item, toRemove: MutableList<Item?>, message: Boolean): Boolean {
if (!usingStaff(p, item.id)) {
val hasBaseRune = p.inventory.contains(item.id, item.amount)
if (!hasBaseRune) {
val baseAmt = p.inventory.getAmount(item.id)
if (baseAmt > 0) {
toRemove.add(Item(item.id, p.inventory.getAmount(item.id)))
}
var amtRemaining = item.amount - baseAmt
val possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(item.id))
for (r in possibleComboRunes) {
if (p.inventory.containsItem(Item(r.id)) && amtRemaining > 0) {
val amt = p.inventory.getAmount(r.id)
if (amtRemaining < amt) {
toRemove.add(Item(r.id, amtRemaining))
amtRemaining = 0
continue
}
amtRemaining -= p.inventory.getAmount(r.id)
toRemove.add(Item(r.id, p.inventory.getAmount(r.id)))
}
}
return if (amtRemaining <= 0) {
true
} else {
p.packetDispatch.sendMessage("You don't have enough " + item.name + "s to cast this spell.")
false
}
}
toRemove.add(item)
return true
}
return true
}
fun attackableNPC(npc: NPC): Boolean{
return npc.definition.hasAction("attack")
}
@JvmStatic
fun getBookFromInterface(id: Int): String{
return when(id){
192 -> "modern"
193 -> "ancient"
430 -> "lunar"
else -> "none"
}
}
}
@@ -0,0 +1,88 @@
package content.global.skill.magic;
import core.game.component.Component;
import core.game.dialogue.DialoguePlugin;
import core.game.node.entity.player.Player;
import core.plugin.Initializable;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
/**
* Handles the SpellbookSwapDialogue dialogue.
* @author Vexia
*
*/
@Initializable
public class SpellbookSwapDialogue extends DialoguePlugin {
/**
* If we're using the perk.
*/
private boolean perk;
/**
* Constructs a new {@Code SpellbookSwapDialogue} {@Code Object}
*/
public SpellbookSwapDialogue() {
/*
* empty.
*/
}
/**
* Constructs a new {@Code SpellbookSwapDialogue} {@Code Object}
* @param player the player.
*/
public SpellbookSwapDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new SpellbookSwapDialogue(player);
}
@Override
public boolean open(Object... args) {
if (args.length > 1) {
perk = true;
interpreter.sendOptions("Select a Spellbook", "Modern", "Ancient", "Lunar");
return true;
}
interpreter.sendOptions("Select a Spellbook", "Ancient", "Modern");
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
if (perk) {
SpellBook book = SpellBook.values()[buttonId - 1];
player.getSpellBookManager().setSpellBook(book);
player.getInterfaceManager().openTab(new Component(book.getInterfaceId()));
end();
return true;
}
int type = 0;
switch (buttonId) {
case 1:
type = 1;
break;
case 2:
type = 2;
break;
}
final SpellBook book = type == 1 ? SpellBook.ANCIENT : SpellBook.MODERN;
player.getSpellBookManager().setSpellBook(book);
player.getInterfaceManager().openTab(new Component(book.getInterfaceId()));
end();
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 3264731 };
}
}
@@ -0,0 +1,7 @@
package content.global.skill.magic
enum class TeleportMethod {
JEWELRY,
SPELL,
NPC
}
@@ -0,0 +1,96 @@
package content.global.skill.magic.ancient;
import core.game.node.entity.player.link.diary.DiaryType;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.SpellType;
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.GameWorld;
import core.game.world.map.Location;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.tools.RandomFunction;
/**
* Represents the plugin used to handle all ancient teleporting plugins.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class AncientTeleportPlugin extends MagicSpell {
/**
* Represents the location to teleport to.
*/
private Location location;
/**
* Constructs a new {@code AncientTeleportPlugin} {@code Object}.
*/
public AncientTeleportPlugin() {
/**
* empty.
*/
}
/**
* Constructs a new {@code AncientTeleportPlugin.java} {@code Object}.
* @param level the level.
* @param experience the experience.
* @param location the location.
* @param items the items.
*/
public AncientTeleportPlugin(final int level, final double experience, final Location location, final Item... items) {
super(SpellBook.ANCIENT, level, experience, null, null, null, items);
this.location = location;
}
@Override
public boolean cast(Entity entity, Node target) {
if (entity.getLocks().isTeleportLocked() || !super.meetsRequirements(entity, true, false)) {
return false;
}
if (entity.getTeleporter().send(location.transform(0, RandomFunction.random(3), 0), getSpellId() == 24 ? TeleportType.HOME : TeleportType.ANCIENT)) {
if (!super.meetsRequirements(entity, true, true)) {
entity.getTeleporter().getCurrentTeleport().stop();
return false;
}
// Use the Home Teleport spell in the Ancient Magicks spellbook<br><br>to teleport to Edgeville
if (entity.isPlayer() && location.equals(Location.create(3087, 3495, 0))) {
entity.asPlayer().getAchievementDiaryManager().finishTask(entity.asPlayer(), DiaryType.VARROCK, 2, 11);
}
entity.setAttribute("teleport:items", super.runes);
entity.setAttribute("magic-delay", GameWorld.getTicks() + 5);
return true;
}
return false;
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
// home
SpellBook.ANCIENT.register(28, new AncientTeleportPlugin(0, 0, Location.create(3087, 3495, 0)));
// paddewwa teleport
SpellBook.ANCIENT.register(20, new AncientTeleportPlugin(54, 64, Location.create(3098, 9882, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.FIRE_RUNE.getId(), 1), new Item(Runes.AIR_RUNE.getId(), 1)));
// sennisten teleport
SpellBook.ANCIENT.register(21, new AncientTeleportPlugin(60, 70, Location.create(3320, 3338, 0), new Item(Runes.SOUL_RUNE.getId(), 1), new Item(Runes.LAW_RUNE.getId(), 2)));
// karyll teleport
SpellBook.ANCIENT.register(22, new AncientTeleportPlugin(66, 76, Location.create(3493, 3472, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.BLOOD_RUNE.getId(), 1)));
// lassar teleport
SpellBook.ANCIENT.register(23, new AncientTeleportPlugin(72, 82, Location.create(3003, 3470, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.WATER_RUNE.getId(), 4)));
// dareeyak teleport
SpellBook.ANCIENT.register(24, new AncientTeleportPlugin(78, 88, Location.create(2966, 3696, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.FIRE_RUNE.getId(), 3), new Item(Runes.AIR_RUNE.getId(), 2)));
// carralangar teleport
SpellBook.ANCIENT.register(25, new AncientTeleportPlugin(84, 82, Location.create(3163, 3664, 0), new Item(Runes.SOUL_RUNE.getId(), 2), new Item(Runes.LAW_RUNE.getId(), 2)));
// annakarl teleport
SpellBook.ANCIENT.register(26, new AncientTeleportPlugin(90, 100, Location.create(3287, 3883, 0), new Item(Runes.BLOOD_RUNE.getId(), 2), new Item(Runes.LAW_RUNE.getId(), 2)));
// ghorrock teleport
SpellBook.ANCIENT.register(27, new AncientTeleportPlugin(96, 106, Location.create(2972, 3873, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.WATER_RUNE.getId(), 8)));
return this;
}
}
@@ -0,0 +1,132 @@
package content.global.skill.magic.ancient;
import java.util.List;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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.Initializable;
import core.plugin.Plugin;
/**
* Handles the Blood spells from the Ancient spellbook.
* @author Emperor
* @version 1.0
*/
@Initializable
public final class BloodSpells extends CombatSpell {
/**
* The projectile for Blood rush.
*/
private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 372, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Blood rush.
*/
private static final Graphics RUSH_END = new Graphics(373, 96);
/**
* The end graphic for Blood burst.
*/
private static final Graphics BURST_END = new Graphics(376, 0);
/**
* The projectile for Blood blitz.
*/
private static final Projectile BLITZ_PROJECTILE = Projectile.create((Entity) null, null, 374, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Blood blitz.
*/
private static final Graphics BLITZ_END = new Graphics(375, 96);
/**
* The end graphic for Blood barrage.
*/
private static final Graphics BARRAGE_END = new Graphics(377, 0);
/**
* Constructs a new {@code BloodSpells} {@code Object}.
*/
public BloodSpells() {
/*
* ( empty.
*/
}
/**
* Constructs a new {@code BloodSpells} {@Code Object}
* @param type The spell type.
* @param impactSound The impact sound id.
* @param anim The animation.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
*/
private BloodSpells(SpellType type, int level, double baseExperience, int sound, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.ANCIENT, level, baseExperience, sound, impactSound, anim, start, projectile, end, runes);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.ANCIENT.register(4, new BloodSpells(SpellType.RUSH, 56, 33.0, -1, -1, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.BLOOD_RUNE.getItem(1), Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2)));
SpellBook.ANCIENT.register(6, new BloodSpells(SpellType.BURST, 68, 39.0, -1, -1, new Animation(1979, Priority.HIGH), null, null, BURST_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4)));
SpellBook.ANCIENT.register(5, new BloodSpells(SpellType.BLITZ, 80, 45.0, -1, -1, new Animation(1978, Priority.HIGH), null, BLITZ_PROJECTILE, BLITZ_END, Runes.BLOOD_RUNE.getItem(4), Runes.DEATH_RUNE.getItem(2)));
SpellBook.ANCIENT.register(7, new BloodSpells(SpellType.BARRAGE, 92, 51.0, -1, -1, new Animation(1979, Priority.HIGH), null, null, BARRAGE_END, Runes.SOUL_RUNE.getItem(1), Runes.BLOOD_RUNE.getItem(4), Runes.DEATH_RUNE.getItem(4)));
return this;
}
@Override
public void visualize(Entity entity, Node target) {
entity.graphics(graphic);
if (projectile != null) {
projectile.transform(entity, (Entity) target, false, 58, 10).send();
}
entity.animate(animation);
sendAudio(entity, getAudio());
}
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if (state.getEstimatedHit() > -1) {
int heal = state.getEstimatedHit() / 4;
if (heal > 0) {
entity.getSkills().heal(heal);
if (entity instanceof Player) {
((Player) entity).getPacketDispatch().sendMessage("You drain some of your opponent's health.");
}
}
}
}
@Override
public BattleState[] getTargets(Entity entity, Entity target) {
if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {
targets[index++] = new BattleState(entity, e);
}
return targets;
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 3);
}
}
@@ -0,0 +1,163 @@
package content.global.skill.magic.ancient;
import java.util.List;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.entity.player.link.audio.Audio;
import core.game.node.entity.state.EntityState;
import core.game.node.item.Item;
import core.game.world.GameWorld;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Handles the Ice spells from the Ancient spellbook.
* @author Emperor
* @version 1.0
*/
@Initializable
public final class IceSpells extends CombatSpell {
/**
* The barrage orb GFX.
*/
private static final Graphics BARRAGE_ORB = new Graphics(1677, 96); //119
/**
* The projectile for Ice rush.
*/
private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 360, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Ice rush.
*/
private static final Graphics RUSH_END = new Graphics(361, 96);
/**
* The projectile for Ice barrage.
*/
private static final Projectile BURST_PROJECTILE = Projectile.create((Entity) null, null, 362, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Ice barrage.
*/
private static final Graphics BURST_END = new Graphics(363, 0);
/**
* The start graphic for Ice rush.
*/
private static final Graphics BLITZ_START = new Graphics(366, 96);
/**
* The end graphic for Ice rush.
*/
private static final Graphics BLITZ_END = new Graphics(367, 96);
/**
* The projectile for Ice barrage.
*/
private static final Projectile BARRAGE_PROJECTILE = Projectile.create((Entity) null, null, 368, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Ice barrage.
*/
private static final Graphics BARRAGE_END = new Graphics(369, 0);
/**
* Constructs a new {@code IceSpells} {@code Object}.
*/
public IceSpells() {
/*
* empty.
*/
}
/**
* Constructs a new {@code IceSpells} {@Code Object}
* @param type The spell type.
* @param impactSound The impact sound id.
* @param anim The animation.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
*/
private IceSpells(SpellType type, int level, double baseExperience, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.ANCIENT, level, baseExperience, 171, impactSound, anim, start, projectile, end, runes);
}
@Override
public void visualize(Entity entity, Node target) {
entity.graphics(graphic);
if (projectile != null) {
projectile.transform(entity, (Entity) target, false, 58, 10).send();
}
entity.animate(animation);
sendAudio(entity, audio);
}
@Override
public void visualizeImpact(Entity entity, Entity target, BattleState state) {
if (state.isFrozen()) {
if (target == entity.getProperties().getCombatPulse().getVictim()) {
sendAudio(target, new Audio(impactAudio, 1, 20));
}
target.graphics(BARRAGE_ORB);
return;
}
super.visualizeImpact(entity, target, state);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.ANCIENT.register(0, new IceSpells(SpellType.RUSH, 58, 34.0, 173, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2), Runes.WATER_RUNE.getItem(2)));
SpellBook.ANCIENT.register(2, new IceSpells(SpellType.BURST, 70, 40.0, 170, new Animation(1979, Priority.HIGH), null, BURST_PROJECTILE, BURST_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4), Runes.WATER_RUNE.getItem(4)));
SpellBook.ANCIENT.register(1, new IceSpells(SpellType.BLITZ, 82, 46.0, 169, new Animation(1978, Priority.HIGH), BLITZ_START, null, BLITZ_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3)));
SpellBook.ANCIENT.register(3, new IceSpells(SpellType.BARRAGE, 94, 52.0, 168, new Animation(1979, Priority.HIGH), null, BARRAGE_PROJECTILE, BARRAGE_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(4), Runes.WATER_RUNE.getItem(6)));
return this;
}
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if (state.getEstimatedHit() == -1) {
return;
}
int ticks = (1 + (type.ordinal() - SpellType.RUSH.ordinal())) * 8;
if (state.getEstimatedHit() > -1) {
if (victim.getAttribute("freeze_immunity", -1) < GameWorld.getTicks()) {
victim.getStateManager().set(EntityState.FROZEN, ticks);
} else if (type == SpellType.BARRAGE) {
state.setFrozen(true);
}
}
}
@Override
public BattleState[] getTargets(Entity entity, Entity target) {
if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {
targets[index++] = new BattleState(entity, e);
}
return targets;
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 4);
}
}
@@ -0,0 +1,180 @@
package content.global.skill.magic.ancient;
import java.util.List;
import core.game.container.impl.EquipmentContainer;
import core.plugin.Initializable;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.entity.state.EntityState;
import core.game.node.item.Item;
import core.game.world.GameWorld;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
/**
* Handles the Miasmic spells that are a part of the Ancient spellbook.
* @author Splinter
* @version 1.0
*/
@Initializable
public final class MiasmicSpells extends CombatSpell {
/**
* The start graphic for Miasmic rush.
*/
private static final Graphics RUSH_START = new Graphics(1845, 0, 15);
/**
* The end graphic for Miasmic rush.
*/
private static final Graphics RUSH_END = new Graphics(1847, 40);
/**
* The start graphic for Miasmic rush.
*/
private static final Graphics BURST_START = new Graphics(1848, 0);
/**
* The end graphic for Miasmic barrage.
*/
private static final Graphics BURST_END = new Graphics(1849, 20, 30);
/**
* The start graphic for Miasmic rush.
*/
private static final Graphics BLITZ_START = new Graphics(1850, 15);
/**
* The end graphic for Miasmic rush.
*/
private static final Graphics BLITZ_END = new Graphics(1851, 0);
/**
* The start graphic for Miasmic rush.
*/
private static final Graphics BARRAGE_START = new Graphics(1853, 0);
/**
* The end graphic for Miasmic barrage.
*/
private static final Graphics BARRAGE_END = new Graphics(1854, 0, 30);
/**
* The item ids of the staves able to cast Miasmic spells.
*/
private static final int[] VALID_STAFF_IDS = { 13867, 13869, 13841, 13843 };
/**
* Constructs a new {@code MiasmicSpells} {@code Object}.
*/
public MiasmicSpells() {
}
/**
* Constructs a new {@code MiasmicSpells} {@Code Object}
* @param type The spell type.
* @param impactSound The impact sound id.
* @param anim The animation.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
*/
private MiasmicSpells(SpellType type, int level, double baseExperience, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.ANCIENT, level, baseExperience, 171, impactSound, anim, start, projectile, end, runes);
}
@Override
public void visualize(Entity entity, Node target) {
entity.graphics(graphic);
if (projectile != null) {
projectile.transform(entity, (Entity) target, false, 58, 10).send();
}
entity.animate(animation);
sendAudio(entity, audio);
}
@Override
public void visualizeImpact(Entity entity, Entity target, BattleState state) {
super.visualizeImpact(entity, target, state);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.ANCIENT.register(16, new MiasmicSpells(SpellType.RUSH, 61, 36.0, 173, new Animation(10513, Priority.HIGH), RUSH_START, null, RUSH_END, Runes.EARTH_RUNE.getItem(1), Runes.SOUL_RUNE.getItem(1), Runes.CHAOS_RUNE.getItem(2)));
SpellBook.ANCIENT.register(17, new MiasmicSpells(SpellType.BURST, 73, 42.0, 170, new Animation(10516, Priority.HIGH), BURST_START, null, BURST_END, Runes.EARTH_RUNE.getItem(3), Runes.SOUL_RUNE.getItem(3), Runes.CHAOS_RUNE.getItem(4)));
SpellBook.ANCIENT.register(18, new MiasmicSpells(SpellType.BLITZ, 85, 48.0, 169, new Animation(10524, Priority.HIGH), BLITZ_START, null, BLITZ_END, Runes.EARTH_RUNE.getItem(3), Runes.SOUL_RUNE.getItem(3), Runes.BLOOD_RUNE.getItem(2)));
SpellBook.ANCIENT.register(19, new MiasmicSpells(SpellType.BARRAGE, 97, 54.0, 168, new Animation(10518, Priority.HIGH), BARRAGE_START, null, BARRAGE_END, Runes.EARTH_RUNE.getItem(4), Runes.SOUL_RUNE.getItem(4), Runes.BLOOD_RUNE.getItem(4)));
return this;
}
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if (victim.getAttribute("miasmic_immunity", -1) < GameWorld.getTicks()) {
victim.getStateManager().register(EntityState.MIASMIC, true, (getSpellId() - 15) * 20);
}
}
/**
* Checks if a valid staff is equipped.
* @param entity The attacking entity.
* @return {@code True} if so.
*/
public boolean validStaffEquipped(Entity entity){
for(int i = 0; i < VALID_STAFF_IDS.length; i++){
if(((Player) entity).getEquipment().getNew(EquipmentContainer.SLOT_WEAPON).getId() == VALID_STAFF_IDS[i]){
return true;
}
}
return false;
}
@Override
public boolean cast(Entity entity, Node target) {
if (!validStaffEquipped(entity) && !GameWorld.getSettings().isDevMode()) {
((Player) entity).getPacketDispatch().sendMessage("You need to be wielding Zuriel's staff in order to cast this spell.");
return false;
}
if (!meetsRequirements(entity, true, false)) {
return false;
}
return super.cast(entity, target);
}
@Override
public BattleState[] getTargets(Entity entity, Entity target) {
if (animation.getId() == 10513 || animation.getId() == 10524
|| !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {
targets[index++] = new BattleState(entity, e);
}
return targets;
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
int add = 9;
if(animation.getId() == 10524 || animation.getId() == 10516){
add = 6;
}
if(animation.getId() == 10513){
add = 4;
}
return getType().getImpactAmount(entity, victim, add);
}
}
@@ -0,0 +1,128 @@
package content.global.skill.magic.ancient;
import java.util.List;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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.Initializable;
import core.plugin.Plugin;
/**
* Handles the Shadow spells from the Ancient spellbook.
* @author Emperor
*/
@Initializable
public final class ShadowSpells extends CombatSpell {
/**
* The projectile for Shadow rush.
*/
private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 378, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Shadow rush.
*/
private static final Graphics RUSH_END = new Graphics(379, 96);
/**
* The projectile for Shadow burst.
*/
private static final Projectile BURST_PROJECTILE = Projectile.create((Entity) null, null, 380, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Shadow burst.
*/
private static final Graphics BURST_END = new Graphics(381, 0);
/**
* The end graphic for Shadow blitz.
*/
private static final Graphics BLITZ_END = new Graphics(382, 96);
/**
* The end graphic for Shadow barrage.
*/
private static final Graphics BARRAGE_END = new Graphics(383, 0);
/**
* Constructs a new {@code ShadowSpells} {@code Object}.
*/
public ShadowSpells() {
/*
* empty.
*/
}
/**
* Constructs a new {@code ShadowSpells} {@Code Object}
* @param type The spell type.
* @param level The level requirement.
* @param sound The casting sound.
* @param impactSound The impact sound id.
* @param anim The animation.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
*/
private ShadowSpells(SpellType type, int level, double baseExperience, int sound, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.ANCIENT, level, baseExperience, sound, impactSound, anim, start, projectile, end, runes);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.ANCIENT.register(12, new ShadowSpells(SpellType.RUSH, 52, 31.0, 175, 176, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.SOUL_RUNE.getItem(1), Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2), Runes.AIR_RUNE.getItem(1)));
SpellBook.ANCIENT.register(14, new ShadowSpells(SpellType.BURST, 64, 37.0, 177, 178, new Animation(1979, Priority.HIGH), null, BURST_PROJECTILE, BURST_END, Runes.SOUL_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4), Runes.AIR_RUNE.getItem(1)));
SpellBook.ANCIENT.register(13, new ShadowSpells(SpellType.BLITZ, 76, 43.0, 181, 182, new Animation(1978, Priority.HIGH), null, null, BLITZ_END, Runes.SOUL_RUNE.getItem(2), Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2)));
SpellBook.ANCIENT.register(15, new ShadowSpells(SpellType.BARRAGE, 88, 48.0, 181, 185, new Animation(1979, Priority.HIGH), null, null, BARRAGE_END, Runes.SOUL_RUNE.getItem(3), Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(4), Runes.AIR_RUNE.getItem(4)));
return this;
}
@Override
public void visualize(Entity entity, Node target) {
entity.graphics(graphic);
if (projectile != null) {
projectile.transform(entity, (Entity) target, false, 58, 10).send();
}
entity.animate(animation);
sendAudio(entity, audio);
}
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if (state.getEstimatedHit() > -1) {
int level = victim.getSkills().getStaticLevel(Skills.ATTACK);
victim.getSkills().updateLevel(Skills.ATTACK, (int) -(level * 0.1), (int) (level - (level * 0.1)));
}
}
@Override
public BattleState[] getTargets(Entity entity, Entity target) {
if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {
targets[index++] = new BattleState(entity, e);
}
return targets;
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 2);
}
}
@@ -0,0 +1,137 @@
package content.global.skill.magic.ancient;
import java.util.List;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.entity.state.EntityState;
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.Initializable;
import core.plugin.Plugin;
/**
* Handles the Smoke spells from the Ancient spellbook.
* @author Emperor
*/
@Initializable
public final class SmokeSpells extends CombatSpell {
/**
* The projectile for Smoke rush.
*/
private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 384, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Smoke rush.
*/
private static final Graphics RUSH_END = new Graphics(385, 96);
/**
* The projectile for Smoke burst.
*/
private static final Projectile BURST_PROJECTILE = Projectile.create((Entity) null, null, 386, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Smoke burst.
*/
private static final Graphics BURST_END = new Graphics(387, 0);
/**
* The projectile for Smoke blitz.
*/
private static final Projectile BLITZ_PROJECTILE = Projectile.create((Entity) null, null, 389, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Smoke blitz.
*/
private static final Graphics BLITZ_END = new Graphics(388, 96);
/**
* The projectile for Smoke barrage.
*/
private static final Projectile BARRAGE_PROJECTILE = Projectile.create((Entity) null, null, 391, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Smoke barrage.
*/
private static final Graphics BARRAGE_END = new Graphics(390, 0);
/**
* Constructs a new {@code SmokeSpells} {@code Object}.
*/
public SmokeSpells() {
/*
* empty.
*/
}
/**
* Constructs a new {@code SmokeSpells} {@Code Object}
* @param type The spell type.
* @param level The level requirement.
* @param sound The casting sound.
* @param impactSound The impact sound id.
* @param anim The animation.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
*/
private SmokeSpells(SpellType type, int level, double baseExperience, int sound, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.ANCIENT, level, baseExperience, sound, impactSound, anim, start, projectile, end, runes);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.ANCIENT.register(8, new SmokeSpells(SpellType.RUSH, 50, 30.0, 176, 177, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(1), Runes.AIR_RUNE.getItem(1)));
SpellBook.ANCIENT.register(10, new SmokeSpells(SpellType.BURST, 62, 36.0, 179, 180, new Animation(1979, Priority.HIGH), null, BURST_PROJECTILE, BURST_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4), Runes.FIRE_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2)));
SpellBook.ANCIENT.register(9, new SmokeSpells(SpellType.BLITZ, 74, 42.0, 183, 184, new Animation(1978, Priority.HIGH), null, BLITZ_PROJECTILE, BLITZ_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2)));
SpellBook.ANCIENT.register(11, new SmokeSpells(SpellType.BARRAGE, 86, 48.0, 183, 185, new Animation(1979, Priority.HIGH), null, BARRAGE_PROJECTILE, BARRAGE_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(4), Runes.FIRE_RUNE.getItem(4), Runes.AIR_RUNE.getItem(4)));
return this;
}
@Override
public void visualize(Entity entity, Node target) {
entity.graphics(graphic);
if (projectile != null) {
projectile.transform(entity, (Entity) target, false, 58, 10).send();
}
entity.animate(animation);
sendAudio(entity, audio);
}
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if (state.getEstimatedHit() > -1) {
victim.getStateManager().register(EntityState.POISONED, false, type.ordinal() >= SpellType.BLITZ.ordinal() ? 48 : 28, entity);
}
}
@Override
public BattleState[] getTargets(Entity entity, Entity target) {
if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {
targets[index++] = new BattleState(entity, e);
}
return targets;
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 1);
}
}
@@ -0,0 +1,104 @@
package content.global.skill.magic.lunar;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.entity.skill.Skills;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.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.system.task.Pulse;
import core.game.world.GameWorld;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Represents the dream magic spell.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class DreamSpell extends MagicSpell {
/**
* Represents the starting animation.
*/
private static final Animation START = Animation.create(6295);
/**
* Represents the dreaming animation.
*/
private static final Animation DREAMING = Animation.create(6296);
/**
* Represents the end animation.
*/
private static final Animation END = Animation.create(6297);
/**
* Represents the graphics of this spell.
*/
private static final Graphics GRAPHIC = new Graphics(1056);
/**
* Constructs a new {@code CureOtherSpell} {@code Object}.
*/
public DreamSpell() {
super(SpellBook.LUNAR, 79, 82, null, null, null, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.BODY_RUNE.getId(), 5) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(10, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player p = (Player) entity;
if (p.getSkills().getLifepoints() == p.getSkills().getStaticLevel(Skills.HITPOINTS)) {
p.getPacketDispatch().sendMessage("You have no need to cast this spell since your hitpoints are already full.");
return false;
}
if (!meetsRequirements(entity, true, true)) {
return false;
}
p.animate(START);
p.lock();
GameWorld.getPulser().submit(new Pulse(4, p) {
@Override
public boolean pulse() {
p.animate(DREAMING);
p.graphics(GRAPHIC);
p.unlock();
return true;
}
});
p.getPulseManager().run(new Pulse(18, p) {
@Override
public boolean pulse() {
p.graphics(GRAPHIC);
p.getSkills().heal(1);
if (p.getSkills().getLifepoints() == p.getSkills().getStaticLevel(Skills.HITPOINTS)) {
stop();
return true;
}
return false;
}
@Override
public void stop() {
super.stop();
p.graphics(new Graphics(-1));
p.animate(END);
}
});
return true;
}
}
@@ -0,0 +1,84 @@
package content.global.skill.magic.lunar;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.ImpactHandler.HitsplatType;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.audio.Audio;
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.Initializable;
import core.plugin.Plugin;
/**
* Represents the energy transfer spell.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class EnergyTransferSpell extends MagicSpell {
/**
* Represents the animation to use.
*/
private static final Animation ANIMATION = new Animation(4411);
/**
* Repesents the graphic, next spells of this spell.
*/
private static final Graphics GRAPHICS = new Graphics(738, 90);
/**
* Constructs a new {@code EnergyTransferSpell} {@code Object}.
*/
public EnergyTransferSpell() {
super(SpellBook.LUNAR, 91, 100, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 3), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.NATURE_RUNE.getId(), 1) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(5, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
if (!(target instanceof Player)) {
return false;
}
final Player player = ((Player) entity);
if (!super.meetsRequirements(player, true, true)) {
return false;
}
final Player o = ((Player) target);
int hp = (int) Math.floor(player.getSkills().getLifepoints() * 0.10);
int run = hp;
if (run > (100 - o.getSettings().getRunEnergy())) {
run = (int) (100 - o.getSettings().getRunEnergy());
}
if (run < 0) {
run = 0;
}
o.getSettings().updateRunEnergy(-run);
player.getImpactHandler().manualHit(player, hp, HitsplatType.NORMAL, 2);
int energy = 100;
energy -= o.getSettings().getSpecialEnergy();
if (energy < 0) {
energy = 0;
}
if (energy > player.getSettings().getSpecialEnergy()) {
energy = player.getSettings().getSpecialEnergy();
}
o.getSettings().setSpecialEnergy(o.getSettings().getSpecialEnergy() + energy);
player.getSettings().setSpecialEnergy(player.getSettings().getSpecialEnergy() - energy);
player.animate(ANIMATION);
player.getAudioManager().send(new Audio (2885), true);
o.graphics(GRAPHICS);
return true;
}
}
@@ -0,0 +1,143 @@
package content.global.skill.magic.lunar;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.plugin.Initializable;
import core.game.node.entity.skill.Skills;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.ImpactHandler.HitsplatType;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.audio.Audio;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
import java.util.Iterator;
import java.util.List;
/**
* Represents the healing spell.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class HealSpell extends MagicSpell {
/**
* Represents the animation for this spell.
*/
private static final Animation ANIMATION = new Animation(4411);
/**
* Represents the graphics of this spell.
*/
private static final Graphics GRAPHICS = new Graphics(738, 90);
/**
* Represents the animation used for the group heal.
*/
private static final Animation ANIMATION_G = new Animation(1979);
/**
* Represents the graphics used for the group heal.
*/
private static final Graphics GRAPHICS_G = new Graphics(734, 90);
/**
* Constructs a new {@code HealSpell} {@code Object}.
*/
public HealSpell() {
/**
* empty.
*/
}
/**
* Constructs a new {@code HealSpell} {@code Object}.
*/
public HealSpell(int level, int experience, Item[] runes) {
super(SpellBook.LUNAR, level, experience, null, null, null, runes);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(29, new HealSpell(92, 101, new Item[] { new Item(Runes.BLOOD_RUNE.getId(), 1), new Item(Runes.LAW_RUNE.getId(), 3), new Item(Runes.ASTRAL_RUNE.getId(), 3) }));
SpellBook.LUNAR.register(30, new HealSpell(92, 101, new Item[] { new Item(Runes.BLOOD_RUNE.getId(), 3), new Item(Runes.LAW_RUNE.getId(), 6), new Item(Runes.ASTRAL_RUNE.getId(), 4) }));
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = (Player) entity;
boolean group = getSpellId() == 30;
int eleven = (int) (player.getSkills().getStaticLevel(Skills.HITPOINTS) * 0.11);
if (player.getSkills().getLifepoints() < eleven) {
player.sendMessage("You need at least 11 percent of your original hitpoints in order to do this.");
return false;
}
if (!group) {
if (!(target instanceof Player)) {
return false;
}
final Player o = (Player) target;
player.face(o);
if (!o.isActive() || o.getLocks().isInteractionLocked()) {
player.getPacketDispatch().sendMessage("This player is busy.");
return false;
}
if (!o.getSettings().isAcceptAid()) {
player.getPacketDispatch().sendMessage("The player is not accepting any aid.");
return false;
}
if (o.getSkills().getLifepoints() == o.getSkills().getLevel(Skills.HITPOINTS)) {
player.getPacketDispatch().sendMessage("The player already has full hitpoints.");
return false;
}
if (!super.meetsRequirements(player, true, true)) {
return false;
}
int transfer = (int) (player.getSkills().getLifepoints() * 0.75);
player.getImpactHandler().manualHit(player, transfer, null);
o.getSkills().heal(transfer);
player.animate(ANIMATION);
player.getAudioManager().send(new Audio(2895), true);
o.getAudioManager().send(new Audio(2892), true);
o.graphics(GRAPHICS);
} else {
List<Player> players = RegionManager.getLocalPlayers(player, 1);
if (!super.meetsRequirements(player, true, true)) {
return false;
}
int percentage = (int) Math.ceil(player.getSkills().getLifepoints() * 0.75);
for (Iterator<Player> it = players.iterator(); it.hasNext();) {
Player p = it.next();
if (p == player || !p.getSettings().isAcceptAid() || !p.isActive() || p.getSkills().getLifepoints() == p.getSkills().getMaximumLifepoints()) {
it.remove();
}
}
if (players.isEmpty()) {
player.getPacketDispatch().sendMessage("There are no players around to replenish.");
return false;
}
if (percentage < 1) {
player.getPacketDispatch().sendMessage("You don't have enough hitpoints left to cast this spell.");
return false;
}
player.getImpactHandler().manualHit(player, percentage, HitsplatType.NORMAL);
player.animate(ANIMATION_G);
player.getAudioManager().send(new Audio(2894), true);
for (Player p : players) {
p.getAudioManager().send(new Audio(2892), true);
p.graphics(GRAPHICS_G);
p.getSkills().heal(percentage);
}
}
return true;
}
}
@@ -0,0 +1,90 @@
package content.global.skill.magic.lunar;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.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.Initializable;
import core.plugin.Plugin;
/**
* Represents the humidify spell.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class HumidifySpell extends MagicSpell {
/**
* Represents the animation of this graphics.
*/
private static final Animation ANIMATION = new Animation(6294);
/**
* Repesents the graphick, next spells of this spell.
*/
private static final Graphics GRAPHIC = new Graphics(1061);
/**
* Represents the empty vessels.
*/
private static final int[] EMPTY = { 229, 1831, 1829, 1827, 1825, 1925, 1923, 1935, 5331, 5332, 5333, 5334, 5335, 5337, 5338, 5339, 6667, 7688, 731, 1980, 434 };
/**
* Represents the full vessels.
*/
private static final int[] FULL = { 227, 1823, 1823, 1823, 1823, 1929, 1921, 1937, 5340, 5340, 5340, 5340, 5340, 5340, 5340, 5340, 6668, 7690, 732, 4458, 1761 };
/**
* Constructs a new {@code CureOtherSpell} {@code Object}.
*/
public HumidifySpell() {
super(SpellBook.LUNAR, 68, 65, ANIMATION, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 1), new Item(Runes.WATER_RUNE.getId(), 3), new Item(Runes.FIRE_RUNE.getId(), 1) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(7, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
Player p = (Player) entity;
boolean good = false;
for (int i = 0; i < EMPTY.length; i++) {
if (p.getInventory().contains(EMPTY[i], 1)) {
good = true;
break;
}
}
if (!good) {
p.sendMessage("You need something which holds water in order to do this spell.");
return false;
}
if (!super.meetsRequirements(p, true, true)) {
return false;
}
p.lock(ANIMATION.getDuration() + 1);
p.animate(ANIMATION);
p.graphics(GRAPHIC);
p.getAudioManager().send(3614);
for (int k = 0; k < 28; k++) {
for (int i = 0; i < 21; i++) {
if (p.getInventory().contains(EMPTY[i], 1)) {
if (p.getInventory().remove(new Item(EMPTY[i]))) {
p.getInventory().add(new Item(FULL[i]));
}
}
}
}
return true;
}
}
@@ -0,0 +1,97 @@
package content.global.skill.magic.lunar;
import core.cache.def.impl.ItemDefinition;
import core.plugin.Initializable;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.interaction.OptionHandler;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.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 hunter kit spell.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class HunterKitSpell extends MagicSpell {
/**
* Represents the hunter kit.
*/
private static final Item KIT = new Item(11159);
/**
* Represents the animation of this graphics.
*/
private static final Animation ANIMATION = new Animation(6303);
/**
* Repesents the graphick, next spells of this spell.
*/
private static final Graphics GRAPHIC = new Graphics(1074);
/**
* Constructs a new {@code CureOtherSpell} {@code Object}.
*/
public HunterKitSpell() {
super(SpellBook.LUNAR, 71, 70, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.EARTH_RUNE.getId(), 2) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(8, this);
ItemDefinition.forId(KIT.getId()).getHandlers().put("option:open", new OptionHandler() {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
if (player.getInventory().freeSlots() < 7) {
player.getPacketDispatch().sendMessage("You don't have enough inventory space.");
return true;
}
if (player.getInventory().remove((Item) node)) {
player.getInventory().add(new Item[] { new Item(10150), new Item(10010), new Item(10006), new Item(10031), new Item(10029), new Item(596), new Item(10008) });
}
return true;
}
@Override
public boolean isWalk() {
return false;
}
});
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
Player p = (Player) entity;
if (p.getInventory().freeSlots() == 0) {
p.getPacketDispatch().sendMessage("Not enough inventory space!");
return false;
}
if (!meetsRequirements(entity, true, true)) {
return false;
}
if (p.getInventory().add(KIT)) {
p.lock(5);
p.animate(ANIMATION);
p.graphics(GRAPHIC);
p.getAudioManager().send(3615, 1, 1);
}
return true;
}
}
@@ -0,0 +1,55 @@
package content.global.skill.magic.lunar
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Items
// Animations
val BAKE_PIE_ANIM = Animation(4413)
val STATSPY_ANIM = Animation(6293)
val CURE_PLANT_ANIM = Animation(4409)
val NPC_CONTACT_ANIM = Animation(4413)
val PLANK_MAKE_ANIM = Animation(6298)
val STRING_JEWELLERY_ANIM = Animation(4412)
val SUPERGLASS_MAKE_ANIM = Animation(4413)
val FERTILE_SOIL_ANIM = Animation(724)
val CURE_ME_ANIM = Animation(4411)
val CURE_GROUP_ANIM = Animation(4409)
val CURE_OTHER_ANIM = Animation(4411)
// Graphics
val BAKE_PIE_GFX = Graphics(746,75)
val STATSPY_GFX = Graphics(1059)
val CURE_PLANT_GFX = Graphics(742,100)
val NPC_CONTACT_GFX = Graphics(730,130)
val PLANK_MAKE_GFX = Graphics(1063, 120)
val STRING_JEWELLERY_GFX = Graphics(728, 100)
val SUPERGLASS_MAKE_GFX = Graphics(729, 120)
val FERTILE_SOIL_GFX = Graphics(141, 96)
val CURE_ME_GFX = Graphics(731, 90)
val CURE_GROUP_GFX = Graphics(751, 130)
val CURE_OTHER_GFX = Graphics(738, 130)
enum class JewelleryString(val unstrung: Int, val strung: Int) {
GOLD(Items.GOLD_AMULET_1673, Items.GOLD_AMULET_1692),
SAPPHIRE(Items.SAPPHIRE_AMULET_1675, Items.SAPPHIRE_AMULET_1694),
EMERALD(Items.EMERALD_AMULET_1677, Items.EMERALD_AMULET_1696),
RUBY(Items.RUBY_AMULET_1679, Items.RUBY_AMULET_1698),
DIAMOND(Items.DIAMOND_AMULET_1681, Items.DIAMOND_AMULET_1700),
DRAGONSTONE(Items.DRAGONSTONE_AMMY_1683, Items.DRAGONSTONE_AMMY_1702),
ONYX(Items.ONYX_AMULET_6579, Items.ONYX_AMULET_6581),
SALVE(Items.SALVE_SHARD_4082, Items.SALVE_AMULET_4081),
HOLY(Items.UNSTRUNG_SYMBOL_1714, Items.UNBLESSED_SYMBOL_1716),
UNHOLY(Items.UNSTRUNG_EMBLEM_1720, Items.UNPOWERED_SYMBOL_1722);
companion object {
val productOfString = values().associate { it.unstrung to it.strung }
fun forId(id : Int) : Int {
return productOfString[id]!!
}
fun unstrungContains(id: Int): Boolean {
return productOfString.contains(id)
}
}
}
@@ -0,0 +1,536 @@
package content.global.skill.magic.lunar
import content.global.skill.cooking.CookableItems
import content.global.skill.farming.CompostBins
import content.global.skill.farming.CompostType
import content.global.skill.farming.FarmingPatch
import content.global.skill.magic.SpellListener
import content.global.skill.magic.spellconsts.Lunar
import core.api.*
import core.game.component.Component
import core.game.node.Node
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.player.link.audio.Audio
import core.game.node.entity.skill.Skills
import core.game.node.entity.state.EntityState
import core.game.node.item.Item
import core.game.node.scenery.Scenery
import core.game.system.command.Privilege
import core.game.system.config.NPCConfigParser
import core.game.system.task.Pulse
import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.repository.Repository
import core.tools.RandomFunction
import org.rs09.consts.Components
import org.rs09.consts.Items
class LunarListeners : SpellListener("lunar"), Commands {
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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)))
player.getAudioManager().send(Audio(200), true)
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!!.asScenery())
}
onCast(Lunar.NPC_CONTACT, NONE) { player, _ ->
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,3618)
}
}
onCast(Lunar.PLANK_MAKE, ITEM) { player, node ->
requires(player, 86, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.NATURE_RUNE_561, 1), Item(Items.EARTH_RUNE_557, 15)))
plankMake(player, node!!.asItem())
}
onCast(Lunar.STRING_JEWELLERY, NONE) { player, _ ->
requires(player, 80, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.EARTH_RUNE_557, 10), Item(Items.WATER_RUNE_555, 5)))
stringJewellery(player)
}
onCast(Lunar.SUPERGLASS_MAKE, NONE) { player, _ ->
requires(player, 77, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.FIRE_RUNE_554, 6), Item(Items.AIR_RUNE_556, 10)))
superglassMake(player)
}
onCast(Lunar.FERTILE_SOIL, OBJECT) { player, node ->
node?.let { fertileSoil(player, node.asScenery()) }
}
onCast(Lunar.CURE_ME, NONE) { player, _ ->
cureMe(player)
}
onCast(Lunar.CURE_GROUP, NONE) { player, _ ->
cureGroup(player)
}
onCast(Lunar.CURE_OTHER, PLAYER) { player, node ->
node?.let { cureOther(player, node) }
}
}
// Lunar spellbook-related debug commands
override fun defineCommands() {
define("poison", privilege = Privilege.ADMIN) { player, strings ->
if(strings.size == 3) {
var dmg = strings[2].toIntOrNull()
val p = Repository.getPlayerByName(strings[1])
if(p == null) {
sendMessage(player, "Player ${strings[1]} does not exist.")
return@define
}
if(dmg != null) {
p?.let { addState(it, EntityState.POISONED, false, (dmg * 10 + 8), player) }
} else {
sendMessage(player, "Damage must be an integer. Format:")
sendMessage(player, "::poison username damage")
}
} else {
sendMessage(player, "Invalid arguments provided. Format:")
sendMessage(player, "::poison username damage")
}
}
}
private fun plankMake(player: Player, item: Item) {
val plankType = PlankType.getForLog(item)
if (plankType == null) {
sendMessage(player, "You need to use this spell on logs.")
return
}
if (!removeItem(player, Item(Items.COINS_995, plankType.price))) {
sendMessage(player, "You need ${plankType.price} coins to convert that log into a plank.")
return
}
lock(player, 3)
setDelay(player, false)
visualizeSpell(player, PLANK_MAKE_ANIM, PLANK_MAKE_GFX, 3617)
removeRunes(player)
replaceSlot(player, item.slot, plankType.plank)
addXP(player, 90.0)
showMagicTab(player)
}
enum class PlankType (val log: Item, val plank: Item, val price: Int) {
WOOD(Item(1511), Item(960), 70),
OAK(Item(1521), Item(8778), 175),
TEAK(Item(6333), Item(8780), 350),
MAHOGANY(Item(6332), Item(8782), 1050);
companion object {
fun getForLog(item: Item): PlankType? {
for (plankType in values()) {
if (plankType.log.id == item.id) {
return plankType
}
}
return null
}
}
}
fun curePlant(player: Player, obj: Scenery){
val fPatch = FarmingPatch.forObject(obj)
if(fPatch == null){
player.sendMessage("You attempt to cast Cure Plant on ${obj.definition.name}!")
player.sendMessage("Nothing interesting happens.")
return
}
val patch = fPatch.getPatchFor(player)
if(!patch.isDiseased && !patch.isWeedy()){
player.sendMessage("It is growing just fine.")
return
}
if(patch.isWeedy()){
player.sendMessage("The weeds are healthy enough already.")
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
}
if(patch.isGrown()){
player.sendMessage("That's not diseased.")
return
}
patch.cureDisease()
removeRunes(player)
addXP(player,60.0)
visualizeSpell(player, CURE_PLANT_ANIM, CURE_PLANT_GFX)
setDelay(player,false)
}
private 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,3620)
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)
}
private 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.lowercase().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)
visualizeSpell(player, BAKE_PIE_ANIM, BAKE_PIE_GFX, 2879)
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
}
})
}
private fun sendTeleport(player: Player, xp: Double, loc: Location){
if(player.locks.isTeleportLocked){
player.sendMessage("A magical force prevents you from teleporting.")
return
}
if(player.teleporter.send(loc,TeleportManager.TeleportType.LUNAR)) {
addXP(player, xp)
removeRunes(player)
setDelay(player, true)
}
}
private 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)
}
private fun stringJewellery(player: Player) {
val playerJewellery = ArrayDeque<Item>()
for(item in player.inventory.toArray()) {
if(item == null) continue
if(!JewelleryString.unstrungContains(item.id)) continue
playerJewellery.add(item)
}
player.pulseManager.run(object : Pulse() {
var counter = 0
override fun pulse(): Boolean {
removeAttribute(player, "spell:runes")
requires(player, 80, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.EARTH_RUNE_557, 10), Item(Items.WATER_RUNE_555, 5)))
if(counter == 0) delay = animationDuration(STRING_JEWELLERY_ANIM) + 1
val item = playerJewellery[0]
val strung = JewelleryString.forId(item.id)
setDelay(player,false)
if(removeItem(player, item) && addItem(player, strung)) {
removeRunes(player, true)
visualizeSpell(player, STRING_JEWELLERY_ANIM, STRING_JEWELLERY_GFX, 2903)
rewardXP(player, Skills.CRAFTING, 4.0)
addXP(player, 83.0)
playerJewellery.remove(item)
if(playerJewellery.isNotEmpty()) removeRunes(player,false) else removeRunes(player,true)
}
counter++
return playerJewellery.isEmpty()
}
})
}
private fun superglassMake(player: Player) {
val GLASSWEED = hashSetOf(Items.SODA_ASH_1781, Items.SEAWEED_401, Items.SWAMP_WEED_10978)
val inv = player.inventory.toArray()
var playerWeed: Int = amountInInventory(player, Items.SODA_ASH_1781) + amountInInventory(player, Items.SEAWEED_401) + amountInInventory(player, Items.SWAMP_WEED_10978)
var playerSand: Int = amountInInventory(player, Items.BUCKET_OF_SAND_1783)
var index: Int = 0
fun addMolten(): Boolean {
if(RandomFunction.randomDouble(1.0) < 0.3) {
if(addItem(player, Items.MOLTEN_GLASS_1775, 2)) return true
} else {
if(addItem(player, Items.MOLTEN_GLASS_1775)) return true
}
return false
}
val size = minOf(playerSand, playerWeed)
if(index != size && size != 0) {
for (item in inv) {
if (item == null) continue
if (index == size) break
if (GLASSWEED.contains(item.id)) {
if (removeItem(player, item) && removeItem(player, Items.BUCKET_OF_SAND_1783) && addMolten()) {
index++
} else {
break
}
}
}
} else if (playerWeed == 0 || playerSand == 0 || size == 0) {
sendMessage(player, "You lack the required ingredients.")
}
if(index == size && size != 0) {
removeRunes(player, true)
visualizeSpell(player, SUPERGLASS_MAKE_ANIM, SUPERGLASS_MAKE_GFX, 2896)
rewardXP(player, Skills.CRAFTING, 10.0)
addXP(player, 78.0)
}
}
private fun fertileSoil(player: Player, target: Scenery) {
if (CompostBins.forObjectID(target.id) != null) {
sendMessage(player, "No, that would be silly.")
return
}
val fPatch = FarmingPatch.forObject(target)
if(fPatch == null) {
sendMessage(player, "Um... I don't want to fertilize that!")
return
}
val patch = fPatch.getPatchFor(player)
if (patch.isGrown()) {
sendMessage(player, "Composting isn't going to make it get any bigger.")
return
}
if (patch.isFertilized()) {
sendMessage(player, "This patch has already been composted.")
return
}
requires(player, 83, arrayOf(Item(Items.ASTRAL_RUNE_9075, 3), Item(Items.NATURE_RUNE_561, 2), Item(Items.EARTH_RUNE_557, 15)))
removeRunes(player, true)
visualizeSpell(player, FERTILE_SOIL_ANIM, FERTILE_SOIL_GFX, 2891)
patch.compost = CompostType.SUPER
sendMessage(player, "You fertilize the soil.")
addXP(player, 87.0)
}
private fun cureMe(player: Player) {
if(!hasState(player, EntityState.POISONED)) {
sendMessage(player, "You are not poisoned.")
return
}
requires(player, 71, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 1), Item(Items.COSMIC_RUNE_564, 2)))
removeRunes(player, true)
visualizeSpell(player, CURE_ME_ANIM, CURE_ME_GFX, 2880)
removeState(player, EntityState.POISONED)
addXP(player, 69.0)
playAudio(player, Audio(2900))
sendMessage(player, "You have been cured of poison.")
}
private fun cureGroup(player: Player) {
requires(player, 74, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 2), Item(Items.COSMIC_RUNE_564, 2)))
removeRunes(player, true)
visualizeSpell(player, CURE_GROUP_ANIM, CURE_GROUP_GFX, 2882)
removeState(player, EntityState.POISONED)
for(acct in RegionManager.getLocalPlayers(player, 1)) {
if(!acct.isActive || acct.locks.isInteractionLocked) {
continue
}
if(!acct.settings.isAcceptAid) {
continue
}
removeState(acct, EntityState.POISONED)
sendMessage(acct, "You have been cured of poison.")
playAudio(acct, Audio(2889), true)
visualize(acct, -1, CURE_GROUP_GFX)
}
addXP(player, 74.0)
}
private fun cureOther(player: Player, target: Node) {
if(!isPlayer(target)) {
sendMessage(player, "You can only cast this spell on other players.")
return
}
val p = target.asPlayer()
if(!p.isActive || p.locks.isInteractionLocked) {
sendMessage(player, "This player is busy.")
return
}
if(!p.settings.isAcceptAid) {
sendMessage(player, "This player is not accepting any aid.")
return
}
if(!hasState(p, EntityState.POISONED)) {
sendMessage(player, "This player is not poisoned.")
return
}
requires(player, 68, arrayOf(Item(Items.ASTRAL_RUNE_9075, 1), Item(Items.LAW_RUNE_563), Item(Items.EARTH_RUNE_557, 10)))
player.face(p)
visualizeSpell(player, CURE_OTHER_ANIM, CURE_OTHER_GFX, 2886)
visualize(p, -1, CURE_OTHER_GFX)
playAudio(p, Audio(2889), true)
removeRunes(player, true)
removeState(p, EntityState.POISONED)
sendMessage(p, "You have been cured of poison.")
addXP(player, 65.0)
}
}
@@ -0,0 +1,68 @@
package content.global.skill.magic.lunar;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.plugin.Initializable;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.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.GameWorld;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
/**
* The magic imbue spell.
* @author 'Vexia
*/
@Initializable
public class MagicImbueSpell extends MagicSpell {
/**
* The graphic.
*/
private static final Graphics GRAPHIC = new Graphics(141, 96);
/**
* The animation.
*/
private static final Animation ANIMATION = new Animation(722);
/**
* Constructs a new {@code StatRestoreSpell} {@code Object}.
*/
public MagicImbueSpell() {
super(SpellBook.LUNAR, 82, 86, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.FIRE_RUNE.getId(), 7), new Item(Runes.WATER_RUNE.getId(), 7) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(13, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
if (player == null) {
return false;
}
if (player.getAttribute("spell:imbue", 0) > GameWorld.getTicks()) {
player.sendMessage("You already have this activated.");
return false;
}
if (!super.meetsRequirements(player, true, true)) {
return false;
}
player.setAttribute("spell:imbue", GameWorld.getTicks() + 20);
player.lock(ANIMATION.getDuration() + 1);
player.graphics(GRAPHIC);
player.animate(ANIMATION);
player.getAudioManager().send(2888, 1, 1);
player.getPacketDispatch().sendMessage("You are charged to combine runes!");
return true;
}
}
@@ -0,0 +1,84 @@
package content.global.skill.magic.lunar;
import core.game.component.Component;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.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.system.task.Pulse;
import core.game.world.GameWorld;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.tools.RandomFunction;
/**
* The spellbook swap spell.
* @author 'Vexia
*/
@Initializable
public class SpellbookSwapSpell extends MagicSpell {
/**
* Represents the animation of this spell.
*/
private final Animation ANIMATION = new Animation(6299);
/**
* Represents the graphics of this spell.
*/
private final Graphics GRAPHIC = new Graphics(1062);
/**
* Constructs a new {@code SpellbookSwapSpell} {@code Object}.
*/
public SpellbookSwapSpell() {
super(SpellBook.LUNAR, 96, 130, null, null, null, new Item[] { new Item(Runes.LAW_RUNE.getId(), 1), new Item(Runes.COSMIC_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 3) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(12, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = (Player) entity;
if (!super.meetsRequirements(player, true, true)) {
return false;
}
player.lock(9);
player.animate(ANIMATION);
player.graphics(GRAPHIC);
player.getDialogueInterpreter().open(3264731);
final int id = RandomFunction.random(1, 500000);
player.setAttribute("spell:swap", id);
GameWorld.getPulser().submit(new Pulse(20, player) {
@Override
public boolean pulse() {
if (player.getAttribute("spell:swap", 0) == id) {
removeTemporarySpell(player);
}
return true;
}
});
return true;
}
/**
* Method used to remove the temp spell swap.
* @param player the player.
*/
public static void removeTemporarySpell(final Player player) {
player.removeAttribute("spell:swap");
player.getSpellBookManager().setSpellBook(SpellBook.LUNAR);
player.getInterfaceManager().openTab(new Component(SpellBook.LUNAR.getInterfaceId()));
}
}
@@ -0,0 +1,96 @@
package content.global.skill.magic.lunar;
import content.data.consumables.Consumables;
import core.game.consumable.Potion;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.audio.Audio;
import core.game.bots.AIPlayer;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
import java.util.List;
@Initializable
public final class StatBoostSpell extends MagicSpell {
private static final Animation ANIMATION = new Animation(4413);
private static final Graphics GRAPHICS = new Graphics(733, 130);
public static final int VIAL = 229;
public StatBoostSpell() {
super(SpellBook.LUNAR, 84, 88, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 3), new Item(Runes.EARTH_RUNE.getId(), 12), new Item(Runes.WATER_RUNE.getId(), 10) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(26, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
Item item = ((Item) target);
final Potion potion = (Potion) Consumables.getConsumableById(item.getId());
player.getInterfaceManager().setViewedTab(6);
if (potion == null) {
player.getPacketDispatch().sendMessage("You can only cast this spell on a potion.");
return false;
}
if (!item.getDefinition().isTradeable() || item.getName().toLowerCase().contains("restore") || item.getName().toLowerCase().contains("zamorak") || item.getName().toLowerCase().contains("saradomin") || item.getName().toLowerCase().contains("combat")) {
player.getPacketDispatch().sendMessage("You can't cast this spell on that item.");
return false;
}
List<Player> pl = RegionManager.getLocalPlayers(player, 1);
int plSize = pl.size() - 1;
int doses = potion.getDose(item);
if (plSize > doses) {
player.getPacketDispatch().sendMessage("You don't have enough doses.");
return false;
}
if (doses > plSize) {
doses = plSize;
}
if (pl.size() == 0) {
return false;
}
if (!super.meetsRequirements(player, true, false)) {
return false;
}
int size = 1;
for (Player players : pl) {
Player o = (Player) players;
if (!o.isActive() || o.getLocks().isInteractionLocked() || o == player) {
continue;
}
if (!o.getSettings().isAcceptAid() && !(o instanceof AIPlayer)) {
continue;
}
o.graphics(GRAPHICS);
o.getAudioManager().send(new Audio (2902), true);
potion.getEffect().activate(o);
size++;
}
if (size == 1) {
player.getPacketDispatch().sendMessage("There is nobody around that has accept aid on to share the potion with you.");
return false;
}
super.meetsRequirements(player, true, true);
potion.getEffect().activate(player);
player.getAudioManager().send(new Audio (2901), true);
player.animate(ANIMATION);
player.graphics(GRAPHICS);
player.getInventory().remove(item);
player.getInventory().add(new Item(potion.getIds()[size - 1]));
return true;
}
}
@@ -0,0 +1,108 @@
package content.global.skill.magic.lunar;
import content.data.consumables.Consumables;
import core.game.consumable.Potion;
import core.plugin.Initializable;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.audio.Audio;
import core.game.bots.AIPlayer;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
import java.util.List;
@Initializable
public class StatRestoreSpell extends MagicSpell {
private static final Animation ANIMATION = new Animation(4413);
private static final Graphics GRAPHICS = new Graphics(733, 130);
private static final int[] IDS = new int[] { 2434, 139, 141, 143, 2430, 127, 129, 131, 3024, 3026, 3028, 3030 };
public StatRestoreSpell() {
super(SpellBook.LUNAR, 81, 84, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.EARTH_RUNE.getId(), 10), new Item(Runes.WATER_RUNE.getId(), 10) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(27, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
Item item = ((Item) target);
final Potion potion = (Potion) Consumables.getConsumableById(item.getId());
player.getInterfaceManager().setViewedTab(6);
if (potion == null) {
player.getPacketDispatch().sendMessage("You can only cast this spell on a potion.");
return false;
}
if (!item.getDefinition().isTradeable() || !isRestore(item.getId())) {
player.getPacketDispatch().sendMessage("You can't cast this spell on that item.");
return false;
}
List<Player> pl = RegionManager.getLocalPlayers(player, 1);
int plSize = pl.size() - 1;
int doses = potion.getDose(item);
if (plSize > doses) {
player.getPacketDispatch().sendMessage("You don't have enough doses.");
return false;
}
if (doses > plSize) {
doses = plSize;
}
if (pl.size() == 0) {
return false;
}
if (!super.meetsRequirements(player, true, false)) {
return false;
}
int size = 1;
for (Player players : pl) {
Player o = (Player) players;
if (!o.isActive() || o.getLocks().isInteractionLocked() || o == player) {
continue;
}
if (!o.getSettings().isAcceptAid() && !(o instanceof AIPlayer)) {
continue;
}
o.graphics(GRAPHICS);
player.getPacketDispatch().sendMessage("You can only cast this spell on a potion.");
potion.getEffect().activate(o);
size++;
}
if (size == 1) {
player.getPacketDispatch().sendMessage("There is nobody around that has accept aid on to share the potion with you.");
return false;
}
super.meetsRequirements(player, true, true);
potion.getEffect().activate(player);
player.getAudioManager().send(new Audio (2899), true);
player.animate(ANIMATION);
player.graphics(GRAPHICS);
player.getInventory().remove(item);
player.getInventory().add(new Item(potion.getIds()[size - 1]));
return true;
}
private boolean isRestore(int id) {
for (int i : IDS) {
if (i == id) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,97 @@
package content.global.skill.magic.lunar;
import core.game.component.CloseEvent;
import core.game.component.Component;
import core.plugin.Initializable;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.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;
/**
* The stat spy spell.
* @author 'Vexia
*/
@Initializable
public final class StatSpySpell 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(734, 120);
/**
* Represents the graphics.
*/
private static final Graphics EYE = new Graphics(1059);
/**
* Represents the component.
*/
private static final Component COMPONENT = new Component(523);
/**
* Represents the array of skills.
*/
private static int[][] SKILLS = { { Skills.ATTACK, 1, 2 }, { Skills.HITPOINTS, 5, 6 }, { Skills.MINING, 9, 10 }, { Skills.STRENGTH, 13, 14 }, { Skills.AGILITY, 17, 18 }, { Skills.SMITHING, 21, 22 }, { Skills.DEFENCE, 25, 26 }, { Skills.HERBLORE, 29, 30 }, { Skills.FISHING, 33, 34 }, { Skills.RANGE, 37, 38 }, { Skills.THIEVING, 41, 42 }, { Skills.COOKING, 45, 46 }, { Skills.PRAYER, 49, 50 }, { Skills.CRAFTING, 53, 54 }, { Skills.FIREMAKING, 57, 58 }, { Skills.MAGIC, 61, 62 }, { Skills.FLETCHING, 65, 66 }, { Skills.WOODCUTTING, 69, 70 }, { Skills.RUNECRAFTING, 73, 74 }, { Skills.SLAYER, 77, 78 }, { Skills.FARMING, 81, 82 }, { Skills.CONSTRUCTION, 85, 86 }, { Skills.HUNTER, 89, 90 }, { Skills.SUMMONING, 93, 94 } };
/**
* Constructs a new {@code CureOtherSpell} {@code Object}.
*/
public StatSpySpell() {
super(SpellBook.LUNAR, 75, 76, ANIMATION, null, null, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.BODY_RUNE.getId(), 5) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.LUNAR.register(9, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
if (!(target instanceof Player)) {
player.getPacketDispatch().sendMessage("You can only cast this spell on players.");
return false;
}
if (super.meetsRequirements(player, true, true)) {
final Player o = ((Player) target);
player.animate(ANIMATION);
player.face(o);
player.getAudioManager().send(3620);
COMPONENT.setCloseEvent(new CloseEvent() {
@Override
public boolean close(Player player, Component c) {
player.getInterfaceManager().restoreTabs();
return true;
}
});
player.graphics(EYE);
o.graphics(GRAPHIC);
player.getAudioManager().send(3621);
for (int[] element : SKILLS) {
player.getPacketDispatch().sendString("" + o.getSkills().getLevel(element[0]) + "", 523, element[1]);
player.getPacketDispatch().sendString("" + o.getSkills().getStaticLevel(element[0]) + "", 523, element[2]);
}
player.getPacketDispatch().sendString((o.getUsername()), 523, 99);
player.getInterfaceManager().openSingleTab(COMPONENT);
return true;
}
return true;
}
}
@@ -0,0 +1,88 @@
package content.global.skill.magic.lunar;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.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.GameWorld;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Handles the vengeance (other) spell.
* @author Emperor
*/
@Initializable
public final class VengeanceSpell extends MagicSpell {
/**
* Constructs a new {@code VengeanceSpell} {@code Object}.
*/
public VengeanceSpell() {
/*
* empty.
*/
}
/**
* Constructs a new {@code VengeanceSpell} {@code Object}.
* @param level The level required.
* @param experience The experience gained from casting this spell.
* @param anim The cast animation.
* @param graphic The graphics.
* @param runes The runes required.
*/
public VengeanceSpell(int level, double experience, Animation anim, Graphics graphic, Item... runes) {
super(SpellBook.LUNAR, level, experience, anim, graphic, null, runes);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
// Vengeance other
SpellBook.LUNAR.register(19, new VengeanceSpell(93, 78, Animation.create(4411), new Graphics(725, 96), Runes.ASTRAL_RUNE.getItem(3), Runes.DEATH_RUNE.getItem(2), Runes.EARTH_RUNE.getItem(10)));
// Vengeance
SpellBook.LUNAR.register(14, new VengeanceSpell(94, 112, Animation.create(4410), new Graphics(726, 96), Runes.ASTRAL_RUNE.getItem(4), Runes.DEATH_RUNE.getItem(2), Runes.EARTH_RUNE.getItem(10)));
return this;
}
@Override
public void visualize(Entity entity, Node target) {
entity.animate(animation);
((Entity) target).graphics(graphic);
}
@Override
public boolean cast(Entity entity, Node target) {
int ticks = GameWorld.getTicks();
boolean vengOther = spellId == 19;
if (entity.getAttribute("vengeance_delay", -1) > ticks) {
((Player) entity).getPacketDispatch().sendMessage("You can only cast vengeance spells once every 30 seconds.");
return false;
}
if (vengOther && (target == null || !(target instanceof Player))) {
return false;
}
Player p = (Player) (vengOther ? target : entity);
if (vengOther) {
if (!p.getSettings().isAcceptAid()) {
((Player) entity).getPacketDispatch().sendMessage("The player is not accepting any aid.");
return false;
}
}
if (!meetsRequirements(entity, true, true)) {
return false;
}
visualize(entity, p);
entity.setAttribute("vengeance_delay", ticks + 50);
p.setAttribute("vengeance", true);
p.getAudioManager().send(vengOther ? 2908 : 2907);
return true;
}
}
@@ -0,0 +1,126 @@
package content.global.skill.magic.modern;
import core.plugin.Initializable;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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 combat spell plugin used to handle air spells.
* @author Emperor
* @version 1.0
*/
@Initializable
public final class AirSpell extends CombatSpell {
/**
* The start graphic for Air strike.
*/
private static final Graphics STRIKE_START = new Graphics(90, 96);
/**
* The projectile for Air strike.
*/
private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 91, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Air strike.
*/
private static final Graphics STRIKE_END = new Graphics(92, 96);
/**
* The start graphic for Air bolt.
*/
private static final Graphics BOLT_START = new Graphics(117, 96);
/**
* The projectile for Air bolt.
*/
private static final Projectile BOLT_PROJECTILE = Projectile.create((Entity) null, null, 118, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Air bolt.
*/
private static final Graphics BOLT_END = new Graphics(119, 96);
/**
* The start graphic for Air blast.
*/
private static final Graphics BLAST_START = new Graphics(132, 96); // 129
/**
* The projectile for Air blast.
*/
private static final Projectile BLAST_PROJECTILE = Projectile.create((Entity) null, null, 133, 40, 36, 52, 75, 15, 11); // 130
/**
* The end graphic for Air blast.
*/
private static final Graphics BLAST_END = new Graphics(134, 96); // 131
/**
* The start graphic for Air wave.
*/
private static final Graphics WAVE_START = new Graphics(158, 96);
/**
* The projectile for Air wave.
*/
private static final Projectile WAVE_PROJECTILE = Projectile.create((Entity) null, null, 159, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Air wave.
*/
private static final Graphics WAVE_END = new Graphics(160, 96);
/**
* The cast animation.
*/
private static final Animation ANIMATION = new Animation(711, Priority.HIGH);
/**
* Constructs a new {@code AirSpell} {@Code Object}
*/
public AirSpell() {
/*
* empty.
*/
}
/**
* Constructs a new {@code AirSpell} {@Code Object}
* @param type The spell type.
* @param level The level requirement.
* @param sound The cast sound.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
* @param runes The rune requirements.
*/
private AirSpell(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.MODERN, level, baseExperience, sound, sound + 1, ANIMATION, start, projectile, end, runes);
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 1);
}
@Override
public Plugin<SpellType> newInstance(SpellType type) throws Throwable {
SpellBook.MODERN.register(1, new AirSpell(SpellType.STRIKE, 1, 5.5, 220, STRIKE_START, STRIKE_PROJECTILE, STRIKE_END, Runes.MIND_RUNE.getItem(1), Runes.AIR_RUNE.getItem(1)));
SpellBook.MODERN.register(10, new AirSpell(SpellType.BOLT, 17, 13.5, 218, BOLT_START, BOLT_PROJECTILE, BOLT_END, Runes.CHAOS_RUNE.getItem(1), Runes.AIR_RUNE.getItem(2)));
SpellBook.MODERN.register(24, new AirSpell(SpellType.BLAST, 41, 25.5, 216, BLAST_START, BLAST_PROJECTILE, BLAST_END, Runes.DEATH_RUNE.getItem(1), Runes.AIR_RUNE.getItem(3)));
SpellBook.MODERN.register(45, new AirSpell(SpellType.WAVE, 62, 36.0, 222, WAVE_START, WAVE_PROJECTILE, WAVE_END, Runes.BLOOD_RUNE.getItem(1), Runes.AIR_RUNE.getItem(5)));
return this;
}
}
@@ -0,0 +1,146 @@
package content.global.skill.magic.modern;
import core.plugin.Initializable;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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.GameWorld;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
/**
* Represents the binding combat spell.
* @author 'Vexia
* @author Emperor
* @version 1.0
*/
@Initializable
public final class BindSpell extends CombatSpell {
/**
* The start graphic for Earth strike.
*/
private static final Graphics BIND_START = new Graphics(177, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile BIND_PROJECTILE = Projectile.create((Entity) null, null, 178, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics BIND_END = new Graphics(181, 96);
/**
* The start graphic for Earth strike.
*/
private static final Graphics SNARE_START = new Graphics(177, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile SNARE_PROJECTILE = Projectile.create((Entity) null, null, 178, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics SNARE_END = new Graphics(180, 96);
/**
* The start graphic for Earth strike.
*/
private static final Graphics ENTANGLE_START = new Graphics(177, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile ENTANGLE_PROJECTILE = Projectile.create((Entity) null, null, 178, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics ENTANGLE_END = new Graphics(179, 96);
/**
* The cast animation.
*/
private static final Animation ANIMATION = new Animation(710, Priority.HIGH);
/**
* Constructs a new {@code BindSpell} {@Code Object}
*/
public BindSpell() {
/**
* empty.
*/
}
/**
* Constructs a new {@code BindSpell} {@code Object}.
* @param type the type.
* @param level the level.
* @param sound the sound.
* @param start the start.
* @param projectile the projectile.
* @param end the end.
* @param runes the runes.
*/
private BindSpell(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.MODERN, level, baseExperience, sound, -1, ANIMATION, start, projectile, end, runes);
}
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if (victim instanceof NPC) {
NPC npc = (NPC) victim;
if (npc.getName().contains("impling")) {
state.setEstimatedHit(-2);
}
}
if (state.getEstimatedHit() == -1) {
return;
}
int tick = 9;
if (getType() == SpellType.BIND) {
state.setEstimatedHit(-2);
}
if (state.getSpell().getSpellId() == 30) {
tick = 17;
} else if (state.getSpell().getSpellId() == 56) {
tick = 25;
}
if (!victim.getLocks().isMovementLocked() && victim instanceof Player) {
((Player) victim).getPacketDispatch().sendMessage("A magical force stops you from moving!");
}
victim.getWalkingQueue().reset();
victim.getLocks().lockMovement(tick);
entity.setAttribute("entangleDelay", GameWorld.getTicks() + tick + 2);
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType() == SpellType.ENTANGLE ? 5 : 3;
}
@Override
public Plugin<SpellType> newInstance(SpellType type) throws Throwable {
// TODO: bind/snare/entangle have separate casting and onhit components
// to their sound effects, in order for splashes to sound distinct, currently
// these just sound like the spells should on success, even if they splash
SpellBook.MODERN.register(12, new BindSpell(SpellType.BIND, 20, 30.0, 101, BIND_START, BIND_PROJECTILE, BIND_END, Runes.NATURE_RUNE.getItem(2), Runes.EARTH_RUNE.getItem(3), Runes.WATER_RUNE.getItem(3)));
SpellBook.MODERN.register(30, new BindSpell(SpellType.SNARE, 50, 60.0, 186, SNARE_START, SNARE_PROJECTILE, SNARE_END, Runes.NATURE_RUNE.getItem(3), Runes.EARTH_RUNE.getItem(4), Runes.WATER_RUNE.getItem(4)));
SpellBook.MODERN.register(56, new BindSpell(SpellType.ENTANGLE, 79, 89.0, 152, ENTANGLE_START, ENTANGLE_PROJECTILE, ENTANGLE_END, Runes.NATURE_RUNE.getItem(4), Runes.EARTH_RUNE.getItem(5), Runes.WATER_RUNE.getItem(5)));
return this;
}
}
@@ -0,0 +1,205 @@
package content.global.skill.magic.modern;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.player.link.diary.DiaryType;
import core.game.node.entity.skill.SkillPulse;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.audio.Audio;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.node.scenery.Scenery;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Represents the the charging orb magic spell.
*
* @author Emperor
* @version 1.0
*/
@Initializable
public final class ChargeOrbSpells extends MagicSpell {
/**
* The animation.
*/
private static final Animation ANIMATION = Animation.create(791);
/**
* The unpowered orb item.
*/
private static final Item UNPOWERED_ORB = new Item(567);
/**
* The object id.
*/
private int objectId;
/**
* The item id.
*/
private int itemId;
/**
* The button that was clicked.
*/
private int buttonId;
/**
* Constructs a new {@code ChargeOrbSpells} {@code Object}
*/
public ChargeOrbSpells() {
/*
* empty.
*/
}
/**
* Constructs a new {@code ChargeOrbSpells} {@code Object}.
*
* @param level The level required.
* @param objectId The object id.
* @param itemId The item to add.
* @param buttonId the button clicked
* @param g The graphics.
* @param runes The runes required.
*/
public ChargeOrbSpells(int level, int objectId, int itemId, int buttonId, Graphics g, Audio a, Item... runes) {
super(SpellBook.MODERN, level, level + 10, ANIMATION, g, a, runes);
this.objectId = objectId;
this.itemId = itemId;
this.buttonId = buttonId;
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.MODERN.register(35, new ChargeOrbSpells(56, 2151, 571, 35, new Graphics(149, 96), new Audio(118), Runes.WATER_RUNE.getItem(30), Runes.COSMIC_RUNE.getItem(3), UNPOWERED_ORB));
SpellBook.MODERN.register(39, new ChargeOrbSpells(60, 29415, 575, 39, new Graphics(151, 96), new Audio(115), Runes.EARTH_RUNE.getItem(30), Runes.COSMIC_RUNE.getItem(3), UNPOWERED_ORB));
SpellBook.MODERN.register(46, new ChargeOrbSpells(63, 2153, 569, 46, new Graphics(152, 96), new Audio(117), Runes.FIRE_RUNE.getItem(30), Runes.COSMIC_RUNE.getItem(3), UNPOWERED_ORB));
SpellBook.MODERN.register(49, new ChargeOrbSpells(66, 2152, 573, 49, new Graphics(150, 96), new Audio(116), Runes.AIR_RUNE.getItem(30), Runes.COSMIC_RUNE.getItem(3), UNPOWERED_ORB));
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
if (!(target instanceof Scenery)) {
return false;
}
Player p = (Player) entity;
Scenery obj = (Scenery) target;
if (obj == null || obj.getId() != objectId) {
p.getPacketDispatch().sendMessage("You can't cast this spell on this object!");
return false;
}
if (obj.getLocation().getDistance(p.getLocation()) > 3) {
p.getPacketDispatch().sendMessage("You're standing too far from the obelisk's reach.");
return false;
}
if (!p.getAchievementDiaryManager().hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 9)
&& objectId == 2151
&& p.getInventory().containsItems(Runes.COSMIC_RUNE.getItem(15), Runes.WATER_RUNE.getItem(150), new Item(UNPOWERED_ORB.getId(), 5))) {
p.setAttribute("/save:diary:seers:water-orb-can-earn", true);
System.out.println("can_earn_true");
p.setAttribute("/save:diary:seers:water-orb", 1);
}
if (!meetsRequirements(entity, true, true)) {
return false;
}
p.faceLocation(obj.getLocation());
visualize(p, target);
if (!p.getPulseManager().hasPulseRunning()) {
p.getPulseManager().run(new ChargeOrbPulse(p, new Item(itemId), target, buttonId));
}
p.getInventory().add(new Item(itemId));
return true;
}
/**
* Represents the pulse for automatically charging orbs on obelisks.
*
* @author Splinter
* @version 1.0
*/
public static class ChargeOrbPulse extends SkillPulse<Item> {
/**
* The item we are going to recieve (always an orb).
*/
public Item item;
/**
* The target of the spell.
*/
public Node target;
/**
* The button (spell) that we clicked.
*/
public int buttonId;
/**
* The unpowered orb item.
*/
private static final Item UNPOWERED_ORB = new Item(567, 1);
/**
* Constructs a new {@code ChargeOrbPulse} {@code Object}.
*
* @param player the player.
* @param target the node.
* @param item the item.
* @param buttonId the clicked button
*/
public ChargeOrbPulse(Player player, Item item, Node target, int buttonId) {
super(player, item);
this.item = item;
this.target = target;
this.buttonId = buttonId;
}
@Override
public boolean checkRequirements() {
if (player.getInventory().contains(UNPOWERED_ORB.getId(), 1)) {
return true;
}
return false;
}
@Override
public void animate() {
player.animate(new Animation(791));
}
@Override
public boolean reward() {
if (getDelay() == 1) {
super.setDelay(4);
return false;
}
if (ChargeOrbSpells.castSpell(player, SpellBook.MODERN, buttonId, target)) {
if (!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 9)
&& player.getAttribute("diary:seers:water-orb-can-earn", false)) {
player.setAttribute("/save:diary:seers:water-orb", 1 + player.getAttribute("diary:seers:water-orb", 0));
}
if (player.getAttribute("diary:seers:water-orb", 0) >= 5) {
player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 9);
player.removeAttribute("diary:seers:water-orb-can-earn");
}
return false;
} else {
return true;
}
}
@Override
public void stop() {
player.removeAttribute("diary:seers:water-orb-can-earn");
}
}
}
@@ -0,0 +1,55 @@
package content.global.skill.magic.modern;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.audio.Audio;
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.Initializable;
import core.plugin.Plugin;
/**
* Represents the charge spell magic spell.
* @author Emperor
* @version 1.0
*/
@Initializable
public final class ChargeSpell extends MagicSpell {
/**
* Constructs a new {@code ChargeSpell} {@code Object}.
*/
public ChargeSpell() {
super(SpellBook.MODERN, 80, 180, Animation.create(811), new Graphics(6, 96), new Audio(1651), new Item[] { Runes.FIRE_RUNE.getItem(3), Runes.BLOOD_RUNE.getItem(3), Runes.AIR_RUNE.getItem(3) });
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.MODERN.register(58, this);
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player p = (Player) entity;
if (p.getLocks().isLocked("charge_cast")) {
p.getPacketDispatch().sendMessage("You need to wait for the spell to recharge.");
return false;
}
if (!meetsRequirements(entity, true, true)) {
return false;
}
p.getLocks().lock("charge_cast", 100);
visualize(entity, target);
p.registerState("godcharge").init();
p.getPacketDispatch().sendMessage("You feel charged with magic power.");
return true;
}
}
@@ -0,0 +1,55 @@
package content.global.skill.magic.modern;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Handles the crumble undead spell.
* @author Emperor
* @version 1.0
*/
@Initializable
public final class CrumbleUndead extends CombatSpell {
/**
* Constructs a new {@code CrumbleUndead} {@code Object}.
*/
public CrumbleUndead() {
super(SpellType.CRUMBLE_UNDEAD, SpellBook.MODERN, 39, 24.5, 122, 123, new Animation(724, Priority.HIGH), new Graphics(145, 96), Projectile.create((Entity) null, null, 146, 40, 36, 52, 75, 15, 11), new Graphics(147, 96), Runes.EARTH_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(1));
}
@Override
public boolean cast(Entity entity, Node target) {
NPC npc = target instanceof NPC ? (NPC) target : null;
if (npc == null || npc.getTask() == null || !npc.getTask().undead) {
((Player) entity).getPacketDispatch().sendMessage("This spell only affects the undead.");
return false;
}
return super.cast(entity, target);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.MODERN.register(22, this);
return this;
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return type.getImpactAmount(entity, victim, 0);
}
}
@@ -0,0 +1,200 @@
package content.global.skill.magic.modern;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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.Initializable;
import core.plugin.Plugin;
/**
* Represents the curse spells.
* @author Emperor
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class CurseSpells extends CombatSpell {
/**
* The start graphic for Earth strike.
*/
private static final Graphics CONFUSE_START = new Graphics(102, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile CONFUSE_PROJECTILE = Projectile.create((Entity) null, null, 103, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics CONFUSE_END = new Graphics(104, 96);
/**
* The start graphic for Earth strike.
*/
private static final Graphics WEAKEN_START = new Graphics(105, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile WEAKEN_PROJECTILE = Projectile.create((Entity) null, null, 106, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics WEAKEN_END = new Graphics(107, 96);
/**
* The start graphic for Earth strike.
*/
private static final Graphics CURSE_START = new Graphics(108, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile CURSE_PROJECTILE = Projectile.create((Entity) null, null, 109, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics CURSE_END = new Graphics(110, 96);
/**
* The start graphic for Earth strike.
*/
private static final Graphics VULNER_START = new Graphics(167, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile VULNER_PROJECTILE = Projectile.create((Entity) null, null, 168, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics VULNER_END = new Graphics(169, 96);
/**
* The start graphic for Earth strike.
*/
private static final Graphics ENFEEBLE_START = new Graphics(170, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile ENFEEBLE_PROJECTILE = Projectile.create((Entity) null, null, 171, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics ENFEEBLE_END = new Graphics(172, 96);
/**
* The start graphic for Earth strike.
*/
private static final Graphics STUN_START = new Graphics(173, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile STUN_PROJECTILE = Projectile.create((Entity) null, null, 174, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics STUN_END = new Graphics(107, 96);
/**
* The cast animation.
*/
private static final Animation LOW_ANIMATION = new Animation(716, Priority.HIGH);
/**
* The cast animation.
*/
private static final Animation HIGH_ANIMATION = new Animation(729, Priority.HIGH);
/**
* Constructs a new {@code EarthSpell} {@Code Object}
*/
public CurseSpells() {
/**
* empty.
*/
}
/**
* Constructs a new {@code CurseSpells} {@code Object}.
* @param type the type.
* @param level the level.
* @param sound the sound.
* @param start the start.
* @param projectile the projectile.
* @param end the end.
* @param runes the runes.
*/
private CurseSpells(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.MODERN, level, baseExperience, sound, -1, type.ordinal() <= SpellType.CURSE.ordinal() ? LOW_ANIMATION : HIGH_ANIMATION, start, projectile, end, runes);
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return 1;
}
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if (state.getEstimatedHit() == -1) {
return;
}
state.setEstimatedHit(-2);
switch (getType()) {
case CONFUSE:
victim.getSkills().drainLevel(Skills.ATTACK, 0.05, 0.05);
break;
case WEAKEN:
victim.getSkills().drainLevel(Skills.STRENGTH, 0.05, 0.05);
break;
case CURSE:
victim.getSkills().drainLevel(Skills.DEFENCE, 0.05, 0.05);
break;
case VULNERABILITY:
victim.getSkills().drainLevel(Skills.DEFENCE, 0.10, 0.10);
break;
case ENFEEBLE:
victim.getSkills().drainLevel(Skills.STRENGTH, 0.10, 0.10);
break;
case STUN:
victim.getSkills().drainLevel(Skills.ATTACK, 0.10, 0.10);
break;
default:
}
}
@Override
public void addExperience(Entity entity, int hit) {
entity.getSkills().addExperience(Skills.MAGIC, getExperience());
}
@Override
public Plugin<SpellType> newInstance(SpellType type) throws Throwable {
SpellBook.MODERN.register(2, new CurseSpells(SpellType.CONFUSE, 3, 13.0, 99, CONFUSE_START, CONFUSE_PROJECTILE, CONFUSE_END, Runes.BODY_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3)));
SpellBook.MODERN.register(7, new CurseSpells(SpellType.WEAKEN, 11, 21.0, 100, WEAKEN_START, WEAKEN_PROJECTILE, WEAKEN_END, Runes.BODY_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3)));
SpellBook.MODERN.register(11, new CurseSpells(SpellType.CURSE, 19, 29.0, 101, CURSE_START, CURSE_PROJECTILE, CURSE_END, Runes.BODY_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(3), Runes.WATER_RUNE.getItem(2)));
SpellBook.MODERN.register(50, new CurseSpells(SpellType.VULNERABILITY, 66, 76.0, 119, VULNER_START, VULNER_PROJECTILE, VULNER_END, Runes.SOUL_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(5), Runes.WATER_RUNE.getItem(5)));
SpellBook.MODERN.register(53, new CurseSpells(SpellType.ENFEEBLE, 73, 83.0, 120, ENFEEBLE_START, ENFEEBLE_PROJECTILE, ENFEEBLE_END, Runes.SOUL_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(8), Runes.WATER_RUNE.getItem(8)));
SpellBook.MODERN.register(57, new CurseSpells(SpellType.STUN, 80, 90.0, 121, STUN_START, STUN_PROJECTILE, STUN_END, Runes.SOUL_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(12), Runes.WATER_RUNE.getItem(12)));
return this;
}
}
@@ -0,0 +1,127 @@
package content.global.skill.magic.modern;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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.Initializable;
import core.plugin.Plugin;
/**
* Represents the earth combat spells.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class EarthSpell extends CombatSpell {
/**
* The start graphic for Earth strike.
*/
private static final Graphics STRIKE_START = new Graphics(96, 96);
/**
* The projectile for Earth strike.
*/
private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 97, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth strike.
*/
private static final Graphics STRIKE_END = new Graphics(98, 96);
/**
* The start graphic for Earth bolt.
*/
private static final Graphics BOLT_START = new Graphics(123, 96);
/**
* The projectile for Earth bolt.
*/
private static final Projectile BOLT_PROJECTILE = Projectile.create((Entity) null, null, 124, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth bolt.
*/
private static final Graphics BOLT_END = new Graphics(125, 96);
/**
* The start graphic for Earth blast.
*/
private static final Graphics BLAST_START = new Graphics(138, 96);
/**
* The projectile for Earth blast.
*/
private static final Projectile BLAST_PROJECTILE = Projectile.create((Entity) null, null, 139, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth blast.
*/
private static final Graphics BLAST_END = new Graphics(140, 96);
/**
* The start graphic for Earth wave.
*/
private static final Graphics WAVE_START = new Graphics(164, 96);
/**
* The projectile for Earth wave.
*/
private static final Projectile WAVE_PROJECTILE = Projectile.create((Entity) null, null, 165, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Earth wave.
*/
private static final Graphics WAVE_END = new Graphics(166, 96);
/**
* The cast animation.
*/
private static final Animation ANIMATION = new Animation(711, Priority.HIGH);
/**
* Constructs a new {@code EarthSpell} {@Code Object}
*/
public EarthSpell() {
/**
* empty.
*/
}
/**
* Constructs a new {@code EarthSpell} {@Code Object}.
* @param type The spell type.
* @param level The level requirement.
* @param sound The cast sound.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
* @param runes The rune requirements.
*/
private EarthSpell(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.MODERN, level, baseExperience, sound, sound + 1, ANIMATION, start, projectile, end, runes);
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 3);
}
@Override
public Plugin<SpellType> newInstance(SpellType type) throws Throwable {
SpellBook.MODERN.register(6, new EarthSpell(SpellType.STRIKE, 9, 9.5, 132, STRIKE_START, STRIKE_PROJECTILE, STRIKE_END, Runes.MIND_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(2), Runes.AIR_RUNE.getItem(1)));
SpellBook.MODERN.register(17, new EarthSpell(SpellType.BOLT, 29, 19.5, 130, BOLT_START, BOLT_PROJECTILE, BOLT_END, Runes.CHAOS_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(3), Runes.AIR_RUNE.getItem(2)));
SpellBook.MODERN.register(33, new EarthSpell(SpellType.BLAST, 53, 31.5, 128, BLAST_START, BLAST_PROJECTILE, BLAST_END, Runes.DEATH_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(4), Runes.AIR_RUNE.getItem(3)));
SpellBook.MODERN.register(52, new EarthSpell(SpellType.WAVE, 70, 40.0, 134, WAVE_START, WAVE_PROJECTILE, WAVE_END, Runes.BLOOD_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(7), Runes.AIR_RUNE.getItem(5)));
return this;
}
}
@@ -0,0 +1,45 @@
package content.global.skill.magic.modern;
import core.game.component.Component;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Represents the enchant crossbow spell.
* @author 'Vexia.
* @version 1.0
*/
@Initializable
public final class EnchantCrossbowSpell extends MagicSpell {
/**
* Constructs a new {@code EnchantCrossbowSpell} {@code Object}.
*/
public EnchantCrossbowSpell() {
super(SpellBook.MODERN, 4, 0, null, null, null, null);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.MODERN.register(3, this);
return null;
}
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
player.getInterfaceManager().open(new Component(432));
int[][] data = new int[][] { { 17, 879 }, { 21, 9335 }, { 25, 880 }, { 28, 9336 }, { 31, 9337 }, { 34, 9338 }, { 37, 9339 }, { 40, 9340 }, { 43, 9341 }, { 46, 9342 } };
for (int i = 0; i < data.length; i++) {
player.getPacketDispatch().sendItemZoomOnInterface(data[i][1], 10, 270, 432, data[i][0]);
}
return true;
}
}
@@ -0,0 +1,128 @@
package content.global.skill.magic.modern;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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.Initializable;
import core.plugin.Plugin;
/**
* Handles the fire spells.
* @author Emperor
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class FireSpell extends CombatSpell {
/**
* The start graphic for Fire strike.
*/
private static final Graphics STRIKE_START = new Graphics(99, 96);
/**
* The projectile for Fire strike.
*/
private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 100, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Fire strike.
*/
private static final Graphics STRIKE_END = new Graphics(101, 96);
/**
* The start graphic for Fire bolt.
*/
private static final Graphics BOLT_START = new Graphics(126, 96);
/**
* The projectile for Fire bolt.
*/
private static final Projectile BOLT_PROJECTILE = Projectile.create((Entity) null, null, 127, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Fire bolt.
*/
private static final Graphics BOLT_END = new Graphics(128, 96);
/**
* The start graphic for Fire blast.
*/
private static final Graphics BLAST_START = new Graphics(129, 96);
/**
* The projectile for Fire blast.
*/
private static final Projectile BLAST_PROJECTILE = Projectile.create((Entity) null, null, 130, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Fire blast.
*/
private static final Graphics BLAST_END = new Graphics(131, 96);
/**
* The start graphic for Fire wave.
*/
private static final Graphics WAVE_START = new Graphics(155, 96);
/**
* The projectile for Fire wave.
*/
private static final Projectile WAVE_PROJECTILE = Projectile.create((Entity) null, null, 156, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Fire wave.
*/
private static final Graphics WAVE_END = new Graphics(157, 96);
/**
* The cast animation.
*/
private static final Animation ANIMATION = new Animation(711, Priority.HIGH);
/**
* Constructs a new {@code FireSpell} {@Code Object}
*/
public FireSpell() {
/*
* empty.
*/
}
/**
* Constructs a new {@code FireSpell} {@code Object}.
* @param type The spell type.
* @param level The level requirement.
* @param sound The cast sound.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
* @param runes The rune requirements.
*/
private FireSpell(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.MODERN, level, baseExperience, sound, sound + 1, ANIMATION, start, projectile, end, runes);
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 4);
}
@Override
public Plugin<SpellType> newInstance(SpellType type) throws Throwable {
SpellBook.MODERN.register(8, new FireSpell(SpellType.STRIKE, 13, 11.5, 160, STRIKE_START, STRIKE_PROJECTILE, STRIKE_END, Runes.MIND_RUNE.getItem(1), Runes.FIRE_RUNE.getItem(3), Runes.AIR_RUNE.getItem(2)));
SpellBook.MODERN.register(20, new FireSpell(SpellType.BOLT, 35, 22.5, 157, BOLT_START, BOLT_PROJECTILE, BOLT_END, Runes.CHAOS_RUNE.getItem(1), Runes.FIRE_RUNE.getItem(4), Runes.AIR_RUNE.getItem(3)));
SpellBook.MODERN.register(38, new FireSpell(SpellType.BLAST, 59, 34.5, 155, BLAST_START, BLAST_PROJECTILE, BLAST_END, Runes.DEATH_RUNE.getItem(1), Runes.FIRE_RUNE.getItem(5), Runes.AIR_RUNE.getItem(4)));
SpellBook.MODERN.register(55, new FireSpell(SpellType.WAVE, 75, 42.5, 162, WAVE_START, WAVE_PROJECTILE, WAVE_END, Runes.BLOOD_RUNE.getItem(1), Runes.FIRE_RUNE.getItem(7), Runes.AIR_RUNE.getItem(5)));
return this;
}
}
@@ -0,0 +1,193 @@
package content.global.skill.magic.modern;
import core.cache.def.impl.ItemDefinition;
import core.game.container.impl.EquipmentContainer;
import core.plugin.Initializable;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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;
import org.rs09.consts.Items;
/**
* Handles the god spells.
* @author Emperor
* @author 'Vexia
*/
@Initializable
public final class GodSpells extends CombatSpell {
/**
* The spell names.
*/
private static final String[] NAMES = new String[] { "Saradomin strike", "Guthix claws", "Flames of Zamorak" };
/**
* The start graphic for Air strike.
*/
private static final Graphics SARA_START = null;
/**
* The projectile for Air strike.
*/
private static final Projectile SARA_PROJECTILE = null;
/**
* The end graphic for Air strike.
*/
private static final Graphics SARA_END = new Graphics(76, 0);
/**
* The start graphic for Air strike.
*/
private static final Graphics GUTHIX_START = null;
/**
* The projectile for Air strike.
*/
private static final Projectile GUTHIX_PROJECTILE = null;
/**
* The end graphic for Air strike.
*/
private static final Graphics GUTHIX_END = new Graphics(77, 0);
/**
* The start graphic for Air strike.
*/
private static final Graphics ZAM_START = null;
/**
* The projectile for Air strike.
*/
private static final Projectile ZAM_PROJECTILE = null;
/**
* The end graphic for Air strike.
*/
private static final Graphics ZAM_END = new Graphics(78, 0);
/**
* The cast animation.
*/
private static final Animation ANIMATION = new Animation(811, Priority.HIGH);
/**
* Constructs a new {@code AirSpell} {@Code Object}
*/
public GodSpells() {
/*
* empty.
*/
}
/**
* Constructs a new {@code GodSpells} {@code Object}.
* @param type the type.
* @param sound the sound.
* @param start the start.
* @param projectile the projectile.
* @param end the end.
* @param runes the runes.
*/
private GodSpells(SpellType type, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.MODERN, 60, 35.0, -1, -1, ANIMATION, start, projectile, end, runes);
}
@Override
public boolean meetsRequirements(Entity caster, boolean message, boolean remove) {
if (caster instanceof NPC) {
return true;
}
if (caster instanceof Player) {
int staffId = ((Player) caster).getEquipment().getNew(EquipmentContainer.SLOT_WEAPON).getId();
int required = -1;
int index = 0;
switch (runes[1].getAmount()) {
case 2: // Saradomin strike
required = 2415;
break;
case 1: // Guthix claws
required = 2416;
index = 1;
break;
case 4: // Flames of Zamorak
required = 2417;
index = 2;
break;
}
Player p = (Player) caster;
if (p.getSavedData().getActivityData().getGodCasts()[index] < 100 && !p.getZoneMonitor().isInZone("mage arena")) {
p.sendMessage("You need to cast " + NAMES[index] + " " + (100 - p.getSavedData().getActivityData().getGodCasts()[index]) + " more times inside the Mage Arena.");
return false;
}
if (staffId != required && !(index == 1 && staffId == Items.VOID_KNIGHT_MACE_8841)) {
if (message) {
((Player) caster).getPacketDispatch().sendMessage("You need to wear a " + ItemDefinition.forId(required).getName() + " to cast this spell.");
}
return false;
}
}
return super.meetsRequirements(caster, message, remove);
}
@Override
public void visualize(Entity entity, Node target) {
super.visualize(entity, target);
if (entity instanceof NPC) {
NPC n = (NPC) entity;
if (n.getId() > 911 && n.getId() < 915 || (n.getId() > 906 && n.getId() < 912)) {
n.getAnimator().forceAnimation(n.getProperties().getAttackAnimation());
}
}
}
@Override
public void visualizeImpact(Entity entity, Entity target, BattleState state) {
if (entity instanceof Player) {
int index = 0; // Saradomin strike
switch (runes[1].getAmount()) {
case 1: // Guthix claws
index = 1;
break;
case 4: // Flames of Zamorak
index = 2;
break;
}
Player p = (Player) entity;
if (p.getSavedData().getActivityData().getGodCasts()[index] < 100) {
p.getSavedData().getActivityData().getGodCasts()[index]++;
if (p.getSavedData().getActivityData().getGodCasts()[index] >= 100) {
p.sendMessage("You can now cast " + NAMES[index] + " outside the Arena.");
}
}
}
super.visualizeImpact(entity, target, state);
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 0);
}
@Override
public Plugin<SpellType> newInstance(SpellType type) throws Throwable {
SpellBook.MODERN.register(41, new GodSpells(SpellType.GOD_STRIKE, -1, SARA_START, SARA_PROJECTILE, SARA_END, Runes.BLOOD_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(2), Runes.AIR_RUNE.getItem(4)));
SpellBook.MODERN.register(42, new GodSpells(SpellType.GOD_STRIKE, -1, GUTHIX_START, GUTHIX_PROJECTILE, GUTHIX_END, Runes.BLOOD_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(1), Runes.AIR_RUNE.getItem(4)));
SpellBook.MODERN.register(43, new GodSpells(SpellType.GOD_STRIKE, -1, ZAM_START, ZAM_PROJECTILE, ZAM_END, Runes.BLOOD_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(4), Runes.AIR_RUNE.getItem(1)));
return this;
}
}
@@ -0,0 +1,46 @@
package content.global.skill.magic.modern
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.audio.Audio
import core.game.system.task.Pulse
import org.json.simple.JSONObject
import core.game.node.entity.state.PlayerState
import core.game.node.entity.state.State
import core.game.world.GameWorld;
@PlayerState("godcharge")
class GodspellChargedState(player: Player? = null) : State(player) {
val DURATION = 700
var startTick: Int = 0
override fun save(root: JSONObject) {
root.put("ticks_elapsed", GameWorld.ticks - startTick)
}
override fun parse(_data: JSONObject) {
if(_data.containsKey("ticks_elapsed")){
startTick = GameWorld.ticks - _data["ticks_elapsed"].toString().toInt()
}
}
override fun newInstance(player: Player?): State {
var ret = GodspellChargedState(player)
ret.startTick = GameWorld.ticks
return ret
}
override fun createPulse() {
player ?: return
if(GameWorld.ticks - startTick >= DURATION) return
pulse = object : Pulse(DURATION) {
override fun pulse(): Boolean {
player.sendMessage("Your magical charge fades away.")
player.clearState("godcharge")
player.audioManager.send(Audio(1650))
pulse = null
return true
}
}
}
}
@@ -0,0 +1,54 @@
package content.global.skill.magic.modern;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.combat.spell.MagicSpell;
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.GameWorld;
import core.game.world.map.Location;
import core.plugin.Plugin;
import core.tools.RandomFunction;
/**
*
* For house teleportation.
*
* @author Jamix77
*
*/
public class HouseTeleportPlugin extends MagicSpell {
public HouseTeleportPlugin(final int level, final double experience, final Item... items) {
super(SpellBook.MODERN, level, experience, null, null, null, items);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
if (((Player)entity).getHouseManager().getLocation().getExitLocation() == null) {
((Player)entity).sendMessage("You must have a house to teleport to before attempting that.");
return false;
}
Location location = ((Player)entity).getHouseManager().getLocation().getExitLocation();
if (entity.getLocks().isTeleportLocked() || !super.meetsRequirements(entity, true, false)) {
return false;
}
if (entity.getTeleporter().send(location.transform(0, RandomFunction.random(3), 0), TeleportType.NORMAL)) {
entity.setAttribute("teleport:items", super.runes);
entity.setAttribute("magic-delay", GameWorld.getTicks() + 5);
((Player) entity).getInventory().remove(super.runes);
return true;
}
return false;
}
}
@@ -0,0 +1,53 @@
package content.global.skill.magic.modern;
import core.game.container.impl.EquipmentContainer;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Represents the iban blast spell.
* @author Emperor
* @version 1.0
*/
@Initializable
public final class IbanBlast extends CombatSpell {
/**
* Constructs a new {@code IbanBlast} {@code Object}.
*/
public IbanBlast() {
super(SpellType.IBANS_BLAST, SpellBook.MODERN, 50, 60.5, -1, -1, new Animation(708, Priority.HIGH), new Graphics(87, 96), Projectile.create((Entity) null, null, 88, 40, 36, 52, 75, 15, 11), new Graphics(89, 96), Runes.FIRE_RUNE.getItem(5), Runes.DEATH_RUNE.getItem(1));
}
@Override
public boolean cast(Entity entity, Node target) {
if (((Player) entity).getEquipment().getNew(EquipmentContainer.SLOT_WEAPON).getId() != 1409) {
((Player) entity).getPacketDispatch().sendMessage("You need to wear Iban's staff to cast this spell.");
return false;
}
return super.cast(entity, target);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.MODERN.register(29, this);
return this;
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return type.getImpactAmount(entity, victim, 0);
}
}
@@ -0,0 +1,57 @@
package content.global.skill.magic.modern;
import core.game.container.impl.EquipmentContainer;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Handles the magic dart spell.
* @author Emperor
*/
@Initializable
public class MagicDart extends CombatSpell {
/**
* Constructs a new {@code MagicDart} {@code Object}.
*/
public MagicDart() {
super(SpellType.MAGIC_DART, SpellBook.MODERN, 50, 30.0, 218, 219, new Animation(1576, Priority.HIGH), null, Projectile.create((Entity) null, null, 330, 40, 36, 52, 75, 15, 11), new Graphics(331, 96), Runes.DEATH_RUNE.getItem(1), Runes.MIND_RUNE.getItem(4));
}
@Override
public boolean cast(Entity entity, Node target) {
if (entity.getSkills().getLevel(Skills.SLAYER) < 55) {
((Player) entity).getPacketDispatch().sendMessage("You need a Slayer level of 55 to cast this spell.");
return false;
}
if (((Player) entity).getEquipment().getNew(EquipmentContainer.SLOT_WEAPON).getId() != 4170) {
((Player) entity).getPacketDispatch().sendMessage("You need to wear a Slayer's staff to cast this spell.");
return false;
}
return super.cast(entity, target);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.MODERN.register(31, this);
return this;
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return type.getImpactAmount(entity, victim, 0);
}
}
@@ -0,0 +1,302 @@
package content.global.skill.magic.modern
import content.global.skill.magic.SpellListener
import content.global.skill.magic.TeleportMethod
import content.global.skill.magic.spellconsts.Modern
import core.game.event.ItemAlchemizationEvent
import core.game.event.TeleportEvent
import core.api.getAttribute
import core.api.sendMessage
import content.global.skill.prayer.Bones
import core.game.interaction.MovementPulse
import core.game.node.entity.Entity
import core.game.node.entity.impl.Projectile
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.node.entity.player.link.audio.Audio
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.entity.skill.Skills
import content.global.skill.smithing.smelting.Bar
import content.global.skill.smithing.smelting.SmeltingPulse
import core.game.node.item.Item
import core.game.world.map.Location
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Items
import core.ServerConstants
import core.api.EquipmentSlot
import core.api.getItemFromEquipment
import core.game.node.entity.combat.spell.MagicStaff
import core.game.node.entity.impl.Animator
class ModernListeners : SpellListener("modern"){
private val CONFUSE_START = Graphics(102, 96)
private val CONFUSE_PROJECTILE = Projectile.create(null as Entity?, null, 103, 40, 36, 52, 75, 15, 11)
private val CONFUSE_END = Graphics(104, 96)
private val WEAKEN_START = Graphics(105, 96)
private val WEAKEN_PROJECTILE = Projectile.create(null as Entity?, null, 106, 40, 36, 52, 75, 15, 11)
private val WEAKEN_END = Graphics(107, 96)
private val CURSE_START = Graphics(108, 96)
private val CURSE_PROJECTILE = Projectile.create(null as Entity?, null, 109, 40, 36, 52, 75, 15, 11)
private val CURSE_END = Graphics(110, 96)
private val VULNER_START = Graphics(167, 96)
private val VULNER_PROJECTILE = Projectile.create(null as Entity?, null, 168, 40, 36, 52, 75, 15, 11)
private val VULNER_END = Graphics(169, 96)
private val ENFEEBLE_START = Graphics(170, 96)
private val ENFEEBLE_PROJECTILE = Projectile.create(null as Entity?, null, 171, 40, 36, 52, 75, 15, 11)
private val ENFEEBLE_END = Graphics(172, 96)
private val STUN_START = Graphics(173, 96)
private val STUN_PROJECTILE = Projectile.create(null as Entity?, null, 174, 40, 36, 52, 75, 15, 11)
private val STUN_END = Graphics(107, 96)
private val LOW_ANIMATION = Animation(716, Animator.Priority.HIGH)
private val HIGH_ANIMATION = Animation(729, Animator.Priority.HIGH)
private val LOW_ALCH_ANIM = Animation(712)
private val LOW_ALCH_GFX = Graphics(112,5)
private val HIGH_ALCH_ANIM = Animation(713)
private val HIGH_ALCH_GFX = Graphics(113,5)
private val BONE_CONVERT_GFX = Graphics(141, 96)
private val BONE_CONVERT_ANIM = Animation(722)
override fun defineListeners() {
onCast(Modern.HOME_TELEPORT, NONE){ player, _ ->
if (!getAttribute(player, "tutorial:complete", false)) {
return@onCast
}
requires(player)
player.teleporter.send(ServerConstants.HOME_LOCATION,TeleportManager.TeleportType.HOME)
setDelay(player,true)
}
onCast(Modern.VARROCK_TELEPORT, NONE){ player, _->
requires(player,25, arrayOf(Item(Items.FIRE_RUNE_554),Item(Items.AIR_RUNE_556,3),Item(Items.LAW_RUNE_563)))
val alternateTeleport = getAttribute(player, "diaries:varrock:alttele", false)
val dest = if(alternateTeleport) Location.create(3165, 3472, 0) else Location.create(3213, 3424, 0)
sendTeleport(player,35.0, dest)
}
onCast(Modern.LUMBRIDGE_TELEPORT, NONE){ player, _ ->
requires(player,31, arrayOf(Item(Items.EARTH_RUNE_557),Item(Items.AIR_RUNE_556,3),Item(Items.LAW_RUNE_563)))
sendTeleport(player,41.0,Location.create(3221, 3219, 0))
}
onCast(Modern.FALADOR_TELEPORT, NONE){ player, _ ->
requires(player,37, arrayOf(Item(Items.WATER_RUNE_555),Item(Items.AIR_RUNE_556,3),Item(Items.LAW_RUNE_563)))
sendTeleport(player,47.0,Location.create(2965, 3378, 0))
}
onCast(Modern.CAMELOT_TELEPORT, NONE){ player, _->
requires(player,45, arrayOf(Item(Items.AIR_RUNE_556,5),Item(Items.LAW_RUNE_563)))
player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 1, 5);
sendTeleport(player,55.5, Location.create(2758, 3478, 0))
}
onCast(Modern.ARDOUGNE_TELEPORT, NONE){ player, _ ->
requires(player,51, arrayOf(Item(Items.WATER_RUNE_555,2),Item(Items.LAW_RUNE_563,2)))
sendTeleport(player,61.0, Location.create(2662, 3307, 0))
}
onCast(Modern.WATCHTOWER_TELEPORT, NONE){ player, _ ->
requires(player,58, arrayOf(Item(Items.EARTH_RUNE_557,2),Item(Items.LAW_RUNE_563,2)))
sendTeleport(player,68.0, Location.create(2549, 3112, 0))
}
onCast(Modern.TROLLHEIM_TELEPORT, NONE){ player, _ ->
requires(player,61, arrayOf(Item(Items.FIRE_RUNE_554,2),Item(Items.LAW_RUNE_563,2)))
sendTeleport(player,68.0, Location.create(2891, 3678, 0))
}
onCast(Modern.APE_ATOLL_TELEPORT, NONE){ player, _ ->
requires(player,64, arrayOf(Item(Items.FIRE_RUNE_554,2),Item(Items.WATER_RUNE_555,2),Item(Items.LAW_RUNE_563,2),Item(Items.BANANA_1963)))
sendTeleport(player,74.0, Location.create(2754, 2784, 0))
}
onCast(Modern.TELEPORT_TO_HOUSE, NONE){ player, _ ->
requires(player,40, arrayOf(Item(Items.LAW_RUNE_563), Item(Items.AIR_RUNE_556), Item(Items.EARTH_RUNE_557)))
attemptHouseTeleport(player)
}
onCast(Modern.LOW_ALCHEMY, ITEM){ player, node ->
val item = node?.asItem() ?: return@onCast
requires(player,21, arrayOf(Item(Items.FIRE_RUNE_554,3),Item(Items.NATURE_RUNE_561)))
alchemize(player,item,high = false)
}
onCast(Modern.HIGH_ALCHEMY, ITEM){ player, node ->
val item = node?.asItem() ?: return@onCast
requires(player,55, arrayOf(Item(Items.FIRE_RUNE_554,5),Item(Items.NATURE_RUNE_561,1)))
alchemize(player,item,high = true)
}
onCast(Modern.SUPERHEAT, ITEM){ player, node ->
val item = node?.asItem() ?: return@onCast
requires(player,43, arrayOf(Item(Items.FIRE_RUNE_554,4),Item(Items.NATURE_RUNE_561,1)))
superheat(player,item)
}
onCast(Modern.BONES_TO_BANANAS, NONE){ player, _ ->
requires(player,15, arrayOf(Item(Items.EARTH_RUNE_557,2), Item(Items.WATER_RUNE_555,2), Item(Items.NATURE_RUNE_561,1)))
boneConvert(player,true)
}
onCast(Modern.BONES_TO_PEACHES, NONE){ player, _ ->
requires(player,60, arrayOf(Item(Items.EARTH_RUNE_557,4), Item(Items.WATER_RUNE_555,4), Item(Items.NATURE_RUNE_561,2)))
boneConvert(player,false)
}
}
private fun boneConvert(player: Player,bananas: Boolean){
val isInMTA = player.zoneMonitor.isInZone("Creature Graveyard")
if(isInMTA && player.getAttribute("tablet-spell",false)){
player.sendMessage("You can not use this tablet in the Mage Training Arena.")
return
}
if(!bananas && !player.savedData.activityData.isBonesToPeaches && !player.getAttribute("tablet-spell",false)){
player.sendMessage("You can only learn this spell from the Mage Training Arena.")
return
}
val bones = if(isInMTA) intArrayOf(6904,6905,6906,6907) else Bones.values().map { it.itemId }.toIntArray()
for(item in player.inventory.toArray()){
item ?: continue
if(isInMTA){
if(bones.contains(item.id)){
val inInventory = player.inventory.getAmount(item.id)
val amount = inInventory * (content.minigame.mta.impl.GraveyardZone.BoneType.forItem(Item(item.id)).ordinal + 1)
if(amount > 0){
player.inventory.remove(Item(item.id,inInventory))
player.inventory.add(Item(if(bananas) Items.BANANA_1963 else Items.PEACH_6883,amount))
}
}
} else {
if(bones.contains(item.id)){
val inInventory = player.inventory.getAmount(item.id)
player.inventory.remove(Item(item.id,inInventory))
player.inventory.add(Item(if(bananas) Items.BANANA_1963 else Items.PEACH_6883,inInventory))
}
}
}
visualizeSpell(player,BONE_CONVERT_ANIM, BONE_CONVERT_GFX)
player.audioManager.send(Audio(114))
removeRunes(player)
addXP(player,if(bananas) 25.0 else 65.0)
setDelay(player,false)
}
private fun superheat(player: Player,item: Item){
if(!item.name.contains("ore") && !item.name.toLowerCase().equals("coal")){
player.sendMessage("You can only cast this spell on ore.")
return
}
// Elemental Workshop I special interaction
if(item.id == Items.ELEMENTAL_ORE_2892) {
sendMessage(player, "Even this spell is not hot enough to heat this item.")
return
}
var bar = Bar.forOre(item.id) ?: return
if(bar == Bar.IRON && player.inventory.getAmount(Items.COAL_453) >= 2 && player.skills.getLevel(Skills.SMITHING) >= Bar.STEEL.level && player.inventory.contains(Items.IRON_ORE_441,1)) bar = Bar.STEEL
if(player.skills.getLevel(Skills.SMITHING) < bar.level){
player.sendMessage("You need a smithing level of ${bar.level} to superheat that ore.")
return
}
for (items in bar.ores) {
if (!player.inventory.contains(items.id, items.amount)) {
player.packetDispatch.sendMessage("You do not have the required ores to make this bar.")
return
}
}
player.lock(3)
removeRunes(player)
addXP(player,53.0)
player.audioManager.send(117)
showMagicTab(player)
player.pulseManager.run(SmeltingPulse(player, item, bar, 1, true))
setDelay(player,false)
}
private fun alchemize(player: Player,item: Item,high:Boolean){
if(item.name == "Coins") player.sendMessage("You can't alchemize something that's already gold!").also { return }
if(!item.definition.isTradeable) player.sendMessage("You can't cast this spell on something like that.").also { return }
if(player.zoneMonitor.isInZone("Alchemists' Playground")){
player.sendMessage("You can only alch items from the cupboards!")
return
}
val coins = Item(995, item.definition.getAlchemyValue(high))
if (coins.amount > 0 && !player.inventory.hasSpaceFor(coins)) {
player.sendMessage("Not enough space in your inventory!")
return
}
if (player.pulseManager.current !is MovementPulse) {
player.pulseManager.clear()
}
val weapon = player.equipment.getItem(getItemFromEquipment(player, EquipmentSlot.WEAPON))
if (weapon != null && !weapon.equals(MagicStaff.FIRE_RUNE)) {
player.animate(Animation(if (high) 9633 else 9625))
player.graphics(Graphics(if (high) 1693 else 1692))
} else {
player.animate(Animation(if (high) 713 else 712))
player.graphics(Graphics(if (high) 113 else 112))
}
if (coins.amount > 0)
player.inventory.add(coins)
player.dispatch(ItemAlchemizationEvent(item.id, high))
player.inventory.remove(Item(item.id, 1))
removeRunes(player)
addXP(player, if (high) 65.0 else 31.0)
showMagicTab(player)
setDelay(player, 5)
}
private fun sendTeleport(player: Player, xp: Double, location: Location){
if(player.locks.isTeleportLocked){
player.removeAttribute("spell:runes")
player.sendMessage("A magical force prevents you from teleporting.")
return
}
val teleType = TeleportManager.TeleportType.NORMAL
if (player.teleporter.send(location, teleType)) {
player.dispatch(TeleportEvent(teleType, TeleportMethod.SPELL, -1, location))
removeRunes(player)
addXP(player, xp)
setDelay(player, true)
}
}
private fun attemptHouseTeleport(player: Player){
if(player.locks.isTeleportLocked){
player.removeAttribute("spell:runes")
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.")
return
}
val teleType = TeleportManager.TeleportType.NORMAL
player.teleporter.send(loc, teleType)
removeRunes(player)
addXP(player,30.0)
setDelay(player,true)
}
}
@@ -0,0 +1,61 @@
package content.global.skill.magic.modern;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Represents the sonic wave spell of an evil chicken.
* @author 'Vexia
* @date 24/11/2013
*/
@Initializable
public final class SonicWaveSpell extends CombatSpell {
/**
* The projectile for Earth strike.
*/
private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 337, 8, 8, 52, 100, 15, 1);
/**
* Constructs a new {@code EarthSpell} {@Code Object}
*/
public SonicWaveSpell() {
/*
* empty.
*/
}
/**
* Constructs a new {@code EarthSpell} {@Code Object}.
* @param type The spell type.
* @param level The level requirement.
* @param sound The cast sound.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
* @param runes The rune requirements.
*/
private SonicWaveSpell(SpellType type, int level, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.MODERN, level, 0.0, sound, sound + 1, null, start, projectile, end, runes);
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 5);
}
@Override
public Plugin<SpellType> newInstance(SpellType type) throws Throwable {
SpellBook.MODERN.register(63232, new SonicWaveSpell(SpellType.STRIKE, 1, -1, new Graphics(337), STRIKE_PROJECTILE, null));
return this;
}
}
@@ -0,0 +1,125 @@
package content.global.skill.magic.modern;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.entity.player.link.prayer.PrayerType;
import core.game.node.entity.state.EntityState;
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.Initializable;
import core.plugin.Plugin;
/**
* Handles the teleportation block spell in the modern spellbook.
* @author Splinter
*
*/
@Initializable
public final class TeleblockSpell extends CombatSpell {
/**
* The projectile for the teleblock spell.
*/
private static final Projectile TELEBLOCK_ORB = Projectile.create((Entity) null, null, 1842, 40, 36, 52, 75, 15, 11);
/**
* The ending graphic for the teleblock spell.
*/
private static final Graphics TELEBLOCK_SUCCESS = new Graphics(1843, 0);
/**
* The starting graphic for the teleblock spell.
*/
private static final Graphics TELEBLOCK_START = new Graphics(1841, 0);
/**
* Constructs a new {@code TeleblockSpell} {@code Object}.
*/
public TeleblockSpell() {
/*
* empty.
*/
}
/**
* Constructs a new {@code TeleblockSpell} {@code Object}.
* @param level - the level needed to cast this spell
* @param baseExperience - the base amount of experience we need to give
* @param impactSound -the sound played on successful impact
* @param anim - the animation to play
* @param start - the starting graphic
* @param projectile - the projectile to send
* @param end - the ending graphic
*/
public TeleblockSpell(SpellType type, int level, double baseExperience, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.MODERN, level, baseExperience, 202, 203, anim, TELEBLOCK_START, TELEBLOCK_ORB, TELEBLOCK_SUCCESS, runes);
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
SpellBook.MODERN.register(63, new TeleblockSpell(SpellType.TELEBLOCK, 85, 80, 203, new Animation(10503, Priority.HIGH), TELEBLOCK_START, TELEBLOCK_ORB, TELEBLOCK_SUCCESS, Runes.LAW_RUNE.getItem(1), Runes.DEATH_RUNE.getItem(1), Runes.CHAOS_RUNE.getItem(1)));
return this;
}
@Override
public void visualize(Entity entity, Node target) {
entity.graphics(graphic);
if (projectile != null) {
projectile.transform(entity, (Entity) target, false, 58, 10).send();
}
entity.animate(animation);
sendAudio(entity, audio);
}
@Override
public boolean cast(Entity entity, Node target) {
if (!(target instanceof Player)) {
entity.asPlayer().sendMessage("You can only cast this spell on another player.");
return false;
}
if (!entity.getZoneMonitor().isInZone("Wilderness") || !((Player) target).getZoneMonitor().isInZone("Wilderness")) {
entity.asPlayer().sendMessage("You and your opponent must both be in the wilderness for you to use this spell.");
return false;
}
if (((Player) target).isTeleBlocked()) {
entity.asPlayer().sendMessage("That player is already affected by this spell.");
return false;
}
if (!meetsRequirements(entity, true, false)) {
return false;
}
return super.cast(entity, target);
}
@Override
public void visualizeImpact(Entity entity, Entity target, BattleState state) {
super.visualizeImpact(entity, target, state);
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return 0;
}
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if(!victim.isTeleBlocked() && victim instanceof Player && state.getStyle().getSwingHandler().isAccurateImpact(entity, victim) && state.getEstimatedHit() > 0){
int ticks = 500;
if(((Player) victim).getPrayer().get(PrayerType.PROTECT_FROM_MAGIC)){
ticks /= 2;
}
victim.getStateManager().set(EntityState.TELEBLOCK, ticks);
} else if(victim.isTeleBlocked()){
entity.asPlayer().sendMessage("Your target is already blocked from teleporting.");
}
}
}
@@ -0,0 +1,102 @@
package content.global.skill.magic.modern;
import core.game.node.entity.combat.spell.Runes;
import core.game.component.Component;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.entity.player.link.audio.Audio;
import core.game.node.item.Item;
import core.game.world.map.Location;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Handles the teleport other spells.
* @author Emperor
*/
@Initializable
public final class TeleotherSpells extends MagicSpell {
/**
* The destination.
*/
private String destination;
/**
* The destination location.
*/
private Location location;
/**
* Constructs a new {@code TeleotherSpells} {@code Object}.
*/
public TeleotherSpells() {
/*
* empty.
*/
}
/**
* Constructs a new {@code TeleotherSpells} {@code Object}.
* @param level The level required.
* @param destination The destination name.
* @param location The location to teleport to.
* @param runes The runes required.
*/
public TeleotherSpells(int level, double experience, String destination, Location location, Item... runes) {
super(SpellBook.MODERN, level, experience, Animation.create(1818), Graphics.create(343), new Audio(199, 0, 0), runes);
this.destination = destination;
this.location = location;
}
@Override
public Plugin<SpellType> newInstance(SpellType arg) throws Throwable {
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)));
return this;
}
@Override
public boolean cast(Entity entity, Node target) {
Player p = (Player) entity;
if (!(target instanceof Player)) {
p.getPacketDispatch().sendMessage("You can only cast this spell on other players.");
return false;
}
if (!entity.getZoneMonitor().teleport(0, null)) {
return false;
}
Player o = (Player) target;
if (!o.isActive() || o.getLocks().isTeleportLocked() || o.getInterfaceManager().isOpened()) {
p.getPacketDispatch().sendMessage("The other player is currently busy.");
return false;
}
if(o.getZoneMonitor().isInZone("Wilderness") && o.getProperties().getCombatPulse().isInCombat()){
p.sendMessage("The other player has their hands full at the moment!");
return true;
}
if (!o.getSettings().isAcceptAid()) {
p.getPacketDispatch().sendMessage("The player is not accepting any aid.");
return false;
}
if (!meetsRequirements(entity, true, true)) {
return false;
}
visualize(entity, target);
Graphics.send(new Graphics(342), o.getLocation());
p.faceLocation(o.getLocation());
o.setAttribute("t-o_location", location);
o.getPacketDispatch().sendString(p.getUsername(), 326,1);
o.getPacketDispatch().sendString(destination, 326, 3);
o.getInterfaceManager().open(new Component(326));
return true;
}
}
@@ -0,0 +1,127 @@
package content.global.skill.magic.modern;
import core.plugin.Initializable;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
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 water spells.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class WaterSpell extends CombatSpell {
/**
* The start graphic for Water strike.
*/
private static final Graphics STRIKE_START = new Graphics(93, 96);
/**
* The projectile for Water strike.
*/
private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 94, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Water strike.
*/
private static final Graphics STRIKE_END = new Graphics(95, 96);
/**
* The start graphic for Water bolt.
*/
private static final Graphics BOLT_START = new Graphics(120, 96);
/**
* The projectile for Water bolt.
*/
private static final Projectile BOLT_PROJECTILE = Projectile.create((Entity) null, null, 121, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Water bolt.
*/
private static final Graphics BOLT_END = new Graphics(122, 96);
/**
* The start graphic for Water blast.
*/
private static final Graphics BLAST_START = new Graphics(135, 96); // 129
/**
* The projectile for Water blast.
*/
private static final Projectile BLAST_PROJECTILE = Projectile.create((Entity) null, null, 136, 40, 36, 52, 75, 15, 11); // 130
/**
* The end graphic for Water blast.
*/
private static final Graphics BLAST_END = new Graphics(137, 96); // 131
/**
* The start graphic for Water wave.
*/
private static final Graphics WAVE_START = new Graphics(161, 96);
/**
* The projectile for Water wave.
*/
private static final Projectile WAVE_PROJECTILE = Projectile.create((Entity) null, null, 162, 40, 36, 52, 75, 15, 11);
/**
* The end graphic for Water wave.
*/
private static final Graphics WAVE_END = new Graphics(163, 96);
/**
* The cast animation.
*/
private static final Animation ANIMATION = new Animation(711, Priority.HIGH);
/**
* Constructs a new {@code WaterSpell} {@Code Object}
*/
public WaterSpell() {
/*
* empty.
*/
}
/**
* Constructs a new {@code WaterSpell} {@Code Object}
* @param type The spell type.
* @param level The level requirement.
* @param sound The cast sound.
* @param start The start graphics.
* @param projectile The projectile.
* @param end The end graphics.
* @param runes The rune requirements.
*/
private WaterSpell(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) {
super(type, SpellBook.MODERN, level, baseExperience, sound, sound + 1, ANIMATION, start, projectile, end, runes);
}
@Override
public int getMaximumImpact(Entity entity, Entity victim, BattleState state) {
return getType().getImpactAmount(entity, victim, 2);
}
@Override
public Plugin<SpellType> newInstance(SpellType type) throws Throwable {
SpellBook.MODERN.register(4, new WaterSpell(SpellType.STRIKE, 5, 7.5, 211, STRIKE_START, STRIKE_PROJECTILE, STRIKE_END, Runes.MIND_RUNE.getItem(1), Runes.WATER_RUNE.getItem(1), Runes.AIR_RUNE.getItem(1)));
SpellBook.MODERN.register(14, new WaterSpell(SpellType.BOLT, 23, 16.5, 209, BOLT_START, BOLT_PROJECTILE, BOLT_END, Runes.CHAOS_RUNE.getItem(1), Runes.WATER_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2)));
SpellBook.MODERN.register(27, new WaterSpell(SpellType.BLAST, 47, 28.5, 207, BLAST_START, BLAST_PROJECTILE, BLAST_END, Runes.DEATH_RUNE.getItem(1), Runes.WATER_RUNE.getItem(3), Runes.AIR_RUNE.getItem(3)));
SpellBook.MODERN.register(48, new WaterSpell(SpellType.WAVE, 65, 37.5, 213, WAVE_START, WAVE_PROJECTILE, WAVE_END, Runes.BLOOD_RUNE.getItem(1), Runes.WATER_RUNE.getItem(7), Runes.AIR_RUNE.getItem(5)));
return this;
}
}
@@ -0,0 +1,44 @@
package content.global.skill.magic.spellconsts
object Lunar {
const val BARBARIAN_TELEPORT = 0
const val CURE_OTHER = 1
const val FERTILE_SOIL = 2
const val CURE_GROUP = 3
const val NPC_CONTACT = 4
const val ENERGY_TRANSFER = 5
const val MONSTER_EXAMINE = 6
const val HUMIDIFY = 7
const val HUNTER_KIT = 8
const val STAT_SPY = 9
const val DREAM = 10
const val PLANK_MAKE = 11
const val SPELLBOOK_SWAP = 12
const val MAGIC_IMBUE = 13
const val VENGEANCE = 14
const val BAKE_PIE = 15
const val HOME_TELEPORT = 16
const val FISHING_GUILD_TELEPORT = 17
const val KHAZARD_TELEPORT = 18
const val VENGEANCE_OTHER = 19
const val MOONCLAN_TELEPORT = 20
const val CATHERBY_TELEPORT = 21
const val STRING_JEWELLERY = 22
const val CURE_ME = 23
const val WATERBIRTH_TELEPORT = 24
const val SUPERGLASS_MAKE = 25
const val BOOST_POTION_SHARE = 26
const val STAT_RESTORE_POT_SHARE = 27
const val ICE_PLATEAU_TELEPORT = 28
const val HEAL_OTHER = 29
const val HEAL_GROUP = 30
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
}
@@ -0,0 +1,25 @@
package content.global.skill.magic.spellconsts
object Modern {
const val HOME_TELEPORT = 0
const val CONFUSE = 2
const val BONES_TO_BANANAS = 9
const val WEAKEN = 11
const val LOW_ALCHEMY = 13
const val VARROCK_TELEPORT = 15
const val LUMBRIDGE_TELEPORT = 18
const val CURSE = 19
const val FALADOR_TELEPORT = 21
const val SUPERHEAT = 25
const val CAMELOT_TELEPORT = 26
const val TELEPORT_TO_HOUSE = 23
const val ARDOUGNE_TELEPORT = 32
const val HIGH_ALCHEMY = 34
const val WATCHTOWER_TELEPORT = 37
const val BONES_TO_PEACHES = 40
const val TROLLHEIM_TELEPORT = 44
const val APE_ATOLL_TELEPORT = 47
const val VULNERABILITY = 50
const val ENFEEBLE = 53
const val STUN = 57
}