Skip to content

Commit

Permalink
commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gc committed Feb 29, 2024
1 parent 9006633 commit bc844dd
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 94 deletions.
12 changes: 12 additions & 0 deletions src/lib/customItems/customItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11521,3 +11521,15 @@ setCustomItem(
},
1
);

setCustomItem(
73_105,
'Moondash charm',
'Coal',
{
customItemData: {
cantDropFromMysteryBoxes: true
}
},
1
);
111 changes: 59 additions & 52 deletions src/lib/minions/data/killableMonsters/custom/SunMoon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,58 +78,65 @@ export const Solis: CustomMonster = {
setupsUsed: ['melee']
};

// export const Celestara: CustomMonster = {
// id: 129_126,
// baseMonster: Monsters.AbyssalSire,
// name: 'Celestara',
// aliases: ['celestara'],
// timeToFinish: Time.Minute * 100,
// hp: 3330,
// table: new LootTable().every('Lunite', [10, 60]).tertiary(300, 'Noom'),
// difficultyRating: 5,
// qpRequired: 260,
// healAmountNeeded: 250 * 200,
// attackStyleToUse: GearStat.AttackStab,
// attackStylesUsed: [GearStat.AttackStab],
// levelRequirements: {
// hitpoints: 110,
// attack: 110,
// strength: 110,
// defence: 110,
// magic: 110,
// ranged: 110,
// slayer: 110
// },
// pohBoosts: {
// pool: {
// 'Ancient rejuvenation pool': 5
// }
// },
// deathProps: {
// hardness: 0.8,
// steepness: 0.999,
// lowestDeathChance: 5,
// highestDeathChance: 70
// },
// minimumFoodHealAmount: 22,
// allItems: resolveItems(['Solite', 'Eagle egg', 'Sun-metal scraps']),
// minimumGearRequirements: {
// melee: {
// ...solisMinGear.stats,
// ranged_strength: 0,
// attack_ranged: 0
// }
// },
// minimumWeaponShieldStats: {
// melee: addStatsOfItemsTogether(resolveItems(['Offhand dragon claw', 'Drygore rapier']), [GearStat.AttackStab])
// },
// itemCost: {
// itemCost: new Bank().add('Super combat potion(4)').add('Heat res. brew', 3).add('Heat res. restore'),
// qtyPerKill: 1
// },
// tameCantKill: true,
// itemsRequired: resolveItems(["Combatant's cape"])
// };
export const Celestara: CustomMonster = {
id: 129_125,
baseMonster: Monsters.AbyssalSire,
name: 'Celestara',
aliases: ['celestara'],
timeToFinish: Time.Minute * 120,
hp: 3330,
table: new LootTable().every('Lunite', [10, 60]).tertiary(300, 'Noom'),
difficultyRating: 5,
qpRequired: 2500,
healAmountNeeded: 350 * 200,
attackStyleToUse: GearStat.AttackStab,
attackStylesUsed: [GearStat.AttackStab],
levelRequirements: {
hitpoints: 120,
attack: 110,
strength: 110,
defence: 110,
magic: 110,
ranged: 110,
slayer: 110
},
pohBoosts: {
pool: {
'Ancient rejuvenation pool': 5
}
},
deathProps: {
hardness: 0.8,
steepness: 0.999,
lowestDeathChance: 10,
highestDeathChance: 80
},
minimumFoodHealAmount: 22,
allItems: resolveItems(['Solite', 'Eagle egg', 'Sun-metal scraps']),
minimumGearRequirements: {
melee: {
...solisMinGear.stats,
ranged_strength: 0,
attack_ranged: 0
}
},
minimumWeaponShieldStats: {
melee: addStatsOfItemsTogether(resolveItems(['Offhand dragon claw', 'Drygore rapier']), [GearStat.AttackStab])
},
itemCost: {
itemCost: new Bank().add('Super combat potion(4)').add('Heat res. brew', 3).add('Heat res. restore'),
qtyPerKill: 1
},
tameCantKill: true,
itemsRequired: resolveItems(["Combatant's cape"]),
customRequirement: async user => {
const tames = await user.fetchTames();
const hasMaxedIgne = tames.some(tame => tame.isMaxedIgneTame());
if (hasMaxedIgne) return null;
return 'You need to have a maxed Igne Tame (best gear, all fed items) to fight Solis.';
},
setupsUsed: ['melee']
};

