Flatpack production mechanics

This commit is contained in:
Bishop 2026-07-20 22:44:08 -05:00
parent 664f1be79b
commit 14bb43b565
2 changed files with 226 additions and 110 deletions

View file

@ -1,120 +1,125 @@
package content.global.skill.construction;
package content.global.skill.construction
import core.cache.def.impl.ItemDefinition;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.game.node.entity.skill.Skills;
import core.game.node.scenery.Scenery;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.tools.Log;
import core.tools.SystemLogger;
import static core.api.ContentAPIKt.log;
import content.global.skill.construction.decoration.workshop.WorkbenchListeners
import core.api.*
import core.cache.def.impl.ItemDefinition
import core.game.interaction.InterfaceListener
import core.game.node.entity.skill.Skills
import core.game.node.scenery.Scenery
import core.tools.Log
/**
* Handles the creating of a decoration object.
* @author Emperor
*
* @author Bishop
*/
@Initializable
public final class ConstructionInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) {
ComponentDefinition.put(396, this);
ComponentDefinition.put(398, this);
ComponentDefinition.put(402, this);
return this;
}
class ConstructionInterface : InterfaceListener {
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
switch (component.getId()) {
case 396:
switch (button) {
case 132:
player.getInterfaceManager().close();
Hotspot hotspot = player.getAttribute("con:hotspot");
Scenery object = player.getAttribute("con:hsobject");
if (hotspot == null || object == null) {
log(this.getClass(), Log.ERR, "Failed building decoration " + hotspot + " : " + object);
break;
}
slot = ((slot % 2 != 0) ? 4 : 0) + (slot >> 1);
if (slot >= hotspot.getHotspot().getDecorations().length) {
log(this.getClass(), Log.ERR, "Failed building decoration " + slot + "/" + hotspot.getHotspot().getDecorations().length);
break;
}
boolean debug = player.isStaff();
Decoration deco = hotspot.getHotspot().getDecorations()[slot];
if (!debug) {
if (player.getSkills().getLevel(Skills.CONSTRUCTION) < deco.getLevel()) {
player.sendMessage("You need to have a Construction level of " + deco.getLevel() + " to build that.");
return true;
}
if (!player.getInventory().containsItems(deco.getItems())) {
player.sendMessage("You don't have the right materials.");
return true;
}
for (int tool : deco.getTools()) {
if (tool == BuildingUtils.WATERING_CAN) {
boolean hasWateringCan = false;
for (int i = 0; i < 8; i++) {
if (player.getInventory().contains(tool - i, 1)) {
hasWateringCan = true;
break;
}
}
if (!hasWateringCan) {
player.sendMessage("You need a watering can to plant this.");
return true;
}
continue;
}
if (!player.getInventory().contains(tool, 1)) {
player.sendMessage("You need a " + ItemDefinition.forId(tool).getName() + " to build this.");
return true;
}
}
}
BuildingUtils.buildDecoration(player, hotspot, deco, object);
return true;
}
break;
case 398:
switch (button) {
case 14:
player.getHouseManager().toggleBuildingMode(player, true);
return true;
case 1:
player.getHouseManager().toggleBuildingMode(player, false);
return true;
case 15:
player.getHouseManager().expelGuests(player);
return true;
case 13:
if (!player.getHouseManager().isInHouse(player)) {
player.sendMessage("You can't do this outside of your house.");
return true;
}
HouseManager.leave(player);
return true;
}
break;
case 402:
int index = button - 160;
log(this.getClass(), Log.FINE, "BuildRoom Interface Index: " + index);
if (index > -1 && index < RoomProperties.values().length) {
player.getDialogueInterpreter().open("con:room", RoomProperties.values()[index]);
return true;
}
break;
}
return false;
}
companion object {
const val DECO_INTERFACE = 396
const val POH_MENU = 398
const val ROOM_INTERFACE = 402
}
override fun defineInterfaceListeners() {
on(DECO_INTERFACE) { player, _, _, buttonID, slot, _ ->
when (buttonID) {
132 -> {
closeInterface(player)
val hotspot = getAttribute<Hotspot?>(player, "con:hotspot", null)
val `object` = getAttribute<Scenery?>(player, "con:hsobject", null)
if (hotspot == null || `object` == null) {
log(this.javaClass, Log.ERR, "Failed building decoration $hotspot : $`object`")
return@on false
}
val slot = (if (slot % 2 != 0) 4 else 0) + (slot shr 1)
if (slot >= hotspot.hotspot.decorations.size) {
log(this.javaClass, Log.ERR, "Failed building decoration " + slot + "/" + hotspot.hotspot.decorations.size)
return@on false
}
val deco = hotspot.hotspot.decorations[slot]
if (!player.isAdmin) {
if (getDynLevel(player, Skills.CONSTRUCTION) < deco.level) {
sendMessage(player, "You need to have a Construction level of " + deco.level + " to build that.")
return@on true
}
if (!player.inventory.containsItems(*deco.items)) { // search for contentAPI way to do this
sendMessage(player, "You don't have the right materials.")
return@on true
}
for (tool in deco.tools) {
if (tool == BuildingUtils.WATERING_CAN) {
var hasWateringCan = false
var i = 0
while (i < 8) {
if (inInventory(player, tool - i)) {
hasWateringCan = true
break
}
i++
}
if (!hasWateringCan) {
sendMessage(player, "You need a watering can to plant this.")
return@on true
}
continue
}
if (!player.inventory.contains(tool, 1)) {
sendMessage(player, "You need a ${ItemDefinition.forId(tool).name} to build this.")
return@on true
}
}
if (getAttribute(player, WorkbenchListeners.attributeFlatpackMode, false) &&
WorkbenchListeners.getMaxLevel(getAttribute(player, WorkbenchListeners.attributeWorkbenchId, 0)) < deco.level) {
sendMessage(player, "You need a better workbench to make this flatpack.") // placeholder
return@on true
}
}
if (getAttribute(player, WorkbenchListeners.attributeFlatpackMode, false)) {
WorkbenchListeners.produceFlatpack(player, deco)
} else {
BuildingUtils.buildDecoration(player, hotspot, deco, `object`)
}
return@on true
}
else -> return@on false
}
}
on(POH_MENU) { player, _, _, buttonID, _, _ ->
when (buttonID) {
14 -> {
player.houseManager.toggleBuildingMode(player, true)
return@on true
}
1 -> {
player.houseManager.toggleBuildingMode(player, false)
return@on true
}
15 -> {
player.houseManager.expelGuests(player)
return@on true
}
13 -> {
if (!player.houseManager.isInHouse(player)) {
player.sendMessage("You can't do this outside of your house.")
return@on true
}
HouseManager.leave(player)
return@on true
}
else -> return@on false
}
}
on(ROOM_INTERFACE) { player, _, _, buttonID, _, _ ->
val index = buttonID - 160
log(this.javaClass, Log.FINE, "BuildRoom Interface Index: $index")
if (index > -1 && index < RoomProperties.values().size) {
player.dialogueInterpreter.open("con:room", RoomProperties.values()[index])
}
return@on true
}
}
}

