Initial implementation of ground items

This commit is contained in:
Ryley Kimmel
2017-11-12 17:57:07 -05:00
parent 397d9b2d6a
commit a75fa743f8
8 changed files with 245 additions and 37 deletions
@@ -0,0 +1,5 @@
plugin {
name = "ground_item"
packageName = "org.apollo.game.plugin.entity"
authors = ["Ryley"]
}
@@ -0,0 +1,13 @@
import org.apollo.game.message.impl.InventoryItemMessage
on { InventoryItemMessage::class }
.where { option == 5 }
.then {
// This is just a stub, for now.
// Several other things need to be done here:
// - Items may only be dropped from your inventory
// - Items dropped must be removed from your inventory
// - Items must be checked to ensure they have a 'drop' option
val item = it.inventory.get(slot)
it.addGroundItem(item, it.position)
}
@@ -0,0 +1,72 @@
import org.apollo.game.GameConstants
import org.apollo.game.model.entity.GroundItem
import org.apollo.game.scheduling.ScheduledTask
/**
* A [ScheduledTask] that manages the globalization and expiration of [GroundItem]s.
*/
class GroundItemSynchronizationTask(private val groundItem: GroundItem) : ScheduledTask(DELAY, false) {
companion object {
/**
* The delay between executions of this task, in pulses.
*/
const val DELAY = 1
/**
* The amount of time, in pulses, in which this [GroundItem] will be globally visible.
*/
const val TRADABLE_TIME_UNTIL_GLOBAL = 60000 / GameConstants.PULSE_DELAY
/**
* The amount of time, in pulses, in which this [GroundItem] will expire and be removed from the [World].
*/
const val UNTRADABLE_TIME_UNTIL_EXPIRE = 180000 / GameConstants.PULSE_DELAY
/**
* The amount of time, in pulses, in which this [GroundItem] will expire and be removed from the [World].
*/
const val TIME_UNTIL_EXPIRE = 180000 / GameConstants.PULSE_DELAY
}
/**
* The amount of game pulses this [ScheduledTask] has been alive.
*/
private var pulses = 0
override fun execute() {
val world = groundItem.world
val owner = world.playerRepository[groundItem.ownerIndex]
val untradable = false // TODO: item.getDefinition().isTradable();
if (!groundItem.isAvailable) {
stop()
return
}
// Untradable items never go global
if (untradable) {
if (pulses >= UNTRADABLE_TIME_UNTIL_EXPIRE) {
world.removeGroundItem(owner, groundItem)
stop()
}
return
}
if (groundItem.isGlobal) {
if (pulses >= TIME_UNTIL_EXPIRE) {
world.removeGroundItem(owner, groundItem)
stop()
}
} else {
if (pulses >= TRADABLE_TIME_UNTIL_GLOBAL) {
groundItem.globalize()
world.addGroundItem(owner, groundItem)
}
}
pulses++
}
}
@@ -0,0 +1,44 @@
import org.apollo.game.message.impl.RemoveTileItemMessage
import org.apollo.game.message.impl.SendTileItemMessage
import org.apollo.game.model.Item
import org.apollo.game.model.Position
import org.apollo.game.model.World
import org.apollo.game.model.entity.GroundItem
import org.apollo.game.model.entity.Player
/**
* Spawns a new local [GroundItem] for this Player at the specified [Position].
*/
fun Player.addGroundItem(item: Item, position: Position) {
world.addGroundItem(this, GroundItem.dropped(world, position, item, this))
}
internal fun World.addGroundItem(player: Player, item: GroundItem) {
val region = regionRepository.fromPosition(item.position)
if (item.isGlobal) {
region.addEntity(item, true)
return
}
groundItems.computeIfAbsent(player.encodedName, { HashSet<GroundItem>() }) += item
val offset = region.getPositionOffset(item)
player.send(SendTileItemMessage(item.item, offset))
schedule(GroundItemSynchronizationTask(item))
}
internal fun World.removeGroundItem(player: Player, item: GroundItem) {
val region = regionRepository.fromPosition(item.position)
if (item.isGlobal) {
region.removeEntity(item)
}
val items = groundItems[player.encodedName] ?: return
items -= item
val offset = region.getPositionOffset(item)
player.send(RemoveTileItemMessage(item.item, offset))
}