This is the source code for the following package: [lando] bloods
// -= Welcome to the DeadZone editor =-
// You can find all the information you'll need on DeadZone API functionality through our wiki page (linked above)
// Above us you can see three tabs called main, utilities, and config which correlate to separate files. You can switch between them whenever you'd like
// Each file has their own purpose and you'll find a short information within them of their intended purpose
// We have included extensive documentation through our wiki. In addition, if you hover over a defined type, you'll see a short description
// This is the "main" script file for you package where the majority of your logic will reside
// Below we have declared three events (OnStart, OnGameTick, and OnStop) which are required for your script to load in-game
// As a side note, any changes will be saved locally for a week so don't worry if you leave this page without committing your files
/**
* Counts the total ticks our package has been running
* @type number
*/
var totalTicksRunning;
var currentStage;
var packageName = "[lando] Blood Runes";
var isExecuting = false;
/**
* Called when your script is initially started. It's a good place to setup variables
*/
function OnStart() {
// Set our totalTicksRunning variable
totalTicksRunning = 0;
currentStage = GameStage.STARTUP;
// After a 300ms delay, send a game message
Utility.invokeLater(function () {
Game.sendGameMessage("initialized..", packageName);
}, 300);
}
/**
* Called every game tick which is roughly 0.6s. You should use this event for state management and for handling your main script logic
*/
function OnGameTick() {
// Increment our total ticks running by one
totalTicksRunning++;
// Update the 2D overlay with the current status
overlay.gameState.setValue( currentStage );
// Block if we're waiting on delays, actions, etc
if( isExecuting ) {
return;
}
switch (currentStage) {
case GameStage.STARTUP:
HandleStartup();
break;
case GameStage.MINING:
HandleMining();
break;
case GameStage.WALK_TO_DARK_ALTAR:
HandleWalkToAltar();
break;
case GameStage.DARK_ALTAR:
HandleDarkAltar();
break;
case GameStage.CRAFTING:
HandleCrafting();
break;
case GameStage.WALK_TO_BLOOD_ALTAR:
HandleWalkToBloodAltar();
break;
case GameStage.BLOOD_ALTAR:
HandleBloodAltar();
break;
case GameStage.RETURNING:
HandleReturn();
break;
default:
Utility.print('Unknown stage.');
Utility.packages.shutdown();
}
}
/**
* Called when your script is stopped.
*/
function OnShutdown() {
Game.sendGameMessage(`Shutting down.. Package was active for ${totalTicksRunning} ticks!`, "My Package");
currentStage = GameStage.STARTUP;
}
/**
* Check for location, inventory items, etc
*/
function HandleStartup() {
// Check for pickaxe
if( !Game.info.inventory.hasItems(ITEM_ID_PICKAXE_IDS, 1) && !Game.info.equipment.hasItems(ITEM_ID_PICKAXE_IDS) )
{
Game.sendGameMessage("Could not find a pickaxe!", packageName);
Utility.packages.shutdown();
return;
}
// Check for chisel
if( !Game.info.inventory.hasItem(ITEM_ID_CHISEL, 1) )
{
Game.sendGameMessage("Could not find a chisel!", packageName);
Utility.packages.shutdown();
return;
}
// Check for region
if( Client.getLocalPlayer().getWorldLocation().getRegionID() != MINING_REGION_ID )
{
Game.sendGameMessage("Please start at Arceuus Runestone mine!", packageName);
Utility.packages.shutdown();
return;
}
// We've made it to the end, we're good to start!
currentStage = GameStage.MINING;
}
/**
* Interact if inventory if not full
*/
function HandleMining() {
// Don't do anything while moving
if( PlayerHelper.isMoving() ) { return; }
// Don't do anything while mining
if( !PlayerHelper.isPlayerIdle() ) { return; }
// Block if depleted
if( Game.getVarbitValue(VARBIT_DENSE_RUNESTONE_NORTH_DEPLETED) != 0 ) { return; }
// Do we have a full inventory?
if( Game.info.inventory.getSize() == 28 )
{
currentStage = GameStage.WALK_TO_DARK_ALTAR;
return;
}
// Find the rock to mine
var mine = Game.info.gameObject.getNearest([GAME_OBJECT_DENSE_ESS_ID]);
if( mine != null )
{
isExecuting = true;
Utility.invokeLater(function () {
Game.interact.gameObject.action(mine, MenuAction.GAME_OBJECT_FIRST_OPTION);
isExecuting = false;
}, Utility.getDelay());
}
}
/**
* Inventory interaction to chisel
*/
function HandleCrafting() {
// Don't do anything while crafting
if( !PlayerHelper.isPlayerIdle() ) { return; }
if( Game.info.inventory.hasItem(ITEM_ID_DARK_BLOCK, 1) )
{
isExecuting = true;
// Click the chisel
var delay = Utility.getDelay();
Utility.invokeLater(function () {
Game.interact.inventory.useItem( ITEM_ID_CHISEL, MenuAction.WIDGET_TARGET);
}, delay);
// Small delay, click the essence
delay += Utility.getDelay() + 300;
Utility.invokeLater(function () {
Game.interact.inventory.useItem( ITEM_ID_DARK_BLOCK, MenuAction.WIDGET_TARGET_ON_WIDGET);
isExecuting = false;
}, delay);
return;
}
currentStage = GameStage.BLOOD_ALTAR;
}
function HandleWalkToAltar() {
/// Let the player walk there
if( PlayerHelper.isWebWalking() ) { return; }
// Walk to the altar
var pos = Client.getLocalPlayer().getWorldLocation();
if( pos.distanceTo(WORLDPOINT_DARK_ALTAR) > DISTANCE_TO_ALTAR )
{
PlayerHelper.webWalkTo(WORLDPOINT_DARK_ALTAR);
}
else
{
// we should be close enough here
currentStage = GameStage.DARK_ALTAR;
}
}
function HandleDarkAltar() {
// Use the essence on the altar
if( Game.info.inventory.hasItem(ITEM_ID_DENSE_BLOCK, 1) )
{
isExecuting = true;
var delay = Utility.getDelay();
Utility.invokeLater(function () {
Game.interact.gameObject.nearest( MenuAction.GAME_OBJECT_FIRST_OPTION, [GAME_OBJECT_DARK_ALTAR] );
}, delay);
// Give it time for animation to play, etc
delay += 1200;
Utility.invokeLater(function () {
isExecuting = false;
}, delay);
}
else
{
currentStage = GameStage.WALK_TO_BLOOD_ALTAR;
}
}
function HandleWalkToBloodAltar() {
/// Let the player walk there
if( PlayerHelper.isWebWalking() ) { return; }
// Walk to the altar
var pos = Client.getLocalPlayer().getWorldLocation();
if( pos.distanceTo(WORLDPOINT_BLOOD_ALTAR) > DISTANCE_TO_ALTAR )
{
PlayerHelper.webWalkTo(WORLDPOINT_BLOOD_ALTAR);
}
else
{
// we should be close enough here
currentStage = GameStage.CRAFTING;
}
}
function HandleBloodAltar() {
if( Game.info.inventory.hasItem(ITEM_ID_FRAGMENTS, 1) )
{
isExecuting = true;
var delay = Utility.getDelay();
Utility.invokeLater(function () {
Game.interact.gameObject.nearest( MenuAction.GAME_OBJECT_FIRST_OPTION, [GAME_OBJECT_BLOOD_ALTAR] );
}, delay);
// Give it time for animation to play, etc
delay += 1200;
Utility.invokeLater(function () {
isExecuting = false;
}, delay);
}
else
{
currentStage = GameStage.RETURNING;
}
}
function HandleReturn() {
/// Let the player walk there
if( PlayerHelper.isWebWalking() ) { return; }
// Walk to the altar
var pos = Client.getLocalPlayer().getWorldLocation();
if( pos.distanceTo(WORLDPOINT_MINE) > DISTANCE_TO_ALTAR )
{
PlayerHelper.webWalkTo(WORLDPOINT_MINE);
}
else
{
// we should be close enough here
currentStage = GameStage.MINING;
}
}
// The utilities file is suppose to act as an extension to your main file as to not cause too much bloat
// We recommend defining functions designed for resuability within this file. An example has been provided below..
const GameStage = Object.freeze({
STARTUP: 'Startup',
MINING: 'Mining',
WALK_TO_DARK_ALTAR: 'Walking to dark altar',
DARK_ALTAR: 'Dark altar',
CRAFTING: 'Crafting',
WALK_TO_BLOOD_ALTAR: 'Walking to blood altar',
BLOOD_ALTAR: 'Blood altar',
RETURNING: 'Returning'
});
const ITEM_ID_PICKAXE_IDS = [
1265, // Bronze pickaxe
1267, // Iron pickaxe
1269, // Steel pickaxe
1271, // Mithril pickaxe
1273, // Adamant pickaxe
1275, // Rune pickaxe
11920, // Dragon pickaxe
23677, // Dragon pickaxe (or)
20014, // 3rd age pickaxe
13243, // Infernal pickaxe
25063, // Infernal pickaxe (or)
23680, // Crystal pickaxe
];
const WORLDPOINT_DARK_ALTAR = new WorldPoint(1718, 3882, 0);
const WORLDPOINT_BLOOD_ALTAR = new WorldPoint(1719, 3828, 0);
const WORLDPOINT_MINE = new WorldPoint(1762, 3855, 0);
const DISTANCE_TO_ALTAR = 10;
const ITEM_ID_CHISEL = 1755;
const ITEM_ID_DENSE_BLOCK = 13445;
const ITEM_ID_DARK_BLOCK = 13446;
const ITEM_ID_FRAGMENTS = 7938;
const GAME_OBJECT_DENSE_ESS_ID = 8981;
const GAME_OBJECT_DARK_ALTAR = 27979;
const GAME_OBJECT_BLOOD_ALTAR = 27978;
const MINING_REGION_ID = 6972;
const VARBIT_DENSE_RUNESTONE_NORTH_DEPLETED = 4927;
const VARBIT_DENSE_RUNESTONE_SOUTH_DEPLETED = 4928;
// Below, you define config items as children of the config object. They have multiple overrides depending on the data type you want to use.
// You define the data type by providing the default value. Supported data types are strings (text), integers (numbers), booleans (tickbox), and lists (dropdown)
// Your config items are updated automatically when changed through the DeadZone Community Package Manager in-game
// Simply define config items below and you can use them anywhere in your package!
/**
* An object which defines list items we can use for one of our config item types
*/
const ListEnum = {
ItemOne: "Item One",
ItemTwo: "Item Two",
ItemThree: "Item Three",
};
/**
* Holds references to all our config items. It is required to have the below config object or your package will not work in-game!
* In addition, don't modify the config object at runtime scuh as adding / removing items. Config items must be defined below and modifying the object at runtime will not be reflected in-game!
*/
const config = {
// You can set the object property to anything you'd like. You'll use it to access your config item to grab / modify its value
testBoolean: ConfigItem.createBoolean("testBoolean", "My Section", "Test Checkbox", "Hover over me to see this description", true),
testString: ConfigItem.createString("testString", "My Section", "Test Input", "Hover over me to see this description", "Default string"),
testInteger: ConfigItem.createInteger("testInteger", "My Section", "Test Number", "Hover over me to see this description", 60),
// You can even define a range for an integer if you'd like apply a constraint to the value (example below shows a range between 0 and 10 inclusive)
testIntegerRange: ConfigItem.createIntegerRange("testIntegerRange", "Second Section", "Test Number Range", "Hover over me to see this description", 0, 10, 2),
// When defining lists, make sure to include an array of strings to appear in the dropdown. We created an enum above which we converted its values to an array below
testList: ConfigItem.createList("testList", "Second Section", "Test Dropdown", "Hover over me to see this description", Object.values(ListEnum), ListEnum.ItemOne),
};
const overlay = {
gameState: OverlayItem.create2d("gameState", "Status", true, 0)
};
/**
* Returns the config item's value which is referenced above by the property "testBoolean"
* @returns {boolean}
*/
function GetBooleanValue() {
// Grab the value of the config item and return it. The value of the config item is updated automatically when any changes occur
return config.testBoolean.getValue();
}
/**
* You can also set the value of a config item which will be reflected in the package config
* @param {boolean} value
*/
function SetBooleanValue(value) {
config.testBoolean.setValue(value);
}