View file

@ -0,0 +1,111 @@
package content.global.skill.construction.decoration.workshop
import content.global.skill.construction.BuildHotspot
import content.global.skill.construction.BuildingUtils
import content.global.skill.construction.ConstructionInterface
import content.global.skill.construction.Decoration
import core.api.*
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.interaction.InterfaceListener
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
import core.game.node.item.Item
import org.rs09.consts.Items
import org.rs09.consts.Scenery
/**
* Handles usage of the workbench, which allows construction of flatpacks.
* @author Bishop
*/
class WorkbenchListeners : InteractionListener, InterfaceListener {
companion object {
const val WORKBENCH_INTERFACE = 397
const val attributeWorkbenchId = "con:workbench"
const val attributeFlatpackMode = "con:flatpack"
const val attributeSelection = "con:flatpack-hotspot"
val WORKBENCHES = intArrayOf(
Scenery.WORKBENCH_13704, // wooden
Scenery.WORKBENCH_13705, // oak
Scenery.WORKBENCH_13706, // steel framed
Scenery.WORKBENCH_13707, // with vice
Scenery.WORKBENCH_13708, // with lathe
)
val FLATPACK_CATEGORIES = arrayOf(
BuildHotspot.CHAIRS_1, // 111
BuildHotspot.BOOKCASE, // 112
BuildHotspot.BARRELS, // 113
BuildHotspot.KITCHEN_TABLE, // 114
BuildHotspot.DINING_TABLE, // 115
BuildHotspot.DINING_BENCH_1, // 116
BuildHotspot.BED, // 117
BuildHotspot.DRESSER, // 118
BuildHotspot.DRAWERS, // 119
BuildHotspot.CLOCK, // 120
BuildHotspot.CAPE_RACK, // 121
BuildHotspot.MAGIC_WARDROBE, // 122
BuildHotspot.ARMOUR_CASE, // 123
BuildHotspot.TREASURE_CHEST, // 124
BuildHotspot.COSTUME_BOX, // 125
BuildHotspot.TOY_BOX, // 126
)
val FLATPACKS = mapOf<Decoration, Int>(
Decoration.CRUDE_CHAIR to Items.CRUDE_WOODEN_CHAIR_8496,
Decoration.OAK_CHAIR to Items.OAK_CHAIR_8502
)
fun getMaxLevel(workbenchId: Int): Int {
return (WORKBENCHES.indexOf(workbenchId) + 1) * 20
}
// TODO: replace with real flatpack item ID lookup
fun produceFlatpack(player: Player, deco: Decoration) {
val reward = FLATPACKS[deco]?: return
if (removeItem(player, deco.items) || player.isAdmin) {
rewardXP(player, Skills.CONSTRUCTION, deco.experience.toDouble())
addItemOrDrop(player, reward)
}
}
}
override fun defineListeners() {
on(WORKBENCHES, IntType.SCENERY, "work-at") { player, node ->
setAttribute(player, attributeWorkbenchId, node.id)
openInterface(player, WORKBENCH_INTERFACE)
return@on true
}
on(WORKBENCHES, IntType.SCENERY, "upgrade") { player, node ->
if (!inInventory(player, Items.OAK_PLANK_8778, 2) || !inInventory(player, Items.STEEL_BAR_2353)) {
return@on false
}
if (removeItem(player, Item(Items.OAK_PLANK_8778, 2)) && removeItem(player, Items.STEEL_BAR_2353)) {
}
return@on true
}
}
override fun defineInterfaceListeners() {
on(WORKBENCH_INTERFACE) { player, _, _, buttonID, _, _ ->
val index = buttonID - 111
if (index < 0 || index >= FLATPACK_CATEGORIES.size) return@on false
val hotspot = FLATPACK_CATEGORIES[index]
setAttribute(player, attributeSelection, hotspot)
setAttribute(player, attributeFlatpackMode, true)
BuildingUtils.openBuildInterface(player, hotspot)
return@on true
}
onClose(ConstructionInterface.DECO_INTERFACE) { player, _ ->
removeAttribute(player, attributeSelection)
removeAttribute(player, attributeFlatpackMode)
return@onClose true
}
}
}