mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-21 18:35:11 -06:00
Ready for primetime
This commit is contained in:
parent
688442e7f0
commit
301d589eef
8 changed files with 222 additions and 83 deletions
|
|
@ -13,7 +13,6 @@ import core.game.world.map.RegionManager;
|
|||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.tools.Log;
|
||||
import core.tools.SystemLogger;
|
||||
import core.plugin.ClassScanner;
|
||||
|
||||
import static core.api.ContentAPIKt.log;
|
||||
|
|
@ -50,7 +49,7 @@ public final class BuildOptionPlugin extends OptionHandler {
|
|||
player.getDialogueInterpreter().open("con:removedec", object);
|
||||
return true;
|
||||
}
|
||||
setAttribute(player, ConstructionInterface.attributeHsObject, node);
|
||||
setAttribute(player, ConstructionInterface.attributeHotspotObj, node);
|
||||
if (BuildingUtils.isDoorHotspot(object)) {
|
||||
int[] pos = BuildingUtils.roomExists(player, object);
|
||||
if (pos != null) {
|
||||
|
|
@ -83,7 +82,7 @@ public final class BuildOptionPlugin extends OptionHandler {
|
|||
int dy = h.getCurrentY() - object.getLocation().getChunkOffsetY();
|
||||
Scenery primaryObj = RegionManager.getObject(object.getLocation().transform(dx, dy, 0));
|
||||
if (primaryObj != null) {
|
||||
setAttribute(player, ConstructionInterface.attributeHsObject, primaryObj);
|
||||
setAttribute(player, ConstructionInterface.attributeHotspotObj, primaryObj);
|
||||
setAttribute(player, ConstructionInterface.attributeHotspot, h);
|
||||
BuildingUtils.openBuildInterface(player, linked[0]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ public final class BuildRoomDialogue extends DialoguePlugin {
|
|||
stage = 2;
|
||||
return true;
|
||||
}
|
||||
this.door = (Scenery) getAttribute(player, ConstructionInterface.attributeHsObject, null);
|
||||
this.door = (Scenery) getAttribute(player, ConstructionInterface.attributeHotspotObj, null);
|
||||
int[] pos = BuildingUtils.getRoomPosition(player, door);
|
||||
roomX = pos[0];
|
||||
roomY = pos[1];
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public final class BuildingUtils {
|
|||
/**
|
||||
* The removing a decoration animation.
|
||||
*/
|
||||
public static final Animation REMOVE_ANIMATION = Animation.create(3685);
|
||||
private static final Animation REMOVE_ANIMATION = Animation.create(3685);
|
||||
|
||||
/**
|
||||
* The plank item.
|
||||
|
|
@ -139,9 +139,13 @@ public final class BuildingUtils {
|
|||
* @param object The object.
|
||||
*/
|
||||
public static void buildDecoration(final Player player, final Hotspot hotspot, final Decoration deco, final Scenery object) {
|
||||
buildDecoration(player, hotspot, deco, object, false, false);
|
||||
}
|
||||
|
||||
public static void buildDecoration(final Player player, final Hotspot hotspot, final Decoration deco, final Scenery object, final boolean bypassCost, final boolean bypassXp) {
|
||||
final int nailAmount = deco.getNailAmount();
|
||||
final NailType type = nailAmount > 0 ? NailType.get(player, nailAmount) : null;
|
||||
if (nailAmount > 0 && type == null) {
|
||||
if (nailAmount > 0 && type == null && !bypassCost) {
|
||||
player.getPacketDispatch().sendMessage("You don't have the right materials.");
|
||||
return;
|
||||
}
|
||||
|
|
@ -165,7 +169,7 @@ public final class BuildingUtils {
|
|||
NailType nail = type;
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
if (nails > 0) {
|
||||
if (nails > 0 && !bypassCost) {
|
||||
if (!type.isBend()) {
|
||||
player.getPacketDispatch().sendMessage("You use a nail.");
|
||||
nails--;
|
||||
|
|
@ -189,12 +193,14 @@ public final class BuildingUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (player.getInventory().remove(deco.getItems()) || player.isAdmin()) {
|
||||
if (player.getInventory().remove(deco.getItems()) || bypassCost || player.isAdmin()) {
|
||||
setDecoration(player, r, room, hotspot, object, deco);
|
||||
player.getSkills().addExperience(Skills.CONSTRUCTION, deco.getExperience(), true);
|
||||
if (!bypassXp) {
|
||||
player.getSkills().addExperience(Skills.CONSTRUCTION, deco.getExperience(), true);
|
||||
|
||||
if (getObjectIdsThatGiveFarmingExperience().contains(deco.getObjectId())) {
|
||||
player.getSkills().addExperience(Skills.FARMING, deco.getExperience(), true);
|
||||
if (getObjectIdsThatGiveFarmingExperience().contains(deco.getObjectId())) {
|
||||
player.getSkills().addExperience(Skills.FARMING, deco.getExperience(), true);
|
||||
}
|
||||
}
|
||||
player.unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import core.game.node.scenery.Scenery
|
|||
import core.tools.Log
|
||||
|
||||
/**
|
||||
* Handles the creation of a decoration object.
|
||||
* @author Emperor
|
||||
* Handles three interfaces related to the Construction skill, namely those which allow a player to build decorations,
|
||||
* toggle building mode/expel guests, and select a room to add to the POH.
|
||||
* @author Bishop
|
||||
*/
|
||||
|
||||
|
|
@ -21,41 +21,57 @@ class ConstructionInterface : InterfaceListener {
|
|||
const val pohMenuInterface = 398
|
||||
const val roomInterface = 402
|
||||
|
||||
const val attributeHotspot = "con:hotspot"
|
||||
const val attributeHsObject = "con:hsobject"
|
||||
const val attributeHotspot = "con:hotspot"
|
||||
const val attributeHotspotObj = "con:hsobject"
|
||||
|
||||
// Register furniture here when it is only obtainable by upgrading, to send the correct rejection message.
|
||||
val upgradeOnly = arrayOf(
|
||||
Decoration.WORKBENCH_WITH_VICE,
|
||||
Decoration.WORKBENCH_WITH_LATHE,
|
||||
)
|
||||
}
|
||||
|
||||
override fun defineInterfaceListeners() {
|
||||
/**
|
||||
* Handles the interface for selecting a decoration to build.
|
||||
*/
|
||||
on(decorationInterface) { player, _, _, buttonID, slot, _ ->
|
||||
when (buttonID) {
|
||||
132 -> {
|
||||
val hotspot = getAttribute<Hotspot?>(player, attributeHotspot, null)
|
||||
val `object` = getAttribute<Scenery?>(player, attributeHsObject, null)
|
||||
val hotspotObj = getAttribute<Scenery?>(player, attributeHotspotObj, null)
|
||||
val flatpackMode = getAttribute(player, WorkbenchListeners.attributeFlatpackMode, false)
|
||||
if (!flatpackMode) {
|
||||
closeInterface(player)
|
||||
}
|
||||
if ((hotspot == null || `object` == null) && !flatpackMode) {
|
||||
log(this.javaClass, Log.ERR, "Failed building decoration $hotspot : $`object`")
|
||||
if ((hotspot == null || hotspotObj == null) && !flatpackMode) {
|
||||
log(this.javaClass, Log.ERR, "Failed building decoration $hotspot : $hotspotObj")
|
||||
return@on false
|
||||
}
|
||||
val slot = (if (slot % 2 != 0) 4 else 0) + (slot shr 1)
|
||||
val decoIndex = (if (slot % 2 != 0) 4 else 0) + (slot shr 1)
|
||||
val buildHotspot = if (flatpackMode) {
|
||||
getAttribute<BuildHotspot?>(player, WorkbenchListeners.attributeSelection, null)?: return@on false
|
||||
} else {
|
||||
hotspot!!.hotspot
|
||||
}
|
||||
if (slot >= buildHotspot.decorations.size) {
|
||||
log(this.javaClass, Log.ERR, "Failed building decoration " + slot + "/" + buildHotspot.decorations.size)
|
||||
if (decoIndex >= buildHotspot.decorations.size) {
|
||||
log(this.javaClass, Log.ERR, "Failed building decoration $decoIndex/${buildHotspot.decorations.size}")
|
||||
return@on false
|
||||
}
|
||||
val deco = buildHotspot.decorations[slot]
|
||||
val deco = buildHotspot.decorations[decoIndex]
|
||||
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.")
|
||||
closeInterface(player)
|
||||
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
|
||||
if (deco in upgradeOnly) {
|
||||
closeInterface(player)
|
||||
sendMessage(player, "That can only be built by upgrading the previous piece of furniture.")
|
||||
return@on true
|
||||
}
|
||||
if (!player.inventory.containsItems(*deco.items)) { // No clean ContentAPI substitute for this
|
||||
closeInterface(player)
|
||||
sendMessage(player, "You don't have the right materials.")
|
||||
return@on true
|
||||
}
|
||||
|
|
@ -76,20 +92,22 @@ class ConstructionInterface : InterfaceListener {
|
|||
}
|
||||
continue
|
||||
}
|
||||
if (!player.inventory.contains(tool, 1)) {
|
||||
if (!inInventory(player, tool)) {
|
||||
closeInterface(player)
|
||||
sendMessage(player, "You need a ${ItemDefinition.forId(tool).name} to build this.")
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
if (flatpackMode && WorkbenchListeners.getBenchLevel(getAttribute(player, WorkbenchListeners.attributeWorkbenchId, 0)) < deco.level) {
|
||||
sendMessage(player, "You need a better workbench to make this flatpack.") // TODO: find authentic dialogue
|
||||
if (flatpackMode && WorkbenchListeners.getBenchLevel(getAttribute(player, WorkbenchListeners.attributeWorkbenchId, 20)) < deco.level) {
|
||||
closeInterface(player)
|
||||
sendMessage(player, "You cannot make this with this workbench.") // Placeholder
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
if (flatpackMode) {
|
||||
WorkbenchListeners.produceFlatpack(player, deco)
|
||||
} else {
|
||||
BuildingUtils.buildDecoration(player, hotspot, deco, `object`)
|
||||
BuildingUtils.buildDecoration(player, hotspot, deco, hotspotObj)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
|
@ -97,6 +115,9 @@ class ConstructionInterface : InterfaceListener {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the interface for managing building mode and POH guests.
|
||||
*/
|
||||
on(pohMenuInterface) { player, _, _, buttonID, _, _ ->
|
||||
when (buttonID) {
|
||||
14 -> {
|
||||
|
|
@ -123,12 +144,14 @@ class ConstructionInterface : InterfaceListener {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the interface for selecting a new room to add to a POH.
|
||||
*/
|
||||
on(roomInterface) { player, _, _, buttonID, _, _ ->
|
||||
val index = buttonID - 160
|
||||
log(this.javaClass, Log.FINE, "BuildRoom Interface Index: $index")
|
||||
if (index > -1 && index < RoomProperties.values().size) {
|
||||
// ContentAPI impl won't work for this
|
||||
player.dialogueInterpreter.open("con:room", RoomProperties.values()[index])
|
||||
player.dialogueInterpreter.open("con:room", RoomProperties.values()[index]) // ContentAPI impl won't work for this
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package content.global.skill.construction
|
||||
|
||||
import content.global.skill.construction.BuildingUtils.buildDecoration
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
|
|
@ -16,7 +15,7 @@ import org.rs09.consts.Items
|
|||
*/
|
||||
|
||||
class FlatpackListener : InteractionListener {
|
||||
val flatpacks = Decoration.values().map { it.flatpackItemID }.toIntArray()
|
||||
val flatpacks = Decoration.values().map { it.flatpackItemID }.filter { it != -1 }.toIntArray()
|
||||
val hotspots = BuildHotspot.values().map { it.objectId }.toIntArray()
|
||||
|
||||
override fun defineListeners() {
|
||||
|
|
@ -27,20 +26,23 @@ class FlatpackListener : InteractionListener {
|
|||
}
|
||||
}
|
||||
|
||||
private fun buildFlatpackOnHotspot(player: Player, used: Item, with: Scenery):Boolean {
|
||||
private fun buildFlatpackOnHotspot(player: Player, used: Item, with: Scenery): Boolean {
|
||||
val hotspotUsed = player.houseManager.getHotspot(with)
|
||||
val decorationUsed = Decoration.forFlatpackItemId(used.id)
|
||||
|
||||
if(!hotspotUsed.hotspot.decorations.contains(decorationUsed)) {
|
||||
if (!hotspotUsed.hotspot.decorations.contains(decorationUsed)) {
|
||||
sendMessage(player, "You can't build that here.")
|
||||
return false
|
||||
}
|
||||
if (!player.inventory.containsItems(Item(Items.HAMMER_2347),Item(Items.SAW_8794))) {
|
||||
if (!inInventory(player, Items.HAMMER_2347) || !inInventory(player, Items.SAW_8794)) {
|
||||
sendMessage(player, "You need a hammer and a saw to build this.")
|
||||
return false
|
||||
}
|
||||
buildDecoration(player, hotspotUsed, decorationUsed, with.asScenery())
|
||||
return true
|
||||
|
||||
if (removeItem(player, used)) {
|
||||
BuildingUtils.buildDecoration(player, hotspotUsed, decorationUsed, with.asScenery(), true, true)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,9 @@ package content.global.skill.construction;
|
|||
|
||||
import core.api.Container;
|
||||
import core.game.world.map.Location;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.PlayerContext;
|
||||
import core.net.packet.out.ClearMinimapFlag;
|
||||
import org.rs09.consts.Items;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
|
@ -12,6 +15,7 @@ import core.game.world.map.Region;
|
|||
import core.game.system.task.Pulse;
|
||||
import core.game.world.map.zone.ZoneType;
|
||||
|
||||
import content.global.skill.construction.decoration.workshop.WorkbenchListeners;
|
||||
import static core.api.ContentAPIKt.*;
|
||||
|
||||
/**
|
||||
|
|
@ -80,6 +84,23 @@ public final class HouseZone extends MapZone {
|
|||
return super.enter(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean move(Entity e, Location from, Location to) {
|
||||
if (e instanceof Player) {
|
||||
Player p = (Player) e;
|
||||
if (getAttribute(p, WorkbenchListeners.attributeSitting, false)) {
|
||||
p.getPulseManager().clear();
|
||||
p.getWalkingQueue().reset();
|
||||
PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(p));
|
||||
if (!getAttribute(p, WorkbenchListeners.attributeStandingUp, false)) {
|
||||
WorkbenchListeners.standUpFromWorkbench(p);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return super.move(e, from, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean death(Entity e, Entity killer) {
|
||||
if (e instanceof Player) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
package content.global.skill.construction.decoration
|
||||
|
||||
import content.global.skill.construction.decoration.workshop.WorkbenchListeners
|
||||
import core.api.animate
|
||||
import core.api.getScenery
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.system.timer.PersistTimer
|
||||
import core.game.system.timer.RSTimer
|
||||
import org.rs09.consts.Scenery
|
||||
import kotlin.collections.get
|
||||
|
||||
/**
|
||||
* Makes a player stay seated by reapplying the current animation occasionally.
|
||||
* An alternative to some features of ChairBenchPlugin.
|
||||
* Written with workbench stools in mind.
|
||||
* @author Bishop
|
||||
*/
|
||||
|
||||
class StaySeated : PersistTimer(10 /*ticks*/, "con:sitting", isSoft = true) {
|
||||
lateinit var player: Player
|
||||
|
||||
private val standAnim = 808 // Same as AppearanceCache.STAND_ANIM
|
||||
|
||||
// Register new chairs and animations here
|
||||
private val sittables = mapOf(
|
||||
Scenery.STOOL_13719 to WorkbenchListeners.animationSit, // wooden workbench stool
|
||||
Scenery.STOOL_13720 to WorkbenchListeners.animationSitOak, // oak workbench stool
|
||||
)
|
||||
|
||||
override fun run(entity: Entity): Boolean {
|
||||
player = entity as Player
|
||||
val localObj = getScenery(player.location)?.id
|
||||
// Don't interrupt a player doing a different animation unless it's the idle animation
|
||||
val currentAnimId = player.animator.animation?.id ?: -1
|
||||
if (localObj in sittables) {
|
||||
if (currentAnimId != sittables[localObj] &&
|
||||
currentAnimId != standAnim &&
|
||||
currentAnimId != -1) {
|
||||
return true
|
||||
}
|
||||
animate(player, sittables[localObj])
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getTimer(vararg args: Any): RSTimer {
|
||||
return StaySeated()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package content.global.skill.construction.decoration.workshop
|
||||
|
||||
import content.global.skill.construction.*
|
||||
import content.global.skill.construction.decoration.StaySeated
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
|
|
@ -10,7 +11,6 @@ import core.game.node.entity.player.Player
|
|||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Direction
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.tools.ticksToCycles
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
|
|
@ -27,9 +27,10 @@ class WorkbenchListeners : InteractionListener, InterfaceListener {
|
|||
|
||||
const val attributeWorkbenchId = "con:workbench:id"
|
||||
const val attributeFlatpackMode = "con:workbench:active"
|
||||
const val attributeDirections = "con:workbench:directions"
|
||||
const val attributeDirections = "con:workbench:directions"
|
||||
const val attributeSelection = "con:workbench:hotspot"
|
||||
const val attributeSitting = "con:workbench:sitting"
|
||||
const val attributeStandingUp = "con:workbench:standing"
|
||||
|
||||
const val animationSitDown = 4103
|
||||
const val animationStandUp = 4105
|
||||
|
|
@ -47,70 +48,89 @@ class WorkbenchListeners : InteractionListener, InterfaceListener {
|
|||
)
|
||||
|
||||
private val stools = intArrayOf(
|
||||
Scenery.STOOL_13719, // wooden
|
||||
Scenery.STOOL_13720, // oak
|
||||
Scenery.STOOL_13719, // wooden stool, bottom 2 tiers
|
||||
Scenery.STOOL_13720, // oak stool, top 3 tiers
|
||||
)
|
||||
|
||||
private val decoCategories = 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
|
||||
BuildHotspot.CHAIRS_1, // ButtonID 111
|
||||
BuildHotspot.BOOKCASE, // ButtonID 112
|
||||
BuildHotspot.BARRELS, // ButtonID 113
|
||||
BuildHotspot.KITCHEN_TABLE, // ButtonID 114
|
||||
BuildHotspot.DINING_TABLE, // ButtonID 115
|
||||
BuildHotspot.DINING_BENCH_1, // ButtonID 116
|
||||
BuildHotspot.BED, // ButtonID 117
|
||||
BuildHotspot.DRESSER, // ButtonID 118
|
||||
BuildHotspot.DRAWERS, // ButtonID 119
|
||||
BuildHotspot.CLOCK, // ButtonID 120
|
||||
BuildHotspot.CAPE_RACK, // ButtonID 121
|
||||
BuildHotspot.MAGIC_WARDROBE, // ButtonID 122
|
||||
BuildHotspot.ARMOUR_CASE, // ButtonID 123
|
||||
BuildHotspot.TREASURE_CHEST, // ButtonID 124
|
||||
BuildHotspot.COSTUME_BOX, // ButtonID 125
|
||||
BuildHotspot.TOY_BOX, // ButtonID 126
|
||||
)
|
||||
|
||||
/**
|
||||
* Returns the maximum construction level of decoration that can be built at a given workbench by id
|
||||
* Returns the maximum construction level of decoration that can be built at a given workbench by id.
|
||||
*/
|
||||
fun getBenchLevel(workbenchId: Int): Int {
|
||||
return (workbenches.indexOf(workbenchId) + 1) * 20
|
||||
return ((workbenches.indexOf(workbenchId) + 1) * 20)
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the player crafting a flatpack, and exchanges its materials for the flatpack item.
|
||||
* Flatpacks are free to produce for players with admin rights.
|
||||
*/
|
||||
fun produceFlatpack(player: Player, deco: Decoration) {
|
||||
val reward = deco.flatpackItemID
|
||||
val animation = if (getScenery(player.location)?.id == Scenery.STOOL_13720) { animationCraftOak } else { animationCraft }
|
||||
if (reward == -1) return
|
||||
if (removeItemsIfPlayerHasEnough(player, *deco.items) || player.isAdmin) {
|
||||
closeInterface(player)
|
||||
lock(player, Animation(animation).duration)
|
||||
lock(player, getAnimation(animation).duration)
|
||||
animate(player, animation)
|
||||
rewardXP(player, Skills.CONSTRUCTION, deco.experience.toDouble())
|
||||
addItemOrDrop(player, reward)
|
||||
}
|
||||
}
|
||||
|
||||
private fun standUp(player: Player) {
|
||||
/**
|
||||
* Animates the player getting up from the workbench's stool.
|
||||
* This occurs on the player's first attempt at movement off of the workbench.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun standUpFromWorkbench(player: Player) {
|
||||
val directions = getAttribute(player, attributeDirections, arrayOf(Direction.WEST, Direction.NORTH, Direction.EAST))
|
||||
lock(player, animationStandUp)
|
||||
val animation = if (getScenery(player.location)?.id == Scenery.STOOL_13720) { animationSitOak } else { animationSit }
|
||||
setAttribute(player, attributeStandingUp, true)
|
||||
lock(player, 1)
|
||||
animate(player, animation)
|
||||
queueScript(player, 0, QueueStrength.SOFT) {
|
||||
forceMove(player, player.location, player.location.transform(directions[2], 1),
|
||||
0, ticksToCycles(1), directions[2], animationStandUp)
|
||||
removeAttributes(player, attributeSitting, attributeDirections)
|
||||
0, ticksToCycles(1), directions[2], animationStandUp) {
|
||||
removeAttributes(player, attributeDirections, attributeSitting, attributeStandingUp)
|
||||
removeTimer<StaySeated>(player)
|
||||
}
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
/**
|
||||
* Animates the player sitting down at the workbench, and opens the workbench interface.
|
||||
*/
|
||||
on(workbenches, IntType.SCENERY, "work-at") { player, node ->
|
||||
setAttribute(player, attributeWorkbenchId, node.id)
|
||||
// Skips the animation if the player is already sitting down.
|
||||
if (getAttribute(player, attributeSitting, false)) {
|
||||
val animation = if (getScenery(player.location)?.id == Scenery.STOOL_13720) { animationSitOak } else { animationSit }
|
||||
animate(player, animation)
|
||||
openInterface(player, workbenchInterface)
|
||||
return@on true
|
||||
}
|
||||
// Ascertains the room rotation from where the stool is, to coordinate animations
|
||||
val baseX = node.location.x - node.location.chunkOffsetX
|
||||
val baseY = node.location.y - node.location.chunkOffsetY
|
||||
for (x in 3..4) {
|
||||
|
|
@ -126,8 +146,10 @@ class WorkbenchListeners : InteractionListener, InterfaceListener {
|
|||
setAttribute(player, attributeDirections, 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)
|
||||
val animation = if (obj.id == Scenery.STOOL_13720) { animationSitOak } else { animationSit }
|
||||
animate(player, animation)
|
||||
setAttribute(player, attributeSitting, true)
|
||||
registerTimer(player, StaySeated())
|
||||
openInterface(player, workbenchInterface)
|
||||
}
|
||||
return@on true
|
||||
|
|
@ -137,31 +159,43 @@ class WorkbenchListeners : InteractionListener, InterfaceListener {
|
|||
return@on true
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles upgrading a workbench with the minimenu option.
|
||||
*/
|
||||
on(workbenches, IntType.SCENERY, "upgrade") { player, node ->
|
||||
if (!inInventory(player, Items.OAK_PLANK_8778, 2) || !inInventory(player, Items.STEEL_BAR_2353)) {
|
||||
sendDialogue(player, "You need two oak planks and a steel bar to upgrade this workbench.") // TODO: find authentic dialogue
|
||||
// I could not find any video of how this looks or what the messages are, so all messages in this listener are placeholders.
|
||||
val hotspot = Hotspot(BuildHotspot.WORKBENCH, 3, 4, 4, 4)
|
||||
val nodeObj = node as core.game.node.scenery.Scenery
|
||||
val resultDeco = Decoration.forObjectId(node.id + 1)
|
||||
if (!player.houseManager.isBuildingMode) {
|
||||
sendMessage(player, "You have to be in building mode to do this.") // I don't actually know if this is true but better safe than sorry.
|
||||
return@on true
|
||||
}
|
||||
if (removeItem(player, Item(Items.OAK_PLANK_8778, 2)) && removeItem(player, Items.STEEL_BAR_2353)) {
|
||||
val hotspotSearchTile = node.location
|
||||
// only the 2nd and 3rd best workbenches have upgrade options
|
||||
val resultDeco = if (node.id == Scenery.WORKBENCH_13706) { // steel framed
|
||||
Decoration.forObjectId(Scenery.WORKBENCH_13707) // with vice
|
||||
} else {
|
||||
Decoration.forObjectId(Scenery.WORKBENCH_13708) // with lathe
|
||||
}
|
||||
if (getDynLevel(player, Skills.CONSTRUCTION) < resultDeco.level) {
|
||||
sendMessage(player, "You need a Construction level of ${resultDeco.level} to upgrade this.")
|
||||
return@on true
|
||||
}
|
||||
if (!inInventory(player, Items.OAK_PLANK_8778, 2) || !inInventory(player, Items.STEEL_BAR_2353)) {
|
||||
sendMessage(player, "You need two oak planks and a steel bar to upgrade this.")
|
||||
return@on true
|
||||
}
|
||||
if (!inInventory(player, Items.HAMMER_2347) || !inInventory(player, Items.SAW_8794)) {
|
||||
sendMessage(player, "You need a hammer and a saw to upgrade this.")
|
||||
return@on true
|
||||
}
|
||||
if (removeItemsIfPlayerHasEnough(player, Item(Items.OAK_PLANK_8778, 2), Item(Items.STEEL_BAR_2353))) {
|
||||
queueScript(player, 0, QueueStrength.SOFT) { stage ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, BuildingUtils.REMOVE_ANIMATION.duration + BuildingUtils.BUILD_MID_ANIM.duration)
|
||||
BuildingUtils.removeDecoration(player, node as core.game.node.scenery.Scenery)
|
||||
return@queueScript delayScript(player, BuildingUtils.REMOVE_ANIMATION.duration)
|
||||
lock(player, BuildingUtils.BUILD_MID_ANIM.duration)
|
||||
// Replaces the workbench with the upgraded form in HouseManager but not immediately in the instance
|
||||
BuildingUtils.buildDecoration(player, hotspot, resultDeco, nodeObj, true, false)
|
||||
return@queueScript delayScript(player, BuildingUtils.BUILD_MID_ANIM.duration)
|
||||
}
|
||||
1 -> {
|
||||
val hotspot = Hotspot(BuildHotspot.WORKBENCH, 3, 4, 4, 4)
|
||||
val hotspotObj = getScenery(hotspotSearchTile)
|
||||
BuildingUtils.buildDecoration(player, hotspot, resultDeco, hotspotObj)
|
||||
return@queueScript delayScript(player, BuildingUtils.BUILD_MID_ANIM.duration)
|
||||
// Temporary replacement until POH can rebuild on next entrance with the correct workbench
|
||||
replaceScenery(nodeObj, resultDeco.objectId, -1)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
|
@ -172,6 +206,9 @@ class WorkbenchListeners : InteractionListener, InterfaceListener {
|
|||
}
|
||||
|
||||
override fun defineInterfaceListeners() {
|
||||
/**
|
||||
* Directs the player to the appropriate decoration building interface.
|
||||
*/
|
||||
on(workbenchInterface) { player, _, _, buttonID, _, _ ->
|
||||
val index = buttonID - 111
|
||||
if (index < 0 || index >= decoCategories.size) return@on false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue