Remove plugins.gradle and factor into common extension

This commit is contained in:
Gary Tierney
2017-09-16 18:49:06 +01:00
parent d323bcd69c
commit 36282cf81e
104 changed files with 608 additions and 408 deletions
+7
View File
@@ -0,0 +1,7 @@
apolloPlugin {
name = "Banking"
packageName = "org.apollo.game.plugin.banking"
authors = [
"Major",
]
}
+7
View File
@@ -0,0 +1,7 @@
name = "Banking"
package = "org.apollo.game.plugin.banking"
authors = [ "Major" ]
[config]
srcDir = "src/"
testDir = "test/"
+76
View File
@@ -0,0 +1,76 @@
import org.apollo.game.action.DistancedAction
import org.apollo.game.message.impl.NpcActionMessage
import org.apollo.game.message.impl.ObjectActionMessage
import org.apollo.game.model.Position
import org.apollo.game.model.entity.Npc
import org.apollo.game.model.entity.Player
import org.apollo.game.model.inter.bank.BankUtils
import org.apollo.net.message.Message
val BANK_BOOTH_ID = 2213
/**
* Hook into the [ObjectActionMessage] and listen for when a bank booth's second action ("Open Bank") is selected.
*/
on { ObjectActionMessage::class }
.where { option == 2 && id == BANK_BOOTH_ID }
.then { BankAction.start(this, it, position) }
/**
* Hook into the [NpcActionMessage] and listen for when a banker's second action ("Open Bank") is selected.
*/
on { NpcActionMessage::class }
.where { option == 2 }
.then {
val npc = it.world.npcRepository[index]
if (npc.id in BANKER_NPCS) {
BankAction.start(this, it, npc.position)
}
}
/**
* The ids of all banker [Npcs][Npc].
*/
val BANKER_NPCS = setOf(166, 494, 495, 496, 497, 498, 499, 1036, 1360, 1702, 2163, 2164, 2354, 2355, 2568, 2569, 2570)
/**
* A [DistancedAction] that opens a [Player]'s bank when they get close enough to a booth or banker.
*
* @property position The [Position] of the booth/[Npc].
*/
class BankAction(player: Player, position: Position) : DistancedAction<Player>(0, true, player, position, DISTANCE) {
companion object {
/**
* The distance threshold that must be reached before the bank interface is opened.
*/
const val DISTANCE = 1
/**
* Starts a [BankAction] for the specified [Player], terminating the [Message] that triggered.
*/
fun start(message: Message, player: Player, position: Position) {
player.startAction(BankAction(player, position))
message.terminate()
}
}
override fun executeAction() {
mob.turnTo(position)
BankUtils.openBank(mob)
stop()
}
override fun equals(other: Any?): Boolean {
return other is BankAction && position == other.position
}
override fun hashCode(): Int {
return position.hashCode()
}
}
+36
View File
@@ -0,0 +1,36 @@
import org.apollo.game.model.Position
import org.apollo.game.plugin.testing.KotlinPluginTest
import org.junit.Test
import org.mockito.Mockito.verify
class OpenBankTest() : KotlinPluginTest() {
companion object {
const val BANK_BOOTH_ID = 2213
const val BANK_TELLER_ID = 166
val BANK_POSITION = Position(3200, 3200, 0)
}
@Test
fun `Interacting with a bank teller should open the players bank`() {
val bankTeller = world.spawnNpc(BANK_TELLER_ID, BANK_POSITION)
// @todo - these option numbers only match by coincidence, we should be looking up the correct ones
player.interactWith(bankTeller, option = 2)
player.waitForActionCompletion()
verify(player).openBank()
}
@Test
fun `Interacting with a bank booth object should open the players bank`() {
val bankBooth = world.spawnObject(BANK_BOOTH_ID, BANK_POSITION)
player.interactWith(bankBooth, option = 2)
player.waitForActionCompletion()
verify(player).openBank()
}
}
+74
View File
@@ -0,0 +1,74 @@
import com.moandjiezana.toml.Toml
import java.nio.file.Paths
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'com.moandjiezana.toml', name: 'toml4j', version: '0.7.1'
}
}
subprojects {
if (it.buildFile.exists()) {
apply plugin: 'apollo-plugin'
repositories {
mavenCentral()
maven {
url { 'https://dl.bintray.com/kotlin/kotlinx/' }
}
}
}
}
task("convertPluginTomlToGradle") {
def pluginTree = fileTree(dir: "${project.rootDir}/game/src/plugins/")
def pluginDefinitions = pluginTree.matching {
include "**/*.toml"
}
pluginDefinitions.each { file ->
def meta = new Toml()
meta.read(file.absoluteFile)
def pluginFolder = Paths.get(file.parentFile.absolutePath)
def name = meta.getString("name", pluginFolder.getFileName().toString())
def normalizedName = name.replaceAll("[^a-zA-Z0-9_]", '_').toLowerCase()
def description = meta.getString("description", "")
def packageName = meta.getString("package", "org.apollo.game.plugin")
def authors = meta.getList("authors", new ArrayList())
def dependencies = meta.getList("dependencies", new ArrayList())
def buildFile = new File(pluginFolder.toFile(), 'build.gradle')
buildFile.withWriter('UTF-8') { writer ->
writer.write("apolloPlugin {\n")
writer.write(" name = \"$normalizedName\"\n")
if (packageName != "org.apollo.game.plugin") {
writer.write(" packageName = \"$packageName\"\n")
}
if (description.length() > 0) {
writer.write(" description = \"$description\"\n")
}
if (authors.size > 0) {
writer.write(" authors = [\n")
authors.each { writer.write(" \"$it\",\n") }
writer.write(" ]\n")
}
if (dependencies.size > 0) {
writer.write(" dependencies = [\n")
dependencies.each { writer.write(" \"$it\",\n") }
writer.write(" ]\n")
}
writer.write("}")
}
}
}
@@ -0,0 +1,3 @@
apolloPlugin {
name = "private-messaging"
}
@@ -0,0 +1,21 @@
import org.apollo.game.message.impl.AddFriendMessage
import org.apollo.game.message.impl.SendFriendMessage
import org.apollo.game.model.entity.setting.PrivacyState
on { AddFriendMessage::class }
.then {
it.addFriend(username)
val friend = it.world.getPlayer(username)
if (friend == null || friend.friendPrivacy == PrivacyState.OFF) {
it.send(SendFriendMessage(username, 0))
return@then
} else {
it.send(SendFriendMessage(username, friend.worldId))
}
if (friend.friendsWith(it.username) && it.friendPrivacy != PrivacyState.OFF) {
friend.send(SendFriendMessage(it.username, it.worldId))
}
}
@@ -0,0 +1,8 @@
import org.apollo.game.message.impl.AddIgnoreMessage
import org.apollo.game.message.impl.RemoveIgnoreMessage
on { AddIgnoreMessage::class }
.then { it.addIgnore(username) }
on { RemoveIgnoreMessage::class }
.then { it.removeIgnore(username) }
@@ -0,0 +1,25 @@
import org.apollo.game.message.impl.ForwardPrivateChatMessage
import org.apollo.game.message.impl.PrivateChatMessage
import org.apollo.game.model.entity.Player
import org.apollo.game.model.entity.setting.PrivacyState.OFF
import org.apollo.game.model.entity.setting.PrivacyState.ON
on { PrivateChatMessage::class }
.then {
val friend = it.world.getPlayer(username)
if (interactionPermitted(it, friend)) {
friend.send(ForwardPrivateChatMessage(it.username, it.privilegeLevel, compressedMessage))
}
}
fun interactionPermitted(player: Player, friend: Player?): Boolean {
val username = player.username
val privacy = friend?.friendPrivacy
if (friend == null || friend.hasIgnored(username)) {
return false
} else {
return if (friend.friendsWith(username)) privacy != OFF else privacy == ON
}
}
+13
View File
@@ -0,0 +1,13 @@
apolloPlugin {
name = "Chat commands"
packageName = "org.apollo.game.plugin.cmd"
authors = [
"Graham",
"Major",
"lare96",
"cubeee",
]
dependencies = [
"util:command",
]
}
+13
View File
@@ -0,0 +1,13 @@
name = "Chat commands"
package = "org.apollo.game.plugin.cmd"
dependencies = [ "command_utilities" ]
authors = [
"Graham",
"Major",
"lare96",
"cubeee"
]
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,17 @@
import com.google.common.primitives.Ints
import org.apollo.game.model.Animation
import org.apollo.game.model.entity.setting.PrivilegeLevel
on_command("animate", PrivilegeLevel.MODERATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::animate [animation-id]"
if(valid_arg_length(arguments, 1, player, invalidSyntax)) {
val id = Ints.tryParse(arguments[0])
if (id == null) {
player.sendMessage(invalidSyntax)
return@then
}
player.playAnimation(Animation(id))
}
}
+5
View File
@@ -0,0 +1,5 @@
import org.apollo.game.model.entity.setting.PrivilegeLevel
// Opens the player's bank if they are an administrator.
on_command("bank", PrivilegeLevel.ADMINISTRATOR)
.then { player -> player.openBank() }
+39
View File
@@ -0,0 +1,39 @@
import com.google.common.primitives.Ints
import org.apollo.cache.def.ItemDefinition
import org.apollo.game.model.entity.setting.PrivilegeLevel
on_command("item", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::item [id] [amount]"
if (!valid_arg_length(arguments, 1..2, player, invalidSyntax)) {
return@then
}
val id = Ints.tryParse(arguments[0])
if (id == null) {
player.sendMessage(invalidSyntax)
return@then
}
var amount = 1
if (arguments.size == 2) {
val amt = Ints.tryParse(arguments[1])
if (amt == null) {
player.sendMessage(invalidSyntax)
return@then
}
amount = amt
}
if (id < 0 || id >= ItemDefinition.count()) {
player.sendMessage("The item id you specified is out of bounds!")
return@then
}
if (amount < 0) {
player.sendMessage("The amount you specified is out of bounds!")
return@then
}
player.inventory.add(id, amount)
}
+66
View File
@@ -0,0 +1,66 @@
import com.google.common.primitives.Ints
import org.apollo.cache.def.ItemDefinition
import org.apollo.cache.def.NpcDefinition
import org.apollo.cache.def.ObjectDefinition
import org.apollo.game.model.entity.setting.PrivilegeLevel
on_command("iteminfo", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::npcinfo [npc id]"
if (!valid_arg_length(arguments, 1, player, invalidSyntax)) {
return@then
}
val id = Ints.tryParse(arguments[0])
if (id == null) {
player.sendMessage(invalidSyntax)
return@then
}
val definition = ItemDefinition.lookup(id)
val members = if (definition.isMembersOnly) "members" else "not members"
player.sendMessage("Item $id is called ${definition.name}, is $members only, and has a " +
"team of ${definition.team}.")
player.sendMessage("Its description is \"${definition.description}\".")
}
on_command("npcinfo", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::npcinfo [npc id]"
if (!valid_arg_length(arguments, 1, player, invalidSyntax)) {
return@then
}
val id = Ints.tryParse(arguments[0])
if (id == null) {
player.sendMessage(invalidSyntax)
return@then
}
val definition = NpcDefinition.lookup(id)
val isCombative = if (definition.hasCombatLevel()) "has a combat level of ${definition.combatLevel}" else
"does not have a combat level"
player.sendMessage("Npc $id is called ${definition.name} and $isCombative.")
player.sendMessage("Its description is \"${definition.description}\".")
}
on_command("objectinfo", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::objectinfo [object id]"
if (!valid_arg_length(arguments, 1, player, invalidSyntax)) {
return@then
}
val id = Ints.tryParse(arguments[0])
if (id == null) {
player.sendMessage(invalidSyntax)
return@then
}
val definition = ObjectDefinition.lookup(id)
player.sendMessage("Object $id is called ${definition.name} and its description is " +
"\"${definition.description}\".")
player.sendMessage("Its width is ${definition.width} and its length is ${definition.length}.")
}
@@ -0,0 +1,11 @@
import org.apollo.game.model.entity.setting.PrivilegeLevel
on_command("broadcast", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val message = arguments.joinToString(" ")
val broadcast = "[Broadcast] ${player.username.capitalize()}: $message"
player.world.playerRepository.forEach { other ->
other.sendMessage(broadcast)
}
}
+60
View File
@@ -0,0 +1,60 @@
import org.apollo.game.model.entity.Player
import org.apollo.game.model.entity.setting.PrivilegeLevel
/**
* Adds a command to mute a player. Admins cannot be muted.
*/
on_command("mute", PrivilegeLevel.MODERATOR)
.then { player ->
val name = arguments.joinToString(" ")
val targetPlayer = player.world.getPlayer(name)
if (validate(player, targetPlayer)) {
targetPlayer.isMuted = true
player.sendMessage("You have just unmuted ${targetPlayer.username}.")
}
}
/**
* Adds a command to unmute a player.
*/
on_command("unmute", PrivilegeLevel.MODERATOR)
.then { player ->
val name = arguments.joinToString(" ")
val targetPlayer = player.world.getPlayer(name)
if (validate(player, targetPlayer)) {
targetPlayer.isMuted = false
player.sendMessage("You have just unmuted ${targetPlayer.username}.")
}
}
/**
* Adds a command to ban a player. Admins cannot be banned.
*/
on_command("ban", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val name = arguments.joinToString(" ")
val targetPlayer = player.world.getPlayer(name)
if (validate(player, targetPlayer)) {
targetPlayer.ban()
targetPlayer.logout() // TODO force logout
player.sendMessage("You have just banned ${targetPlayer.username}.")
}
}
/**
* Ensures the player isn't null, and that they aren't an Administrator.
*/
fun validate(player: Player, targetPlayer: Player?): Boolean {
if (targetPlayer == null) {
player.sendMessage("That player does not exist.")
return false
} else if (targetPlayer.privilegeLevel == PrivilegeLevel.ADMINISTRATOR) {
player.sendMessage("You cannot perform this action on Administrators.")
return false
}
return true
}
+86
View File
@@ -0,0 +1,86 @@
import com.google.common.primitives.Doubles
import com.google.common.primitives.Ints
import org.apollo.game.model.entity.Skill
import org.apollo.game.model.entity.SkillSet
import org.apollo.game.model.entity.setting.PrivilegeLevel
/**
* Maximises the player's skill set.
*/
on_command("max", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val skills = player.skillSet
for (skill in 0 until skills.size()) {
skills.addExperience(skill, SkillSet.MAXIMUM_EXP)
}
}
/**
* Levels the specified skill to the specified level, optionally updating the current level as well.
*/
on_command("level", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::level [skill-id] [level] <old>"
if (arguments.size !in 2..3) {
player.sendMessage(invalidSyntax)
return@then
}
val skillId = Ints.tryParse(arguments[0])
if (skillId == null) {
player.sendMessage(invalidSyntax)
return@then
}
val level = Ints.tryParse(arguments[1])
if (level == null) {
player.sendMessage(invalidSyntax)
return@then
}
if (skillId !in 0..20 || level !in 1..99) {
player.sendMessage(invalidSyntax)
return@then
}
val experience = SkillSet.getExperienceForLevel(level).toDouble()
var current = level
if (arguments.size == 3 && arguments[2] == "old") {
val skill = player.skillSet.getSkill(skillId)
current = skill.currentLevel
}
player.skillSet.setSkill(skillId, Skill(experience, current, level))
}
/**
* Adds the specified amount of experience to the specified skill.
*/
on_command("xp", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::xp [skill-id] [experience]"
if (arguments.size != 2) {
player.sendMessage(invalidSyntax)
return@then
}
val skillId = Ints.tryParse(arguments[0])
if (skillId == null) {
player.sendMessage(invalidSyntax)
return@then
}
val experience = Doubles.tryParse(arguments[1])
if (experience == null) {
player.sendMessage(invalidSyntax)
return@then
}
if (skillId !in 0..20 || experience <= 0) {
player.sendMessage("Invalid syntax - ::xp [skill-id] [experience]")
return@then
}
player.skillSet.addExperience(skillId, experience)
}
+110
View File
@@ -0,0 +1,110 @@
import com.google.common.primitives.Ints
import org.apollo.game.model.Position
import org.apollo.game.model.entity.Npc
import org.apollo.game.model.entity.setting.PrivilegeLevel
/**
* An array of npcs that cannot be spawned.
*/
val blacklist: IntArray = intArrayOf()
/**
* Spawns a non-blacklisted npc in the specified position, or the player's position if both 'x' and
* 'y' are not supplied.
*/
on_command("spawn", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::spawn [npc id] [optional-x] [optional-y] [optional-z]"
if (arguments.size !in intArrayOf(1, 3, 4)) {
player.sendMessage(invalidSyntax)
return@then
}
val id = Ints.tryParse(arguments[0])
if (id == null) {
player.sendMessage(invalidSyntax)
return@then
}
if (id in blacklist) {
player.sendMessage("Sorry, npc $id is blacklisted!")
return@then
}
val position: Position?
if (arguments.size == 1) {
position = player.position
} else {
var height = player.position.height
if (arguments.size == 4) {
val h = Ints.tryParse(arguments[3])
if (h == null) {
player.sendMessage(invalidSyntax)
return@then
}
height = h
}
position = Position(arguments[1].toInt(), arguments[2].toInt(), height)
}
player.world.register(Npc(player.world, id, position))
}
/**
* Mass spawns npcs around the player.
*/
on_command("mass", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::mass [npc id] [range (1-5)]"
if (arguments.size != 2) {
player.sendMessage(invalidSyntax)
return@then
}
val id = Ints.tryParse(arguments[0])
if (id == null) {
player.sendMessage(invalidSyntax)
return@then
}
val range = Ints.tryParse(arguments[1])
if (range == null) {
player.sendMessage(invalidSyntax)
return@then
}
if (id < 0 || range !in 1..5) {
player.sendMessage(invalidSyntax)
return@then
}
if (id in blacklist) {
player.sendMessage("Sorry, npc $id is blacklisted!")
return@then
}
val centerPosition = player.position
val minX = centerPosition.x - range
val minY = centerPosition.y - range
val maxX = centerPosition.x + range
val maxY = centerPosition.y + range
val z = centerPosition.height
for (x in minX..maxX) {
for (y in minY..maxY) {
player.world.register(Npc(player.world, id, Position(x, y, z)))
}
}
player.sendMessage("Mass spawning npcs with id $id.")
}
/**
* Unregisters all npcs from the world npc repository.
*/
on_command("clearnpcs", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
player.world.npcRepository.forEach { npc -> player.world.unregister(npc) }
player.sendMessage("Unregistered all npcs from the world.")
}
@@ -0,0 +1,48 @@
import com.google.common.primitives.Ints
import org.apollo.game.model.Position
import org.apollo.game.model.entity.setting.PrivilegeLevel
/**
* Sends the player's position.
*/
on_command("pos", PrivilegeLevel.MODERATOR)
.then { player ->
player.sendMessage("You are at: ${player.position}.")
}
/**
* Teleports the player to the specified position.
*/
on_command("tele", PrivilegeLevel.ADMINISTRATOR)
.then { player ->
val invalidSyntax = "Invalid syntax - ::tele [x] [y] [optional-z]"
if (!valid_arg_length(arguments, 2..3, player, invalidSyntax)) {
return@then
}
val x = Ints.tryParse(arguments[0])
if (x == null) {
player.sendMessage(invalidSyntax)
return@then
}
val y = Ints.tryParse(arguments[1])
if (y == null) {
player.sendMessage(invalidSyntax)
return@then
}
var z = player.position.height
if (arguments.size == 3) {
val plane = Ints.tryParse(arguments[2])
if (plane == null) {
player.sendMessage(invalidSyntax)
return@then
}
z = plane
}
if (z in 0..4) {
player.teleport(Position(x, y, z))
}
}
+7
View File
@@ -0,0 +1,7 @@
apolloPlugin {
name = "consumables"
packageName = "org.apollo.game.plugin.consumables"
authors = [
"Gary Tierney",
]
}
+8
View File
@@ -0,0 +1,8 @@
name = "consumables"
package = "org.apollo.game.plugin.consumables"
authors = [ "Gary Tierney" ]
dependencies = []
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,82 @@
package org.apollo.plugin.consumables
import org.apollo.game.model.entity.Player
import org.apollo.game.model.entity.Skill
/**
* An item that can be consumed to restore or buff stats.
*/
abstract class Consumable(val name: String, val id: Int, val sound: Int, val delay: Int, val replacement: Int?) {
abstract fun addEffect(player: Player)
fun consume(player: Player, slot: Int) {
addEffect(player)
player.inventory.reset(slot)
if (replacement != null) {
player.inventory.add(replacement)
}
}
}
private val consumables = mutableMapOf<Int, Consumable>()
fun isConsumable(itemId: Int) = consumables.containsKey(itemId)
fun lookupConsumable(itemId: Int): Consumable = consumables.get(itemId)!!
fun consumable(consumable: Consumable) = consumables.put(consumable.id, consumable)
enum class FoodOrDrinkType(val action: String) {
FOOD("eat"), DRINK("drink")
}
class FoodOrDrink : Consumable {
companion object {
const val EAT_FOOD_SOUND = 317
}
val restoration: Int
val type: FoodOrDrinkType
constructor(
name: String,
id: Int,
delay: Int,
type: FoodOrDrinkType,
restoration: Int,
replacement: Int? = null
) : super(name, id, EAT_FOOD_SOUND, delay, replacement) {
this.type = type
this.restoration = restoration
}
override fun addEffect(player: Player) {
val hitpoints = player.skillSet.getSkill(Skill.HITPOINTS)
val hitpointsLevel = hitpoints.currentLevel
val newHitpointsLevel = Math.min(hitpointsLevel + restoration, hitpoints.maximumLevel)
player.sendMessage("You ${type.action} the $name.")
if (newHitpointsLevel > hitpointsLevel) {
player.sendMessage("It heals some health.")
}
player.skillSet.setCurrentLevel(Skill.HITPOINTS, newHitpointsLevel)
}
}
/**
* Define a new type of [Consumable] food.
*/
fun food(name: String, id: Int, restoration: Int, replacement: Int? = null, delay: Int = 3) {
consumable(FoodOrDrink(name, id, delay, FoodOrDrinkType.FOOD, restoration, replacement))
}
/**
* Define a new type of [Consumable] drink.
*/
fun drink(name: String, id: Int, restoration: Int, replacement: Int? = null, delay: Int = 3) {
consumable(FoodOrDrink(name, id, delay, FoodOrDrinkType.DRINK, restoration, replacement))
}
@@ -0,0 +1,36 @@
import org.apollo.game.action.AsyncAction
import org.apollo.game.message.impl.ItemOptionMessage
import org.apollo.game.model.Animation
import org.apollo.game.model.entity.Player
import org.apollo.net.message.Message
import org.apollo.plugin.consumables.*
on { ItemOptionMessage::class }
.where { option == 1 && isConsumable(id) }
.then {
ConsumeAction.start(this, it, lookupConsumable(id), slot)
}
class ConsumeAction(val consumable: Consumable, player: Player, val slot: Int) :
AsyncAction<Player>(CONSUME_STARTUP_DELAY, true, player) {
companion object {
const val CONSUME_ANIMATION_ID = 829
const val CONSUME_STARTUP_DELAY = 2
/**
* Starts a [ConsumeAction] for the specified [Player], terminating the [Message] that triggered it.
*/
fun start(message: Message, player: Player, consumable: Consumable, slot: Int) {
player.startAction(ConsumeAction(consumable, player, slot))
message.terminate()
}
}
suspend override fun executeActionAsync() {
consumable.consume(mob, slot)
mob.playAnimation(Animation(CONSUME_ANIMATION_ID))
wait(consumable.delay)
}
}
@@ -0,0 +1,24 @@
import org.apollo.plugin.consumables.drink
//# Wine
drink(name = "jug_of_wine", id = 1993, restoration = 11)
//# Hot Drinks
drink(name = "nettle_tea", id = 4239, restoration = 3)
drink(name = "nettle_tea", id = 4240, restoration = 3)
//# Gnome Cocktails
drink(name = "fruit_blast", id = 2034, restoration = 9)
drink(name = "fruit_blast", id = 2084, restoration = 9)
drink(name = "pineapple_punch", id = 2036, restoration = 9)
drink(name = "pineapple_punch", id = 2048, restoration = 9)
drink(name = "wizard_blizzard", id = 2040, restoration = 5) // -4 attack, +5 strength also
drink(name = "wizard_blizzard", id = 2054, restoration = 5) // -4 attack, +5 strength also
drink(name = "short_green_guy", id = 2038, restoration = 5) // -4 attack, +5 strength also
drink(name = "short_green_guy", id = 2080, restoration = 5) // -4 attack, +5 strength also
drink(name = "drunk_dragon", id = 2032, restoration = 5) // -4 attack, +6 strength also
drink(name = "drunk_dragon", id = 2092, restoration = 5) // -4 attack, +6 strength also
drink(name = "chocolate_saturday", id = 2030, restoration = 7) // -4 attack, +6 strength also
drink(name = "chocolate_saturday", id = 2074, restoration = 7) // -4 attack, +6 strength also
drink(name = "blurberry_special", id = 2028, restoration = 7) // -4 attack, +6 strength also
drink(name = "blurberry_special", id = 2064, restoration = 7) // -4 attack, +6 strength also
@@ -0,0 +1,159 @@
import org.apollo.plugin.consumables.food
food(name = "anchovies", id = 319, restoration = 1)
food(name = "crab_meat", id = 7521, restoration = 2, replacement = 7523)
food(name = "crab_meat", id = 7523, restoration = 2, replacement = 7524)
food(name = "crab_meat", id = 7524, restoration = 2, replacement = 7525)
food(name = "crab_meat", id = 7525, restoration = 2, replacement = 7526)
food(name = "crab_meat", id = 7526, restoration = 2)
food(name = "shrimp", id = 315, restoration = 3)
food(name = "sardine", id = 325, restoration = 3)
food(name = "cooked_meat", id = 2142, restoration = 3)
food(name = "cooked_chicken", id = 2140, restoration = 3)
food(name = "ugthanki_meat", id = 1861, restoration = 3)
food(name = "karambwanji", id = 3151, restoration = 3)
food(name = "cooked_rabbit", id = 3228, restoration = 5)
food(name = "herring", id = 347, restoration = 6)
food(name = "trout", id = 333, restoration = 7)
food(name = "cod", id = 339, restoration = 7)
food(name = "mackeral", id = 355, restoration = 7)
food(name = "roast_rabbit", id = 7223, restoration = 7)
food(name = "pike", id = 351, restoration = 8)
food(name = "lean_snail_meat", id = 3371, restoration = 8)
food(name = "salmon", id = 329, restoration = 9)
food(name = "tuna", id = 361, restoration = 10)
food(name = "lobster", id = 379, restoration = 12)
food(name = "bass", id = 365, restoration = 13)
food(name = "swordfish", id = 373, restoration = 14)
food(name = "cooked_jubbly", id = 7568, restoration = 15)
food(name = "monkfish", id = 7946, restoration = 16)
food(name = "cooked_karambwan", id = 3144, restoration = 18, delay = 0)
food(name = "shark", id = 385, restoration = 20)
food(name = "sea_turtle", id = 397, restoration = 21)
food(name = "manta_ray", id = 391, restoration = 22)
//# Breads/Wraps
food(name = "bread", id = 2309, restoration = 5)
food(name = "oomlie_wrap", id = 2343, restoration = 14)
food(name = "ugthanki_kebab", id = 1883, restoration = 19)
//# Fruits
food(name = "banana", id = 1963, restoration = 2)
food(name = "sliced_banana", id = 3162, restoration = 2)
food(name = "lemon", id = 2102, restoration = 2)
food(name = "lemon_chunks", id = 2104, restoration = 2)
food(name = "lemon_slices", id = 2106, restoration = 2)
food(name = "lime", id = 2120, restoration = 2)
food(name = "lime_chunks", id = 2122, restoration = 2)
food(name = "lime_slices", id = 2124, restoration = 2)
food(name = "strawberry", id = 5504, restoration = 5)
food(name = "papaya_fruit", id = 5972, restoration = 8)
food(name = "pineapple_chunks", id = 2116, restoration = 2)
food(name = "pineapple_ring", id = 2118, restoration = 2)
food(name = "orange", id = 2108, restoration = 2)
food(name = "orange_rings", id = 2110, restoration = 2)
food(name = "orange_slices", id = 2112, restoration = 2)
//# Pies
//# TODO: pie special effects (e.g. fish pie raises fishing level)
food(name = "redberry_pie", id = 2325, restoration = 5, replacement = 2333, delay = 1)
food(name = "redberry_pie", id = 2333, restoration = 5, delay = 1)
food(name = "meat_pie", id = 2327, restoration = 6, replacement = 2331, delay = 1)
food(name = "meat_pie", id = 2331, restoration = 6, delay = 1)
food(name = "apple_pie", id = 2323, restoration = 7, replacement = 2335, delay = 1)
food(name = "apple_pie", id = 2335, restoration = 7, delay = 1)
food(name = "fish_pie", id = 7188, restoration = 6, replacement = 7190, delay = 1)
food(name = "fish_pie", id = 7190, restoration = 6, delay = 1)
food(name = "admiral_pie", id = 7198, restoration = 8, replacement = 7200, delay = 1)
food(name = "admiral_pie", id = 7200, restoration = 8, delay = 1)
food(name = "wild_pie", id = 7208, restoration = 11, replacement = 7210, delay = 1)
food(name = "wild_pie", id = 7210, restoration = 11, delay = 1)
food(name = "summer_pie", id = 7218, restoration = 11, replacement = 7220, delay = 1)
food(name = "summer_pie", id = 7220, restoration = 11, delay = 1)
//# Stews
food(name = "stew", id = 2003, restoration = 11)
food(name = "banana_stew", id = 4016, restoration = 11)
food(name = "curry", id = 2011, restoration = 19)
//# Pizzas
food(name = "plain_pizza", id = 2289, restoration = 7, replacement = 2291)
food(name = "plain_pizza", id = 2291, restoration = 7)
food(name = "meat_pizza", id = 2293, restoration = 8, replacement = 2295)
food(name = "meat_pizza", id = 2295, restoration = 8)
food(name = "anchovy_pizza", id = 2297, restoration = 9, replacement = 2299)
food(name = "anchovy_pizza", id = 2299, restoration = 9)
food(name = "pineapple_pizza", id = 2301, restoration = 11, replacement = 2303)
food(name = "pineapple_pizza", id = 2303, restoration = 11)
//# Cakes
food(name = "fishcake", id = 7530, restoration = 11)
food(name = "cake", id = 1891, restoration = 4, replacement = 1893)
food(name = "cake", id = 1893, restoration = 4, replacement = 1895)
food(name = "cake", id = 1895, restoration = 4)
food(name = "chocolate_cake", id = 1897, restoration = 5, replacement = 1899)
food(name = "chocolate_cake", id = 1899, restoration = 5, replacement = 1901)
food(name = "chocolate_cake", id = 1901, restoration = 5)
//# Vegetables
food(name = "potato", id = 1942, restoration = 1)
food(name = "spinach_roll", id = 1969, restoration = 2)
food(name = "baked_potato", id = 6701, restoration = 4)
food(name = "sweetcorn", id = 5988, restoration = 10)
food(name = "sweetcorn_bowl", id = 7088, restoration = 13)
food(name = "potato_with_butter", id = 6703, restoration = 14)
food(name = "chili_potato", id = 7054, restoration = 14)
food(name = "potato_with_cheese", id = 6705, restoration = 16)
food(name = "egg_potato", id = 7056, restoration = 16)
food(name = "mushroom_potato", id = 7058, restoration = 20)
food(name = "tuna_potato", id = 7060, restoration = 22)
//# Dairy
food(name = "cheese", id = 1985, restoration = 2)
food(name = "pot_of_cream", id = 2130, restoration = 1)
//# Gnome Food
food(name = "toads_legs", id = 2152, restoration = 3)
//# Gnome Bowls
food(name = "worm_hole", id = 2191, restoration = 12)
food(name = "worm_hole", id = 2233, restoration = 12)
food(name = "vegetable_ball", id = 2195, restoration = 12)
food(name = "vegetable_ball", id = 2235, restoration = 12)
food(name = "tangled_toads_legs", id = 2187, restoration = 15)
food(name = "tangled_toads_legs", id = 2231, restoration = 15)
food(name = "chocolate_bomb", id = 2185, restoration = 15)
food(name = "chocolate_bomb", id = 2229, restoration = 15)
//# Gnome Crunchies
food(name = "toad_crunchies", id = 2217, restoration = 7)
food(name = "toad_crunchies", id = 2243, restoration = 7)
food(name = "spicy_crunchies", id = 2213, restoration = 7)
food(name = "spicy_crunchies", id = 2241, restoration = 7)
food(name = "worm_crunchies", id = 2205, restoration = 8)
food(name = "worm_crunchies", id = 2237, restoration = 8)
food(name = "chocchip_crunchies", id = 2209, restoration = 7)
food(name = "chocchip_crunchies", id = 2239, restoration = 7)
//# Gnome Battas
food(name = "fruit_batta", id = 2225, restoration = 11)
food(name = "fruit_batta", id = 2277, restoration = 11)
food(name = "toad_batta", id = 2221, restoration = 11)
food(name = "toad_batta", id = 2255, restoration = 11)
food(name = "worm_batta", id = 2219, restoration = 11)
food(name = "worm_batta", id = 2253, restoration = 11)
food(name = "vegetable_batta", id = 2227, restoration = 11)
food(name = "vegetable_batta", id = 2281, restoration = 11)
food(name = "cheese_tom_batta", id = 2223, restoration = 11)
food(name = "cheese_tom_batta", id = 2259, restoration = 11)
@@ -0,0 +1,86 @@
package org.apollo.plugin.consumables
import org.apollo.game.message.impl.ItemOptionMessage
import org.apollo.game.model.entity.Skill
import org.apollo.game.plugin.testing.KotlinPluginTest
import org.apollo.game.plugin.testing.mockito.KotlinMockitoExtensions.matches
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
class FoodOrDrinkTests : KotlinPluginTest() {
companion object {
const val TEST_FOOD_NAME = "test_food"
const val TEST_FOOD_ID = 2000
const val TEST_FOOD_RESTORATION = 5
const val TEST_DRINK_NAME = "test_drink"
const val TEST_DRINK_ID = 2001
const val TEST_DRINK_RESTORATION = 5
const val HP_LEVEL = 5
const val MAX_HP_LEVEL = 10
}
@Before override fun setup() {
super.setup()
val skills = player.skillSet
skills.setCurrentLevel(Skill.HITPOINTS, HP_LEVEL)
skills.setMaximumLevel(Skill.HITPOINTS, MAX_HP_LEVEL)
food("test_food", TEST_FOOD_ID, TEST_FOOD_RESTORATION)
drink("test_drink", TEST_DRINK_ID, TEST_DRINK_RESTORATION)
}
@Test fun `Consuming food or drink should restore the players hitpoints`() {
val expectedHpLevel = TEST_FOOD_RESTORATION + HP_LEVEL
player.notify(ItemOptionMessage(1, -1, TEST_FOOD_ID, 1))
player.waitForActionCompletion()
val currentHpLevel = player.skillSet.getCurrentLevel(Skill.HITPOINTS)
assertThat(currentHpLevel).isEqualTo(expectedHpLevel)
}
@Test fun `A message should be sent notifying the player if the item restored hitpoints`() {
player.notify(ItemOptionMessage(1, -1, TEST_FOOD_ID, 1))
player.waitForActionCompletion()
verify(player).sendMessage(matches {
assertThat(this).contains("heals some health")
})
}
@Test fun `A message should not be sent to the player if the item did not restore hitpoints`() {
player.skillSet.setCurrentLevel(Skill.HITPOINTS, MAX_HP_LEVEL)
player.notify(ItemOptionMessage(1, -1, TEST_FOOD_ID, 1))
player.waitForActionCompletion()
verify(player, never()).sendMessage(matches {
assertThat(this).contains("heals some health")
})
}
@Test fun `A message should be sent saying the player has drank an item when consuming a drink`() {
player.notify(ItemOptionMessage(1, -1, TEST_DRINK_ID, 1))
player.waitForActionCompletion()
verify(player).sendMessage(matches {
assertThat(this).contains("You drink the ${TEST_DRINK_NAME}")
})
}
@Test fun `A message should be sent saying the player has eaten an item when consuming food`() {
player.notify(ItemOptionMessage(1, -1, TEST_FOOD_ID, 1))
player.waitForActionCompletion()
verify(player).sendMessage(matches {
assertThat(this).contains("You eat the ${TEST_FOOD_NAME}")
})
}
}
+7
View File
@@ -0,0 +1,7 @@
apolloPlugin {
name = "training-dummy"
packageName = "org.apollo.game.plugin.entity"
authors = [
"Gary Tierney",
]
}
+7
View File
@@ -0,0 +1,7 @@
name = "training-dummy"
package = "org.apollo.game.plugin.entity"
authors = [ "Gary Tierney" ]
[config]
srcDir = "src/"
testDir = "test/"
+71
View File
@@ -0,0 +1,71 @@
import kotlinx.coroutines.experimental.*
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.selects.select
import org.apollo.game.action.AsyncDistancedAction
import org.apollo.game.action.DistancedAction
import org.apollo.game.message.impl.ObjectActionMessage
import org.apollo.game.model.Animation
import org.apollo.game.model.Position
import org.apollo.game.model.entity.*
import org.apollo.net.message.Message
/**
* A list of [ObjectDefinition] identifiers which are training dummies.
*/
val DUMMY_IDS = setOf<Int>(823)
on { ObjectActionMessage::class }
.where { option == 2 && id in DUMMY_IDS }
.then { DummyAction.start(this, it, position) }
class DummyAction(val player: Player, position: Position) : AsyncDistancedAction<Player>(0, true, player, position, DISTANCE) {
companion object {
/**
* The maximum level a player can be before the dummy stops giving XP.
*/
const val LEVEL_THRESHOLD = 8
/**
* The number of experience points per hit.
*/
const val EXP_PER_HIT = 5.0
/**
* The minimum distance a player can be from the dummy.
*/
const val DISTANCE = 1
/**
* The [Animation] played when a player hits a dummy.
*/
val PUNCH_ANIMATION = Animation(422)
/**
* Starts a [DummyAction] for the specified [Player], terminating the [Message] that triggered it.
*/
fun start(message: Message, player: Player, position: Position) {
player.startAction(DummyAction(player, position))
message.terminate()
}
}
override suspend fun executeActionAsync() {
mob.sendMessage("You hit the dummy.")
mob.turnTo(this.position)
mob.playAnimation(PUNCH_ANIMATION)
wait()
val skills = player.skillSet
if (skills.getSkill(Skill.ATTACK).maximumLevel >= LEVEL_THRESHOLD) {
player.sendMessage("There is nothing more you can learn from hitting a dummy.")
} else {
skills.addExperience(Skill.ATTACK, EXP_PER_HIT)
}
}
}
@@ -0,0 +1,43 @@
import org.apollo.game.model.Position
import org.apollo.game.model.entity.Skill
import org.apollo.game.plugin.testing.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import org.mockito.Mockito.contains
import org.mockito.Mockito.verify
class TrainingDummyTest : KotlinPluginTest() {
companion object {
const val DUMMY_ID = 823
val DUMMY_POSITION = Position(3200, 3230, 0)
}
@Test fun `Hitting the training dummy should give the player attack experience`() {
val dummy = world.spawnObject(DUMMY_ID, DUMMY_POSITION)
val skills = player.skillSet
val beforeExp = skills.getExperience(Skill.ATTACK)
player.interactWith(dummy, option = 2)
player.waitForActionCompletion()
val afterExp = skills.getExperience(Skill.ATTACK)
assertThat(afterExp).isGreaterThan(beforeExp)
}
@Test fun `The player should stop getting attack experience from the training dummy at level 8`() {
val dummy = world.spawnObject(DUMMY_ID, DUMMY_POSITION)
val skills = player.skillSet
skills.setMaximumLevel(Skill.ATTACK, 8)
val beforeExp = skills.getExperience(Skill.ATTACK)
player.interactWith(dummy, option = 2)
player.waitForActionCompletion()
val afterExp = skills.getExperience(Skill.ATTACK)
verify(player).sendMessage(contains("nothing more you can learn"))
assertThat(afterExp).isEqualTo(beforeExp)
}
}
+7
View File
@@ -0,0 +1,7 @@
apolloPlugin {
name = "emote-tab"
packageName = "org.apollo.game.plugin.widget"
authors = [
"Gary Tierney",
]
}
+7
View File
@@ -0,0 +1,7 @@
name = "emote-tab"
package = "org.apollo.game.plugin.widget"
authors = [ "Gary Tierney" ]
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,50 @@
import org.apollo.game.message.impl.ButtonMessage
import org.apollo.game.model.Animation
val ANGRY_EMOTE = Animation(859)
val BECKON_EMOTE = Animation(864)
val BLOW_KISS_EMOTE = Animation(1368)
val BOW_EMOTE = Animation(858)
val CHEER_EMOTE = Animation(862)
val CLAP_EMOTE = Animation(865)
val CLIMB_ROPE_EMOTE = Animation(1130)
val CRY_EMOTE = Animation(860)
val DANCE_EMOTE = Animation(866)
val GLASS_BOX_EMOTE = Animation(1131)
val GLASS_WALL_EMOTE = Animation(1128)
val GOBLIN_BOW_EMOTE = Animation(2127)
val GOBLIN_DANCE_EMOTE = Animation(2128)
val HEAD_BANG_EMOTE = Animation(2108)
val JIG_EMOTE = Animation(2106)
val JOY_JUMP_EMOTE = Animation(2109)
val LAUGH_EMOTE = Animation(861)
val LEAN_EMOTE = Animation(1129)
val NO_EMOTE = Animation(856)
val PANIC_EMOTE = Animation(2105)
val RASPBERRY_EMOTE = Animation(2110)
val SALUTE_EMOTE = Animation(2112)
val SHRUG_EMOTE = Animation(2113)
val SPIN_EMOTE = Animation(2107)
val THINKING_EMOTE = Animation(857)
val WAVE_EMOTE = Animation(863)
val YAWN_EMOTE = Animation(2111)
val YES_EMOTE = Animation(855)
val EMOTE_MAP = mapOf<Int, Animation>(
162 to THINKING_EMOTE, 6_503 to CLIMB_ROPE_EMOTE, 169 to NO_EMOTE,
164 to BOW_EMOTE, 13_384 to GOBLIN_DANCE_EMOTE, 161 to CRY_EMOTE,
170 to LAUGH_EMOTE, 171 to CHEER_EMOTE, 163 to WAVE_EMOTE,
167 to BECKON_EMOTE, 3_362 to PANIC_EMOTE, 172 to CLAP_EMOTE,
166 to DANCE_EMOTE, 13_363 to JIG_EMOTE, 13_364 to SPIN_EMOTE,
13_365 to HEAD_BANG_EMOTE, 6_506 to LEAN_EMOTE, 165 to ANGRY_EMOTE,
13_368 to YAWN_EMOTE, 13_366 to JOY_JUMP_EMOTE, 667 to GLASS_BOX_EMOTE,
13_367 to RASPBERRY_EMOTE, 13_369 to SALUTE_EMOTE, 13_370 to SHRUG_EMOTE,
11_100 to BLOW_KISS_EMOTE, 666 to GLASS_WALL_EMOTE, 168 to YES_EMOTE,
13_383 to GOBLIN_BOW_EMOTE
)
on { ButtonMessage::class }
.where { widgetId in EMOTE_MAP }
.then {
it.playAnimation(EMOTE_MAP[widgetId])
}
+12
View File
@@ -0,0 +1,12 @@
apolloPlugin {
name = "following"
packageName = "org.apollo.game.plugin.entity"
authors = [
"Gary Tierney",
]
dependencies = [
"walkto",
"command_utilities",
"player_action",
]
}
+8
View File
@@ -0,0 +1,8 @@
name = "following"
package = "org.apollo.game.plugin.entity"
authors = [ "Gary Tierney" ]
dependencies = [ "walkto", "command_utilities", "player_action"]
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,52 @@
package org.apollo.plugin.entity.following
import org.apollo.game.action.Action
import org.apollo.game.model.Direction
import org.apollo.game.model.Position
import org.apollo.game.model.entity.Mob
import org.apollo.game.model.entity.Player
import org.apollo.net.message.Message
import org.apollo.plugin.entity.walkto.walkBehind
import org.apollo.plugin.entity.walkto.walkTo
class FollowAction(player: Player, val target: Player) : Action<Player>(0, true, player) {
var lastPosition: Position? = null
companion object {
fun start(player: Player, target: Player, message: Message? = null) {
player.startAction(FollowAction(player, target))
message?.terminate()
}
}
override fun execute() {
if (!target.isActive) {
stop()
return
}
mob.interactingMob = target
if (target.position == lastPosition) {
return
}
val distance = mob.position.getDistance(target.position)
if (distance >= 15) {
stop()
return
}
if (mob.position == target.position) {
val directions = Direction.NESW
val directionOffset = (Math.random() * directions.size).toInt()
mob.walkTo(target.position.step(1, directions[directionOffset]))
return
}
mob.walkBehind(target)
lastPosition = target.position
}
}
@@ -0,0 +1,11 @@
import com.google.common.primitives.Ints
import org.apollo.game.message.impl.PlayerActionMessage
import org.apollo.game.model.entity.setting.PrivilegeLevel
import org.apollo.plugin.entity.following.FollowAction
on_player_event { PlayerActionEvent::class }
.where { action == PlayerActionType.FOLLOW }
.then {
FollowAction.start(it, target)
terminate()
}
@@ -0,0 +1,7 @@
apolloPlugin {
name = "player_action"
packageName = "org.apollo.game.plugin.entity"
authors = [
"Gary Tierney",
]
}
@@ -0,0 +1,8 @@
name = "player_action"
package = "org.apollo.game.plugin.entity"
authors = [ "Gary Tierney" ]
dependencies = []
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,35 @@
import org.apollo.game.message.impl.SetPlayerActionMessage
import org.apollo.game.model.entity.Player
import org.apollo.game.model.event.PlayerEvent
import java.util.*
enum class PlayerActionType(val displayName: String, val slot: Int, val primary: Boolean = true) {
ATTACK("Attack", 2),
CHALLENGE("Challenge", 2),
FOLLOW("Follow", 4),
TRADE("Trade with", 5)
}
class PlayerActionEvent(player: Player, val target: Player, val action: PlayerActionType) : PlayerEvent(player)
private val playerActionsMap = mutableMapOf<Player, EnumSet<PlayerActionType>>()
private val Player.actions: EnumSet<PlayerActionType>
get() = playerActionsMap.computeIfAbsent(this, { EnumSet.noneOf(PlayerActionType::class.java) })
fun Player.enableAction(action: PlayerActionType) {
send(SetPlayerActionMessage(action.displayName, action.slot, action.primary))
actions.add(action)
}
fun Player.disableAction(action: PlayerActionType) {
send(SetPlayerActionMessage("null", action.slot, action.primary))
actions.remove(action)
}
fun Player.actionEnabled(action: PlayerActionType): Boolean {
return actions.contains(action)
}
fun Player.actionAt(slot: Int): PlayerActionType? {
return actions.find { it.slot == slot }
}
@@ -0,0 +1,18 @@
import org.apollo.game.message.impl.PlayerActionMessage
import org.apollo.game.model.event.impl.LoginEvent
on { PlayerActionMessage::class }
.then {
val action = it.actionAt(option)
if (action != null) {
it.world.submit(PlayerActionEvent(it, it.world.playerRepository[index], action))
}
terminate()
}
on_player_event { LoginEvent::class }
.then {
it.enableAction(PlayerActionType.FOLLOW)
it.enableAction(PlayerActionType.TRADE)
}
+10
View File
@@ -0,0 +1,10 @@
apolloPlugin {
name = "spawning"
packageName = "org.apollo.game.plugin.entity"
authors = [
"Gary Tierney",
]
dependencies = [
"entity_lookup",
]
}
+8
View File
@@ -0,0 +1,8 @@
name = "spawning"
package = "org.apollo.game.plugin.entity"
authors = [ "Gary Tierney" ]
dependencies = [ "entity_lookup" ]
[config]
srcDir = "src/"
testDir = "test/"
+13
View File
@@ -0,0 +1,13 @@
import org.apollo.game.model.*
data class Spawn(val id: Int?, val name: String, val position: Position, val facing: Direction,
val spawnAnimation: Animation? = null,
val spawnGraphic: Graphic? = null)
object Spawns {
val list = mutableListOf<Spawn>()
}
fun npc_spawn(name: String, x: Int, y: Int, z: Int = 0, id: Int? = null, facing: Direction = Direction.NORTH) {
Spawns.list.add(Spawn(id, name, Position(x, y, z), facing))
}
@@ -0,0 +1,24 @@
import org.apollo.cache.def.NpcDefinition
import org.apollo.game.model.entity.Npc
start { world ->
Spawns.list.forEach {
val definition = if (it.id != null) NpcDefinition.lookup(it.id!!) else lookup_npc(it.name)
if (definition == null) {
throw IllegalArgumentException("Invalid NPC name or ID ${it.name}, ${it.id}")
}
val npc = Npc(world, definition.id, it.position)
npc.turnTo(it.position.step(1, it.facing))
if (it.spawnAnimation != null) {
npc.playAnimation(it.spawnAnimation)
}
if (it.spawnGraphic != null) {
npc.playGraphic(it.spawnGraphic)
}
world.register(npc)
}
}
+7
View File
@@ -0,0 +1,7 @@
apolloPlugin {
name = "walkto"
packageName = "org.apollo.plugin.entity.walkto"
authors = [
"Gary Tierney",
]
}
+4
View File
@@ -0,0 +1,4 @@
name = "walkto"
package = "org.apollo.plugin.entity.walkto"
authors = ["Gary Tierney"]
dependencies = []
+59
View File
@@ -0,0 +1,59 @@
package org.apollo.plugin.entity.walkto
import org.apollo.game.model.Direction
import org.apollo.game.model.Position
import org.apollo.game.model.entity.*
import org.apollo.game.model.entity.obj.GameObject
import org.apollo.game.model.entity.path.SimplePathfindingAlgorithm
private fun bounds(target: Entity): Pair<Int, Int> = when (target) {
is GameObject -> {
val orientation = Direction.WNES[target.orientation]
val rotated = (orientation == Direction.WEST || orientation == Direction.EAST)
val width = if (rotated) target.definition.length else target.definition.width
val height = if (rotated) target.definition.width else target.definition.length
Pair(width, height)
}
is Npc -> Pair(target.definition.size, target.definition.size)
is Player -> Pair(1, 1)
else -> error("Invalid entity type")
}
fun Mob.walkTo(target: Entity, positioningDirection: Direction? = null) {
val (sourceWidth, sourceHeight) = bounds(target)
val (targetWidth, targetHeight) = bounds(target)
val direction = positioningDirection ?: Direction.between(position, target.position)
val dx = direction.deltaX()
val dy = direction.deltaY()
val targetX = if (dx <= 0) target.position.x else target.position.x + targetWidth - 1
val targetY = if (dy <= 0) target.position.y else target.position.y + targetHeight - 1
val offsetX = if (dx < 0) -sourceWidth else if (dx > 0) 1 else 0
val offsetY = if (dy < 0) -sourceHeight else if (dy > 0) 1 else 0
walkTo(Position(targetX + offsetX, targetY + offsetY, position.height))
}
fun Mob.walkBehind(target: Mob) {
walkTo(target, target.lastDirection.opposite())
}
fun Mob.walkTo(target: Position, positionPredicate: (Position) -> Boolean = { true }) {
if (position == target) {
return
}
val pathfinder = SimplePathfindingAlgorithm(world.collisionManager)
val path = pathfinder.find(position, target)
for (step in path) {
if (!positionPredicate.invoke(step)) {
return
}
walkingQueue.addStep(step)
}
}
@@ -0,0 +1,10 @@
apolloPlugin {
name = "al-kharid npc spawns"
packageName = "org.apollo.game.plugin.locations"
authors = [
"Jesse W",
]
dependencies = [
"spawning",
]
}
@@ -0,0 +1,8 @@
name = "al-kharid npc spawns"
package = "org.apollo.game.plugin.locations"
authors = [ "Jesse W" ]
dependencies = [ "spawning" ]
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,111 @@
import org.apollo.game.model.Direction
// Generic npcs
npc_spawn("man", x = 3276, y = 3186)
npc_spawn("man", x = 3282, y = 3197)
npc_spawn("man", id = 3, x = 3301, y = 3200)
npc_spawn("man", id = 3, x = 3300, y = 3208)
npc_spawn("man", id = 2, x = 3297, y = 3196)
npc_spawn("man", id = 16, x = 3294, y = 3204)
npc_spawn("spider", x = 3319, y = 3145)
npc_spawn("spider", x = 3319, y = 3140)
npc_spawn("spider", x = 3323, y = 3138)
npc_spawn("scorpion", x = 3282, y = 3149)
//Camels
npc_spawn("cam_the_camel", x = 3295, y = 3232)
npc_spawn("elly_the_camel", x = 3312, y = 3210)
npc_spawn("camel", x = 3285, y = 3198)
npc_spawn("ollie_the_camel", x = 3291, y = 3209)
npc_spawn("al_the_camel", x = 3275, y = 3162)
// Quest npc
npc_spawn("osman", x = 3286, y = 3180, facing = Direction.EAST)
npc_spawn("hassan", x = 3302, y = 3163)
npc_spawn("father_reen", x = 3272, y = 3158)
npc_spawn("man", id = 663, x = 3297, y = 3287)
// Boarder guards
npc_spawn("border_guard", x = 3268, y = 3226)
npc_spawn("border_guard", x = 3267, y = 3226)
npc_spawn("border_guard", x = 3268, y = 3229, facing = Direction.SOUTH)
npc_spawn("border_guard", x = 3267, y = 3229, facing = Direction.SOUTH)
// Palace guards
npc_spawn("Al-Kharid warrior", x = 3285, y = 3174)
npc_spawn("Al-Kharid warrior", x = 3283, y = 3168)
npc_spawn("Al-Kharid warrior", x = 3285, y = 3169)
npc_spawn("Al-Kharid warrior", x = 3290, y = 3162)
npc_spawn("Al-Kharid warrior", x = 3295, y = 3170)
npc_spawn("Al-Kharid warrior", x = 3300, y = 3175)
npc_spawn("Al-Kharid warrior", x = 3300, y = 3171)
npc_spawn("Al-Kharid warrior", x = 3301, y = 3168)
// Shanty pass
npc_spawn("shantay_guard", x = 3301, y = 3120)
npc_spawn("shantay_guard", x = 3302, y = 3126)
npc_spawn("shantay_guard", x = 3306, y = 3126)
npc_spawn("shantay_guard", id = 838, x = 3303, y = 3118)
// Mine
npc_spawn("scorpion", x = 3296, y = 3294)
npc_spawn("scorpion", x = 3298, y = 3280)
npc_spawn("scorpion", x = 3299, y = 3299)
npc_spawn("scorpion", x = 3299, y = 3309)
npc_spawn("scorpion", x = 3300, y = 3287)
npc_spawn("scorpion", x = 3300, y = 3315)
npc_spawn("scorpion", x = 3301, y = 3305)
npc_spawn("scorpion", x = 3301, y = 3312)
// Functional npcs
npc_spawn("gnome_pilot", x = 3279, y = 3213)
npc_spawn("banker", id = 496, x = 3267, y = 3164, facing = Direction.EAST)
npc_spawn("banker", id = 496, x = 3267, y = 3167, facing = Direction.EAST)
npc_spawn("banker", id = 496, x = 3267, y = 3169, facing = Direction.EAST)
npc_spawn("banker", id = 497, x = 3267, y = 3166, facing = Direction.EAST)
npc_spawn("banker", id = 497, x = 3267, y = 3168, facing = Direction.EAST)
npc_spawn("gem_trader", x = 3287, y = 3210)
npc_spawn("zeke", x = 3289, y = 3189)
npc_spawn("shantay", x = 3304, y = 3124)
npc_spawn("rug_merchant", id = 2296, x = 3311, y = 3109, facing = Direction.WEST)
npc_spawn("ranael", x = 3315, y = 3163)
npc_spawn("shop_keeper", id = 524, x = 3315, y = 3178)
npc_spawn("shop_assistant", id = 525, x = 3315, y = 3180, facing = Direction.WEST)
npc_spawn("louie_legs", x = 3316, y = 3175, facing = Direction.WEST)
npc_spawn("ellis", x = 3274, y = 3192)
npc_spawn("dommik", x = 3321, y = 3193)
npc_spawn("tool_leprechaun", x = 3319, y = 3204)
npc_spawn("ali_morrisane", x = 3304, y = 3211, facing = Direction.EAST)
npc_spawn("silk_trader", x = 3300, y = 3203)
npc_spawn("karim", x = 3273, y = 3180)
@@ -0,0 +1,10 @@
apolloPlugin {
name = "edgeville npc spawns"
packageName = "org.apollo.game.plugin.locations"
authors = [
"Jesse W",
]
dependencies = [
"spawning",
]
}
@@ -0,0 +1,8 @@
name = "edgeville npc spawns"
package = "org.apollo.game.plugin.locations"
authors = [ "Jesse W" ]
dependencies = [ "spawning" ]
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,51 @@
import org.apollo.game.model.Direction
// Generic npcs
npc_spawn("man", x = 3095, y = 3508)
npc_spawn("man", x = 3095, y = 3511)
npc_spawn("man", x = 3098, y = 3509)
npc_spawn("man", id = 2, x = 3093, y = 3511)
npc_spawn("man", id = 3, x = 3097, y = 3508)
npc_spawn("man", id = 3, x = 3092, y = 3508)
npc_spawn("man", id = 3, x = 3097, y = 3512)
npc_spawn("guard", x = 3086, y = 3516)
npc_spawn("guard", x = 3094, y = 3518)
npc_spawn("guard", x = 3108, y = 3514)
npc_spawn("guard", x = 3110, y = 3514)
npc_spawn("guard", x = 3113, y = 3514)
npc_spawn("guard", x = 3113, y = 3516)
npc_spawn("sheep", id = 43, x = 3050, y = 3516)
npc_spawn("sheep", id = 43, x = 3051, y = 3514)
npc_spawn("sheep", id = 43, x = 3056, y = 3517)
npc_spawn("ram", id = 3673, x = 3048, y = 3515)
npc_spawn("monk", x = 3044, y = 3491)
npc_spawn("monk", x = 3045, y = 3483)
npc_spawn("monk", x = 3045, y = 3497)
npc_spawn("monk", x = 3050, y = 3490)
npc_spawn("monk", x = 3054, y = 3490)
npc_spawn("monk", x = 3058, y = 3497)
// Functional npcs
npc_spawn("richard", x = 3098, y = 3516)
npc_spawn("doris", x = 3079, y = 3491)
npc_spawn("brother_jered", x = 3045, y = 3488)
npc_spawn("brother_althric", x = 3054, y = 3504)
npc_spawn("abbot_langley", x = 3059, y = 3484)
npc_spawn("oziach", x = 3067, y = 3518, facing = Direction.EAST)
npc_spawn("shop_keeper", id = 528, x = 3079, y = 3509)
npc_spawn("shop_assistant", id = 529, x = 3082, y = 3513)
npc_spawn("banker", x = 3096, y = 3489, facing = Direction.WEST)
npc_spawn("banker", x = 3096, y = 3491, facing = Direction.WEST)
npc_spawn("banker", x = 3096, y = 3492)
npc_spawn("banker", x = 3098, y = 3492)
npc_spawn("mage_of_zamorak", x = 3106, y = 3560)
@@ -0,0 +1,10 @@
apolloPlugin {
name = "falador npc spawns"
packageName = "org.apollo.game.plugin.locations"
authors = [
"Jesse W",
]
dependencies = [
"spawning",
]
}
+8
View File
@@ -0,0 +1,8 @@
name = "falador npc spawns"
package = "org.apollo.game.plugin.locations"
authors = [ "Jesse W" ]
dependencies = [ "spawning" ]
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,168 @@
// Generic npcs
npc_spawn("chicken", x = 2965, y = 3345)
npc_spawn("duck", x = 2988, y = 3383)
npc_spawn("duck", x = 2992, y = 3383)
npc_spawn("duck", x = 2993, y = 3385)
npc_spawn("drunken_man", x = 2957, y = 3368, z = 1)
npc_spawn("dwarf", id = 118, x = 3023, y = 3334)
npc_spawn("dwarf", id = 118, x = 3027, y = 3341)
npc_spawn("dwarf", id = 118, x = 3012, y = 3341)
npc_spawn("dwarf", id = 118, x = 3017, y = 3346, z = 1)
npc_spawn("dwarf", id = 118, x = 3011, y = 3341, z = 1)
npc_spawn("dwarf", id = 121, x = 3027, y = 3341)
npc_spawn("dwarf", id = 382, x = 3017, y = 3340)
npc_spawn("dwarf", id = 3294, x = 3022, y = 3338)
npc_spawn("dwarf", id = 3295, x = 3021, y = 3341)
npc_spawn("gardener", x = 2998, y = 3385)
npc_spawn("gardener", x = 3019, y = 3369)
npc_spawn("gardener", id = 3234, x = 3016, y = 3386)
npc_spawn("guard", x = 2965, y = 3394)
npc_spawn("guard", x = 2964, y = 3396)
npc_spawn("guard", x = 2966, y = 3397)
npc_spawn("guard", x = 2964, y = 3384)
npc_spawn("guard", x = 2963, y = 3380)
npc_spawn("guard", x = 3006, y = 3325)
npc_spawn("guard", x = 3008, y = 3320)
npc_spawn("guard", x = 3006, y = 3322)
npc_spawn("guard", x = 3038, y = 3356)
npc_spawn("guard", id = 10, x = 2942, y = 3375)
npc_spawn("guard", id = 10, x = 3040, y = 3352)
npc_spawn("guard", id = 3230, x = 2967, y = 3395)
npc_spawn("guard", id = 3230, x = 2966, y = 3392)
npc_spawn("guard", id = 3230, x = 2963, y = 3376)
npc_spawn("guard", id = 3230, x = 2954, y = 3382)
npc_spawn("guard", id = 3230, x = 2950, y = 3377)
npc_spawn("guard", id = 3230, x = 2968, y = 3381)
npc_spawn("guard", id = 3231, x = 3033, y = 3389, z = 1)
npc_spawn("guard", id = 3231, x = 3041, y = 3388, z = 1)
npc_spawn("guard", id = 3231, x = 3048, y = 3389, z = 1)
npc_spawn("guard", id = 3231, x = 3056, y = 3389, z = 1)
npc_spawn("guard", id = 3231, x = 3062, y = 3386, z = 1)
npc_spawn("guard", id = 3231, x = 3058, y = 3329, z = 1)
npc_spawn("guard", id = 3231, x = 3050, y = 3329, z = 1)
npc_spawn("guard", id = 3231, x = 3038, y = 3329, z = 1)
npc_spawn("guard", id = 3231, x = 3029, y = 3329, z = 1)
npc_spawn("swan", x = 2960, y = 3359)
npc_spawn("swan", x = 2963, y = 3360)
npc_spawn("swan", x = 2968, y = 3359)
npc_spawn("swan", x = 2971, y = 3360)
npc_spawn("swan", x = 2976, y = 3358)
npc_spawn("swan", x = 2989, y = 3384)
npc_spawn("man", id = 3223, x = 2991, y = 3365)
npc_spawn("man", id = 3225, x = 3037, y = 3345, z = 1)
npc_spawn("white_knight", x = 2983, y = 3343)
npc_spawn("white_knight", x = 2981, y = 3334)
npc_spawn("white_knight", x = 2988, y = 3335)
npc_spawn("white_knight", x = 2996, y = 3342)
npc_spawn("white_knight", x = 2960, y = 3340)
npc_spawn("white_knight", x = 2962, y = 3336)
npc_spawn("white_knight", x = 2974, y = 3342)
npc_spawn("white_knight", x = 2972, y = 3345)
npc_spawn("white_knight", x = 2977, y = 3348)
npc_spawn("white_knight", id = 3348, x = 2971, y = 3340)
npc_spawn("white_knight", id = 3348, x = 2978, y = 3350)
npc_spawn("white_knight", x = 2964, y = 3330, z = 1)
npc_spawn("white_knight", x = 2968, y = 3334, z = 1)
npc_spawn("white_knight", x = 2969, y = 3339, z = 1)
npc_spawn("white_knight", x = 2978, y = 3332, z = 1)
npc_spawn("white_knight", x = 2958, y = 3340, z = 1)
npc_spawn("white_knight", x = 2960, y = 3343, z = 1)
npc_spawn("white_knight", id = 3348, x = 2987, y = 3334, z = 1)
npc_spawn("white_knight", id = 3348, x = 2983, y = 3336, z = 1)
npc_spawn("white_knight", id = 3348, x = 2987, y = 3334, z = 1)
npc_spawn("white_knight", id = 3348, x = 2979, y = 3348, z = 1)
npc_spawn("white_knight", id = 3348, x = 2964, y = 3337, z = 1)
npc_spawn("white_knight", id = 3349, x = 2989, y = 3344, z = 1)
npc_spawn("white_knight", x = 2985, y = 3342, z = 2)
npc_spawn("white_knight", id = 3348, x = 2979, y = 3348, z = 2)
npc_spawn("white_knight", id = 3348, x = 2974, y = 3329, z = 2)
npc_spawn("white_knight", id = 3348, x = 2982, y = 3341, z = 2)
npc_spawn("white_knight", id = 3349, x = 2990, y = 3341, z = 2)
npc_spawn("white_knight", id = 3349, x = 2971, y = 3330, z = 2)
npc_spawn("white_knight", id = 3349, x = 2965, y = 3350, z = 2)
npc_spawn("white_knight", id = 3349, x = 2965, y = 3329, z = 2)
npc_spawn("white_knight", id = 3350, x = 2961, y = 3347, z = 2)
npc_spawn("white_knight", id = 3349, x = 2962, y = 3339, z = 3)
npc_spawn("white_knight", id = 3350, x = 2960, y = 3336, z = 3)
npc_spawn("white_knight", id = 3350, x = 2984, y = 3349, z = 3)
npc_spawn("woman", id = 3226, x = 2991, y = 3384)
// Functional npcs
npc_spawn("apprentice_workman", id = 3235, x = 2971, y = 3369, z = 1)
npc_spawn("banker", id = 495, x = 2945, y = 3366)
npc_spawn("banker", id = 495, x = 2946, y = 3366)
npc_spawn("banker", id = 495, x = 2947, y = 3366)
npc_spawn("banker", id = 495, x = 2948, y = 3366)
npc_spawn("banker", x = 2949, y = 3366)
npc_spawn("banker", x = 3015, y = 3353)
npc_spawn("banker", x = 3014, y = 3353)
npc_spawn("banker", x = 3013, y = 3353)
npc_spawn("banker", x = 3012, y = 3353)
npc_spawn("banker", x = 3011, y = 3353)
npc_spawn("banker", x = 3010, y = 3353)
npc_spawn("cassie", x = 2976, y = 3383)
npc_spawn("emily", x = 2954, y = 3372)
npc_spawn("flynn", x = 2950, y = 3387)
npc_spawn("hairdresser", x = 2944, y = 3380)
npc_spawn("herquin", x = 2945, y = 3335)
npc_spawn("heskel", x = 3007, y = 3374)
npc_spawn("kaylee", x = 2957, y = 3372)
npc_spawn("tina", x = 2955, y = 3371, z = 1)
npc_spawn("tool_leprechaun", x = 3005, y = 3370)
npc_spawn("squire", x = 2977, y = 3343)
npc_spawn("sir_tiffy_cashien", x = 2997, y = 3373)
npc_spawn("sir_amik_varze", x = 2960, y = 3336, z = 2)
npc_spawn("sir_vyvin", x = 2983, y = 3335, z = 2)
npc_spawn("shop_keeper", id = 524, x = 2955, y = 3389)
npc_spawn("shop_assistant", id = 525, x = 2957, y = 3387)
npc_spawn("wayne", x = 2972, y = 3312)
npc_spawn("workman", id = 3236, x = 2975, y = 3369, z = 1)
npc_spawn("wyson_the_gardener", x = 3028, y = 3381)
@@ -0,0 +1,10 @@
apolloPlugin {
name = "lumbridge npc spawns"
packageName = "org.apollo.game.plugin.locations"
authors = [
"Gary Tierney",
]
dependencies = [
"spawning",
]
}
@@ -0,0 +1,8 @@
name = "lumbridge npc spawns"
package = "org.apollo.game.plugin.locations"
authors = [ "Gary Tierney" ]
dependencies = [ "spawning" ]
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,11 @@
npc_spawn("woman", id = 4, x = 3232, y = 3207)
npc_spawn("man", id = 1, x = 3231, y = 3237)
npc_spawn("man", id = 2, x = 3224, y = 3240)
npc_spawn("woman", id = 5, x = 3229, y = 2329)
npc_spawn("hans", x = 3221, y = 3221)
npc_spawn("father aereck", x = 3243, y = 3210)
npc_spawn("bob", x = 3231, y = 3203)
npc_spawn("shop keeper", x = 3212, y = 3247)
npc_spawn("shop assistant", x = 3211, y = 3245)
npc_spawn("lumbridge guide", x = 323, y = 3229)
@@ -0,0 +1,10 @@
apolloPlugin {
name = "tutorial island npc spawns"
packageName = "org.apollo.game.plugin.locations"
authors = [
"Jesse W",
]
dependencies = [
"spawning",
]
}
@@ -0,0 +1,8 @@
name = "tutorial island npc spawns"
package = "org.apollo.game.plugin.locations"
authors = [ "Jesse W" ]
dependencies = [ "spawning" ]
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,41 @@
import org.apollo.game.model.Direction
// Functional npcs
// 'Above-ground' npcs
npc_spawn("master_chef", x = 3076, y = 3085)
npc_spawn("quest_guide", x = 3086, y = 3122)
npc_spawn("financial_advisor", x = 3127, y = 3124, facing = Direction.WEST)
npc_spawn("brother_brace", x = 3124, y = 3107, facing = Direction.EAST)
npc_spawn("magic_instructor", x = 3140, y = 3085)
// 'Below-ground' npcs
// Note: They aren't actually on a different plane, they're just in a different location that
// pretends to be underground.
npc_spawn("mining_instructor", x = 3081, y = 9504)
npc_spawn("combat_instructor", x = 3104, y = 9506)
// Non-humanoid npcs
npc_spawn("fishing_spot", id = 316, x = 3102, y = 3093)
npc_spawn("chicken", x = 3140, y = 3095)
npc_spawn("chicken", x = 3140, y = 3093)
npc_spawn("chicken", x = 3138, y = 3092)
npc_spawn("chicken", x = 3137, y = 3094)
npc_spawn("chicken", x = 3138, y = 3095)
// 'Below-ground' npcs
// Note: They aren't actually on a different plane, they're just in a different location that
// pretends to be underground.
npc_spawn("giant_rat", id = 87, x = 3105, y = 9514)
npc_spawn("giant_rat", id = 87, x = 3105, y = 9517)
npc_spawn("giant_rat", id = 87, x = 3106, y = 9514)
npc_spawn("giant_rat", id = 87, x = 3104, y = 9514)
npc_spawn("giant_rat", id = 87, x = 3105, y = 9519)
npc_spawn("giant_rat", id = 87, x = 3109, y = 9516)
npc_spawn("giant_rat", id = 87, x = 3108, y = 9520)
npc_spawn("giant_rat", id = 87, x = 3102, y = 9517)
@@ -0,0 +1,10 @@
apolloPlugin {
name = "varrock npc spawns"
packageName = "org.apollo.game.plugin.locations"
authors = [
"Jesse W",
]
dependencies = [
"spawning",
]
}
+8
View File
@@ -0,0 +1,8 @@
name = "varrock npc spawns"
package = "org.apollo.game.plugin.locations"
authors = [ "Jesse W" ]
dependencies = [ "spawning" ]
[config]
srcDir = "src/"
testDir = "test/"
@@ -0,0 +1,267 @@
import org.apollo.game.model.Direction
npc_spawn("barbarian_woman", x = 3222, y = 3399)
npc_spawn("bear", id = 106, x = 3289, y = 3351)
npc_spawn("black_knight", x = 3238, y = 3514)
npc_spawn("black_knight", x = 3227, y = 3518)
npc_spawn("black_knight", x = 3279, y = 3502)
npc_spawn("dark_wizard", id = 174, x = 3230, y = 3366)
npc_spawn("dark_wizard", id = 174, x = 3228, y = 3368)
npc_spawn("dark_wizard", id = 174, x = 3225, y = 3367)
npc_spawn("dark_wizard", id = 174, x = 3226, y = 3365)
npc_spawn("dark_wizard", id = 174, x = 3226, y = 3372)
npc_spawn("dark_wizard", id = 174, x = 3231, y = 3371)
npc_spawn("dark_wizard", id = 172, x = 3229, y = 3372)
npc_spawn("dark_wizard", id = 172, x = 3224, y = 3370)
npc_spawn("dark_wizard", id = 172, x = 3228, y = 3366)
npc_spawn("dark_wizard", id = 172, x = 3232, y = 3368)
npc_spawn("dark_wizard", id = 172, x = 3226, y = 3369)
npc_spawn("giant_rat", id = 87, x = 3292, y = 3375)
npc_spawn("giant_rat", id = 87, x = 3265, y = 3384)
npc_spawn("giant_rat", id = 87, x = 3267, y = 3381)
npc_spawn("guard", id = 368, x = 3263, y = 3407, facing = Direction.SOUTH)
npc_spawn("jeremy_clerksin", x = 3253, y = 3477)
npc_spawn("martina_scorsby", x = 3256, y = 3481)
npc_spawn("man", x = 3281, y = 3500)
npc_spawn("man", x = 3193, y = 3394)
npc_spawn("man", x = 3159, y = 3429)
npc_spawn("man", x = 3245, y = 3394)
npc_spawn("man", x = 3283, y = 3492, z = 1)
npc_spawn("man", id = 2, x = 3283, y = 3492, z = 1)
npc_spawn("man", id = 2, x = 3263, y = 3400)
npc_spawn("man", id = 3, x = 3227, y = 3395, z = 1)
npc_spawn("man", id = 3, x = 3231, y = 3399, z = 1)
npc_spawn("mugger", x = 3251, y = 3390)
npc_spawn("mugger", x = 3177, y = 3363)
npc_spawn("tramp", id = 2792, x = 3177, y = 3363)
npc_spawn("woman", x = 3221, y = 3396)
npc_spawn("woman", id = 5, x = 3279, y = 3497)
npc_spawn("woman", id = 25, x = 3278, y = 3492)
npc_spawn("thief", x = 3285, y = 3500)
npc_spawn("thief", x = 3234, y = 3389)
npc_spawn("thief", x = 3188, y = 3383)
npc_spawn("thief", x = 3184, y = 3390)
npc_spawn("thief", x = 3188, y = 3394)
npc_spawn("unicorn", x = 3286, y = 3342)
npc_spawn("unicorn", x = 3279, y = 3345)
// North Guards
npc_spawn("guard", x = 3244, y = 3500)
npc_spawn("guard", x = 3247, y = 3503)
// East Guards
npc_spawn("guard", x = 3271, y = 3431)
npc_spawn("guard", x = 3270, y = 3425)
npc_spawn("guard", x = 3274, y = 3421)
npc_spawn("guard", x = 3274, y = 3427)
// South Guards
npc_spawn("guard", x = 3210, y = 3382)
npc_spawn("guard", x = 3212, y = 3380)
npc_spawn("guard", x = 3207, y = 3376)
// West Guards
npc_spawn("guard", x = 3174, y = 3427)
npc_spawn("guard", x = 3176, y = 3430)
npc_spawn("guard", x = 3176, y = 3427)
npc_spawn("guard", x = 3180, y = 3399)
npc_spawn("guard", x = 3175, y = 3415, z = 1)
npc_spawn("guard", x = 3174, y = 3403, z = 1)
// Varrock Palace
npc_spawn("guard", x = 3210, y = 3461)
npc_spawn("guard", x = 3211, y = 3465)
npc_spawn("guard", x = 3214, y = 3462)
npc_spawn("guard", x = 3216, y = 3464)
npc_spawn("guard", x = 3220, y = 3461)
npc_spawn("guard", x = 3206, y = 3461)
npc_spawn("guard", x = 3204, y = 3495)
npc_spawn("guard", x = 3204, y = 3495, z = 1)
npc_spawn("guard", x = 3205, y = 3492, z = 1)
npc_spawn("guard", x = 3203, y = 3492, z = 1)
npc_spawn("guard", x = 3205, y = 3497, z = 1)
npc_spawn("guard", x = 3221, y = 3471, z = 2)
npc_spawn("guard", x = 3214, y = 3474, z = 2)
npc_spawn("guard", x = 3215, y = 3471, z = 2)
npc_spawn("guard", x = 3211, y = 3471, z = 2)
npc_spawn("guard", x = 3209, y = 3473, z = 2)
npc_spawn("guard", x = 3212, y = 3475, z = 2)
npc_spawn("guard", x = 3207, y = 3477, z = 2)
npc_spawn("guard", x = 3203, y = 3476, z = 2)
npc_spawn("guard", x = 3205, y = 3479, z = 2)
npc_spawn("guard", x = 3203, y = 3483, z = 2)
npc_spawn("guard", x = 3221, y = 3485, z = 2)
npc_spawn("monk_of_zamorak", id = 189, x = 3213, y = 3476)
npc_spawn("warrior_woman", x = 3203, y = 3490)
npc_spawn("warrior_woman", x = 3205, y = 3493)
// Varrock/Lumbridge Pen
npc_spawn("swan", x = 3261, y = 3354)
npc_spawn("swan", x = 3260, y = 3356)
npc_spawn("ram", id = 3673, x = 3238, y = 3346)
npc_spawn("ram", id = 3673, x = 3248, y = 3352)
npc_spawn("ram", id = 3673, x = 3260, y = 3348)
npc_spawn("sheep", id = 42, x = 3263, y = 3347)
npc_spawn("sheep", id = 42, x = 3268, y = 3350)
npc_spawn("sheep", id = 42, x = 3252, y = 3352)
npc_spawn("sheep", id = 42, x = 3243, y = 3344)
npc_spawn("sheep", id = 42, x = 3235, y = 3347)
npc_spawn("sheep", id = 3579, x = 3234, y = 3344)
npc_spawn("sheep", id = 3579, x = 3241, y = 3347)
npc_spawn("sheep", id = 3579, x = 3257, y = 3350)
// Champions Guild
npc_spawn("chicken", x = 3195, y = 3359)
npc_spawn("chicken", x = 3198, y = 3356)
npc_spawn("chicken", x = 3195, y = 3355)
npc_spawn("chicken", id = 1017, x = 3196, y = 3353)
npc_spawn("chicken", id = 1017, x = 3197, y = 3356)
npc_spawn("evil_chicken", x = 3198, y = 3359)
// Function Npc
npc_spawn("apothecary", x = 3196, y = 3403)
npc_spawn("captain_rovin", x = 3204, y = 3496, z = 2)
npc_spawn("curator", x = 3256, y = 3447)
npc_spawn("dimintheis", x = 3280, y = 3403)
npc_spawn("dr_harlow", x = 3224, y = 3398)
npc_spawn("ellamaria", x = 3228, y = 3475)
npc_spawn("father_lawrence", x = 3253, y = 3484)
npc_spawn("guidors_wife", id = 342, x = 3280, y = 3382)
npc_spawn("guidor", x = 3284, y = 3381, facing = Direction.SOUTH)
npc_spawn("guild_master", x = 3189, y = 3360)
npc_spawn("gypsy", x = 3203, y = 3423)
npc_spawn("hooknosed_jack", x = 3268, y = 3400)
npc_spawn("jonny_the_beard", x = 3223, y = 3395)
npc_spawn("johnathon", x = 3278, y = 3503, z = 1)
npc_spawn("katrine", x = 3185, y = 3386)
npc_spawn("king_roald", x = 3223, y = 3473)
npc_spawn("master_farmer", x = 3243, y = 3349)
npc_spawn("pox", x = 3267, y = 3399)
npc_spawn("reldo", x = 3210, y = 3492)
npc_spawn("romeo", x = 3211, y = 3423)
npc_spawn("shilop", x = 3211, y = 3435)
npc_spawn("sir_prysin", x = 3204, y = 3472)
npc_spawn("tarquin", x = 3203, y = 3344, facing = Direction.SOUTH)
npc_spawn("tool_leprechaun", x = 3182, y = 3355)
npc_spawn("tool_leprechaun", x = 3229, y = 3455)
npc_spawn("tramp", id = 641, x = 3207, y = 3392)
npc_spawn("wilough", x = 3222, y = 3437)
// Shop Npc
npc_spawn("aubury", x = 3253, y = 3401)
npc_spawn("baraek", x = 3217, y = 3434)
npc_spawn("bartender", x = 3226, y = 3400)
npc_spawn("bartender", id = 1921, x = 3277, y = 3487)
npc_spawn("fancy_dress_shop_owner", x = 3281, y = 3398)
npc_spawn("horvik", x = 3229, y = 3438)
npc_spawn("lowe", x = 3233, y = 3421)
npc_spawn("scavvo", x = 3192, y = 3353, z = 1)
npc_spawn("shop_keeper", id = 551, x = 3206, y = 3399)
npc_spawn("shop_assistant", id = 552, x = 3207, y = 3396)
npc_spawn("shop_keeper", id = 522, x = 3216, y = 3414)
npc_spawn("shop_assistant", id = 523, x = 3216, y = 3417)
npc_spawn("tea_seller", x = 3271, y = 3411)
npc_spawn("thessalia", x = 3206, y = 3417)
npc_spawn("zaff", x = 3203, y = 3434)
// Juliet House
npc_spawn("draul_leptoc", x = 3228, y = 3475)
npc_spawn("juliet", x = 3159, y = 3425, z = 1)
npc_spawn("phillipa", x = 3160, y = 3429, z = 1)
// Gertrude House
npc_spawn("gertrude", x = 3153, y = 3413)
npc_spawn("kanel", x = 3155, y = 3405, facing = Direction.EAST)
npc_spawn("philop", x = 3150, y = 3405, facing = Direction.SOUTH)
// Small Bank
npc_spawn("banker", id = 495, x = 3252, y = 3418)
npc_spawn("banker", id = 494, x = 3252, y = 3418)
npc_spawn("banker", id = 494, x = 3252, y = 3418)
npc_spawn("banker", id = 494, x = 3252, y = 3418)
// Big Bank
npc_spawn("banker", id = 494, x = 3187, y = 3436, facing = Direction.WEST)
npc_spawn("banker", id = 494, x = 3187, y = 3440, facing = Direction.WEST)
npc_spawn("banker", id = 494, x = 3187, y = 3444, facing = Direction.WEST)
npc_spawn("banker", id = 495, x = 3187, y = 3438, facing = Direction.WEST)
npc_spawn("banker", id = 495, x = 3187, y = 3442, facing = Direction.WEST)
+3
View File
@@ -0,0 +1,3 @@
apolloPlugin {
name = "logout"
}
+1
View File
@@ -0,0 +1 @@
name = "logout"
+5
View File
@@ -0,0 +1,5 @@
val LOGOUT_BUTTON_ID = 2458
on_button(LOGOUT_BUTTON_ID)
.where { widgetId == LOGOUT_BUTTON_ID }
.then { it.logout() }
+19
View File
@@ -0,0 +1,19 @@
import org.apollo.game.message.impl.ButtonMessage
import org.apollo.game.plugin.testing.KotlinPluginTest
import org.junit.Test
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
class LogoutTests : KotlinPluginTest() {
companion object {
const val LOGOUT_BUTTON_ID = 2458
}
@Test fun `The player should be logged out when they click the logout button`() {
player.notify(ButtonMessage(LOGOUT_BUTTON_ID))
verify(player, times(1)).logout()
}
}
+3
View File
@@ -0,0 +1,3 @@
apolloPlugin {
name = "run"
}
+1
View File
@@ -0,0 +1 @@
name = "run"
+10
View File
@@ -0,0 +1,10 @@
import org.apollo.game.message.impl.ButtonMessage
val WALK_BUTTON_ID = 152
val RUN_BUTTON_ID = 153
on { ButtonMessage::class }
.where { widgetId == WALK_BUTTON_ID || widgetId == RUN_BUTTON_ID }
.then {
it.toggleRunning()
}
+4
View File
@@ -0,0 +1,4 @@
apolloPlugin {
name = "command utilities"
packageName = "org.apollo.game.plugins.util"
}
+5
View File
@@ -0,0 +1,5 @@
name = "command utilities"
package = "org.apollo.game.plugins.util"
[config]
srcDir = "src/"
+20
View File
@@ -0,0 +1,20 @@
import org.apollo.game.model.entity.Player
/**
* Checks whether the amount of arguments provided is correct, sending the player the specified
* message if not.
*/
fun valid_arg_length(args: Array<String>, length: IntRange, player: Player, message: String): Boolean {
val valid = length.contains(args.size)
if (!valid) {
player.sendMessage(message)
}
return valid
}
/**
* Checks whether the amount of arguments provided is correct, sending the player the specified
* message if not.
*/
fun valid_arg_length(args: Array<String>, length: Int, player: Player, message: String)
= valid_arg_length(args, IntRange(length, length), player, message)
+4
View File
@@ -0,0 +1,4 @@
apolloPlugin {
name = "entity lookup"
packageName = "org.apollo.game.plugins.util"
}
+2
View File
@@ -0,0 +1,2 @@
name = "entity lookup"
package = "org.apollo.game.plugins.util"
+24
View File
@@ -0,0 +1,24 @@
import org.apollo.cache.def.*
fun lookup_object(name: String): ObjectDefinition? {
return find_entity(ObjectDefinition::getDefinitions, ObjectDefinition::getName, name)
}
fun lookup_npc(name: String): NpcDefinition? {
return find_entity(NpcDefinition::getDefinitions, NpcDefinition::getName, name)
}
fun lookup_item(name: String): ItemDefinition? {
return find_entity(ItemDefinition::getDefinitions, ItemDefinition::getName, name)
}
private fun <T : Any> find_entity(definitionsProvider: () -> Array<T>,
nameSupplier: T.() -> String,
name: String): T? {
val normalizedName = name.replace('_', ' ')
val definitions = definitionsProvider.invoke();
val matcher: (T) -> Boolean = { it.nameSupplier().equals(normalizedName, true) }
return definitions.filter(matcher).firstOrNull()
}
@@ -0,0 +1,15 @@
import org.apollo.cache.def.ItemDefinition
import org.apollo.game.plugin.testing.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
class LookupTests : KotlinPluginTest() {
@Test fun itemLookup() {
val testItem = ItemDefinition(0)
testItem.name = "sword"
ItemDefinition.init(arrayOf(testItem))
assertThat(lookup_item("sword")).isEqualTo(testItem);
}
}