Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package world.gregs.voidps.engine.client.instruction.handle

import com.github.michaelbull.logging.InlineLogger
import world.gregs.voidps.engine.client.instruction.InstructionHandler
import world.gregs.voidps.engine.client.instruction.InterfaceHandler
import world.gregs.voidps.engine.client.ui.closeInterfaces
import world.gregs.voidps.engine.entity.character.mode.interact.ItemOnPlayerInteract
import world.gregs.voidps.engine.entity.character.player.Player
import world.gregs.voidps.engine.entity.character.player.Players
import world.gregs.voidps.engine.entity.character.player.name
import world.gregs.voidps.engine.entity.item.Item
import world.gregs.voidps.network.client.instruction.InteractInterfacePlayer

class InterfaceOnPlayerOptionHandler(
Expand All @@ -16,9 +19,19 @@ class InterfaceOnPlayerOptionHandler(
val (playerIndex, interfaceId, componentId, itemId, itemSlot) = instruction
val target = Players.indexed(playerIndex) ?: return false

val (id, component, item) = handler.getInterfaceItem(player, interfaceId, componentId, itemId, itemSlot) ?: return false
if ((interfaceId == 192 || interfaceId == 193) && itemId == -1) {
player.closeInterfaces()
player["magic_spell"] = "$interfaceId:$componentId"
player["spellbook"] = if (interfaceId == 193) 1 else 0
player.mode = ItemOnPlayerInteract(target, "$interfaceId:$componentId", Item.EMPTY, -1, player)
return true
}

val (id, component, item) = handler.getInterfaceItem(player, interfaceId, componentId, itemId, itemSlot)
?: return false
player.closeInterfaces()
player.mode = ItemOnPlayerInteract(target, "$id:$component", item, itemSlot, player)

return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ open class Interact(
interacted = false
clearInteracted = false
}
if (!character.hasMenuOpen()) {
// Don't move if we just interacted at range
if (!character.hasMenuOpen() && !interacted) {
super.tick()
}
if (!interacted || updateRange) {
Expand Down
7 changes: 5 additions & 2 deletions game/src/main/kotlin/content/entity/combat/Combat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,12 @@ class Combat(val combatDefinitions: CombatDefinitions) :
} else if (character is Player) {
val style = character.fightStyle
if (style == "magic" || style == "blaze") {
if (Magic.castSpell(character, target)) {
CombatApi.swing(character, target, character.weapon.id, style)
if (!Magic.castSpell(character, target)) {
character.mode = EmptyMode
character.target = null
return
}
CombatApi.swing(character, target, character.weapon.id, style)
} else {
CombatApi.swing(character, target, character.weapon.id, style)
}
Expand Down
49 changes: 49 additions & 0 deletions game/src/main/kotlin/content/skill/magic/CombatSpellsOnPlayer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package content.skill.magic

import com.github.michaelbull.logging.InlineLogger
import content.skill.magic.spell.spell
import world.gregs.voidps.cache.definition.Params
import world.gregs.voidps.engine.Script
import world.gregs.voidps.engine.client.variable.hasClock
import world.gregs.voidps.engine.client.variable.start
import world.gregs.voidps.engine.data.definition.InterfaceDefinitions
import world.gregs.voidps.engine.entity.Approachable
import world.gregs.voidps.engine.entity.character.mode.EmptyMode
import world.gregs.voidps.engine.entity.character.player.name

class CombatSpellsOnPlayer : Script {
private val logger = InlineLogger()

init {
Approachable.onPlayer.getOrPut("*") { mutableListOf() }.add { interact ->
val id = interact.id
if (!id.startsWith("192:") &&!id.startsWith("193:") &&!id.startsWith("194:") &&!id.startsWith("430:")) return@add
if (hasClock("action_delay")) return@add

val parts = id.split(":")
val ifaceId = parts[0].toInt()
val compId = parts[1].toInt()

val defs = InterfaceDefinitions.definitions
if (ifaceId >= defs.size) return@add
val def = defs[ifaceId]
val component = def.components?.get(compId)?: return@add
val spell = component.stringId

if (component.params?.get(Params.id("cast_id")) == null) return@add

logger.debug { "Spell $id ($spell) on ${interact.target.name}" }
approachRange(10)
this.spell = spell
set("one_time", true)

start("action_delay", 4)
Magic.castSpell(this@add, interact.target)

// End Interact, let Combat mode handle subsequent casts
if (mode == interact) {
mode = EmptyMode
}
}
}
}
6 changes: 5 additions & 1 deletion game/src/main/kotlin/content/skill/magic/Magic.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ import world.gregs.voidps.engine.get
object Magic {
fun castSpell(source: Character, target: Character): Boolean {
if (source.spell.isNotBlank() && source is Player && !source.removeSpellItems(source.spell)) {
source.clear("autocast")
if (!source.contains("spell")) {
source.clear("autocast")
}
source.clear("spell")
source.clear("one_time")
return false
}
val spell = source.spell
Expand Down
6 changes: 5 additions & 1 deletion game/src/main/kotlin/content/skill/magic/book/SpellRunes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ class SpellRunes : Script {
init {
combatPrepare(style = "magic") { _ ->
if (spell.isNotBlank() && !hasSpellItems(spell)) {
clear("autocast")
if (!contains("spell")) {
clear("autocast")
}
clear("spell")
clear("one_time")
false
} else {
true
Expand Down
6 changes: 4 additions & 2 deletions game/src/main/kotlin/content/skill/magic/spell/Spells.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ class Spells : Script {
return@combatAttack
}
if (spell.endsWith("_burst") || spell.endsWith("_barrage")) {
val targets = multiTargets(target, 9)
val targets = multiTargets(this, target, 9)
for (targ in targets) {
targ.directHit(this, random.nextInt(0..damage), type, weapon, spell)
// damage can be -1 on a miss — clamp to 0
val splash = if (damage > 0) random.nextInt(0..damage) else 0
targ.directHit(this, splash, type, weapon, spell)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import world.gregs.voidps.engine.entity.character.player.Players
import world.gregs.voidps.engine.entity.character.player.skill.Skill
import world.gregs.voidps.engine.map.spiral

fun multiTargets(target: Character, hits: Int): List<Character> {
fun multiTargets(source: Character, target: Character, hits: Int): List<Character> {
val group = if (target is Player) Players else NPCs
val targets = mutableListOf<Character>()
for (tile in target.tile.spiral(1)) {
val characters = group.at(tile)
for (character in characters) {
if (character == target || !character.inMultiCombat) {
if (character == target || character == source || !character.inMultiCombat) {
continue
}
targets.add(character)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Chinchompa : Script {

combatAttack("range") { (target, damage, type, weapon, spell) ->
if (weapon.id.endsWith("chinchompa") && target.inMultiCombat) {
val targets = multiTargets(target, if (target is Player) 9 else 11)
val targets = multiTargets(this, target, if (target is Player) 9 else 11)
for (targ in targets) {
targ.directHit(this, random.nextInt(0..damage), type, weapon, spell)
}
Expand Down