Skip to content

Commit

Permalink
Merge pull request #3 from TristonPlummer/master
Browse files Browse the repository at this point in the history
Sync with upstream
  • Loading branch information
tristonplummer authored Mar 24, 2019
2 parents d20e269 + 84e178a commit 6246e02
Show file tree
Hide file tree
Showing 22 changed files with 332 additions and 70 deletions.
41 changes: 35 additions & 6 deletions data/packets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,41 @@ out-packets:

in-packets:

- message: gg.rsmod.game.message.impl.OpLocUMessage
type: FIXED
opcode: 44
length: 15
structure:
- name: pos_z
sign: UNSIGNED
type: SHORT
order: LITTLE
trans: ADD
- name: slot
sign: UNSIGNED
type: SHORT
order: LITTLE
- name: movement_type
sign: UNSIGNED
type: BYTE
trans: ADD
- name: unknown
sign: UNSIGNED
type: INT
order: LITTLE
- name: pos_x
sign: UNSIGNED
type: SHORT
order: LITTLE
trans: ADD
- name: obj
sign: UNSIGNED
type: SHORT
- name: item
sign: UNSIGNED
type: SHORT
order: LITTLE

- message: gg.rsmod.game.message.impl.IfButtonDMessage
type: FIXED
opcode: 57
Expand Down Expand Up @@ -1161,12 +1196,6 @@ in-packets:
opcode: 43
ignore: true

- message: gg.rsmod.game.message.impl.IgnoreMessage # TODO: OPLOCU
type: FIXED
opcode: 44
length: 15
ignore: true

