This commit is contained in:
Bishop 2026-07-21 23:10:44 -05:00
parent 3722762b70
commit af167f1431
4 changed files with 78 additions and 73 deletions

View file

@ -65,7 +65,7 @@ public enum BuildHotspot {
* Low-level Work shop hotspots.
*/
REPAIR(15448, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.REPAIR_BENCH, Decoration.WHETSTONE, Decoration.ARMOUR_STAND),
WORKBENCH(15439, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKBENCH_WOODEN, Decoration.WORKBENCH_OAK,Decoration.WORKBENCH_STEEL_FRAME, Decoration.WORKBENCH_WITH_VICE,Decoration.WORKBENCH_WITH_LATHE),
WORKBENCH(15439, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKBENCH_WOODEN, Decoration.WORKBENCH_OAK,Decoration.WORKBENCH_STEEL_FRAME, Decoration.WORKBENCH_WITH_VICE, Decoration.WORKBENCH_WITH_LATHE),
CRAFTING(15441, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.CRAFTING_TABLE_1, Decoration.CRAFTING_TABLE_2,Decoration.CRAFTING_TABLE_3, Decoration.CRAFTING_TABLE_4),
TOOL1(15443, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2, Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4, Decoration.TOOL_STORE_5),
TOOL2(15444, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),

View file

@ -9,6 +9,7 @@ import core.game.interaction.OptionHandler;
import core.game.node.Node;
import core.game.node.entity.player.Player;
import core.game.node.scenery.Scenery;
import core.game.world.map.RegionManager;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.tools.Log;
@ -16,6 +17,7 @@ import core.tools.SystemLogger;
import core.plugin.ClassScanner;
import static core.api.ContentAPIKt.log;
import static core.api.ContentAPIKt.setAttribute;
/**
* The build option handling plugin.
@ -71,6 +73,26 @@ public final class BuildOptionPlugin extends OptionHandler {
return true;
}
BuildHotspot[] linked = BuildHotspot.getLinkedHotspots(hotspot.getHotspot());
if (linked != null && linked[0] != hotspot.getHotspot()) {
Room room = player.getHouseManager().getRoom(object.getLocation());
if (room == null) return true;
for (Hotspot h : room.getHotspots()) {
if (h.getHotspot() == linked[0]) {
int dx = h.getCurrentX() - object.getLocation().getChunkOffsetX();
int dy = h.getCurrentY() - object.getLocation().getChunkOffsetY();
Scenery primaryObj = RegionManager.getObject(object.getLocation().transform(dx, dy, 0));
if (primaryObj != null) {
setAttribute(player, "con:hsobject", primaryObj);
setAttribute(player, "con:hotspot", h);
BuildingUtils.openBuildInterface(player, linked[0]);
}
return true;
}
}
return true;
}
player.setAttribute("con:hotspot", hotspot);
BuildingUtils.openBuildInterface(player, hotspot.getHotspot());
return true;

View file

@ -29,8 +29,10 @@ class ConstructionInterface : InterfaceListener {
val hotspot = getAttribute<Hotspot?>(player, "con:hotspot", null)
val `object` = getAttribute<Scenery?>(player, "con:hsobject", null)
val flatpackMode = getAttribute(player, WorkbenchListeners.attributeFlatpackMode, false)
if ((hotspot == null || `object` == null) && !flatpackMode) {
if (!flatpackMode) {
closeInterface(player)
}
if ((hotspot == null || `object` == null) && !flatpackMode) {
log(this.javaClass, Log.ERR, "Failed building decoration $hotspot : $`object`")
return@on false
}
@ -40,7 +42,6 @@ class ConstructionInterface : InterfaceListener {
} else {
hotspot!!.hotspot
}
closeInterface(player)
if (slot >= buildHotspot.decorations.size) {
log(this.javaClass, Log.ERR, "Failed building decoration " + slot + "/" + buildHotspot.decorations.size)
return@on false
@ -78,7 +79,7 @@ class ConstructionInterface : InterfaceListener {
}
}
if (flatpackMode && WorkbenchListeners.getBenchLevel(getAttribute(player, WorkbenchListeners.attributeWorkbenchId, 0)) < deco.level) {
sendDialogue(player, "You need a better workbench to make this flatpack.") // TODO: find authentic dialogue
sendMessage(player, "You need a better workbench to make this flatpack.") // TODO: find authentic dialogue
return@on true
}
}

View file

@ -12,9 +12,9 @@ import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.game.node.item.Item
import core.game.node.scenery.SceneryBuilder
import core.game.world.map.Direction
import core.game.world.map.RegionManager
import core.game.world.update.flag.context.Animation
import core.tools.ticksToCycles
import org.rs09.consts.Items
import org.rs09.consts.Scenery
@ -29,10 +29,10 @@ class WorkbenchListeners : InteractionListener, InterfaceListener {
const val workbenchInterface = 397
const val attributeWorkbenchId = "con:workbench"
const val attributeFlatpackMode = "con:flatpack"
const val attributeSelection = "con:flatpack-hotspot"
const val attributeCrafting = "con:crafting"
const val attributeStandUp = "con:stand-up"
const val attributeFlatpackMode = "con:flatpack:active"
const val attributeSelection = "con:flatpack:hotspot"
const val attributeReturnDir = "con:flatpack:direction"
const val attributeSuccess = "con:flatpack:success"
const val animationSitDown = 4103
const val animationStandUp = 4105
@ -41,8 +41,6 @@ class WorkbenchListeners : InteractionListener, InterfaceListener {
const val animationCraft = 4109
const val animationCraftOak = 4110
const val `nothing` = 15440
private val workbenches = intArrayOf(
Scenery.WORKBENCH_13704, // lv20, wooden
Scenery.WORKBENCH_13705, // lv40, oak
@ -81,76 +79,60 @@ class WorkbenchListeners : InteractionListener, InterfaceListener {
fun produceFlatpack(player: Player, deco: Decoration) {
val reward = deco.flatpackItemID
val directions = getAttribute(player, attributeReturnDir, arrayOf(Direction.WEST, Direction.NORTH, Direction.EAST))
val animation = if (getScenery(player.location)?.id == Scenery.STOOL_13720) { animationCraftOak } else { animationCraft }
if (reward == -1) return
if (removeItemsIfPlayerHasEnough(player, *deco.items) || player.isAdmin) {
setAttribute(player, attributeCrafting, true)
setAttribute(player, attributeSuccess, true)
closeInterface(player)
rewardXP(player, Skills.CONSTRUCTION, deco.experience.toDouble())
addItemOrDrop(player, reward)
}
}
private fun sitDown(player: Player) {
val chunk = RegionManager.getRegionChunk(player.location)
for (x in 3..4) {
for (y in 3..4) {
val obj = chunk.objects[x][y]
if (obj != null && obj.id in stools) {
val oakStool = obj.id == Scenery.STOOL_13720
val stoolId = obj.id
val finalDir = when (Pair(x,y)) {
Pair(3,3) -> Direction.EAST
Pair(3,4) -> Direction.SOUTH
Pair(4,3) -> Direction.NORTH
else -> Direction.WEST
}
val sittingAnim = if (oakStool) animationSitOak else animationSit
val craftingAnim = if (oakStool) animationCraftOak else animationCraft
animate(player, animationSitDown)
queueScript(player, 1, QueueStrength.NORMAL) { stage ->
when (stage) {
0 -> {
SceneryBuilder.replace(obj, obj.transform(`nothing`))
animate(player, sittingAnim)
forceMove(player, player.location, player.location.transform(finalDir, -1), 0, 1000)
return@queueScript delayScript(player, 1)
}
else -> {
if (!getAttribute(player, attributeStandUp, false)) {
if (getAttribute(player, attributeCrafting, false)) {
removeAttribute(player, attributeCrafting)
animate(player, craftingAnim)
} else {
animate(player, sittingAnim)
}
return@queueScript delayScript(player, 2)
} else {
// Clean up and put the player back to normal
removeAttribute(player, attributeStandUp)
SceneryBuilder.replace(chunk.objects[x][y], obj.transform(stoolId))
animate(player, animationStandUp)
forceMove(player, player.location, player.location.transform(finalDir, 1), 0, 1000)
return@queueScript stopExecuting(player)
}
}
}
}
return
}
animate(player, animation)
lock(player, Animation(animation).duration + 1)
queueScript(player, Animation(animation).duration, QueueStrength.SOFT) {
forceMove(player, player.location, player.location.transform(directions[2], 1),
0, ticksToCycles(1), directions[1], animationStandUp)
return@queueScript stopExecuting(player)
}
}
}
private fun standUp(player: Player) {
setAttribute(player, attributeStandUp, true)
val directions = getAttribute(player, attributeReturnDir, arrayOf(Direction.WEST, Direction.NORTH, Direction.EAST))
lock(player, 2)
queueScript(player, 1, QueueStrength.SOFT) {
forceMove(player, player.location, player.location.transform(directions[2], 1),
0, ticksToCycles(1), directions[1], animationStandUp)
return@queueScript stopExecuting(player)
}
}
}
override fun defineListeners() {
on(workbenches, IntType.SCENERY, "work-at") { player, node ->
face(player, node)
sitDown(player)
setAttribute(player, attributeWorkbenchId, node.id)
openInterface(player, workbenchInterface)
val baseX = node.location.x - node.location.chunkOffsetX
val baseY = node.location.y - node.location.chunkOffsetY
for (x in 3..4) {
for (y in 3..4) {
val obj = getScenery(baseX + x, baseY + y, node.location.z) ?: continue
if (obj.id in stools) {
val directions = when (Pair(x,y)) {
Pair(3,3) -> arrayOf(Direction.WEST, Direction.NORTH, Direction.EAST)
Pair(3,4) -> arrayOf(Direction.NORTH, Direction.EAST, Direction.SOUTH)
Pair(4,3) -> arrayOf(Direction.SOUTH, Direction.WEST, Direction.NORTH)
else -> arrayOf(Direction.EAST, Direction.SOUTH, Direction.WEST)
}
setAttribute(player, attributeWorkbenchId, node.id)
setAttribute(player, attributeReturnDir, directions)
forceMove(player, player.location, player.location.transform(directions[0], 1),
0, ticksToCycles(1), directions[1], animationSitDown) {
animate(player, if (obj.id == Scenery.STOOL_13720) animationSitOak else animationSit)
openInterface(player, workbenchInterface)
}
return@on true
}
}
}
return@on true
}
on(workbenches, IntType.SCENERY, "upgrade") { player, node ->
@ -179,16 +161,16 @@ class WorkbenchListeners : InteractionListener, InterfaceListener {
onClose(workbenchInterface) { player, _ ->
if (!getAttribute(player, attributeFlatpackMode, false)) {
standUp(player)
removeAttribute(player, attributeSelection)
removeAttribute(player, attributeFlatpackMode)
removeAttributes(player, attributeFlatpackMode, attributeReturnDir, attributeSelection, attributeSuccess, attributeWorkbenchId)
}
return@onClose true
}
onClose(ConstructionInterface.decorationInterface) { player, _ ->
standUp(player)
removeAttribute(player, attributeSelection)
removeAttribute(player, attributeFlatpackMode)
if (getAttribute(player, attributeFlatpackMode, false) && !getAttribute(player, attributeSuccess, false)) {
standUp(player)
}
removeAttributes(player, attributeFlatpackMode, attributeReturnDir, attributeSelection, attributeSuccess, attributeWorkbenchId)
return@onClose true
}
}