Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to robots to obtain nearby experience orbs #3702

Open
wants to merge 7 commits into
base: master-MC1.12
Choose a base branch
from
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
13 changes: 12 additions & 1 deletion src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@ opencomputers {
# two real experience points, redstone is worth 5.
oreXpRate: 4.0

# This determines how much experience a robot gets for each suck.
suckXpRate: 1.0

# This is the amount of additional energy that fits into a robots
# internal buffer for each level it gains. So with the default values,
# at maximum level (30) a robot will have an internal buffer size of
Expand Down Expand Up @@ -1003,6 +1006,10 @@ opencomputers {
"allow default"
]

whitelist: []

blacklist: []

# The time in seconds to wait for a response to a request before timing
# out and returning an error message. If this is zero (the default) the
# request will never time out.
Expand Down Expand Up @@ -1400,6 +1407,10 @@ opencomputers {
# be performed by the trading upgrade
tradingRange: 8.0

# The maximum range between the drone/robot and a experience orb for a suck to
# be performed by the experience upgrade
suckXpRange: 8.0

# Radius the MFU is able to operate in
mfuRange: 3

Expand Down Expand Up @@ -1645,7 +1656,7 @@ opencomputers {

# This setting assigns the budget call cost to invoke bitblt to write vram
# to a screen. Video ram can bitblit to a screen which can cause real life
# network laod the defaults settings put bitblit network impact close to gpu.set
# network load the defaults settings put bitblit network impact close to gpu.set
# Increase these values to throttle bitblt more. The cost tier N is bitbltCost * 2^(tier)
# default is .5, which gives: .5, 1, 4
bitbltCost: 0.5
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/li/cil/oc/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ class Settings(val config: Config) {
val robotActionXp = config.getDouble("robot.xp.actionXp") max 0
val robotExhaustionXpRate = config.getDouble("robot.xp.exhaustionXpRate") max 0
val robotOreXpRate = config.getDouble("robot.xp.oreXpRate") max 0
val robotSuckXpRate = config.getDouble("robot.xp.suckXpRate") max 0
val bufferPerLevel = config.getDouble("robot.xp.bufferPerLevel") max 0
val toolEfficiencyPerLevel = config.getDouble("robot.xp.toolEfficiencyPerLevel") max 0
val harvestSpeedBoostPerLevel = config.getDouble("robot.xp.harvestSpeedBoostPerLevel") max 0
Expand Down Expand Up @@ -387,6 +388,7 @@ class Settings(val config: Config) {
val serverRackSwitchTier = (config.getInt("misc.serverRackSwitchTier") - 1) max Tier.None min Tier.Three
val redstoneDelay = config.getDouble("misc.redstoneDelay") max 0
val tradingRange = config.getDouble("misc.tradingRange") max 0
val suckXpRange = config.getDouble("misc.suckXpRange") max 0
val mfuRange = config.getInt("misc.mfuRange") max 0 min 128

// ----------------------------------------------------------------------- //
Expand Down
29 changes: 26 additions & 3 deletions src/main/scala/li/cil/oc/server/component/UpgradeExperience.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package li.cil.oc.server.component

import java.util

import li.cil.oc.Constants
import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute
import li.cil.oc.api.driver.DeviceInfo.DeviceClass
Expand All @@ -15,7 +14,7 @@ import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network.Visibility
import li.cil.oc.api.prefab.AbstractManagedEnvironment
import li.cil.oc.util.UpgradeExperience
import li.cil.oc.util.{BlockPosition, UpgradeExperience}
import net.minecraft.enchantment.EnchantmentHelper
import net.minecraft.entity.item.EntityXPOrb
import net.minecraft.init.Items
Expand All @@ -24,7 +23,7 @@ import net.minecraft.nbt.NBTTagCompound
import scala.collection.convert.WrapAsJava._
import scala.collection.convert.WrapAsScala._

class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends AbstractManagedEnvironment with DeviceInfo {
class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends AbstractManagedEnvironment with traits.WorldAware with DeviceInfo {
final val MaxLevel = 30

override val node = api.Network.newNode(this, Visibility.Network).
Expand All @@ -42,6 +41,8 @@ class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends A

override def getDeviceInfo: util.Map[String, String] = deviceInfo

override def position: BlockPosition = BlockPosition(host)

var experience = 0.0

var level = 0
Expand Down Expand Up @@ -110,6 +111,28 @@ class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends A
result(true)
}

@Callback(doc = """function():number -- suck experience from nearby. return the amount of sucked experience""")
def suck(context: Context, args: Arguments): Array[AnyRef] = {
val nearBounds = position.bounds
val farBounds = nearBounds.offset(Settings.get.suckXpRange, Settings.get.suckXpRange, Settings.get.suckXpRange)
val bounds = nearBounds.union(farBounds)
var gained = 0D
entitiesInBounds[EntityXPOrb](classOf[EntityXPOrb], bounds).foreach(orb => {

if (!orb.isDead && orb.xpValue > 0) {
val copy = experience.toDouble
addExperience(orb.xpValue * Settings.get.robotSuckXpRate)
val added = (experience.toDouble - copy) / Settings.get.robotSuckXpRate
gained += added
orb.xpValue = (orb.xpValue - added.toInt)
if (orb.xpValue <= 0) {
orb.setDead()
}
}
})
result(gained)
}

private def updateClient() = host match {
case robot: internal.Robot => robot.synchronizeSlot(robot.componentSlot(node.address))
case _ =>
Expand Down