- message: gg.rsmod.game.message.impl.IgnoreMessage # Unknown
type: FIXED
opcode: 45
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fun ItemContainer.getNetworth(world: World): Long {
* @return
* The removal [ItemTransaction].
*/
fun ItemContainer.transfer(to: ItemContainer, item: Item, beginSlot: Int = -1, note: Boolean = false, unnote: Boolean = false): ItemTransaction? {
fun ItemContainer.transfer(to: ItemContainer, item: Item, fromSlot: Int = -1, toSlot: Int = -1, note: Boolean = false, unnote: Boolean = false): ItemTransaction? {
check(item.amount > 0)

/**
Expand All @@ -55,12 +55,12 @@ fun ItemContainer.transfer(to: ItemContainer, item: Item, beginSlot: Int = -1, n
*/
val finalItem = if (note) copy.toNoted(definitions) else if (unnote) copy.toUnnoted(definitions) else copy

val add = to.add(finalItem.id, finalItem.amount, assureFullInsertion = false)
val add = to.add(finalItem.id, finalItem.amount, assureFullInsertion = false, beginSlot = toSlot)
if (add.completed == 0) {
return null
}

val remove = remove(item.id, add.completed, assureFullRemoval = true, beginSlot = beginSlot)
val remove = remove(item.id, add.completed, assureFullRemoval = true, beginSlot = fromSlot)
if (remove.completed == 0) {
add.revert(to)
return null
Expand Down
12 changes: 7 additions & 5 deletions game/plugins/src/main/kotlin/gg/rsmod/plugins/api/ext/MiscExt.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package gg.rsmod.plugins.api.ext

import gg.rsmod.game.model.World
import java.text.DecimalFormat
import java.text.Format
import java.util.concurrent.ThreadLocalRandom

/**
* @author Tom <[email protected]>
*/

private val RANDOM = ThreadLocalRandom.current()

fun Number.appendToString(string: String): String = "$this $string" + (if (this != 1) "s" else "")

fun Number.format(format: Format): String = format.format(this)
Expand All @@ -21,8 +23,8 @@ fun String.parseAmount(): Long = when {
else -> substring(0, length).toLong()
}

fun interpolate(minChance: Int, maxChance: Int, minLvl: Int, maxLvl: Int, playerLvl: Int): Int =
minChance + (maxChance - minChance) * (playerLvl - minLvl) / (maxLvl - minLvl)
fun Int.interpolate(minChance: Int, maxChance: Int, minLvl: Int, maxLvl: Int): Int =
minChance + (maxChance - minChance) * (this - minLvl) / (maxLvl - minLvl)

fun World.interpolate(minChance: Int, maxChance: Int, minLvl: Int, maxLvl: Int, playerLvl: Int, cap: Int): Boolean =
random(cap) <= interpolate(minChance, maxChance, minLvl, maxLvl, playerLvl)
fun Int.interpolate(minChance: Int, maxChance: Int, minLvl: Int, maxLvl: Int, cap: Int): Boolean =
RANDOM.nextInt(cap) <= interpolate(minChance, maxChance, minLvl, maxLvl)
13 changes: 10 additions & 3 deletions game/plugins/src/main/kotlin/gg/rsmod/plugins/api/ext/PawnExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,21 @@ fun Pawn.showHitbar(percentage: Int, type: HitbarType) {
pendingHits.add(Hit.Builder().onlyShowHitbar().setHitbarType(type.id).setHitbarPercentage(percentage).setHitbarMaxPercentage(type.pixelsWide).build())
}

fun Pawn.freeze(cycles: Int, onFreeze: () -> Unit): Boolean {
fun Pawn.freeze(cycles: Int, onFreeze: () -> Unit) {
if (timers.has(FROZEN_TIMER)) {
return false
return
}
stopMovement()
timers[FROZEN_TIMER] = cycles
onFreeze()
return true
}

fun Pawn.freeze(cycles: Int) {
freeze(cycles) {
if (this is Player) {
this.message("You have been frozen.")
}
}
}

fun Pawn.stun(cycles: Int, onStun: () -> Unit): Boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gg.rsmod.plugins.content.inter.bank

import gg.rsmod.game.model.World
import gg.rsmod.game.model.container.ItemContainer
import gg.rsmod.game.model.entity.Player
import gg.rsmod.game.model.item.Item
Expand Down Expand Up @@ -58,7 +59,7 @@ object Bank {
copy.copyAttr(item)
}

val transfer = from.transfer(to, item = copy, beginSlot = i, note = note, unnote = !note)
val transfer = from.transfer(to, item = copy, fromSlot = i, note = note, unnote = !note)
withdrawn += transfer?.completed ?: 0

if (from[i] == null) {
Expand Down Expand Up @@ -108,7 +109,8 @@ object Bank {
copy.copyAttr(item)
}

val transfer = from.transfer(to, item = copy, beginSlot = i, note = false, unnote = true)
val placeholderSlot = to.removePlaceholder(p.world, copy)
val transfer = from.transfer(to, item = copy, fromSlot = i, toSlot = placeholderSlot, note = false, unnote = true)

if (transfer != null) {
deposited += transfer.completed
Expand Down Expand Up @@ -140,6 +142,15 @@ object Bank {
p.setVarbit(BANK_YOUR_LOOT_VARBIT, 0)
}

fun ItemContainer.removePlaceholder(world: World, item: Item): Int {
val def = item.toUnnoted(world.definitions).getDef(world.definitions)
val slot = if (def.placeholderId > 0) indexOfFirst { it?.id == def.placeholderId && it.amount == 0 } else -1
if (slot != -1) {
this[slot] = null
}
return slot
}

fun ItemContainer.shift() {
val newItems = Array<Item?>(capacity) { null }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gg.rsmod.plugins.content.inter.bank
import gg.rsmod.game.model.attr.INTERACTING_ITEM_SLOT
import gg.rsmod.game.model.attr.OTHER_ITEM_SLOT_ATTR
import gg.rsmod.plugins.content.inter.bank.Bank.insert
import gg.rsmod.plugins.content.inter.bank.Bank.removePlaceholder
import gg.rsmod.plugins.content.inter.bank.Bank.shift

on_interface_open(Bank.BANK_INTERFACE_ID) {
Expand Down Expand Up @@ -46,7 +47,9 @@ on_button(interfaceId = Bank.BANK_INTERFACE_ID, component = 42) {
val item = from[i] ?: continue

val total = item.amount
val deposited = from.transfer(to, item, beginSlot = i, note = false, unnote = true)?.completed ?: 0

val placeholderSlot = to.removePlaceholder(p.world, item)
val deposited = from.transfer(to, item, fromSlot = i, toSlot = placeholderSlot, note = false, unnote = true)?.completed ?: 0
if (total != deposited) {
// Was not able to deposit the whole stack of [item].
}
Expand All @@ -70,7 +73,9 @@ on_button(interfaceId = Bank.BANK_INTERFACE_ID, component = 44) {
val item = from[i] ?: continue

val total = item.amount
val deposited = from.transfer(to, item, beginSlot = i, note = false, unnote = true)?.completed ?: 0

val placeholderSlot = to.removePlaceholder(p.world, item)
val deposited = from.transfer(to, item, fromSlot = i, toSlot = placeholderSlot, note = false, unnote = true)?.completed ?: 0
if (total != deposited) {
// Was not able to deposit the whole stack of [item].
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ fun store(p: Player, slot: Int, amount: Int) {
fun store(p: Player, item: Item, amount: Int, beginSlot: Int = -1): Boolean {
val container = p.containers.computeIfAbsent(CONTAINER_KEY) { ItemContainer(p.world.definitions, CONTAINER_KEY) }

val transferred = p.inventory.transfer(container, item = Item(item, amount).copyAttr(item), beginSlot = beginSlot)?.completed ?: 0
val transferred = p.inventory.transfer(container, item = Item(item, amount).copyAttr(item), fromSlot = beginSlot)?.completed ?: 0
if (transferred == 0) {
p.message("The bag's too full.")
return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ object Woodcutting {
break
}

if (p.world.interpolate(minChance = 60, maxChance = 190, minLvl = 1, maxLvl = 99,
playerLvl = p.getSkills().getCurrentLevel(Skills.WOODCUTTING), cap = 255)) {
val level = p.getSkills().getCurrentLevel(Skills.WOODCUTTING)
if (level.interpolate(minChance = 60, maxChance = 190, minLvl = 1, maxLvl = 99, cap = 255)) {
p.filterableMessage("You get some ${logName}s.")
p.playSound(3600)
p.inventory.add(tree.log)
Expand Down
86 changes: 62 additions & 24 deletions game/src/main/kotlin/gg/rsmod/game/action/ObjectPathAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package gg.rsmod.game.action
import gg.rsmod.game.fs.def.ObjectDef
import gg.rsmod.game.message.impl.SetMapFlagMessage
import gg.rsmod.game.model.Direction
import gg.rsmod.game.model.attr.INTERACTING_ITEM
import gg.rsmod.game.model.attr.INTERACTING_OBJ_ATTR
import gg.rsmod.game.model.attr.INTERACTING_OPT_ATTR
import gg.rsmod.game.model.collision.ObjectType
import gg.rsmod.game.model.entity.Entity
import gg.rsmod.game.model.entity.GameObject
import gg.rsmod.game.model.entity.Pawn
import gg.rsmod.game.model.entity.Player
import gg.rsmod.game.model.entity.*
import gg.rsmod.game.model.path.PathRequest
import gg.rsmod.game.model.path.Route
import gg.rsmod.game.model.queue.QueueTask
Expand All @@ -20,6 +18,7 @@ import gg.rsmod.game.plugin.Plugin
import gg.rsmod.util.AabbUtil
import gg.rsmod.util.DataConstants
import java.util.*
import kotlin.math.log

/**
* This class is responsible for calculating distances and valid interaction
Expand All @@ -29,38 +28,68 @@ import java.util.*
*/
object ObjectPathAction {

val walkPlugin: Plugin.() -> Unit = {
val player = ctx as Player
val obj = player.attr[INTERACTING_OBJ_ATTR]!!.get()!!
val opt = player.attr[INTERACTING_OPT_ATTR]!!
val lineOfSightRange = player.world.plugins.getObjInteractionDistance(obj.id)
fun walk(client: Client, obj: GameObject, lineOfSightRange: Int?, logic: Plugin.() -> Unit) {

player.queue(TaskPriority.STANDARD) {
client.queue(TaskPriority.STANDARD) {
terminateAction = {
player.stopMovement()
player.write(SetMapFlagMessage(255, 255))
client.stopMovement()
client.write(SetMapFlagMessage(255, 255))
}

val route = walkTo(obj, lineOfSightRange)
if (route.success) {
if (lineOfSightRange == null || lineOfSightRange > 0) {
faceObj(player, obj)
}
if (!player.world.plugins.executeObject(player, obj.getTransform(player), opt)) {
player.message(Entity.NOTHING_INTERESTING_HAPPENS)
if (player.world.devContext.debugObjects) {
player.message("Unhandled object action: [opt=$opt, id=${obj.id}, type=${obj.type}, rot=${obj.rot}, x=${obj.tile.x}, z=${obj.tile.z}]")
}
faceObj(client, obj)
}
client.executePlugin(logic)
} else {
player.faceTile(obj.tile)
if (player.timers.has(FROZEN_TIMER)) {
player.message(Entity.MAGIC_STOPS_YOU_FROM_MOVING)
client.faceTile(obj.tile)
if (client.timers.has(FROZEN_TIMER)) {
client.message(Entity.MAGIC_STOPS_YOU_FROM_MOVING)
} else {
player.message(Entity.YOU_CANT_REACH_THAT)
client.message(Entity.YOU_CANT_REACH_THAT)
}
}
}
}

val itemOnObjectPlugin: Plugin.() -> Unit = {

val client = ctx as Client
val player = ctx as Player

val item = player.attr[INTERACTING_ITEM]!!.get()!!
val obj = player.attr[INTERACTING_OBJ_ATTR]!!.get()!!
val lineOfSightRange = player.world.plugins.getObjInteractionDistance(obj.id)

walk(client, obj, lineOfSightRange) {
if (!player.world.plugins.executeItemOnObject(player, obj.getTransform(player), item.id)) {
player.message(Entity.NOTHING_INTERESTING_HAPPENS)
if (player.world.devContext.debugObjects) {
player.message("Unhandled item on object: [item=$item, id=${obj.id}, type=${obj.type}, rot=${obj.rot}, x=${obj.tile.x}, z=${obj.tile.z}]")
}
}
}
}

val objectInteractPlugin: Plugin.() -> Unit = {

val client = ctx as Client
val player = ctx as Player

val obj = player.attr[INTERACTING_OBJ_ATTR]!!.get()!!
val opt = player.attr[INTERACTING_OPT_ATTR]
val lineOfSightRange = player.world.plugins.getObjInteractionDistance(obj.id)

walk(client, obj, lineOfSightRange) {
if (!player.world.plugins.executeObject(player, obj.getTransform(player), opt!!)) {
player.message(Entity.NOTHING_INTERESTING_HAPPENS)
if (player.world.devContext.debugObjects) {
player.message("Unhandled object action: [opt=$opt, id=${obj.id}, type=${obj.type}, rot=${obj.rot}, x=${obj.tile.x}, z=${obj.tile.z}]")
}
}
}

}

private suspend fun QueueTask.walkTo(obj: GameObject, lineOfSightRange: Int?): Route {
Expand Down Expand Up @@ -140,7 +169,7 @@ object ObjectPathAction {

if (wall) {
/**
* Check if the [pawn] is within interaction distance of the wall.
* Check if the pawn is within interaction distance of the wall.
*/
if (pawn.tile.isWithinRadius(tile, 1)) {
val dir = Direction.between(tile, pawn.tile)
Expand Down Expand Up @@ -182,6 +211,11 @@ object ObjectPathAction {
}

val route = pawn.createPathFindingStrategy().calculateRoute(builder.build())

if (pawn.timers.has(FROZEN_TIMER) && !pawn.tile.sameAs(route.tail)) {
return Route(ArrayDeque(), success = false, tail = pawn.tile)
}

pawn.walkPath(route.path)

val last = pawn.movementQueue.peekLast()
Expand All @@ -194,6 +228,10 @@ object ObjectPathAction {
return Route(ArrayDeque(), success = false, tail = pawn.tile)
}

if (pawn.timers.has(FROZEN_TIMER) && !pawn.tile.sameAs(route.tail)) {
return Route(ArrayDeque(), success = false, tail = pawn.tile)
}

if (wall && !route.success && pawn.tile.isWithinRadius(tile, 1) && Direction.between(tile, pawn.tile) !in blockedWallDirections) {
return Route(route.path, success = true, tail = route.tail)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class MessageDecoderSet {
put(OpHeldDMessage::class.java, OpHeldDDecoder(), OpHeldDHandler(), structures)

put(OpHeldTMessage::class.java, OpHeldTDecoder(), OpHeldTHandler(), structures)
put(OpLocUMessage::class.java, OpLocUDecoder(), OpLocUHandler(), structures)

put(OpObj1Message::class.java, OpObj1Decoder(), OpObj1Handler(), structures)
put(OpObj3Message::class.java, OpObj3Decoder(), OpObj3Handler(), structures)
Expand Down
Loading

0 comments on commit 6246e02

Please sign in to comment.