export const SunMoonMonsters = {
Solis
Expand Down
16 changes: 10 additions & 6 deletions src/lib/premiumPatronTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,27 @@ export async function premiumPatronTime(
timeMs: number,
tier: number,
userToGive: MUser,
interaction: ChatInputCommandInteraction
interaction: ChatInputCommandInteraction | null
) {
if (![1, 2, 3, 4, 5, 6].includes(tier)) return 'Invalid input.';
if (timeMs < Time.Second || timeMs > Time.Year * 3) return 'Invalid input.';

const currentBalanceTier = userToGive.user.premium_balance_tier;

if (currentBalanceTier !== null && currentBalanceTier !== tier) {
if (interaction && currentBalanceTier !== null && currentBalanceTier !== tier) {
await handleMahojiConfirmation(
interaction,
`They already have Tier ${currentBalanceTier}; this will replace the existing balance entirely, are you sure?`
);
}
await handleMahojiConfirmation(
interaction,
`Are you sure you want to add ${formatDuration(timeMs)} of Tier ${tier} patron to ${userToGive}?`
);

if (interaction) {
await handleMahojiConfirmation(
interaction,
`Are you sure you want to add ${formatDuration(timeMs)} of Tier ${tier} patron to ${userToGive}?`
);
}

await userToGive.update({
premium_balance_tier: tier
});
Expand Down
2 changes: 1 addition & 1 deletion src/lib/tames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const tameFeedableItems: FeedableItem[] = [
{
item: getOSItem('Impling locator'),
description: 'Allows your tame to passively catch implings',
tameSpeciesCanBeFedThis: [TameSpeciesID.Eagle],
tameSpeciesCanBeFedThis: [TameSpeciesID.Eagle, TameSpeciesID.Igne],
announcementString: 'Your tame now has the ability to find and catch implings.'
}
];
Expand Down
10 changes: 8 additions & 2 deletions src/mahoji/commands/divination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,13 @@ You have ${portentCharges[portent.id]} charges left, and you receive ${

let hasWispBuster = false;
let hasDivineHand = false;
if (user.hasEquipped('Wisp-buster')) {

const shouldAttemptToUseDivineHand =
user.hasEquipped('Divine hand') ||
(user.bank.has('Divine hand') && method.id === MemoryHarvestType.ConvertToEnergy);
const shouldAttemptToUseWispBuster = user.hasEquipped('Wisp-buster') || !shouldAttemptToUseDivineHand;

if (shouldAttemptToUseWispBuster) {
const boostResult = await inventionItemBoost({
user,
inventionID: InventionID.WispBuster,
Expand All @@ -279,7 +285,7 @@ You have ${portentCharges[portent.id]} charges left, and you receive ${
);
hasWispBuster = true;
}
} else if (user.hasEquipped('Divine hand')) {
} else if (shouldAttemptToUseDivineHand) {
const boostResult = await inventionItemBoost({
user,
inventionID: InventionID.DivineHand,
Expand Down
85 changes: 85 additions & 0 deletions src/mahoji/commands/testershop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Time } from 'e';
import { ApplicationCommandOptionType, CommandRunOptions } from 'mahoji';
import { Bank } from 'oldschooljs';

import { premiumPatronTime } from '../../lib/premiumPatronTime';
import { roboChimpUserFetch } from '../../lib/roboChimp';
import { OSBMahojiCommand } from '../lib/util';

const shop = [
{
name: 'Tester gift box',
cost: 30
},
{
name: '1 Month T3',
cost: 300
},
{
name: 'Double loot token',
cost: 80
}
] as const;

export const testerShopCommand: OSBMahojiCommand = {
name: 'testershop',
description: 'Buy things using your testing points.',
options: [
{
type: ApplicationCommandOptionType.String,
name: 'name',
description: 'The item to buy.',
required: true,
choices: shop.map(i => ({
name: `${i.name} (${i.cost} points)`,
value: i.name
}))
},
{
type: ApplicationCommandOptionType.Integer,
name: 'quantity',
description: 'The quantity (defaults to 1).',
required: false,
min_value: 1
}
],
run: async ({ options, userID }: CommandRunOptions<{ name: string; quantity?: number }>) => {
const user = await mUserFetch(userID);
const robochimpUser = await roboChimpUserFetch(userID);
const item = shop.find(i => i.name === options.name);
if (!item) return 'Invalid item.';
const quantity = options.quantity ?? 1;
const cost = item.cost * quantity;
if (robochimpUser.testing_points_balance < cost) {
return `You don't have enough points to buy ${quantity}x ${item.name}.`;
}
await roboChimpClient.user.update({
data: {
testing_points_balance: {
decrement: cost
}
},
where: {
id: BigInt(userID)
}
});

debugLog(`Tester shop: ${user.id} bought ${quantity}x ${item.name} for ${cost} points.`);
switch (item.name) {
case 'Tester gift box': {
const loot = new Bank().add('Tester gift box', quantity);
await user.addItemsToBank({ items: loot, collectionLog: true });
return `You bought ${loot}!`;
}
case '1 Month T3': {
const res = await premiumPatronTime(Time.Day * 31, 3, user, null);
return res;
}
case 'Double loot token': {
const loot = new Bank().add('Double loot token', quantity);
await user.addItemsToBank({ items: loot, collectionLog: true });
return `You bought ${loot}!`;
}
}
}
};
75 changes: 42 additions & 33 deletions src/tasks/tames/tameTasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,37 @@ function doubleLootCheck(tame: Tame, loot: Bank) {
return { loot, doubleLootMsg };
}

async function handleImplingLocator(user: MUser, tame: MTame, duration: number, loot: Bank, messages: string[]) {
if (tame.hasBeenFed('Impling locator')) {
const result = await handlePassiveImplings(user, {
type: 'MonsterKilling',
duration
} as ActivityTaskData);
if (result && result.bank.length > 0) {
const actualImplingLoot = new Bank();
for (const [item, qty] of result.bank.items()) {
const openable = allOpenables.find(i => i.id === item.id)!;
assert(!isEmpty(openable));
actualImplingLoot.add(
isFunction(openable.output)
? (
await openable.output({
user,
quantity: qty,
self: openable,
totalLeaguesPoints: 0
})
).bank
: openable.output.roll(qty)
);
}
loot.add(actualImplingLoot);
messages.push(`${tame} caught ${result.bank} with their Impling locator!`);
await tame.addToStatsBank('implings_loot', actualImplingLoot);
}
}
}

export async function runTameTask(activity: TameActivity, tame: Tame) {
async function handleFinish(res: { loot: Bank | null; message: string; user: MUser }) {
const previousTameCl = new Bank({ ...(tame.max_total_loot as ItemBank) });
Expand Down Expand Up @@ -184,18 +215,23 @@ export async function runTameTask(activity: TameActivity, tame: Tame) {
}
}
const loot = mon.loot({ quantity: killQty, tame });
const messages: string[] = [];

let str = `${user}, ${tameName(tame)} finished killing ${quantity}x ${mon.name}.${
activity.deaths > 0 ? ` ${tameName(tame)} died ${activity.deaths}x times.` : ''
}`;
const boosts = [];
if (oriIsApplying) {
boosts.push('25% extra loot (ate an Ori)');
messages.push('25% extra loot (ate an Ori)');
}
if (boosts.length > 0) {
str += `\n\n**Boosts:** ${boosts.join(', ')}.`;
if (messages.length > 0) {
str += `\n\n**Messages:** ${messages.join(', ')}.`;
}
const { doubleLootMsg } = doubleLootCheck(tame, loot);
str += doubleLootMsg;

const mTame = new MTame(tame);
await handleImplingLocator(user, mTame, activity.duration, loot, messages);

const { itemsAdded } = await user.addItemsToBank({ items: loot, collectionLog: false });
await trackLoot({
duration: activity.duration,
Expand Down Expand Up @@ -263,6 +299,8 @@ export async function runTameTask(activity: TameActivity, tame: Tame) {
const messages: string[] = [];
const loot = new Bank();

await handleImplingLocator(user, mTame, activity.duration, loot, messages);

let actualOpenQuantityWithBonus = 0;
for (let i = 0; i < activityData.quantity; i++) {
actualOpenQuantityWithBonus += randInt(1, 3);
Expand Down Expand Up @@ -311,35 +349,6 @@ export async function runTameTask(activity: TameActivity, tame: Tame) {
loot.add(openingLoot);
}

if (mTame.hasBeenFed('Impling locator')) {
const result = await handlePassiveImplings(user, {
type: 'MonsterKilling',
duration: activity.duration
} as ActivityTaskData);
if (result && result.bank.length > 0) {
const actualImplingLoot = new Bank();
for (const [item, qty] of result.bank.items()) {
const openable = allOpenables.find(i => i.id === item.id)!;
assert(!isEmpty(openable));
actualImplingLoot.add(
isFunction(openable.output)
? (
await openable.output({
user,
quantity: qty,
self: openable,
totalLeaguesPoints: 0
})
).bank
: openable.output.roll(qty)
);
}
loot.add(actualImplingLoot);
messages.push(`${mTame} caught ${result.bank} with their Impling locator!`);
await mTame.addToStatsBank('implings_loot', actualImplingLoot);
}
}

let str = `${user}, ${mTame} finished completing ${activityData.quantity}x ${itemNameFromID(
clueTier.scrollID
)}. (${Math.floor(calcPerHour(activityData.quantity, activity.duration)).toFixed(1)} clues/hr)`;
Expand Down

0 comments on commit bc844dd

Please sign in to comment.